aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/HD-Audio-Controls.txt100
-rw-r--r--sound/pci/hda/Kconfig39
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/alc260_quirks.c1272
-rw-r--r--sound/pci/hda/alc262_quirks.c1353
-rw-r--r--sound/pci/hda/alc268_quirks.c636
-rw-r--r--sound/pci/hda/alc269_quirks.c681
-rw-r--r--sound/pci/hda/alc662_quirks.c1408
-rw-r--r--sound/pci/hda/alc680_quirks.c222
-rw-r--r--sound/pci/hda/alc861_quirks.c725
-rw-r--r--sound/pci/hda/alc861vd_quirks.c605
-rw-r--r--sound/pci/hda/alc880_quirks.c1898
-rw-r--r--sound/pci/hda/alc882_quirks.c3755
-rw-r--r--sound/pci/hda/alc_quirks.c467
-rw-r--r--sound/pci/hda/hda_codec.c353
-rw-r--r--sound/pci/hda/hda_codec.h30
-rw-r--r--sound/pci/hda/hda_eld.c46
-rw-r--r--sound/pci/hda/hda_intel.c76
-rw-r--r--sound/pci/hda/hda_local.h10
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c7
-rw-r--r--sound/pci/hda/patch_ca0110.c3
-rw-r--r--sound/pci/hda/patch_ca0132.c1097
-rw-r--r--sound/pci/hda/patch_cirrus.c19
-rw-r--r--sound/pci/hda/patch_cmedia.c17
-rw-r--r--sound/pci/hda/patch_conexant.c71
-rw-r--r--sound/pci/hda/patch_hdmi.c704
-rw-r--r--sound/pci/hda/patch_realtek.c18190
-rw-r--r--sound/pci/hda/patch_sigmatel.c31
-rw-r--r--sound/pci/hda/patch_via.c6095
30 files changed, 18696 insertions, 21220 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Controls.txt b/Documentation/sound/alsa/HD-Audio-Controls.txt
new file mode 100644
index 000000000000..1482035243e6
--- /dev/null
+++ b/Documentation/sound/alsa/HD-Audio-Controls.txt
@@ -0,0 +1,100 @@
1This file explains the codec-specific mixer controls.
2
3Realtek codecs
4--------------
5
6* Channel Mode
7 This is an enum control to change the surround-channel setup,
8 appears only when the surround channels are available.
9 It gives the number of channels to be used, "2ch", "4ch", "6ch",
10 and "8ch". According to the configuration, this also controls the
11 jack-retasking of multi-I/O jacks.
12
13* Auto-Mute Mode
14 This is an enum control to change the auto-mute behavior of the
15 headphone and line-out jacks. If built-in speakers and headphone
16 and/or line-out jacks are available on a machine, this controls
17 appears.
18 When there are only either headphones or line-out jacks, it gives
19 "Disabled" and "Enabled" state. When enabled, the speaker is muted
20 automatically when a jack is plugged.
21
22 When both headphone and line-out jacks are present, it gives
23 "Disabled", "Speaker Only" and "Line-Out+Speaker". When
24 speaker-only is chosen, plugging into a headphone or a line-out jack
25 mutes the speakers, but not line-outs. When line-out+speaker is
26 selected, plugging to a headphone jack mutes both speakers and
27 line-outs.
28
29
30IDT/Sigmatel codecs
31-------------------
32
33* Analog Loopback
34 This control enables/disables the analog-loopback circuit. This
35 appears only when "loopback" is set to true in a codec hint
36 (see HD-Audio.txt). Note that on some codecs the analog-loopback
37 and the normal PCM playback are exclusive, i.e. when this is on, you
38 won't hear any PCM stream.
39
40* Swap Center/LFE
41 Swaps the center and LFE channel order. Normally, the left
42 corresponds to the center and the right to the LFE. When this is
43 ON, the left to the LFE and the right to the center.
44
45* Headphone as Line Out
46 When this control is ON, treat the headphone jacks as line-out
47 jacks. That is, the headphone won't auto-mute the other line-outs,
48 and no HP-amp is set to the pins.
49
50* Mic Jack Mode, Line Jack Mode, etc
51 These enum controls the direction and the bias of the input jack
52 pins. Depending on the jack type, it can set as "Mic In" and "Line
53 In", for determining the input bias, or it can be set to "Line Out"
54 when the pin is a multi-I/O jack for surround channels.
55
56
57VIA codecs
58----------
59
60* Smart 5.1
61 An enum control to re-task the multi-I/O jacks for surround outputs.
62 When it's ON, the corresponding input jacks (usually a line-in and a
63 mic-in) are switched as the surround and the CLFE output jacks.
64
65* Independent HP
66 When this enum control is enabled, the headphone output is routed
67 from an individual stream (the third PCM such as hw:0,2) instead of
68 the primary stream. In the case the headphone DAC is shared with a
69 side or a CLFE-channel DAC, the DAC is switched to the headphone
70 automatically.
71
72* Loopback Mixing
73 An enum control to determine whether the analog-loopback route is
74 enabled or not. When it's enabled, the analog-loopback is mixed to
75 the front-channel. Also, the same route is used for the headphone
76 and speaker outputs. As a side-effect, when this mode is set, the
77 individual volume controls will be no longer available for
78 headphones and speakers because there is only one DAC connected to a
79 mixer widget.
80
81* Dynamic Power-Control
82 This control determines whether the dynamic power-control per jack
83 detection is enabled or not. When enabled, the widgets power state
84 (D0/D3) are changed dynamically depending on the jack plugging
85 state for saving power consumptions. However, if your system
86 doesn't provide a proper jack-detection, this won't work; in such a
87 case, turn this control OFF.
88
89* Jack Detect
90 This control is provided only for VT1708 codec which gives no proper
91 unsolicited event per jack plug. When this is on, the driver polls
92 the jack detection so that the headphone auto-mute can work, while
93 turning this off would reduce the power consumption.
94
95
96Conexant codecs
97---------------
98
99* Auto-Mute Mode
100 See Reatek codecs.
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 0ea5cc60ac78..7489b4608551 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -14,6 +14,19 @@ menuconfig SND_HDA_INTEL
14 14
15if SND_HDA_INTEL 15if SND_HDA_INTEL
16 16
17config SND_HDA_PREALLOC_SIZE
18 int "Pre-allocated buffer size for HD-audio driver"
19 range 0 32768
20 default 64
21 help
22 Specifies the default pre-allocated buffer-size in kB for the
23 HD-audio driver. A larger buffer (e.g. 2048) is preferred
24 for systems using PulseAudio. The default 64 is chosen just
25 for compatibility reasons.
26
27 Note that the pre-allocation size can be changed dynamically
28 via a proc file (/proc/asound/card*/pcm*/sub*/prealloc), too.
29
17config SND_HDA_HWDEP 30config SND_HDA_HWDEP
18 bool "Build hwdep interface for HD-audio driver" 31 bool "Build hwdep interface for HD-audio driver"
19 select SND_HWDEP 32 select SND_HWDEP
@@ -83,6 +96,19 @@ config SND_HDA_CODEC_REALTEK
83 snd-hda-codec-realtek. 96 snd-hda-codec-realtek.
84 This module is automatically loaded at probing. 97 This module is automatically loaded at probing.
85 98
99config SND_HDA_ENABLE_REALTEK_QUIRKS
100 bool "Build static quirks for Realtek codecs"
101 depends on SND_HDA_CODEC_REALTEK
102 default y
103 help
104 Say Y here to build the static quirks codes for Realtek codecs.
105 If you need the "model" preset that the default BIOS auto-parser
106 can't handle, turn this option on.
107
108 If your device works with model=auto option, basically you don't
109 need the quirk code. By turning this off, you can reduce the
110 module size quite a lot.
111
86config SND_HDA_CODEC_ANALOG 112config SND_HDA_CODEC_ANALOG
87 bool "Build Analog Device HD-audio codec support" 113 bool "Build Analog Device HD-audio codec support"
88 default y 114 default y
@@ -171,6 +197,19 @@ config SND_HDA_CODEC_CA0110
171 snd-hda-codec-ca0110. 197 snd-hda-codec-ca0110.
172 This module is automatically loaded at probing. 198 This module is automatically loaded at probing.
173 199
200config SND_HDA_CODEC_CA0132
201 bool "Build Creative CA0132 codec support"
202 depends on SND_HDA_INTEL
203 default y
204 help
205 Say Y here to include Creative CA0132 codec support in
206 snd-hda-intel driver.
207
208 When the HD-audio driver is built as a module, the codec
209 support code is also built as another module,
210 snd-hda-codec-ca0132.
211 This module is automatically loaded at probing.
212
174config SND_HDA_CODEC_CMEDIA 213config SND_HDA_CODEC_CMEDIA
175 bool "Build C-Media HD-audio codec support" 214 bool "Build C-Media HD-audio codec support"
176 default y 215 default y
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 17ef3658f34b..87365d5ea2a9 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -13,6 +13,7 @@ snd-hda-codec-idt-objs := patch_sigmatel.o
13snd-hda-codec-si3054-objs := patch_si3054.o 13snd-hda-codec-si3054-objs := patch_si3054.o
14snd-hda-codec-cirrus-objs := patch_cirrus.o 14snd-hda-codec-cirrus-objs := patch_cirrus.o
15snd-hda-codec-ca0110-objs := patch_ca0110.o 15snd-hda-codec-ca0110-objs := patch_ca0110.o
16snd-hda-codec-ca0132-objs := patch_ca0132.o
16snd-hda-codec-conexant-objs := patch_conexant.o 17snd-hda-codec-conexant-objs := patch_conexant.o
17snd-hda-codec-via-objs := patch_via.o 18snd-hda-codec-via-objs := patch_via.o
18snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o 19snd-hda-codec-hdmi-objs := patch_hdmi.o hda_eld.o
@@ -42,6 +43,9 @@ endif
42ifdef CONFIG_SND_HDA_CODEC_CA0110 43ifdef CONFIG_SND_HDA_CODEC_CA0110
43obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o 44obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
44endif 45endif
46ifdef CONFIG_SND_HDA_CODEC_CA0132
47obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0132.o
48endif
45ifdef CONFIG_SND_HDA_CODEC_CONEXANT 49ifdef CONFIG_SND_HDA_CODEC_CONEXANT
46obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o 50obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
47endif 51endif
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c
new file mode 100644
index 000000000000..21ec2cb100b0
--- /dev/null
+++ b/sound/pci/hda/alc260_quirks.c
@@ -0,0 +1,1272 @@
1/*
2 * ALC260 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC260 models */
7enum {
8 ALC260_AUTO,
9 ALC260_BASIC,
10 ALC260_HP,
11 ALC260_HP_DC7600,
12 ALC260_HP_3013,
13 ALC260_FUJITSU_S702X,
14 ALC260_ACER,
15 ALC260_WILL,
16 ALC260_REPLACER_672V,
17 ALC260_FAVORIT100,
18#ifdef CONFIG_SND_DEBUG
19 ALC260_TEST,
20#endif
21 ALC260_MODEL_LAST /* last tag */
22};
23
24static const hda_nid_t alc260_dac_nids[1] = {
25 /* front */
26 0x02,
27};
28
29static const hda_nid_t alc260_adc_nids[1] = {
30 /* ADC0 */
31 0x04,
32};
33
34static const hda_nid_t alc260_adc_nids_alt[1] = {
35 /* ADC1 */
36 0x05,
37};
38
39/* NIDs used when simultaneous access to both ADCs makes sense. Note that
40 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
41 */
42static const hda_nid_t alc260_dual_adc_nids[2] = {
43 /* ADC0, ADC1 */
44 0x04, 0x05
45};
46
47#define ALC260_DIGOUT_NID 0x03
48#define ALC260_DIGIN_NID 0x06
49
50static const struct hda_input_mux alc260_capture_source = {
51 .num_items = 4,
52 .items = {
53 { "Mic", 0x0 },
54 { "Front Mic", 0x1 },
55 { "Line", 0x2 },
56 { "CD", 0x4 },
57 },
58};
59
60/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
61 * headphone jack and the internal CD lines since these are the only pins at
62 * which audio can appear. For flexibility, also allow the option of
63 * recording the mixer output on the second ADC (ADC0 doesn't have a
64 * connection to the mixer output).
65 */
66static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
67 {
68 .num_items = 3,
69 .items = {
70 { "Mic/Line", 0x0 },
71 { "CD", 0x4 },
72 { "Headphone", 0x2 },
73 },
74 },
75 {
76 .num_items = 4,
77 .items = {
78 { "Mic/Line", 0x0 },
79 { "CD", 0x4 },
80 { "Headphone", 0x2 },
81 { "Mixer", 0x5 },
82 },
83 },
84
85};
86
87/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
88 * the Fujitsu S702x, but jacks are marked differently.
89 */
90static const struct hda_input_mux alc260_acer_capture_sources[2] = {
91 {
92 .num_items = 4,
93 .items = {
94 { "Mic", 0x0 },
95 { "Line", 0x2 },
96 { "CD", 0x4 },
97 { "Headphone", 0x5 },
98 },
99 },
100 {
101 .num_items = 5,
102 .items = {
103 { "Mic", 0x0 },
104 { "Line", 0x2 },
105 { "CD", 0x4 },
106 { "Headphone", 0x6 },
107 { "Mixer", 0x5 },
108 },
109 },
110};
111
112/* Maxdata Favorit 100XS */
113static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
114 {
115 .num_items = 2,
116 .items = {
117 { "Line/Mic", 0x0 },
118 { "CD", 0x4 },
119 },
120 },
121 {
122 .num_items = 3,
123 .items = {
124 { "Line/Mic", 0x0 },
125 { "CD", 0x4 },
126 { "Mixer", 0x5 },
127 },
128 },
129};
130
131/*
132 * This is just place-holder, so there's something for alc_build_pcms to look
133 * at when it calculates the maximum number of channels. ALC260 has no mixer
134 * element which allows changing the channel mode, so the verb list is
135 * never used.
136 */
137static const struct hda_channel_mode alc260_modes[1] = {
138 { 2, NULL },
139};
140
141
142/* Mixer combinations
143 *
144 * basic: base_output + input + pc_beep + capture
145 * HP: base_output + input + capture_alt
146 * HP_3013: hp_3013 + input + capture
147 * fujitsu: fujitsu + capture
148 * acer: acer + capture
149 */
150
151static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
152 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
153 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
154 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
155 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
156 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
157 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
158 { } /* end */
159};
160
161static const struct snd_kcontrol_new alc260_input_mixer[] = {
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
168 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
170 { } /* end */
171};
172
173/* update HP, line and mono out pins according to the master switch */
174static void alc260_hp_master_update(struct hda_codec *codec)
175{
176 update_speakers(codec);
177}
178
179static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
183 struct alc_spec *spec = codec->spec;
184 *ucontrol->value.integer.value = !spec->master_mute;
185 return 0;
186}
187
188static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
189 struct snd_ctl_elem_value *ucontrol)
190{
191 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
192 struct alc_spec *spec = codec->spec;
193 int val = !*ucontrol->value.integer.value;
194
195 if (val == spec->master_mute)
196 return 0;
197 spec->master_mute = val;
198 alc260_hp_master_update(codec);
199 return 1;
200}
201
202static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
203 {
204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
205 .name = "Master Playback Switch",
206 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
207 .info = snd_ctl_boolean_mono_info,
208 .get = alc260_hp_master_sw_get,
209 .put = alc260_hp_master_sw_put,
210 },
211 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
214 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
215 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
216 HDA_OUTPUT),
217 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
218 { } /* end */
219};
220
221static const struct hda_verb alc260_hp_unsol_verbs[] = {
222 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
223 {},
224};
225
226static void alc260_hp_setup(struct hda_codec *codec)
227{
228 struct alc_spec *spec = codec->spec;
229
230 spec->autocfg.hp_pins[0] = 0x0f;
231 spec->autocfg.speaker_pins[0] = 0x10;
232 spec->autocfg.speaker_pins[1] = 0x11;
233 spec->automute = 1;
234 spec->automute_mode = ALC_AUTOMUTE_PIN;
235}
236
237static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
238 {
239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
240 .name = "Master Playback Switch",
241 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
242 .info = snd_ctl_boolean_mono_info,
243 .get = alc260_hp_master_sw_get,
244 .put = alc260_hp_master_sw_put,
245 },
246 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
247 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
248 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
249 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
250 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
252 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
253 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
254 { } /* end */
255};
256
257static void alc260_hp_3013_setup(struct hda_codec *codec)
258{
259 struct alc_spec *spec = codec->spec;
260
261 spec->autocfg.hp_pins[0] = 0x15;
262 spec->autocfg.speaker_pins[0] = 0x10;
263 spec->autocfg.speaker_pins[1] = 0x11;
264 spec->automute = 1;
265 spec->automute_mode = ALC_AUTOMUTE_PIN;
266}
267
268static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
269 .ops = &snd_hda_bind_vol,
270 .values = {
271 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
272 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
273 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
274 0
275 },
276};
277
278static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
279 .ops = &snd_hda_bind_sw,
280 .values = {
281 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
282 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
283 0
284 },
285};
286
287static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
288 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
289 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
290 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
291 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
292 { } /* end */
293};
294
295static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
297 {},
298};
299
300static void alc260_hp_3012_setup(struct hda_codec *codec)
301{
302 struct alc_spec *spec = codec->spec;
303
304 spec->autocfg.hp_pins[0] = 0x10;
305 spec->autocfg.speaker_pins[0] = 0x0f;
306 spec->autocfg.speaker_pins[1] = 0x11;
307 spec->autocfg.speaker_pins[2] = 0x15;
308 spec->automute = 1;
309 spec->automute_mode = ALC_AUTOMUTE_PIN;
310}
311
312/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
313 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
314 */
315static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
316 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
317 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
318 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
319 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
320 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
321 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
322 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
323 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
324 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
325 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
326 { } /* end */
327};
328
329/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
330 * versions of the ALC260 don't act on requests to enable mic bias from NID
331 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
332 * datasheet doesn't mention this restriction. At this stage it's not clear
333 * whether this behaviour is intentional or is a hardware bug in chip
334 * revisions available in early 2006. Therefore for now allow the
335 * "Headphone Jack Mode" control to span all choices, but if it turns out
336 * that the lack of mic bias for this NID is intentional we could change the
337 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
338 *
339 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
340 * don't appear to make the mic bias available from the "line" jack, even
341 * though the NID used for this jack (0x14) can supply it. The theory is
342 * that perhaps Acer have included blocking capacitors between the ALC260
343 * and the output jack. If this turns out to be the case for all such
344 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
345 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
346 *
347 * The C20x Tablet series have a mono internal speaker which is controlled
348 * via the chip's Mono sum widget and pin complex, so include the necessary
349 * controls for such models. On models without a "mono speaker" the control
350 * won't do anything.
351 */
352static const struct snd_kcontrol_new alc260_acer_mixer[] = {
353 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
354 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
355 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
356 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
357 HDA_OUTPUT),
358 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
359 HDA_INPUT),
360 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
361 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
362 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
363 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
364 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
365 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
366 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
367 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
368 { } /* end */
369};
370
371/* Maxdata Favorit 100XS: one output and one input (0x12) jack
372 */
373static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
374 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
375 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
376 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
377 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
378 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
379 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
380 { } /* end */
381};
382
383/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
384 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
385 */
386static const struct snd_kcontrol_new alc260_will_mixer[] = {
387 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
388 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
389 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
390 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
391 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
392 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
393 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
394 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
395 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
396 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
397 { } /* end */
398};
399
400/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
401 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
402 */
403static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
404 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
405 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
406 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
408 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
409 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
410 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
411 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
412 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
413 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
414 { } /* end */
415};
416
417/*
418 * initialization verbs
419 */
420static const struct hda_verb alc260_init_verbs[] = {
421 /* Line In pin widget for input */
422 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
423 /* CD pin widget for input */
424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
425 /* Mic1 (rear panel) pin widget for input and vref at 80% */
426 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
427 /* Mic2 (front panel) pin widget for input and vref at 80% */
428 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
429 /* LINE-2 is used for line-out in rear */
430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
431 /* select line-out */
432 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
433 /* LINE-OUT pin */
434 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
435 /* enable HP */
436 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
437 /* enable Mono */
438 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
439 /* mute capture amp left and right */
440 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 /* set connection select to line in (default select for this ADC) */
442 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
443 /* mute capture amp left and right */
444 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 /* set connection select to line in (default select for this ADC) */
446 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
447 /* set vol=0 Line-Out mixer amp left and right */
448 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
449 /* unmute pin widget amp left and right (no gain on this amp) */
450 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
451 /* set vol=0 HP mixer amp left and right */
452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 /* unmute pin widget amp left and right (no gain on this amp) */
454 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
455 /* set vol=0 Mono mixer amp left and right */
456 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
457 /* unmute pin widget amp left and right (no gain on this amp) */
458 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
459 /* unmute LINE-2 out pin */
460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
461 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
462 * Line In 2 = 0x03
463 */
464 /* mute analog inputs */
465 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
466 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
467 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
468 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
469 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
470 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
471 /* mute Front out path */
472 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
473 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
474 /* mute Headphone out path */
475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
476 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
477 /* mute Mono out path */
478 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
479 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
480 { }
481};
482
483#if 0 /* should be identical with alc260_init_verbs? */
484static const struct hda_verb alc260_hp_init_verbs[] = {
485 /* Headphone and output */
486 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
487 /* mono output */
488 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
489 /* Mic1 (rear panel) pin widget for input and vref at 80% */
490 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
491 /* Mic2 (front panel) pin widget for input and vref at 80% */
492 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
493 /* Line In pin widget for input */
494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
495 /* Line-2 pin widget for output */
496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
497 /* CD pin widget for input */
498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
499 /* unmute amp left and right */
500 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
501 /* set connection select to line in (default select for this ADC) */
502 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
503 /* unmute Line-Out mixer amp left and right (volume = 0) */
504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
505 /* mute pin widget amp left and right (no gain on this amp) */
506 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
507 /* unmute HP mixer amp left and right (volume = 0) */
508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
509 /* mute pin widget amp left and right (no gain on this amp) */
510 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
511 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
512 * Line In 2 = 0x03
513 */
514 /* mute analog inputs */
515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
517 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
518 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
520 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
521 /* Unmute Front out path */
522 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
523 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
524 /* Unmute Headphone out path */
525 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
526 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
527 /* Unmute Mono out path */
528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
529 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
530 { }
531};
532#endif
533
534static const struct hda_verb alc260_hp_3013_init_verbs[] = {
535 /* Line out and output */
536 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
537 /* mono output */
538 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
539 /* Mic1 (rear panel) pin widget for input and vref at 80% */
540 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
541 /* Mic2 (front panel) pin widget for input and vref at 80% */
542 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
543 /* Line In pin widget for input */
544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
545 /* Headphone pin widget for output */
546 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
547 /* CD pin widget for input */
548 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
549 /* unmute amp left and right */
550 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
551 /* set connection select to line in (default select for this ADC) */
552 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
553 /* unmute Line-Out mixer amp left and right (volume = 0) */
554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
555 /* mute pin widget amp left and right (no gain on this amp) */
556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
557 /* unmute HP mixer amp left and right (volume = 0) */
558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
559 /* mute pin widget amp left and right (no gain on this amp) */
560 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
561 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
562 * Line In 2 = 0x03
563 */
564 /* mute analog inputs */
565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
570 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
571 /* Unmute Front out path */
572 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
573 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
574 /* Unmute Headphone out path */
575 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
577 /* Unmute Mono out path */
578 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
579 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
580 { }
581};
582
583/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
584 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
585 * audio = 0x16, internal speaker = 0x10.
586 */
587static const struct hda_verb alc260_fujitsu_init_verbs[] = {
588 /* Disable all GPIOs */
589 {0x01, AC_VERB_SET_GPIO_MASK, 0},
590 /* Internal speaker is connected to headphone pin */
591 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
592 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
593 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
594 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
595 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
596 /* Ensure all other unused pins are disabled and muted. */
597 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
598 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
599 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
600 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
601 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
602 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
605
606 /* Disable digital (SPDIF) pins */
607 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
608 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
609
610 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
611 * when acting as an output.
612 */
613 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
614
615 /* Start with output sum widgets muted and their output gains at min */
616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
618 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
622 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
623 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
624 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
625
626 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
627 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
628 /* Unmute Line1 pin widget output buffer since it starts as an output.
629 * If the pin mode is changed by the user the pin mode control will
630 * take care of enabling the pin's input/output buffers as needed.
631 * Therefore there's no need to enable the input buffer at this
632 * stage.
633 */
634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
635 /* Unmute input buffer of pin widget used for Line-in (no equiv
636 * mixer ctrl)
637 */
638 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
639
640 /* Mute capture amp left and right */
641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
642 /* Set ADC connection select to match default mixer setting - line
643 * in (on mic1 pin)
644 */
645 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
646
647 /* Do the same for the second ADC: mute capture input amp and
648 * set ADC connection to line in (on mic1 pin)
649 */
650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
651 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
652
653 /* Mute all inputs to mixer widget (even unconnected ones) */
654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
662
663 { }
664};
665
666/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
667 * similar laptops (adapted from Fujitsu init verbs).
668 */
669static const struct hda_verb alc260_acer_init_verbs[] = {
670 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
671 * the headphone jack. Turn this on and rely on the standard mute
672 * methods whenever the user wants to turn these outputs off.
673 */
674 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
675 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
676 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
677 /* Internal speaker/Headphone jack is connected to Line-out pin */
678 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 /* Internal microphone/Mic jack is connected to Mic1 pin */
680 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
681 /* Line In jack is connected to Line1 pin */
682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
683 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
684 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
685 /* Ensure all other unused pins are disabled and muted. */
686 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
687 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
688 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
689 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
690 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
691 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
692 /* Disable digital (SPDIF) pins */
693 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
694 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
695
696 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
697 * bus when acting as outputs.
698 */
699 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
700 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
701
702 /* Start with output sum widgets muted and their output gains at min */
703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
704 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
705 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
707 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
708 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
710 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
711 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
712
713 /* Unmute Line-out pin widget amp left and right
714 * (no equiv mixer ctrl)
715 */
716 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
717 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
718 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
719 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
720 * inputs. If the pin mode is changed by the user the pin mode control
721 * will take care of enabling the pin's input/output buffers as needed.
722 * Therefore there's no need to enable the input buffer at this
723 * stage.
724 */
725 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727
728 /* Mute capture amp left and right */
729 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
730 /* Set ADC connection select to match default mixer setting - mic
731 * (on mic1 pin)
732 */
733 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
734
735 /* Do similar with the second ADC: mute capture input amp and
736 * set ADC connection to mic to match ALSA's default state.
737 */
738 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
739 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
740
741 /* Mute all inputs to mixer widget (even unconnected ones) */
742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
745 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
746 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
747 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
748 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
749 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
750
751 { }
752};
753
754/* Initialisation sequence for Maxdata Favorit 100XS
755 * (adapted from Acer init verbs).
756 */
757static const struct hda_verb alc260_favorit100_init_verbs[] = {
758 /* GPIO 0 enables the output jack.
759 * Turn this on and rely on the standard mute
760 * methods whenever the user wants to turn these outputs off.
761 */
762 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
763 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
764 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
765 /* Line/Mic input jack is connected to Mic1 pin */
766 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
767 /* Ensure all other unused pins are disabled and muted. */
768 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
769 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
770 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
771 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
772 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
773 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
774 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
776 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
778 /* Disable digital (SPDIF) pins */
779 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
780 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
781
782 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
783 * bus when acting as outputs.
784 */
785 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
786 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
787
788 /* Start with output sum widgets muted and their output gains at min */
789 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
791 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
792 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
794 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
795 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
796 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
797 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
798
799 /* Unmute Line-out pin widget amp left and right
800 * (no equiv mixer ctrl)
801 */
802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
803 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
804 * inputs. If the pin mode is changed by the user the pin mode control
805 * will take care of enabling the pin's input/output buffers as needed.
806 * Therefore there's no need to enable the input buffer at this
807 * stage.
808 */
809 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
810
811 /* Mute capture amp left and right */
812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
813 /* Set ADC connection select to match default mixer setting - mic
814 * (on mic1 pin)
815 */
816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
817
818 /* Do similar with the second ADC: mute capture input amp and
819 * set ADC connection to mic to match ALSA's default state.
820 */
821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 /* Mute all inputs to mixer widget (even unconnected ones) */
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
833
834 { }
835};
836
837static const struct hda_verb alc260_will_verbs[] = {
838 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
839 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
840 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
841 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
842 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
843 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
844 {}
845};
846
847static const struct hda_verb alc260_replacer_672v_verbs[] = {
848 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
849 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
850 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
851
852 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
853 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
854 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
855
856 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
857 {}
858};
859
860/* toggle speaker-output according to the hp-jack state */
861static void alc260_replacer_672v_automute(struct hda_codec *codec)
862{
863 unsigned int present;
864
865 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
866 present = snd_hda_jack_detect(codec, 0x0f);
867 if (present) {
868 snd_hda_codec_write_cache(codec, 0x01, 0,
869 AC_VERB_SET_GPIO_DATA, 1);
870 snd_hda_codec_write_cache(codec, 0x0f, 0,
871 AC_VERB_SET_PIN_WIDGET_CONTROL,
872 PIN_HP);
873 } else {
874 snd_hda_codec_write_cache(codec, 0x01, 0,
875 AC_VERB_SET_GPIO_DATA, 0);
876 snd_hda_codec_write_cache(codec, 0x0f, 0,
877 AC_VERB_SET_PIN_WIDGET_CONTROL,
878 PIN_OUT);
879 }
880}
881
882static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
883 unsigned int res)
884{
885 if ((res >> 26) == ALC_HP_EVENT)
886 alc260_replacer_672v_automute(codec);
887}
888
889static const struct hda_verb alc260_hp_dc7600_verbs[] = {
890 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
891 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
892 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
893 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
894 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
896 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
898 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
899 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
900 {}
901};
902
903/* Test configuration for debugging, modelled after the ALC880 test
904 * configuration.
905 */
906#ifdef CONFIG_SND_DEBUG
907static const hda_nid_t alc260_test_dac_nids[1] = {
908 0x02,
909};
910static const hda_nid_t alc260_test_adc_nids[2] = {
911 0x04, 0x05,
912};
913/* For testing the ALC260, each input MUX needs its own definition since
914 * the signal assignments are different. This assumes that the first ADC
915 * is NID 0x04.
916 */
917static const struct hda_input_mux alc260_test_capture_sources[2] = {
918 {
919 .num_items = 7,
920 .items = {
921 { "MIC1 pin", 0x0 },
922 { "MIC2 pin", 0x1 },
923 { "LINE1 pin", 0x2 },
924 { "LINE2 pin", 0x3 },
925 { "CD pin", 0x4 },
926 { "LINE-OUT pin", 0x5 },
927 { "HP-OUT pin", 0x6 },
928 },
929 },
930 {
931 .num_items = 8,
932 .items = {
933 { "MIC1 pin", 0x0 },
934 { "MIC2 pin", 0x1 },
935 { "LINE1 pin", 0x2 },
936 { "LINE2 pin", 0x3 },
937 { "CD pin", 0x4 },
938 { "Mixer", 0x5 },
939 { "LINE-OUT pin", 0x6 },
940 { "HP-OUT pin", 0x7 },
941 },
942 },
943};
944static const struct snd_kcontrol_new alc260_test_mixer[] = {
945 /* Output driver widgets */
946 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
947 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
948 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
949 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
950 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
951 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
952
953 /* Modes for retasking pin widgets
954 * Note: the ALC260 doesn't seem to act on requests to enable mic
955 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
956 * mention this restriction. At this stage it's not clear whether
957 * this behaviour is intentional or is a hardware bug in chip
958 * revisions available at least up until early 2006. Therefore for
959 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
960 * choices, but if it turns out that the lack of mic bias for these
961 * NIDs is intentional we could change their modes from
962 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
963 */
964 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
965 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
966 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
967 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
968 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
969 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
970
971 /* Loopback mixer controls */
972 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
973 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
974 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
975 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
976 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
977 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
978 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
979 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
980 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
981 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
982 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
983 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
984 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
985 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
986
987 /* Controls for GPIO pins, assuming they are configured as outputs */
988 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
989 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
990 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
991 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
992
993 /* Switches to allow the digital IO pins to be enabled. The datasheet
994 * is ambigious as to which NID is which; testing on laptops which
995 * make this output available should provide clarification.
996 */
997 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
998 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
999
1000 /* A switch allowing EAPD to be enabled. Some laptops seem to use
1001 * this output to turn on an external amplifier.
1002 */
1003 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
1004 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
1005
1006 { } /* end */
1007};
1008static const struct hda_verb alc260_test_init_verbs[] = {
1009 /* Enable all GPIOs as outputs with an initial value of 0 */
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
1012 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
1013
1014 /* Enable retasking pins as output, initially without power amp */
1015 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1016 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1019 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1020 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1021
1022 /* Disable digital (SPDIF) pins initially, but users can enable
1023 * them via a mixer switch. In the case of SPDIF-out, this initverb
1024 * payload also sets the generation to 0, output to be in "consumer"
1025 * PCM format, copyright asserted, no pre-emphasis and no validity
1026 * control.
1027 */
1028 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
1029 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
1030
1031 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
1032 * OUT1 sum bus when acting as an output.
1033 */
1034 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
1035 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
1036 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
1037 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
1038
1039 /* Start with output sum widgets muted and their output gains at min */
1040 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1041 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1042 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1043 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1044 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1045 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1046 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1047 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1048 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1049
1050 /* Unmute retasking pin widget output buffers since the default
1051 * state appears to be output. As the pin mode is changed by the
1052 * user the pin mode control will take care of enabling the pin's
1053 * input/output buffers as needed.
1054 */
1055 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1056 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1057 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1059 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1060 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1061 /* Also unmute the mono-out pin widget */
1062 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1063
1064 /* Mute capture amp left and right */
1065 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1066 /* Set ADC connection select to match default mixer setting (mic1
1067 * pin)
1068 */
1069 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
1070
1071 /* Do the same for the second ADC: mute capture input amp and
1072 * set ADC connection to mic1 pin
1073 */
1074 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1075 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
1076
1077 /* Mute all inputs to mixer widget (even unconnected ones) */
1078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1079 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1080 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1081 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1082 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1083 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1084 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1085 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1086
1087 { }
1088};
1089#endif
1090
1091/*
1092 * ALC260 configurations
1093 */
1094static const char * const alc260_models[ALC260_MODEL_LAST] = {
1095 [ALC260_BASIC] = "basic",
1096 [ALC260_HP] = "hp",
1097 [ALC260_HP_3013] = "hp-3013",
1098 [ALC260_HP_DC7600] = "hp-dc7600",
1099 [ALC260_FUJITSU_S702X] = "fujitsu",
1100 [ALC260_ACER] = "acer",
1101 [ALC260_WILL] = "will",
1102 [ALC260_REPLACER_672V] = "replacer",
1103 [ALC260_FAVORIT100] = "favorit100",
1104#ifdef CONFIG_SND_DEBUG
1105 [ALC260_TEST] = "test",
1106#endif
1107 [ALC260_AUTO] = "auto",
1108};
1109
1110static const struct snd_pci_quirk alc260_cfg_tbl[] = {
1111 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
1112 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
1113 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
1114 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
1115 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
1116 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
1117 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
1118 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
1119 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
1120 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
1121 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
1122 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
1123 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
1124 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
1125 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
1126 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
1127 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
1128 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
1129 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
1130 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
1131 {}
1132};
1133
1134static const struct alc_config_preset alc260_presets[] = {
1135 [ALC260_BASIC] = {
1136 .mixers = { alc260_base_output_mixer,
1137 alc260_input_mixer },
1138 .init_verbs = { alc260_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1140 .dac_nids = alc260_dac_nids,
1141 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1142 .adc_nids = alc260_dual_adc_nids,
1143 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1144 .channel_mode = alc260_modes,
1145 .input_mux = &alc260_capture_source,
1146 },
1147 [ALC260_HP] = {
1148 .mixers = { alc260_hp_output_mixer,
1149 alc260_input_mixer },
1150 .init_verbs = { alc260_init_verbs,
1151 alc260_hp_unsol_verbs },
1152 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1153 .dac_nids = alc260_dac_nids,
1154 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1155 .adc_nids = alc260_adc_nids_alt,
1156 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1157 .channel_mode = alc260_modes,
1158 .input_mux = &alc260_capture_source,
1159 .unsol_event = alc_sku_unsol_event,
1160 .setup = alc260_hp_setup,
1161 .init_hook = alc_inithook,
1162 },
1163 [ALC260_HP_DC7600] = {
1164 .mixers = { alc260_hp_dc7600_mixer,
1165 alc260_input_mixer },
1166 .init_verbs = { alc260_init_verbs,
1167 alc260_hp_dc7600_verbs },
1168 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1169 .dac_nids = alc260_dac_nids,
1170 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1171 .adc_nids = alc260_adc_nids_alt,
1172 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1173 .channel_mode = alc260_modes,
1174 .input_mux = &alc260_capture_source,
1175 .unsol_event = alc_sku_unsol_event,
1176 .setup = alc260_hp_3012_setup,
1177 .init_hook = alc_inithook,
1178 },
1179 [ALC260_HP_3013] = {
1180 .mixers = { alc260_hp_3013_mixer,
1181 alc260_input_mixer },
1182 .init_verbs = { alc260_hp_3013_init_verbs,
1183 alc260_hp_3013_unsol_verbs },
1184 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1185 .dac_nids = alc260_dac_nids,
1186 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
1187 .adc_nids = alc260_adc_nids_alt,
1188 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1189 .channel_mode = alc260_modes,
1190 .input_mux = &alc260_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc260_hp_3013_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC260_FUJITSU_S702X] = {
1196 .mixers = { alc260_fujitsu_mixer },
1197 .init_verbs = { alc260_fujitsu_init_verbs },
1198 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1199 .dac_nids = alc260_dac_nids,
1200 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1201 .adc_nids = alc260_dual_adc_nids,
1202 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1203 .channel_mode = alc260_modes,
1204 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
1205 .input_mux = alc260_fujitsu_capture_sources,
1206 },
1207 [ALC260_ACER] = {
1208 .mixers = { alc260_acer_mixer },
1209 .init_verbs = { alc260_acer_init_verbs },
1210 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1211 .dac_nids = alc260_dac_nids,
1212 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1213 .adc_nids = alc260_dual_adc_nids,
1214 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1215 .channel_mode = alc260_modes,
1216 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
1217 .input_mux = alc260_acer_capture_sources,
1218 },
1219 [ALC260_FAVORIT100] = {
1220 .mixers = { alc260_favorit100_mixer },
1221 .init_verbs = { alc260_favorit100_init_verbs },
1222 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1223 .dac_nids = alc260_dac_nids,
1224 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
1225 .adc_nids = alc260_dual_adc_nids,
1226 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1227 .channel_mode = alc260_modes,
1228 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
1229 .input_mux = alc260_favorit100_capture_sources,
1230 },
1231 [ALC260_WILL] = {
1232 .mixers = { alc260_will_mixer },
1233 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
1234 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1235 .dac_nids = alc260_dac_nids,
1236 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1237 .adc_nids = alc260_adc_nids,
1238 .dig_out_nid = ALC260_DIGOUT_NID,
1239 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1240 .channel_mode = alc260_modes,
1241 .input_mux = &alc260_capture_source,
1242 },
1243 [ALC260_REPLACER_672V] = {
1244 .mixers = { alc260_replacer_672v_mixer },
1245 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
1246 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
1247 .dac_nids = alc260_dac_nids,
1248 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
1249 .adc_nids = alc260_adc_nids,
1250 .dig_out_nid = ALC260_DIGOUT_NID,
1251 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1252 .channel_mode = alc260_modes,
1253 .input_mux = &alc260_capture_source,
1254 .unsol_event = alc260_replacer_672v_unsol_event,
1255 .init_hook = alc260_replacer_672v_automute,
1256 },
1257#ifdef CONFIG_SND_DEBUG
1258 [ALC260_TEST] = {
1259 .mixers = { alc260_test_mixer },
1260 .init_verbs = { alc260_test_init_verbs },
1261 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
1262 .dac_nids = alc260_test_dac_nids,
1263 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
1264 .adc_nids = alc260_test_adc_nids,
1265 .num_channel_mode = ARRAY_SIZE(alc260_modes),
1266 .channel_mode = alc260_modes,
1267 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
1268 .input_mux = alc260_test_capture_sources,
1269 },
1270#endif
1271};
1272
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c
new file mode 100644
index 000000000000..8d2097d77642
--- /dev/null
+++ b/sound/pci/hda/alc262_quirks.c
@@ -0,0 +1,1353 @@
1/*
2 * ALC262 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC262 models */
7enum {
8 ALC262_AUTO,
9 ALC262_BASIC,
10 ALC262_HIPPO,
11 ALC262_HIPPO_1,
12 ALC262_FUJITSU,
13 ALC262_HP_BPC,
14 ALC262_HP_BPC_D7000_WL,
15 ALC262_HP_BPC_D7000_WF,
16 ALC262_HP_TC_T5735,
17 ALC262_HP_RP5700,
18 ALC262_BENQ_ED8,
19 ALC262_SONY_ASSAMD,
20 ALC262_BENQ_T31,
21 ALC262_ULTRA,
22 ALC262_LENOVO_3000,
23 ALC262_NEC,
24 ALC262_TOSHIBA_S06,
25 ALC262_TOSHIBA_RX1,
26 ALC262_TYAN,
27 ALC262_MODEL_LAST /* last tag */
28};
29
30#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
31#define ALC262_DIGIN_NID ALC880_DIGIN_NID
32
33#define alc262_dac_nids alc260_dac_nids
34#define alc262_adc_nids alc882_adc_nids
35#define alc262_adc_nids_alt alc882_adc_nids_alt
36#define alc262_capsrc_nids alc882_capsrc_nids
37#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
38
39#define alc262_modes alc260_modes
40#define alc262_capture_source alc882_capture_source
41
42static const hda_nid_t alc262_dmic_adc_nids[1] = {
43 /* ADC0 */
44 0x09
45};
46
47static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
48
49static const struct snd_kcontrol_new alc262_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
53 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
55 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
57 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
58 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
60 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
61 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
62 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
63 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
64 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
65 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
66 { } /* end */
67};
68
69/* update HP, line and mono-out pins according to the master switch */
70#define alc262_hp_master_update alc260_hp_master_update
71
72static void alc262_hp_bpc_setup(struct hda_codec *codec)
73{
74 struct alc_spec *spec = codec->spec;
75
76 spec->autocfg.hp_pins[0] = 0x1b;
77 spec->autocfg.speaker_pins[0] = 0x16;
78 spec->automute = 1;
79 spec->automute_mode = ALC_AUTOMUTE_PIN;
80}
81
82static void alc262_hp_wildwest_setup(struct hda_codec *codec)
83{
84 struct alc_spec *spec = codec->spec;
85
86 spec->autocfg.hp_pins[0] = 0x15;
87 spec->autocfg.speaker_pins[0] = 0x16;
88 spec->automute = 1;
89 spec->automute_mode = ALC_AUTOMUTE_PIN;
90}
91
92#define alc262_hp_master_sw_get alc260_hp_master_sw_get
93#define alc262_hp_master_sw_put alc260_hp_master_sw_put
94
95#define ALC262_HP_MASTER_SWITCH \
96 { \
97 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
98 .name = "Master Playback Switch", \
99 .info = snd_ctl_boolean_mono_info, \
100 .get = alc262_hp_master_sw_get, \
101 .put = alc262_hp_master_sw_put, \
102 }, \
103 { \
104 .iface = NID_MAPPING, \
105 .name = "Master Playback Switch", \
106 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
107 }
108
109
110static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
111 ALC262_HP_MASTER_SWITCH,
112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
115 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
116 HDA_OUTPUT),
117 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
118 HDA_OUTPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
122 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
123 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
124 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
127 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
128 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
129 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
130 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
131 { } /* end */
132};
133
134static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
135 ALC262_HP_MASTER_SWITCH,
136 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
137 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
139 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
140 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
141 HDA_OUTPUT),
142 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
143 HDA_OUTPUT),
144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
149 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
150 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
151 { } /* end */
152};
153
154static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
155 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
156 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
157 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
158 { } /* end */
159};
160
161/* mute/unmute internal speaker according to the hp jack and mute state */
162static void alc262_hp_t5735_setup(struct hda_codec *codec)
163{
164 struct alc_spec *spec = codec->spec;
165
166 spec->autocfg.hp_pins[0] = 0x15;
167 spec->autocfg.speaker_pins[0] = 0x14;
168 spec->automute = 1;
169 spec->automute_mode = ALC_AUTOMUTE_PIN;
170}
171
172static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
173 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
174 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
176 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
177 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
179 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
180 { } /* end */
181};
182
183static const struct hda_verb alc262_hp_t5735_verbs[] = {
184 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
185 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
186
187 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
188 { }
189};
190
191static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
192 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
193 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
194 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
197 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
198 { } /* end */
199};
200
201static const struct hda_verb alc262_hp_rp5700_verbs[] = {
202 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
203 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
205 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
206 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
207 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
208 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
209 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
210 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
211 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
212 {}
213};
214
215static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
216 .num_items = 1,
217 .items = {
218 { "Line", 0x1 },
219 },
220};
221
222/* bind hp and internal speaker mute (with plug check) as master switch */
223#define alc262_hippo_master_update alc262_hp_master_update
224#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
225#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
226
227#define ALC262_HIPPO_MASTER_SWITCH \
228 { \
229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
230 .name = "Master Playback Switch", \
231 .info = snd_ctl_boolean_mono_info, \
232 .get = alc262_hippo_master_sw_get, \
233 .put = alc262_hippo_master_sw_put, \
234 }, \
235 { \
236 .iface = NID_MAPPING, \
237 .name = "Master Playback Switch", \
238 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
239 (SUBDEV_SPEAKER(0) << 16), \
240 }
241
242static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
243 ALC262_HIPPO_MASTER_SWITCH,
244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
246 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
247 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
248 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
250 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
251 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
254 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
255 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
256 { } /* end */
257};
258
259static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
260 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
261 ALC262_HIPPO_MASTER_SWITCH,
262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
271 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272 { } /* end */
273};
274
275/* mute/unmute internal speaker according to the hp jack and mute state */
276static void alc262_hippo_setup(struct hda_codec *codec)
277{
278 struct alc_spec *spec = codec->spec;
279
280 spec->autocfg.hp_pins[0] = 0x15;
281 spec->autocfg.speaker_pins[0] = 0x14;
282 spec->automute = 1;
283 spec->automute_mode = ALC_AUTOMUTE_AMP;
284}
285
286static void alc262_hippo1_setup(struct hda_codec *codec)
287{
288 struct alc_spec *spec = codec->spec;
289
290 spec->autocfg.hp_pins[0] = 0x1b;
291 spec->autocfg.speaker_pins[0] = 0x14;
292 spec->automute = 1;
293 spec->automute_mode = ALC_AUTOMUTE_AMP;
294}
295
296
297static const struct snd_kcontrol_new alc262_sony_mixer[] = {
298 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
299 ALC262_HIPPO_MASTER_SWITCH,
300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
303 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
304 { } /* end */
305};
306
307static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
308 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
309 ALC262_HIPPO_MASTER_SWITCH,
310 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
313 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
314 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
315 { } /* end */
316};
317
318static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
319 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
320 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
321 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
322 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
323 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
324 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
325 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
326 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
327 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
328 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
329 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
330 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
331 { } /* end */
332};
333
334static const struct hda_verb alc262_tyan_verbs[] = {
335 /* Headphone automute */
336 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
337 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
339
340 /* P11 AUX_IN, white 4-pin connector */
341 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
342 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
343 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
344 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
345
346 {}
347};
348
349/* unsolicited event for HP jack sensing */
350static void alc262_tyan_setup(struct hda_codec *codec)
351{
352 struct alc_spec *spec = codec->spec;
353
354 spec->autocfg.hp_pins[0] = 0x1b;
355 spec->autocfg.speaker_pins[0] = 0x15;
356 spec->automute = 1;
357 spec->automute_mode = ALC_AUTOMUTE_AMP;
358}
359
360
361#define alc262_capture_mixer alc882_capture_mixer
362#define alc262_capture_alt_mixer alc882_capture_alt_mixer
363
364/*
365 * generic initialization of ADC, input mixers and output mixers
366 */
367static const struct hda_verb alc262_init_verbs[] = {
368 /*
369 * Unmute ADC0-2 and set the default input to mic-in
370 */
371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377
378 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
379 * mixer widget
380 * Note: PASD motherboards uses the Line In 2 as the input for
381 * front panel mic (mic 2)
382 */
383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
389
390 /*
391 * Set up output mixers (0x0c - 0x0e)
392 */
393 /* set vol=0 to output mixers */
394 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
397 /* set up input amps for analog loopback */
398 /* Amp Indices: DAC = 0, mixer = 1 */
399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
405
406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
407 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
408 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
409 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
410 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
412
413 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
414 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
415 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
416 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
418
419 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
420 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
421
422 /* FIXME: use matrix-type input source selection */
423 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
424 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
428 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
429 /* Input mixer2 */
430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
433 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
434 /* Input mixer3 */
435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
439
440 { }
441};
442
443static const struct hda_verb alc262_eapd_verbs[] = {
444 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
445 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
446 { }
447};
448
449static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
450 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
451 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
452 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
453
454 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
455 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
456 {}
457};
458
459static const struct hda_verb alc262_sony_unsol_verbs[] = {
460 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
461 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
462 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
463
464 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
465 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {}
467};
468
469static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
470 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
471 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
473 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
474 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
475 { } /* end */
476};
477
478static const struct hda_verb alc262_toshiba_s06_verbs[] = {
479 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
482 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
483 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
484 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
485 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
486 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
487 {}
488};
489
490static void alc262_toshiba_s06_setup(struct hda_codec *codec)
491{
492 struct alc_spec *spec = codec->spec;
493
494 spec->autocfg.hp_pins[0] = 0x15;
495 spec->autocfg.speaker_pins[0] = 0x14;
496 spec->ext_mic_pin = 0x18;
497 spec->int_mic_pin = 0x12;
498 spec->auto_mic = 1;
499 spec->automute = 1;
500 spec->automute_mode = ALC_AUTOMUTE_PIN;
501}
502
503/*
504 * nec model
505 * 0x15 = headphone
506 * 0x16 = internal speaker
507 * 0x18 = external mic
508 */
509
510static const struct snd_kcontrol_new alc262_nec_mixer[] = {
511 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
512 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
513
514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
517
518 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
520 { } /* end */
521};
522
523static const struct hda_verb alc262_nec_verbs[] = {
524 /* Unmute Speaker */
525 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
526
527 /* Headphone */
528 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
530
531 /* External mic to headphone */
532 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
533 /* External mic to speaker */
534 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
535 {}
536};
537
538/*
539 * fujitsu model
540 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
541 * 0x1b = port replicator headphone out
542 */
543
544static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
545 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
546 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
547 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
549 {}
550};
551
552static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
553 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
555 {}
556};
557
558static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
559 /* Front Mic pin: input vref at 50% */
560 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
561 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
562 {}
563};
564
565static const struct hda_input_mux alc262_fujitsu_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Mic", 0x0 },
569 { "Internal Mic", 0x1 },
570 { "CD", 0x4 },
571 },
572};
573
574static const struct hda_input_mux alc262_HP_capture_source = {
575 .num_items = 5,
576 .items = {
577 { "Mic", 0x0 },
578 { "Front Mic", 0x1 },
579 { "Line", 0x2 },
580 { "CD", 0x4 },
581 { "AUX IN", 0x6 },
582 },
583};
584
585static const struct hda_input_mux alc262_HP_D7000_capture_source = {
586 .num_items = 4,
587 .items = {
588 { "Mic", 0x0 },
589 { "Front Mic", 0x2 },
590 { "Line", 0x1 },
591 { "CD", 0x4 },
592 },
593};
594
595static void alc262_fujitsu_setup(struct hda_codec *codec)
596{
597 struct alc_spec *spec = codec->spec;
598
599 spec->autocfg.hp_pins[0] = 0x14;
600 spec->autocfg.hp_pins[1] = 0x1b;
601 spec->autocfg.speaker_pins[0] = 0x15;
602 spec->automute = 1;
603 spec->automute_mode = ALC_AUTOMUTE_AMP;
604}
605
606/* bind volumes of both NID 0x0c and 0x0d */
607static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
608 .ops = &snd_hda_bind_vol,
609 .values = {
610 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
611 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
612 0
613 },
614};
615
616static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
617 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
618 {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "Master Playback Switch",
621 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
622 .info = snd_ctl_boolean_mono_info,
623 .get = alc262_hp_master_sw_get,
624 .put = alc262_hp_master_sw_put,
625 },
626 {
627 .iface = NID_MAPPING,
628 .name = "Master Playback Switch",
629 .private_value = 0x1b,
630 },
631 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
632 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
636 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
637 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
638 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
639 { } /* end */
640};
641
642static void alc262_lenovo_3000_setup(struct hda_codec *codec)
643{
644 struct alc_spec *spec = codec->spec;
645
646 spec->autocfg.hp_pins[0] = 0x1b;
647 spec->autocfg.speaker_pins[0] = 0x14;
648 spec->autocfg.speaker_pins[1] = 0x16;
649 spec->automute = 1;
650 spec->automute_mode = ALC_AUTOMUTE_AMP;
651}
652
653static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
655 {
656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
657 .name = "Master Playback Switch",
658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
659 .info = snd_ctl_boolean_mono_info,
660 .get = alc262_hp_master_sw_get,
661 .put = alc262_hp_master_sw_put,
662 },
663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
665 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
668 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
669 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
670 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
671 { } /* end */
672};
673
674static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
675 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
676 ALC262_HIPPO_MASTER_SWITCH,
677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
679 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
680 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
681 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
682 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
683 { } /* end */
684};
685
686/* additional init verbs for Benq laptops */
687static const struct hda_verb alc262_EAPD_verbs[] = {
688 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
689 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
690 {}
691};
692
693static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
694 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
695 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
696
697 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
698 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
699 {}
700};
701
702/* Samsung Q1 Ultra Vista model setup */
703static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
704 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
705 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
708 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
709 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
710 { } /* end */
711};
712
713static const struct hda_verb alc262_ultra_verbs[] = {
714 /* output mixer */
715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
718 /* speaker */
719 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
720 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
722 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
723 /* HP */
724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
727 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
728 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
729 /* internal mic */
730 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
731 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
732 /* ADC, choose mic */
733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
734 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
735 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
736 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
737 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
738 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
739 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
740 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
741 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
742 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
743 {}
744};
745
746/* mute/unmute internal speaker according to the hp jack and mute state */
747static void alc262_ultra_automute(struct hda_codec *codec)
748{
749 struct alc_spec *spec = codec->spec;
750 unsigned int mute;
751
752 mute = 0;
753 /* auto-mute only when HP is used as HP */
754 if (!spec->cur_mux[0]) {
755 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
756 if (spec->jack_present)
757 mute = HDA_AMP_MUTE;
758 }
759 /* mute/unmute internal speaker */
760 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
761 HDA_AMP_MUTE, mute);
762 /* mute/unmute HP */
763 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
764 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
765}
766
767/* unsolicited event for HP jack sensing */
768static void alc262_ultra_unsol_event(struct hda_codec *codec,
769 unsigned int res)
770{
771 if ((res >> 26) != ALC_HP_EVENT)
772 return;
773 alc262_ultra_automute(codec);
774}
775
776static const struct hda_input_mux alc262_ultra_capture_source = {
777 .num_items = 2,
778 .items = {
779 { "Mic", 0x1 },
780 { "Headphone", 0x7 },
781 },
782};
783
784static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
785 struct snd_ctl_elem_value *ucontrol)
786{
787 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
788 struct alc_spec *spec = codec->spec;
789 int ret;
790
791 ret = alc_mux_enum_put(kcontrol, ucontrol);
792 if (!ret)
793 return 0;
794 /* reprogram the HP pin as mic or HP according to the input source */
795 snd_hda_codec_write_cache(codec, 0x15, 0,
796 AC_VERB_SET_PIN_WIDGET_CONTROL,
797 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
798 alc262_ultra_automute(codec); /* mute/unmute HP */
799 return ret;
800}
801
802static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
803 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
804 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .name = "Capture Source",
808 .info = alc_mux_enum_info,
809 .get = alc_mux_enum_get,
810 .put = alc262_ultra_mux_enum_put,
811 },
812 {
813 .iface = NID_MAPPING,
814 .name = "Capture Source",
815 .private_value = 0x15,
816 },
817 { } /* end */
818};
819
820static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
821 /*
822 * Unmute ADC0-2 and set the default input to mic-in
823 */
824 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
826 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
827 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
828 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
829 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
830
831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
832 * mixer widget
833 * Note: PASD motherboards uses the Line In 2 as the input for
834 * front panel mic (mic 2)
835 */
836 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
843 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
844
845 /*
846 * Set up output mixers (0x0c - 0x0e)
847 */
848 /* set vol=0 to output mixers */
849 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
850 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
851 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
852
853 /* set up input amps for analog loopback */
854 /* Amp Indices: DAC = 0, mixer = 1 */
855 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
856 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
857 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
858 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
859 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
860 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
861
862 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
864 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
865
866 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
867 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
868
869 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
870 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
871
872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
873 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
874 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
876 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
877
878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
879 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
880 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
881 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
882 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
883 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
884
885
886 /* FIXME: use matrix-type input source selection */
887 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
888 /* Input mixer1: only unmute Mic */
889 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
890 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
891 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
892 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
893 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
894 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
895 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
896 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
897 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
898 /* Input mixer2 */
899 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
900 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
901 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
902 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
903 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
904 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
908 /* Input mixer3 */
909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
918
919 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
920
921 { }
922};
923
924static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
925 /*
926 * Unmute ADC0-2 and set the default input to mic-in
927 */
928 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
929 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
930 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
931 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
932 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
933 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
934
935 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
936 * mixer widget
937 * Note: PASD motherboards uses the Line In 2 as the input for front
938 * panel mic (mic 2)
939 */
940 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
943 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
944 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
945 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
946 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
949 /*
950 * Set up output mixers (0x0c - 0x0e)
951 */
952 /* set vol=0 to output mixers */
953 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
954 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
956
957 /* set up input amps for analog loopback */
958 /* Amp Indices: DAC = 0, mixer = 1 */
959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
961 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
962 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
963 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
964 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
965
966
967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
968 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
969 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
970 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
971 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
973 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
974
975 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
976 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
977
978 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
979 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
980
981 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
982 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
983 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
984 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
985 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
986 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
987
988 /* FIXME: use matrix-type input source selection */
989 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
990 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
991 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
992 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
993 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
994 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
996 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
998 /* Input mixer2 */
999 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1000 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1001 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1002 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1003 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1004 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1005 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1006 /* Input mixer3 */
1007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
1010 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
1011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
1012 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
1013 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
1014
1015 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1016
1017 { }
1018};
1019
1020static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
1021
1022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
1023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1024 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
1025
1026 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
1027 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
1028 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1029 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
1030
1031 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
1032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1033 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1034 {}
1035};
1036
1037/*
1038 * configuration and preset
1039 */
1040static const char * const alc262_models[ALC262_MODEL_LAST] = {
1041 [ALC262_BASIC] = "basic",
1042 [ALC262_HIPPO] = "hippo",
1043 [ALC262_HIPPO_1] = "hippo_1",
1044 [ALC262_FUJITSU] = "fujitsu",
1045 [ALC262_HP_BPC] = "hp-bpc",
1046 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
1047 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
1048 [ALC262_HP_RP5700] = "hp-rp5700",
1049 [ALC262_BENQ_ED8] = "benq",
1050 [ALC262_BENQ_T31] = "benq-t31",
1051 [ALC262_SONY_ASSAMD] = "sony-assamd",
1052 [ALC262_TOSHIBA_S06] = "toshiba-s06",
1053 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
1054 [ALC262_ULTRA] = "ultra",
1055 [ALC262_LENOVO_3000] = "lenovo-3000",
1056 [ALC262_NEC] = "nec",
1057 [ALC262_TYAN] = "tyan",
1058 [ALC262_AUTO] = "auto",
1059};
1060
1061static const struct snd_pci_quirk alc262_cfg_tbl[] = {
1062 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
1063 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
1064 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
1065 ALC262_HP_BPC),
1066 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
1067 ALC262_HP_BPC),
1068 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
1069 ALC262_HP_BPC),
1070 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
1071 ALC262_AUTO),
1072 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
1073 ALC262_HP_BPC),
1074 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
1075 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
1076 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
1077 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
1078 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
1079 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
1080 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
1081 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
1082 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
1083 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
1084 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
1085 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
1086 ALC262_HP_TC_T5735),
1087 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
1088 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1089 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
1090 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
1091 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
1092 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
1093 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
1094 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
1095#if 0 /* disable the quirk since model=auto works better in recent versions */
1096 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
1097 ALC262_SONY_ASSAMD),
1098#endif
1099 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
1100 ALC262_TOSHIBA_RX1),
1101 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
1102 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
1103 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
1104 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
1105 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
1106 ALC262_ULTRA),
1107 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
1108 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
1109 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
1110 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
1111 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
1112 {}
1113};
1114
1115static const struct alc_config_preset alc262_presets[] = {
1116 [ALC262_BASIC] = {
1117 .mixers = { alc262_base_mixer },
1118 .init_verbs = { alc262_init_verbs },
1119 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1120 .dac_nids = alc262_dac_nids,
1121 .hp_nid = 0x03,
1122 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1123 .channel_mode = alc262_modes,
1124 .input_mux = &alc262_capture_source,
1125 },
1126 [ALC262_HIPPO] = {
1127 .mixers = { alc262_hippo_mixer },
1128 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
1129 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1130 .dac_nids = alc262_dac_nids,
1131 .hp_nid = 0x03,
1132 .dig_out_nid = ALC262_DIGOUT_NID,
1133 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1134 .channel_mode = alc262_modes,
1135 .input_mux = &alc262_capture_source,
1136 .unsol_event = alc_sku_unsol_event,
1137 .setup = alc262_hippo_setup,
1138 .init_hook = alc_inithook,
1139 },
1140 [ALC262_HIPPO_1] = {
1141 .mixers = { alc262_hippo1_mixer },
1142 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
1143 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1144 .dac_nids = alc262_dac_nids,
1145 .hp_nid = 0x02,
1146 .dig_out_nid = ALC262_DIGOUT_NID,
1147 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1148 .channel_mode = alc262_modes,
1149 .input_mux = &alc262_capture_source,
1150 .unsol_event = alc_sku_unsol_event,
1151 .setup = alc262_hippo1_setup,
1152 .init_hook = alc_inithook,
1153 },
1154 [ALC262_FUJITSU] = {
1155 .mixers = { alc262_fujitsu_mixer },
1156 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1157 alc262_fujitsu_unsol_verbs },
1158 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1159 .dac_nids = alc262_dac_nids,
1160 .hp_nid = 0x03,
1161 .dig_out_nid = ALC262_DIGOUT_NID,
1162 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1163 .channel_mode = alc262_modes,
1164 .input_mux = &alc262_fujitsu_capture_source,
1165 .unsol_event = alc_sku_unsol_event,
1166 .setup = alc262_fujitsu_setup,
1167 .init_hook = alc_inithook,
1168 },
1169 [ALC262_HP_BPC] = {
1170 .mixers = { alc262_HP_BPC_mixer },
1171 .init_verbs = { alc262_HP_BPC_init_verbs },
1172 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1173 .dac_nids = alc262_dac_nids,
1174 .hp_nid = 0x03,
1175 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1176 .channel_mode = alc262_modes,
1177 .input_mux = &alc262_HP_capture_source,
1178 .unsol_event = alc_sku_unsol_event,
1179 .setup = alc262_hp_bpc_setup,
1180 .init_hook = alc_inithook,
1181 },
1182 [ALC262_HP_BPC_D7000_WF] = {
1183 .mixers = { alc262_HP_BPC_WildWest_mixer },
1184 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1185 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1186 .dac_nids = alc262_dac_nids,
1187 .hp_nid = 0x03,
1188 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1189 .channel_mode = alc262_modes,
1190 .input_mux = &alc262_HP_D7000_capture_source,
1191 .unsol_event = alc_sku_unsol_event,
1192 .setup = alc262_hp_wildwest_setup,
1193 .init_hook = alc_inithook,
1194 },
1195 [ALC262_HP_BPC_D7000_WL] = {
1196 .mixers = { alc262_HP_BPC_WildWest_mixer,
1197 alc262_HP_BPC_WildWest_option_mixer },
1198 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
1199 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1200 .dac_nids = alc262_dac_nids,
1201 .hp_nid = 0x03,
1202 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1203 .channel_mode = alc262_modes,
1204 .input_mux = &alc262_HP_D7000_capture_source,
1205 .unsol_event = alc_sku_unsol_event,
1206 .setup = alc262_hp_wildwest_setup,
1207 .init_hook = alc_inithook,
1208 },
1209 [ALC262_HP_TC_T5735] = {
1210 .mixers = { alc262_hp_t5735_mixer },
1211 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
1212 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1213 .dac_nids = alc262_dac_nids,
1214 .hp_nid = 0x03,
1215 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1216 .channel_mode = alc262_modes,
1217 .input_mux = &alc262_capture_source,
1218 .unsol_event = alc_sku_unsol_event,
1219 .setup = alc262_hp_t5735_setup,
1220 .init_hook = alc_inithook,
1221 },
1222 [ALC262_HP_RP5700] = {
1223 .mixers = { alc262_hp_rp5700_mixer },
1224 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
1225 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1226 .dac_nids = alc262_dac_nids,
1227 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1228 .channel_mode = alc262_modes,
1229 .input_mux = &alc262_hp_rp5700_capture_source,
1230 },
1231 [ALC262_BENQ_ED8] = {
1232 .mixers = { alc262_base_mixer },
1233 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
1234 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1235 .dac_nids = alc262_dac_nids,
1236 .hp_nid = 0x03,
1237 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1238 .channel_mode = alc262_modes,
1239 .input_mux = &alc262_capture_source,
1240 },
1241 [ALC262_SONY_ASSAMD] = {
1242 .mixers = { alc262_sony_mixer },
1243 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
1244 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1245 .dac_nids = alc262_dac_nids,
1246 .hp_nid = 0x02,
1247 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1248 .channel_mode = alc262_modes,
1249 .input_mux = &alc262_capture_source,
1250 .unsol_event = alc_sku_unsol_event,
1251 .setup = alc262_hippo_setup,
1252 .init_hook = alc_inithook,
1253 },
1254 [ALC262_BENQ_T31] = {
1255 .mixers = { alc262_benq_t31_mixer },
1256 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
1257 alc_hp15_unsol_verbs },
1258 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1259 .dac_nids = alc262_dac_nids,
1260 .hp_nid = 0x03,
1261 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1262 .channel_mode = alc262_modes,
1263 .input_mux = &alc262_capture_source,
1264 .unsol_event = alc_sku_unsol_event,
1265 .setup = alc262_hippo_setup,
1266 .init_hook = alc_inithook,
1267 },
1268 [ALC262_ULTRA] = {
1269 .mixers = { alc262_ultra_mixer },
1270 .cap_mixer = alc262_ultra_capture_mixer,
1271 .init_verbs = { alc262_ultra_verbs },
1272 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1273 .dac_nids = alc262_dac_nids,
1274 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1275 .channel_mode = alc262_modes,
1276 .input_mux = &alc262_ultra_capture_source,
1277 .adc_nids = alc262_adc_nids, /* ADC0 */
1278 .capsrc_nids = alc262_capsrc_nids,
1279 .num_adc_nids = 1, /* single ADC */
1280 .unsol_event = alc262_ultra_unsol_event,
1281 .init_hook = alc262_ultra_automute,
1282 },
1283 [ALC262_LENOVO_3000] = {
1284 .mixers = { alc262_lenovo_3000_mixer },
1285 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
1286 alc262_lenovo_3000_unsol_verbs,
1287 alc262_lenovo_3000_init_verbs },
1288 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1289 .dac_nids = alc262_dac_nids,
1290 .hp_nid = 0x03,
1291 .dig_out_nid = ALC262_DIGOUT_NID,
1292 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1293 .channel_mode = alc262_modes,
1294 .input_mux = &alc262_fujitsu_capture_source,
1295 .unsol_event = alc_sku_unsol_event,
1296 .setup = alc262_lenovo_3000_setup,
1297 .init_hook = alc_inithook,
1298 },
1299 [ALC262_NEC] = {
1300 .mixers = { alc262_nec_mixer },
1301 .init_verbs = { alc262_nec_verbs },
1302 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1303 .dac_nids = alc262_dac_nids,
1304 .hp_nid = 0x03,
1305 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1306 .channel_mode = alc262_modes,
1307 .input_mux = &alc262_capture_source,
1308 },
1309 [ALC262_TOSHIBA_S06] = {
1310 .mixers = { alc262_toshiba_s06_mixer },
1311 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
1312 alc262_eapd_verbs },
1313 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1314 .capsrc_nids = alc262_dmic_capsrc_nids,
1315 .dac_nids = alc262_dac_nids,
1316 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
1317 .num_adc_nids = 1, /* single ADC */
1318 .dig_out_nid = ALC262_DIGOUT_NID,
1319 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1320 .channel_mode = alc262_modes,
1321 .unsol_event = alc_sku_unsol_event,
1322 .setup = alc262_toshiba_s06_setup,
1323 .init_hook = alc_inithook,
1324 },
1325 [ALC262_TOSHIBA_RX1] = {
1326 .mixers = { alc262_toshiba_rx1_mixer },
1327 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
1328 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1329 .dac_nids = alc262_dac_nids,
1330 .hp_nid = 0x03,
1331 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1332 .channel_mode = alc262_modes,
1333 .input_mux = &alc262_capture_source,
1334 .unsol_event = alc_sku_unsol_event,
1335 .setup = alc262_hippo_setup,
1336 .init_hook = alc_inithook,
1337 },
1338 [ALC262_TYAN] = {
1339 .mixers = { alc262_tyan_mixer },
1340 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
1341 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
1342 .dac_nids = alc262_dac_nids,
1343 .hp_nid = 0x02,
1344 .dig_out_nid = ALC262_DIGOUT_NID,
1345 .num_channel_mode = ARRAY_SIZE(alc262_modes),
1346 .channel_mode = alc262_modes,
1347 .input_mux = &alc262_capture_source,
1348 .unsol_event = alc_sku_unsol_event,
1349 .setup = alc262_tyan_setup,
1350 .init_hook = alc_hp_automute,
1351 },
1352};
1353
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c
new file mode 100644
index 000000000000..be58bf2f3aec
--- /dev/null
+++ b/sound/pci/hda/alc268_quirks.c
@@ -0,0 +1,636 @@
1/*
2 * ALC267/ALC268 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC268 models */
7enum {
8 ALC268_AUTO,
9 ALC267_QUANTA_IL1,
10 ALC268_3ST,
11 ALC268_TOSHIBA,
12 ALC268_ACER,
13 ALC268_ACER_DMIC,
14 ALC268_ACER_ASPIRE_ONE,
15 ALC268_DELL,
16 ALC268_ZEPTO,
17#ifdef CONFIG_SND_DEBUG
18 ALC268_TEST,
19#endif
20 ALC268_MODEL_LAST /* last tag */
21};
22
23/*
24 * ALC268 channel source setting (2 channel)
25 */
26#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
27#define alc268_modes alc260_modes
28
29static const hda_nid_t alc268_dac_nids[2] = {
30 /* front, hp */
31 0x02, 0x03
32};
33
34static const hda_nid_t alc268_adc_nids[2] = {
35 /* ADC0-1 */
36 0x08, 0x07
37};
38
39static const hda_nid_t alc268_adc_nids_alt[1] = {
40 /* ADC0 */
41 0x08
42};
43
44static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
45
46static const struct snd_kcontrol_new alc268_base_mixer[] = {
47 /* output mixer control */
48 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
49 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
50 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
53 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
54 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
55 { }
56};
57
58static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
59 /* output mixer control */
60 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
61 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
62 ALC262_HIPPO_MASTER_SWITCH,
63 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
65 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
66 { }
67};
68
69static const struct hda_verb alc268_eapd_verbs[] = {
70 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
71 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
72 { }
73};
74
75/* Toshiba specific */
76static const struct hda_verb alc268_toshiba_verbs[] = {
77 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
78 { } /* end */
79};
80
81/* Acer specific */
82/* bind volumes of both NID 0x02 and 0x03 */
83static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
84 .ops = &snd_hda_bind_vol,
85 .values = {
86 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
87 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
88 0
89 },
90};
91
92static void alc268_acer_setup(struct hda_codec *codec)
93{
94 struct alc_spec *spec = codec->spec;
95
96 spec->autocfg.hp_pins[0] = 0x14;
97 spec->autocfg.speaker_pins[0] = 0x15;
98 spec->automute = 1;
99 spec->automute_mode = ALC_AUTOMUTE_AMP;
100}
101
102#define alc268_acer_master_sw_get alc262_hp_master_sw_get
103#define alc268_acer_master_sw_put alc262_hp_master_sw_put
104
105static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
106 /* output mixer control */
107 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
108 {
109 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
110 .name = "Master Playback Switch",
111 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
112 .info = snd_ctl_boolean_mono_info,
113 .get = alc268_acer_master_sw_get,
114 .put = alc268_acer_master_sw_put,
115 },
116 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
117 { }
118};
119
120static const struct snd_kcontrol_new alc268_acer_mixer[] = {
121 /* output mixer control */
122 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
123 {
124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
125 .name = "Master Playback Switch",
126 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
127 .info = snd_ctl_boolean_mono_info,
128 .get = alc268_acer_master_sw_get,
129 .put = alc268_acer_master_sw_put,
130 },
131 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
133 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
134 { }
135};
136
137static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
138 /* output mixer control */
139 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
140 {
141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
142 .name = "Master Playback Switch",
143 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
144 .info = snd_ctl_boolean_mono_info,
145 .get = alc268_acer_master_sw_get,
146 .put = alc268_acer_master_sw_put,
147 },
148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
149 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
150 { }
151};
152
153static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
154 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
156 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
157 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
158 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
160 { }
161};
162
163static const struct hda_verb alc268_acer_verbs[] = {
164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
165 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
166 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
167 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
168 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
169 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
170 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 { }
172};
173
174/* unsolicited event for HP jack sensing */
175#define alc268_toshiba_setup alc262_hippo_setup
176
177static void alc268_acer_lc_setup(struct hda_codec *codec)
178{
179 struct alc_spec *spec = codec->spec;
180 spec->autocfg.hp_pins[0] = 0x15;
181 spec->autocfg.speaker_pins[0] = 0x14;
182 spec->automute = 1;
183 spec->automute_mode = ALC_AUTOMUTE_AMP;
184 spec->ext_mic_pin = 0x18;
185 spec->int_mic_pin = 0x12;
186 spec->auto_mic = 1;
187}
188
189static const struct snd_kcontrol_new alc268_dell_mixer[] = {
190 /* output mixer control */
191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
192 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
195 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
196 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
197 { }
198};
199
200static const struct hda_verb alc268_dell_verbs[] = {
201 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
203 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
204 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
205 { }
206};
207
208/* mute/unmute internal speaker according to the hp jack and mute state */
209static void alc268_dell_setup(struct hda_codec *codec)
210{
211 struct alc_spec *spec = codec->spec;
212
213 spec->autocfg.hp_pins[0] = 0x15;
214 spec->autocfg.speaker_pins[0] = 0x14;
215 spec->ext_mic_pin = 0x18;
216 spec->int_mic_pin = 0x19;
217 spec->auto_mic = 1;
218 spec->automute = 1;
219 spec->automute_mode = ALC_AUTOMUTE_PIN;
220}
221
222static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
223 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
227 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
228 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
229 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
230 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
231 { }
232};
233
234static const struct hda_verb alc267_quanta_il1_verbs[] = {
235 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
236 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
237 { }
238};
239
240static void alc267_quanta_il1_setup(struct hda_codec *codec)
241{
242 struct alc_spec *spec = codec->spec;
243 spec->autocfg.hp_pins[0] = 0x15;
244 spec->autocfg.speaker_pins[0] = 0x14;
245 spec->ext_mic_pin = 0x18;
246 spec->int_mic_pin = 0x19;
247 spec->auto_mic = 1;
248 spec->automute = 1;
249 spec->automute_mode = ALC_AUTOMUTE_PIN;
250}
251
252/*
253 * generic initialization of ADC, input mixers and output mixers
254 */
255static const struct hda_verb alc268_base_init_verbs[] = {
256 /* Unmute DAC0-1 and set vol = 0 */
257 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
258 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
259
260 /*
261 * Set up output mixers (0x0c - 0x0e)
262 */
263 /* set vol=0 to output mixers */
264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
265 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
266
267 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
268 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
269
270 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
271 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
273 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
274 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
276 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
277 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
278
279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
280 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
281 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
282 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
283 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
284
285 /* set PCBEEP vol = 0, mute connections */
286 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
287 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
288 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
289
290 /* Unmute Selector 23h,24h and set the default input to mic-in */
291
292 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
294 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
295 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296
297 { }
298};
299
300/* only for model=test */
301#ifdef CONFIG_SND_DEBUG
302/*
303 * generic initialization of ADC, input mixers and output mixers
304 */
305static const struct hda_verb alc268_volume_init_verbs[] = {
306 /* set output DAC */
307 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
308 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
309
310 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
311 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
312 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
313 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
314 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
315
316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
318 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319
320 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
321 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
322 { }
323};
324#endif /* CONFIG_SND_DEBUG */
325
326static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
327 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
328 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
329 { } /* end */
330};
331
332static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
333 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
334 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
335 _DEFINE_CAPSRC(1),
336 { } /* end */
337};
338
339static const struct snd_kcontrol_new alc268_capture_mixer[] = {
340 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
341 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
342 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
343 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
344 _DEFINE_CAPSRC(2),
345 { } /* end */
346};
347
348static const struct hda_input_mux alc268_capture_source = {
349 .num_items = 4,
350 .items = {
351 { "Mic", 0x0 },
352 { "Front Mic", 0x1 },
353 { "Line", 0x2 },
354 { "CD", 0x3 },
355 },
356};
357
358static const struct hda_input_mux alc268_acer_capture_source = {
359 .num_items = 3,
360 .items = {
361 { "Mic", 0x0 },
362 { "Internal Mic", 0x1 },
363 { "Line", 0x2 },
364 },
365};
366
367static const struct hda_input_mux alc268_acer_dmic_capture_source = {
368 .num_items = 3,
369 .items = {
370 { "Mic", 0x0 },
371 { "Internal Mic", 0x6 },
372 { "Line", 0x2 },
373 },
374};
375
376#ifdef CONFIG_SND_DEBUG
377static const struct snd_kcontrol_new alc268_test_mixer[] = {
378 /* Volume widgets */
379 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
380 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
382 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
383 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
384 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
385 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
386 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
387 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
388 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
389 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
390 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
391 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
392 /* The below appears problematic on some hardwares */
393 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
394 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
395 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
396 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
397 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
398
399 /* Modes for retasking pin widgets */
400 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
401 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
402 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
403 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
404
405 /* Controls for GPIO pins, assuming they are configured as outputs */
406 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
407 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
408 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
409 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
410
411 /* Switches to allow the digital SPDIF output pin to be enabled.
412 * The ALC268 does not have an SPDIF input.
413 */
414 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
415
416 /* A switch allowing EAPD to be enabled. Some laptops seem to use
417 * this output to turn on an external amplifier.
418 */
419 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
420 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
421
422 { } /* end */
423};
424#endif
425
426/*
427 * configuration and preset
428 */
429static const char * const alc268_models[ALC268_MODEL_LAST] = {
430 [ALC267_QUANTA_IL1] = "quanta-il1",
431 [ALC268_3ST] = "3stack",
432 [ALC268_TOSHIBA] = "toshiba",
433 [ALC268_ACER] = "acer",
434 [ALC268_ACER_DMIC] = "acer-dmic",
435 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
436 [ALC268_DELL] = "dell",
437 [ALC268_ZEPTO] = "zepto",
438#ifdef CONFIG_SND_DEBUG
439 [ALC268_TEST] = "test",
440#endif
441 [ALC268_AUTO] = "auto",
442};
443
444static const struct snd_pci_quirk alc268_cfg_tbl[] = {
445 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
446 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
447 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
448 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
449 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
450 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
451 ALC268_ACER_ASPIRE_ONE),
452 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
453 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
454 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
455 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
456 /* almost compatible with toshiba but with optional digital outs;
457 * auto-probing seems working fine
458 */
459 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
460 ALC268_AUTO),
461 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
462 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
463 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
464 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
465 {}
466};
467
468/* Toshiba laptops have no unique PCI SSID but only codec SSID */
469static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
470 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
471 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
472 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
473 ALC268_TOSHIBA),
474 {}
475};
476
477static const struct alc_config_preset alc268_presets[] = {
478 [ALC267_QUANTA_IL1] = {
479 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
480 alc268_capture_nosrc_mixer },
481 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
482 alc267_quanta_il1_verbs },
483 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
484 .dac_nids = alc268_dac_nids,
485 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
486 .adc_nids = alc268_adc_nids_alt,
487 .hp_nid = 0x03,
488 .num_channel_mode = ARRAY_SIZE(alc268_modes),
489 .channel_mode = alc268_modes,
490 .unsol_event = alc_sku_unsol_event,
491 .setup = alc267_quanta_il1_setup,
492 .init_hook = alc_inithook,
493 },
494 [ALC268_3ST] = {
495 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
496 alc268_beep_mixer },
497 .init_verbs = { alc268_base_init_verbs },
498 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
499 .dac_nids = alc268_dac_nids,
500 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
501 .adc_nids = alc268_adc_nids_alt,
502 .capsrc_nids = alc268_capsrc_nids,
503 .hp_nid = 0x03,
504 .dig_out_nid = ALC268_DIGOUT_NID,
505 .num_channel_mode = ARRAY_SIZE(alc268_modes),
506 .channel_mode = alc268_modes,
507 .input_mux = &alc268_capture_source,
508 },
509 [ALC268_TOSHIBA] = {
510 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
511 alc268_beep_mixer },
512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
513 alc268_toshiba_verbs },
514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
515 .dac_nids = alc268_dac_nids,
516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
517 .adc_nids = alc268_adc_nids_alt,
518 .capsrc_nids = alc268_capsrc_nids,
519 .hp_nid = 0x03,
520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
521 .channel_mode = alc268_modes,
522 .input_mux = &alc268_capture_source,
523 .unsol_event = alc_sku_unsol_event,
524 .setup = alc268_toshiba_setup,
525 .init_hook = alc_inithook,
526 },
527 [ALC268_ACER] = {
528 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
529 alc268_beep_mixer },
530 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
531 alc268_acer_verbs },
532 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
533 .dac_nids = alc268_dac_nids,
534 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
535 .adc_nids = alc268_adc_nids_alt,
536 .capsrc_nids = alc268_capsrc_nids,
537 .hp_nid = 0x02,
538 .num_channel_mode = ARRAY_SIZE(alc268_modes),
539 .channel_mode = alc268_modes,
540 .input_mux = &alc268_acer_capture_source,
541 .unsol_event = alc_sku_unsol_event,
542 .setup = alc268_acer_setup,
543 .init_hook = alc_inithook,
544 },
545 [ALC268_ACER_DMIC] = {
546 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
547 alc268_beep_mixer },
548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
549 alc268_acer_verbs },
550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
551 .dac_nids = alc268_dac_nids,
552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
553 .adc_nids = alc268_adc_nids_alt,
554 .capsrc_nids = alc268_capsrc_nids,
555 .hp_nid = 0x02,
556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
557 .channel_mode = alc268_modes,
558 .input_mux = &alc268_acer_dmic_capture_source,
559 .unsol_event = alc_sku_unsol_event,
560 .setup = alc268_acer_setup,
561 .init_hook = alc_inithook,
562 },
563 [ALC268_ACER_ASPIRE_ONE] = {
564 .mixers = { alc268_acer_aspire_one_mixer,
565 alc268_beep_mixer,
566 alc268_capture_nosrc_mixer },
567 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
568 alc268_acer_aspire_one_verbs },
569 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
570 .dac_nids = alc268_dac_nids,
571 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
572 .adc_nids = alc268_adc_nids_alt,
573 .capsrc_nids = alc268_capsrc_nids,
574 .hp_nid = 0x03,
575 .num_channel_mode = ARRAY_SIZE(alc268_modes),
576 .channel_mode = alc268_modes,
577 .unsol_event = alc_sku_unsol_event,
578 .setup = alc268_acer_lc_setup,
579 .init_hook = alc_inithook,
580 },
581 [ALC268_DELL] = {
582 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
583 alc268_capture_nosrc_mixer },
584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
585 alc268_dell_verbs },
586 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
587 .dac_nids = alc268_dac_nids,
588 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
589 .adc_nids = alc268_adc_nids_alt,
590 .capsrc_nids = alc268_capsrc_nids,
591 .hp_nid = 0x02,
592 .num_channel_mode = ARRAY_SIZE(alc268_modes),
593 .channel_mode = alc268_modes,
594 .unsol_event = alc_sku_unsol_event,
595 .setup = alc268_dell_setup,
596 .init_hook = alc_inithook,
597 },
598 [ALC268_ZEPTO] = {
599 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
600 alc268_beep_mixer },
601 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
602 alc268_toshiba_verbs },
603 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
604 .dac_nids = alc268_dac_nids,
605 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
606 .adc_nids = alc268_adc_nids_alt,
607 .capsrc_nids = alc268_capsrc_nids,
608 .hp_nid = 0x03,
609 .dig_out_nid = ALC268_DIGOUT_NID,
610 .num_channel_mode = ARRAY_SIZE(alc268_modes),
611 .channel_mode = alc268_modes,
612 .input_mux = &alc268_capture_source,
613 .unsol_event = alc_sku_unsol_event,
614 .setup = alc268_toshiba_setup,
615 .init_hook = alc_inithook,
616 },
617#ifdef CONFIG_SND_DEBUG
618 [ALC268_TEST] = {
619 .mixers = { alc268_test_mixer, alc268_capture_mixer },
620 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
621 alc268_volume_init_verbs,
622 alc268_beep_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
624 .dac_nids = alc268_dac_nids,
625 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
626 .adc_nids = alc268_adc_nids_alt,
627 .capsrc_nids = alc268_capsrc_nids,
628 .hp_nid = 0x03,
629 .dig_out_nid = ALC268_DIGOUT_NID,
630 .num_channel_mode = ARRAY_SIZE(alc268_modes),
631 .channel_mode = alc268_modes,
632 .input_mux = &alc268_capture_source,
633 },
634#endif
635};
636
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c
new file mode 100644
index 000000000000..14fdcf29b154
--- /dev/null
+++ b/sound/pci/hda/alc269_quirks.c
@@ -0,0 +1,681 @@
1/*
2 * ALC269/ALC270/ALC275/ALC276 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC269 models */
7enum {
8 ALC269_AUTO,
9 ALC269_BASIC,
10 ALC269_QUANTA_FL1,
11 ALC269_AMIC,
12 ALC269_DMIC,
13 ALC269VB_AMIC,
14 ALC269VB_DMIC,
15 ALC269_FUJITSU,
16 ALC269_LIFEBOOK,
17 ALC271_ACER,
18 ALC269_MODEL_LAST /* last tag */
19};
20
21/*
22 * ALC269 channel source setting (2 channel)
23 */
24#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
25
26#define alc269_dac_nids alc260_dac_nids
27
28static const hda_nid_t alc269_adc_nids[1] = {
29 /* ADC1 */
30 0x08,
31};
32
33static const hda_nid_t alc269_capsrc_nids[1] = {
34 0x23,
35};
36
37static const hda_nid_t alc269vb_adc_nids[1] = {
38 /* ADC1 */
39 0x09,
40};
41
42static const hda_nid_t alc269vb_capsrc_nids[1] = {
43 0x22,
44};
45
46#define alc269_modes alc260_modes
47#define alc269_capture_source alc880_lg_lw_capture_source
48
49static const struct snd_kcontrol_new alc269_base_mixer[] = {
50 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
51 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
52 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
53 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
54 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
55 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
56 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
57 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
58 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
59 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
60 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
61 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
62 { } /* end */
63};
64
65static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
66 /* output mixer control */
67 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
68 {
69 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
70 .name = "Master Playback Switch",
71 .subdevice = HDA_SUBDEV_AMP_FLAG,
72 .info = snd_hda_mixer_amp_switch_info,
73 .get = snd_hda_mixer_amp_switch_get,
74 .put = alc268_acer_master_sw_put,
75 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
76 },
77 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
78 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
79 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
80 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
81 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
82 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
83 { }
84};
85
86static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
87 /* output mixer control */
88 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
89 {
90 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
91 .name = "Master Playback Switch",
92 .subdevice = HDA_SUBDEV_AMP_FLAG,
93 .info = snd_hda_mixer_amp_switch_info,
94 .get = snd_hda_mixer_amp_switch_get,
95 .put = alc268_acer_master_sw_put,
96 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
97 },
98 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
99 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
100 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
102 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
103 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
105 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
106 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
107 { }
108};
109
110static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
111 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
113 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
114 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
115 { } /* end */
116};
117
118static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
119 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
123 { } /* end */
124};
125
126static const struct snd_kcontrol_new alc269_asus_mixer[] = {
127 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
128 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
129 { } /* end */
130};
131
132/* capture mixer elements */
133static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
134 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
135 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
136 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
138 { } /* end */
139};
140
141static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
142 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
143 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
144 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
145 { } /* end */
146};
147
148static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
149 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
150 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
152 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
153 { } /* end */
154};
155
156static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
157 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
158 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
159 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
160 { } /* end */
161};
162
163/* FSC amilo */
164#define alc269_fujitsu_mixer alc269_laptop_mixer
165
166static const struct hda_verb alc269_quanta_fl1_verbs[] = {
167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
168 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
169 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
170 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
171 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
172 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
173 { }
174};
175
176static const struct hda_verb alc269_lifebook_verbs[] = {
177 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
178 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
179 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
180 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
181 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
182 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
183 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
184 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
185 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
186 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
187 { }
188};
189
190/* toggle speaker-output according to the hp-jack state */
191static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
192{
193 alc_hp_automute(codec);
194
195 snd_hda_codec_write(codec, 0x20, 0,
196 AC_VERB_SET_COEF_INDEX, 0x0c);
197 snd_hda_codec_write(codec, 0x20, 0,
198 AC_VERB_SET_PROC_COEF, 0x680);
199
200 snd_hda_codec_write(codec, 0x20, 0,
201 AC_VERB_SET_COEF_INDEX, 0x0c);
202 snd_hda_codec_write(codec, 0x20, 0,
203 AC_VERB_SET_PROC_COEF, 0x480);
204}
205
206#define alc269_lifebook_speaker_automute \
207 alc269_quanta_fl1_speaker_automute
208
209static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
210{
211 unsigned int present_laptop;
212 unsigned int present_dock;
213
214 present_laptop = snd_hda_jack_detect(codec, 0x18);
215 present_dock = snd_hda_jack_detect(codec, 0x1b);
216
217 /* Laptop mic port overrides dock mic port, design decision */
218 if (present_dock)
219 snd_hda_codec_write(codec, 0x23, 0,
220 AC_VERB_SET_CONNECT_SEL, 0x3);
221 if (present_laptop)
222 snd_hda_codec_write(codec, 0x23, 0,
223 AC_VERB_SET_CONNECT_SEL, 0x0);
224 if (!present_dock && !present_laptop)
225 snd_hda_codec_write(codec, 0x23, 0,
226 AC_VERB_SET_CONNECT_SEL, 0x1);
227}
228
229static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
230 unsigned int res)
231{
232 switch (res >> 26) {
233 case ALC_HP_EVENT:
234 alc269_quanta_fl1_speaker_automute(codec);
235 break;
236 case ALC_MIC_EVENT:
237 alc_mic_automute(codec);
238 break;
239 }
240}
241
242static void alc269_lifebook_unsol_event(struct hda_codec *codec,
243 unsigned int res)
244{
245 if ((res >> 26) == ALC_HP_EVENT)
246 alc269_lifebook_speaker_automute(codec);
247 if ((res >> 26) == ALC_MIC_EVENT)
248 alc269_lifebook_mic_autoswitch(codec);
249}
250
251static void alc269_quanta_fl1_setup(struct hda_codec *codec)
252{
253 struct alc_spec *spec = codec->spec;
254 spec->autocfg.hp_pins[0] = 0x15;
255 spec->autocfg.speaker_pins[0] = 0x14;
256 spec->automute_mixer_nid[0] = 0x0c;
257 spec->automute = 1;
258 spec->automute_mode = ALC_AUTOMUTE_MIXER;
259 spec->ext_mic_pin = 0x18;
260 spec->int_mic_pin = 0x19;
261 spec->auto_mic = 1;
262}
263
264static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
265{
266 alc269_quanta_fl1_speaker_automute(codec);
267 alc_mic_automute(codec);
268}
269
270static void alc269_lifebook_setup(struct hda_codec *codec)
271{
272 struct alc_spec *spec = codec->spec;
273 spec->autocfg.hp_pins[0] = 0x15;
274 spec->autocfg.hp_pins[1] = 0x1a;
275 spec->autocfg.speaker_pins[0] = 0x14;
276 spec->automute_mixer_nid[0] = 0x0c;
277 spec->automute = 1;
278 spec->automute_mode = ALC_AUTOMUTE_MIXER;
279}
280
281static void alc269_lifebook_init_hook(struct hda_codec *codec)
282{
283 alc269_lifebook_speaker_automute(codec);
284 alc269_lifebook_mic_autoswitch(codec);
285}
286
287static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
288 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
289 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
290 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
291 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
292 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
295 {}
296};
297
298static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
299 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
300 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
301 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
302 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
303 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
305 {}
306};
307
308static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
309 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
310 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
311 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
313 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
314 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
315 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
316 {}
317};
318
319static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
320 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
321 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
322 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
323 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
325 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
326 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
327 {}
328};
329
330static const struct hda_verb alc271_acer_dmic_verbs[] = {
331 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
332 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
333 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
336 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
337 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
338 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
339 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
340 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
341 { }
342};
343
344static void alc269_laptop_amic_setup(struct hda_codec *codec)
345{
346 struct alc_spec *spec = codec->spec;
347 spec->autocfg.hp_pins[0] = 0x15;
348 spec->autocfg.speaker_pins[0] = 0x14;
349 spec->automute_mixer_nid[0] = 0x0c;
350 spec->automute = 1;
351 spec->automute_mode = ALC_AUTOMUTE_MIXER;
352 spec->ext_mic_pin = 0x18;
353 spec->int_mic_pin = 0x19;
354 spec->auto_mic = 1;
355}
356
357static void alc269_laptop_dmic_setup(struct hda_codec *codec)
358{
359 struct alc_spec *spec = codec->spec;
360 spec->autocfg.hp_pins[0] = 0x15;
361 spec->autocfg.speaker_pins[0] = 0x14;
362 spec->automute_mixer_nid[0] = 0x0c;
363 spec->automute = 1;
364 spec->automute_mode = ALC_AUTOMUTE_MIXER;
365 spec->ext_mic_pin = 0x18;
366 spec->int_mic_pin = 0x12;
367 spec->auto_mic = 1;
368}
369
370static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
371{
372 struct alc_spec *spec = codec->spec;
373 spec->autocfg.hp_pins[0] = 0x21;
374 spec->autocfg.speaker_pins[0] = 0x14;
375 spec->automute_mixer_nid[0] = 0x0c;
376 spec->automute = 1;
377 spec->automute_mode = ALC_AUTOMUTE_MIXER;
378 spec->ext_mic_pin = 0x18;
379 spec->int_mic_pin = 0x19;
380 spec->auto_mic = 1;
381}
382
383static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
384{
385 struct alc_spec *spec = codec->spec;
386 spec->autocfg.hp_pins[0] = 0x21;
387 spec->autocfg.speaker_pins[0] = 0x14;
388 spec->automute_mixer_nid[0] = 0x0c;
389 spec->automute = 1;
390 spec->automute_mode = ALC_AUTOMUTE_MIXER;
391 spec->ext_mic_pin = 0x18;
392 spec->int_mic_pin = 0x12;
393 spec->auto_mic = 1;
394}
395
396/*
397 * generic initialization of ADC, input mixers and output mixers
398 */
399static const struct hda_verb alc269_init_verbs[] = {
400 /*
401 * Unmute ADC0 and set the default input to mic-in
402 */
403 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
404
405 /*
406 * Set up output mixers (0x02 - 0x03)
407 */
408 /* set vol=0 to output mixers */
409 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
410 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
411
412 /* set up input amps for analog loopback */
413 /* Amp Indices: DAC = 0, mixer = 1 */
414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
420
421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
425 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
426 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
427 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
428
429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
430 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
431
432 /* FIXME: use Mux-type input source selection */
433 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
434 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
435 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
436
437 /* set EAPD */
438 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
439 { }
440};
441
442static const struct hda_verb alc269vb_init_verbs[] = {
443 /*
444 * Unmute ADC0 and set the default input to mic-in
445 */
446 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
447
448 /*
449 * Set up output mixers (0x02 - 0x03)
450 */
451 /* set vol=0 to output mixers */
452 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
453 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
454
455 /* set up input amps for analog loopback */
456 /* Amp Indices: DAC = 0, mixer = 1 */
457 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
458 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
459 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
460 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
463
464 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
465 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
467 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
468 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
469 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
471
472 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
473 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
474
475 /* FIXME: use Mux-type input source selection */
476 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
477 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
478 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
479
480 /* set EAPD */
481 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
482 { }
483};
484
485/*
486 * configuration and preset
487 */
488static const char * const alc269_models[ALC269_MODEL_LAST] = {
489 [ALC269_BASIC] = "basic",
490 [ALC269_QUANTA_FL1] = "quanta",
491 [ALC269_AMIC] = "laptop-amic",
492 [ALC269_DMIC] = "laptop-dmic",
493 [ALC269_FUJITSU] = "fujitsu",
494 [ALC269_LIFEBOOK] = "lifebook",
495 [ALC269_AUTO] = "auto",
496};
497
498static const struct snd_pci_quirk alc269_cfg_tbl[] = {
499 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
500 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
501 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
502 ALC269_AMIC),
503 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
504 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
505 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
506 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
507 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
508 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
509 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
510 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
511 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
512 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
513 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
514 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
515 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
516 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
517 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
518 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
519 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
520 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
521 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
522 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
523 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
524 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
525 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
526 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
527 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
528 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
529 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
530 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
531 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
532 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
533 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
534 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
535 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
538 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
539 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
540 ALC269_DMIC),
541 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
542 ALC269_DMIC),
543 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
544 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
545 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
546 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
547 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
548 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
549 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
550 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
551 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
552 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
553 {}
554};
555
556static const struct alc_config_preset alc269_presets[] = {
557 [ALC269_BASIC] = {
558 .mixers = { alc269_base_mixer },
559 .init_verbs = { alc269_init_verbs },
560 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
561 .dac_nids = alc269_dac_nids,
562 .hp_nid = 0x03,
563 .num_channel_mode = ARRAY_SIZE(alc269_modes),
564 .channel_mode = alc269_modes,
565 .input_mux = &alc269_capture_source,
566 },
567 [ALC269_QUANTA_FL1] = {
568 .mixers = { alc269_quanta_fl1_mixer },
569 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
570 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
571 .dac_nids = alc269_dac_nids,
572 .hp_nid = 0x03,
573 .num_channel_mode = ARRAY_SIZE(alc269_modes),
574 .channel_mode = alc269_modes,
575 .input_mux = &alc269_capture_source,
576 .unsol_event = alc269_quanta_fl1_unsol_event,
577 .setup = alc269_quanta_fl1_setup,
578 .init_hook = alc269_quanta_fl1_init_hook,
579 },
580 [ALC269_AMIC] = {
581 .mixers = { alc269_laptop_mixer },
582 .cap_mixer = alc269_laptop_analog_capture_mixer,
583 .init_verbs = { alc269_init_verbs,
584 alc269_laptop_amic_init_verbs },
585 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
586 .dac_nids = alc269_dac_nids,
587 .hp_nid = 0x03,
588 .num_channel_mode = ARRAY_SIZE(alc269_modes),
589 .channel_mode = alc269_modes,
590 .unsol_event = alc_sku_unsol_event,
591 .setup = alc269_laptop_amic_setup,
592 .init_hook = alc_inithook,
593 },
594 [ALC269_DMIC] = {
595 .mixers = { alc269_laptop_mixer },
596 .cap_mixer = alc269_laptop_digital_capture_mixer,
597 .init_verbs = { alc269_init_verbs,
598 alc269_laptop_dmic_init_verbs },
599 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
600 .dac_nids = alc269_dac_nids,
601 .hp_nid = 0x03,
602 .num_channel_mode = ARRAY_SIZE(alc269_modes),
603 .channel_mode = alc269_modes,
604 .unsol_event = alc_sku_unsol_event,
605 .setup = alc269_laptop_dmic_setup,
606 .init_hook = alc_inithook,
607 },
608 [ALC269VB_AMIC] = {
609 .mixers = { alc269vb_laptop_mixer },
610 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
611 .init_verbs = { alc269vb_init_verbs,
612 alc269vb_laptop_amic_init_verbs },
613 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
614 .dac_nids = alc269_dac_nids,
615 .hp_nid = 0x03,
616 .num_channel_mode = ARRAY_SIZE(alc269_modes),
617 .channel_mode = alc269_modes,
618 .unsol_event = alc_sku_unsol_event,
619 .setup = alc269vb_laptop_amic_setup,
620 .init_hook = alc_inithook,
621 },
622 [ALC269VB_DMIC] = {
623 .mixers = { alc269vb_laptop_mixer },
624 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
625 .init_verbs = { alc269vb_init_verbs,
626 alc269vb_laptop_dmic_init_verbs },
627 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
628 .dac_nids = alc269_dac_nids,
629 .hp_nid = 0x03,
630 .num_channel_mode = ARRAY_SIZE(alc269_modes),
631 .channel_mode = alc269_modes,
632 .unsol_event = alc_sku_unsol_event,
633 .setup = alc269vb_laptop_dmic_setup,
634 .init_hook = alc_inithook,
635 },
636 [ALC269_FUJITSU] = {
637 .mixers = { alc269_fujitsu_mixer },
638 .cap_mixer = alc269_laptop_digital_capture_mixer,
639 .init_verbs = { alc269_init_verbs,
640 alc269_laptop_dmic_init_verbs },
641 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
642 .dac_nids = alc269_dac_nids,
643 .hp_nid = 0x03,
644 .num_channel_mode = ARRAY_SIZE(alc269_modes),
645 .channel_mode = alc269_modes,
646 .unsol_event = alc_sku_unsol_event,
647 .setup = alc269_laptop_dmic_setup,
648 .init_hook = alc_inithook,
649 },
650 [ALC269_LIFEBOOK] = {
651 .mixers = { alc269_lifebook_mixer },
652 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
653 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
654 .dac_nids = alc269_dac_nids,
655 .hp_nid = 0x03,
656 .num_channel_mode = ARRAY_SIZE(alc269_modes),
657 .channel_mode = alc269_modes,
658 .input_mux = &alc269_capture_source,
659 .unsol_event = alc269_lifebook_unsol_event,
660 .setup = alc269_lifebook_setup,
661 .init_hook = alc269_lifebook_init_hook,
662 },
663 [ALC271_ACER] = {
664 .mixers = { alc269_asus_mixer },
665 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
666 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
667 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
668 .dac_nids = alc269_dac_nids,
669 .adc_nids = alc262_dmic_adc_nids,
670 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
671 .capsrc_nids = alc262_dmic_capsrc_nids,
672 .num_channel_mode = ARRAY_SIZE(alc269_modes),
673 .channel_mode = alc269_modes,
674 .input_mux = &alc269_capture_source,
675 .dig_out_nid = ALC880_DIGOUT_NID,
676 .unsol_event = alc_sku_unsol_event,
677 .setup = alc269vb_laptop_dmic_setup,
678 .init_hook = alc_inithook,
679 },
680};
681
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c
new file mode 100644
index 000000000000..e69a6ea3083a
--- /dev/null
+++ b/sound/pci/hda/alc662_quirks.c
@@ -0,0 +1,1408 @@
1/*
2 * ALC662/ALC663/ALC665/ALC670 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC662 models */
7enum {
8 ALC662_AUTO,
9 ALC662_3ST_2ch_DIG,
10 ALC662_3ST_6ch_DIG,
11 ALC662_3ST_6ch,
12 ALC662_5ST_DIG,
13 ALC662_LENOVO_101E,
14 ALC662_ASUS_EEEPC_P701,
15 ALC662_ASUS_EEEPC_EP20,
16 ALC663_ASUS_M51VA,
17 ALC663_ASUS_G71V,
18 ALC663_ASUS_H13,
19 ALC663_ASUS_G50V,
20 ALC662_ECS,
21 ALC663_ASUS_MODE1,
22 ALC662_ASUS_MODE2,
23 ALC663_ASUS_MODE3,
24 ALC663_ASUS_MODE4,
25 ALC663_ASUS_MODE5,
26 ALC663_ASUS_MODE6,
27 ALC663_ASUS_MODE7,
28 ALC663_ASUS_MODE8,
29 ALC272_DELL,
30 ALC272_DELL_ZM1,
31 ALC272_SAMSUNG_NC10,
32 ALC662_MODEL_LAST,
33};
34
35#define ALC662_DIGOUT_NID 0x06
36#define ALC662_DIGIN_NID 0x0a
37
38static const hda_nid_t alc662_dac_nids[3] = {
39 /* front, rear, clfe */
40 0x02, 0x03, 0x04
41};
42
43static const hda_nid_t alc272_dac_nids[2] = {
44 0x02, 0x03
45};
46
47static const hda_nid_t alc662_adc_nids[2] = {
48 /* ADC1-2 */
49 0x09, 0x08
50};
51
52static const hda_nid_t alc272_adc_nids[1] = {
53 /* ADC1-2 */
54 0x08,
55};
56
57static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
58static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
59
60
61/* input MUX */
62/* FIXME: should be a matrix-type input source selection */
63static const struct hda_input_mux alc662_capture_source = {
64 .num_items = 4,
65 .items = {
66 { "Mic", 0x0 },
67 { "Front Mic", 0x1 },
68 { "Line", 0x2 },
69 { "CD", 0x4 },
70 },
71};
72
73static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
74 .num_items = 2,
75 .items = {
76 { "Mic", 0x1 },
77 { "Line", 0x2 },
78 },
79};
80
81static const struct hda_input_mux alc663_capture_source = {
82 .num_items = 3,
83 .items = {
84 { "Mic", 0x0 },
85 { "Front Mic", 0x1 },
86 { "Line", 0x2 },
87 },
88};
89
90#if 0 /* set to 1 for testing other input sources below */
91static const struct hda_input_mux alc272_nc10_capture_source = {
92 .num_items = 16,
93 .items = {
94 { "Autoselect Mic", 0x0 },
95 { "Internal Mic", 0x1 },
96 { "In-0x02", 0x2 },
97 { "In-0x03", 0x3 },
98 { "In-0x04", 0x4 },
99 { "In-0x05", 0x5 },
100 { "In-0x06", 0x6 },
101 { "In-0x07", 0x7 },
102 { "In-0x08", 0x8 },
103 { "In-0x09", 0x9 },
104 { "In-0x0a", 0x0a },
105 { "In-0x0b", 0x0b },
106 { "In-0x0c", 0x0c },
107 { "In-0x0d", 0x0d },
108 { "In-0x0e", 0x0e },
109 { "In-0x0f", 0x0f },
110 },
111};
112#endif
113
114/*
115 * 2ch mode
116 */
117static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
118 { 2, NULL }
119};
120
121/*
122 * 2ch mode
123 */
124static const struct hda_verb alc662_3ST_ch2_init[] = {
125 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
126 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
127 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
128 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
129 { } /* end */
130};
131
132/*
133 * 6ch mode
134 */
135static const struct hda_verb alc662_3ST_ch6_init[] = {
136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
138 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
141 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
142 { } /* end */
143};
144
145static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
146 { 2, alc662_3ST_ch2_init },
147 { 6, alc662_3ST_ch6_init },
148};
149
150/*
151 * 2ch mode
152 */
153static const struct hda_verb alc662_sixstack_ch6_init[] = {
154 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
155 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
156 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
157 { } /* end */
158};
159
160/*
161 * 6ch mode
162 */
163static const struct hda_verb alc662_sixstack_ch8_init[] = {
164 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
165 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
166 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
167 { } /* end */
168};
169
170static const struct hda_channel_mode alc662_5stack_modes[2] = {
171 { 2, alc662_sixstack_ch6_init },
172 { 6, alc662_sixstack_ch8_init },
173};
174
175/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
176 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
177 */
178
179static const struct snd_kcontrol_new alc662_base_mixer[] = {
180 /* output mixer control */
181 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
182 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
183 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
184 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
185 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
186 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
187 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
188 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
189 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
190
191 /*Input mixer control */
192 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
193 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
194 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
195 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
196 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
197 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
200 { } /* end */
201};
202
203static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
204 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
205 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
206 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
215 { } /* end */
216};
217
218static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
219 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
220 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
222 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
224 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
226 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
227 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
228 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
229 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
230 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
231 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
232 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
233 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
234 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
235 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
236 { } /* end */
237};
238
239static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
240 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
241 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
242 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
243 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
244 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
249 { } /* end */
250};
251
252static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
253 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
254 ALC262_HIPPO_MASTER_SWITCH,
255
256 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
258 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
259
260 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
261 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
262 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
263 { } /* end */
264};
265
266static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
267 ALC262_HIPPO_MASTER_SWITCH,
268 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
270 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
271 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
274 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
275 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
277 { } /* end */
278};
279
280static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
281 .ops = &snd_hda_bind_vol,
282 .values = {
283 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
284 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
285 0
286 },
287};
288
289static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
290 .ops = &snd_hda_bind_sw,
291 .values = {
292 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
293 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
294 0
295 },
296};
297
298static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
299 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
300 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
303 { } /* end */
304};
305
306static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
307 .ops = &snd_hda_bind_sw,
308 .values = {
309 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
310 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
311 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
312 0
313 },
314};
315
316static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
317 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
318 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
319 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
321 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
322 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
323
324 { } /* end */
325};
326
327static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
328 .ops = &snd_hda_bind_sw,
329 .values = {
330 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
331 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
332 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
333 0
334 },
335};
336
337static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
338 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
339 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
340 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
341 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
342 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
343 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
344 { } /* end */
345};
346
347static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
349 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
353 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
354 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
355 { } /* end */
356};
357
358static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
359 .ops = &snd_hda_bind_vol,
360 .values = {
361 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
362 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
363 0
364 },
365};
366
367static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
368 .ops = &snd_hda_bind_sw,
369 .values = {
370 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
371 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
372 0
373 },
374};
375
376static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
377 HDA_BIND_VOL("Master Playback Volume",
378 &alc663_asus_two_bind_master_vol),
379 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
380 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
381 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
382 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
383 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
384 { } /* end */
385};
386
387static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
388 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
389 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
390 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
391 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
394 { } /* end */
395};
396
397static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
398 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
399 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
400 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
403
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
408 { } /* end */
409};
410
411static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
412 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
413 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
414 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
415
416 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
417 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
418 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
419 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
420 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
421 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
422 { } /* end */
423};
424
425static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
426 .ops = &snd_hda_bind_sw,
427 .values = {
428 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
429 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
430 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
431 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
432 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
433 0
434 },
435};
436
437static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
438 .ops = &snd_hda_bind_sw,
439 .values = {
440 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
441 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
442 0
443 },
444};
445
446static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
447 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
448 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
449 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
450 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
451 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
452 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
453 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
456 { } /* end */
457};
458
459static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
460 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
461 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
462 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
463 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
464 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
465 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
466 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
467 { } /* end */
468};
469
470
471static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
472 {
473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
474 .name = "Channel Mode",
475 .info = alc_ch_mode_info,
476 .get = alc_ch_mode_get,
477 .put = alc_ch_mode_put,
478 },
479 { } /* end */
480};
481
482static const struct hda_verb alc662_init_verbs[] = {
483 /* ADC: mute amp left and right */
484 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
485 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
486
487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
488 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
489 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
490 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
491 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
492 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
493
494 /* Front Pin: output 0 (0x0c) */
495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
496 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
497
498 /* Rear Pin: output 1 (0x0d) */
499 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
501
502 /* CLFE Pin: output 2 (0x0e) */
503 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
505
506 /* Mic (rear) pin: input vref at 80% */
507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
509 /* Front Mic pin: input vref at 80% */
510 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
511 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
512 /* Line In pin: input */
513 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
514 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
515 /* Line-2 In: Headphone output (output 0 - 0x0c) */
516 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
517 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
518 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
519 /* CD pin widget for input */
520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
521
522 /* FIXME: use matrix-type input source selection */
523 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
524 /* Input mixer */
525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
527
528 { }
529};
530
531static const struct hda_verb alc662_eapd_init_verbs[] = {
532 /* always trun on EAPD */
533 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
534 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
535 { }
536};
537
538static const struct hda_verb alc662_sue_init_verbs[] = {
539 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
540 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
541 {}
542};
543
544static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
545 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
546 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
547 {}
548};
549
550/* Set Unsolicited Event*/
551static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
552 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
554 {}
555};
556
557static const struct hda_verb alc663_m51va_init_verbs[] = {
558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
559 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
560 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
561 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
562 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
563 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
564 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
565 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
566 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
567 {}
568};
569
570static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
571 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
572 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
573 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
574 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
575 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
576 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
577 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
578 {}
579};
580
581static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
583 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
585 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
588 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
589 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
590 {}
591};
592
593static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
594 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
595 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
596 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
597 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
598 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
600 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
601 {}
602};
603
604static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
606 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
607 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
608 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
614 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
615 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
616 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
617 {}
618};
619
620static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
621 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
622 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
623 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
625 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
626 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
628 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
629 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
630 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
631 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
632 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
633 {}
634};
635
636static const struct hda_verb alc663_g71v_init_verbs[] = {
637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
638 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
639 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
640
641 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
642 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
643 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
644
645 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT},
646 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_MIC_EVENT},
647 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
648 {}
649};
650
651static const struct hda_verb alc663_g50v_init_verbs[] = {
652 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
653 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
655
656 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
657 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
658 {}
659};
660
661static const struct hda_verb alc662_ecs_init_verbs[] = {
662 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
664 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
665 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
666 {}
667};
668
669static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
670 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
671 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
672 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
674 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
675 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
676 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
679 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
680 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
681 {}
682};
683
684static const struct hda_verb alc272_dell_init_verbs[] = {
685 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
686 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
688 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
689 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
690 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
691 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
692 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
693 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
694 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
695 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
696 {}
697};
698
699static const struct hda_verb alc663_mode7_init_verbs[] = {
700 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
701 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
702 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
703 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
704 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
705 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
706 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
707 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
708 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
709 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
710 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
711 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
712 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
713 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
714 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
715 {}
716};
717
718static const struct hda_verb alc663_mode8_init_verbs[] = {
719 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
721 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
723 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
725 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
727 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
728 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
729 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
732 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
733 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
734 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {}
736};
737
738static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
739 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
740 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
741 { } /* end */
742};
743
744static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
745 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
746 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
747 { } /* end */
748};
749
750static void alc662_lenovo_101e_setup(struct hda_codec *codec)
751{
752 struct alc_spec *spec = codec->spec;
753
754 spec->autocfg.hp_pins[0] = 0x1b;
755 spec->autocfg.line_out_pins[0] = 0x14;
756 spec->autocfg.speaker_pins[0] = 0x15;
757 spec->automute = 1;
758 spec->detect_line = 1;
759 spec->automute_lines = 1;
760 spec->automute_mode = ALC_AUTOMUTE_AMP;
761}
762
763static void alc662_eeepc_setup(struct hda_codec *codec)
764{
765 struct alc_spec *spec = codec->spec;
766
767 alc262_hippo1_setup(codec);
768 spec->ext_mic_pin = 0x18;
769 spec->int_mic_pin = 0x19;
770 spec->auto_mic = 1;
771}
772
773static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
774{
775 struct alc_spec *spec = codec->spec;
776
777 spec->autocfg.hp_pins[0] = 0x14;
778 spec->autocfg.speaker_pins[0] = 0x1b;
779 spec->automute = 1;
780 spec->automute_mode = ALC_AUTOMUTE_AMP;
781}
782
783static void alc663_m51va_setup(struct hda_codec *codec)
784{
785 struct alc_spec *spec = codec->spec;
786 spec->autocfg.hp_pins[0] = 0x21;
787 spec->autocfg.speaker_pins[0] = 0x14;
788 spec->automute_mixer_nid[0] = 0x0c;
789 spec->automute = 1;
790 spec->automute_mode = ALC_AUTOMUTE_MIXER;
791 spec->ext_mic_pin = 0x18;
792 spec->int_mic_pin = 0x12;
793 spec->auto_mic = 1;
794}
795
796/* ***************** Mode1 ******************************/
797static void alc663_mode1_setup(struct hda_codec *codec)
798{
799 struct alc_spec *spec = codec->spec;
800 spec->autocfg.hp_pins[0] = 0x21;
801 spec->autocfg.speaker_pins[0] = 0x14;
802 spec->automute_mixer_nid[0] = 0x0c;
803 spec->automute = 1;
804 spec->automute_mode = ALC_AUTOMUTE_MIXER;
805 spec->ext_mic_pin = 0x18;
806 spec->int_mic_pin = 0x19;
807 spec->auto_mic = 1;
808}
809
810/* ***************** Mode2 ******************************/
811static void alc662_mode2_setup(struct hda_codec *codec)
812{
813 struct alc_spec *spec = codec->spec;
814 spec->autocfg.hp_pins[0] = 0x1b;
815 spec->autocfg.speaker_pins[0] = 0x14;
816 spec->automute = 1;
817 spec->automute_mode = ALC_AUTOMUTE_PIN;
818 spec->ext_mic_pin = 0x18;
819 spec->int_mic_pin = 0x19;
820 spec->auto_mic = 1;
821}
822
823/* ***************** Mode3 ******************************/
824static void alc663_mode3_setup(struct hda_codec *codec)
825{
826 struct alc_spec *spec = codec->spec;
827 spec->autocfg.hp_pins[0] = 0x21;
828 spec->autocfg.hp_pins[0] = 0x15;
829 spec->autocfg.speaker_pins[0] = 0x14;
830 spec->automute = 1;
831 spec->automute_mode = ALC_AUTOMUTE_PIN;
832 spec->ext_mic_pin = 0x18;
833 spec->int_mic_pin = 0x19;
834 spec->auto_mic = 1;
835}
836
837/* ***************** Mode4 ******************************/
838static void alc663_mode4_setup(struct hda_codec *codec)
839{
840 struct alc_spec *spec = codec->spec;
841 spec->autocfg.hp_pins[0] = 0x21;
842 spec->autocfg.speaker_pins[0] = 0x14;
843 spec->autocfg.speaker_pins[1] = 0x16;
844 spec->automute_mixer_nid[0] = 0x0c;
845 spec->automute_mixer_nid[1] = 0x0e;
846 spec->automute = 1;
847 spec->automute_mode = ALC_AUTOMUTE_MIXER;
848 spec->ext_mic_pin = 0x18;
849 spec->int_mic_pin = 0x19;
850 spec->auto_mic = 1;
851}
852
853/* ***************** Mode5 ******************************/
854static void alc663_mode5_setup(struct hda_codec *codec)
855{
856 struct alc_spec *spec = codec->spec;
857 spec->autocfg.hp_pins[0] = 0x15;
858 spec->autocfg.speaker_pins[0] = 0x14;
859 spec->autocfg.speaker_pins[1] = 0x16;
860 spec->automute_mixer_nid[0] = 0x0c;
861 spec->automute_mixer_nid[1] = 0x0e;
862 spec->automute = 1;
863 spec->automute_mode = ALC_AUTOMUTE_MIXER;
864 spec->ext_mic_pin = 0x18;
865 spec->int_mic_pin = 0x19;
866 spec->auto_mic = 1;
867}
868
869/* ***************** Mode6 ******************************/
870static void alc663_mode6_setup(struct hda_codec *codec)
871{
872 struct alc_spec *spec = codec->spec;
873 spec->autocfg.hp_pins[0] = 0x1b;
874 spec->autocfg.hp_pins[0] = 0x15;
875 spec->autocfg.speaker_pins[0] = 0x14;
876 spec->automute_mixer_nid[0] = 0x0c;
877 spec->automute = 1;
878 spec->automute_mode = ALC_AUTOMUTE_MIXER;
879 spec->ext_mic_pin = 0x18;
880 spec->int_mic_pin = 0x19;
881 spec->auto_mic = 1;
882}
883
884/* ***************** Mode7 ******************************/
885static void alc663_mode7_setup(struct hda_codec *codec)
886{
887 struct alc_spec *spec = codec->spec;
888 spec->autocfg.hp_pins[0] = 0x1b;
889 spec->autocfg.hp_pins[0] = 0x21;
890 spec->autocfg.speaker_pins[0] = 0x14;
891 spec->autocfg.speaker_pins[0] = 0x17;
892 spec->automute = 1;
893 spec->automute_mode = ALC_AUTOMUTE_PIN;
894 spec->ext_mic_pin = 0x18;
895 spec->int_mic_pin = 0x19;
896 spec->auto_mic = 1;
897}
898
899/* ***************** Mode8 ******************************/
900static void alc663_mode8_setup(struct hda_codec *codec)
901{
902 struct alc_spec *spec = codec->spec;
903 spec->autocfg.hp_pins[0] = 0x21;
904 spec->autocfg.hp_pins[1] = 0x15;
905 spec->autocfg.speaker_pins[0] = 0x14;
906 spec->autocfg.speaker_pins[0] = 0x17;
907 spec->automute = 1;
908 spec->automute_mode = ALC_AUTOMUTE_PIN;
909 spec->ext_mic_pin = 0x18;
910 spec->int_mic_pin = 0x12;
911 spec->auto_mic = 1;
912}
913
914static void alc663_g71v_setup(struct hda_codec *codec)
915{
916 struct alc_spec *spec = codec->spec;
917 spec->autocfg.hp_pins[0] = 0x21;
918 spec->autocfg.line_out_pins[0] = 0x15;
919 spec->autocfg.speaker_pins[0] = 0x14;
920 spec->automute = 1;
921 spec->automute_mode = ALC_AUTOMUTE_AMP;
922 spec->detect_line = 1;
923 spec->automute_lines = 1;
924 spec->ext_mic_pin = 0x18;
925 spec->int_mic_pin = 0x12;
926 spec->auto_mic = 1;
927}
928
929#define alc663_g50v_setup alc663_m51va_setup
930
931static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
932 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
933 ALC262_HIPPO_MASTER_SWITCH,
934
935 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
936 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
937 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
938
939 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
940 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
941 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
942 { } /* end */
943};
944
945static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
946 /* Master Playback automatically created from Speaker and Headphone */
947 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
948 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
949 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
950 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
951
952 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
955
956 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
957 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
958 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
959 { } /* end */
960};
961
962
963/*
964 * configuration and preset
965 */
966static const char * const alc662_models[ALC662_MODEL_LAST] = {
967 [ALC662_3ST_2ch_DIG] = "3stack-dig",
968 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
969 [ALC662_3ST_6ch] = "3stack-6ch",
970 [ALC662_5ST_DIG] = "5stack-dig",
971 [ALC662_LENOVO_101E] = "lenovo-101e",
972 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
973 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
974 [ALC662_ECS] = "ecs",
975 [ALC663_ASUS_M51VA] = "m51va",
976 [ALC663_ASUS_G71V] = "g71v",
977 [ALC663_ASUS_H13] = "h13",
978 [ALC663_ASUS_G50V] = "g50v",
979 [ALC663_ASUS_MODE1] = "asus-mode1",
980 [ALC662_ASUS_MODE2] = "asus-mode2",
981 [ALC663_ASUS_MODE3] = "asus-mode3",
982 [ALC663_ASUS_MODE4] = "asus-mode4",
983 [ALC663_ASUS_MODE5] = "asus-mode5",
984 [ALC663_ASUS_MODE6] = "asus-mode6",
985 [ALC663_ASUS_MODE7] = "asus-mode7",
986 [ALC663_ASUS_MODE8] = "asus-mode8",
987 [ALC272_DELL] = "dell",
988 [ALC272_DELL_ZM1] = "dell-zm1",
989 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
990 [ALC662_AUTO] = "auto",
991};
992
993static const struct snd_pci_quirk alc662_cfg_tbl[] = {
994 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
995 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
996 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
997 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
998 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
999 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
1000 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
1001 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
1002 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
1003 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
1004 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
1005 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
1006 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
1007 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
1008 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
1009 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
1010 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
1011 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
1012 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
1013 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
1014 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
1015 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
1016 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
1017 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
1018 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
1019 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
1020 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
1021 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
1022 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
1023 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
1024 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
1025 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
1026 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
1027 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
1028 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
1029 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
1030 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
1031 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
1032 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
1033 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
1034 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
1035 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
1036 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
1037 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
1038 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
1039 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
1040 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
1041 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
1042 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
1043 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
1044 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
1045 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
1046 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
1047 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
1048 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
1049 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
1050 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
1051 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
1052 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
1053 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
1054 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
1055 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
1056 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
1057 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
1058 ALC662_3ST_6ch_DIG),
1059 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
1060 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
1061 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
1062 ALC662_3ST_6ch_DIG),
1063 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
1064 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
1065 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
1066 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
1067 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
1068 ALC662_3ST_6ch_DIG),
1069 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
1070 ALC663_ASUS_H13),
1071 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
1072 {}
1073};
1074
1075static const struct alc_config_preset alc662_presets[] = {
1076 [ALC662_3ST_2ch_DIG] = {
1077 .mixers = { alc662_3ST_2ch_mixer },
1078 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1079 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1080 .dac_nids = alc662_dac_nids,
1081 .dig_out_nid = ALC662_DIGOUT_NID,
1082 .dig_in_nid = ALC662_DIGIN_NID,
1083 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1084 .channel_mode = alc662_3ST_2ch_modes,
1085 .input_mux = &alc662_capture_source,
1086 },
1087 [ALC662_3ST_6ch_DIG] = {
1088 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1089 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1090 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1091 .dac_nids = alc662_dac_nids,
1092 .dig_out_nid = ALC662_DIGOUT_NID,
1093 .dig_in_nid = ALC662_DIGIN_NID,
1094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1095 .channel_mode = alc662_3ST_6ch_modes,
1096 .need_dac_fix = 1,
1097 .input_mux = &alc662_capture_source,
1098 },
1099 [ALC662_3ST_6ch] = {
1100 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
1101 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1102 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1103 .dac_nids = alc662_dac_nids,
1104 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1105 .channel_mode = alc662_3ST_6ch_modes,
1106 .need_dac_fix = 1,
1107 .input_mux = &alc662_capture_source,
1108 },
1109 [ALC662_5ST_DIG] = {
1110 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
1111 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
1112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1113 .dac_nids = alc662_dac_nids,
1114 .dig_out_nid = ALC662_DIGOUT_NID,
1115 .dig_in_nid = ALC662_DIGIN_NID,
1116 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
1117 .channel_mode = alc662_5stack_modes,
1118 .input_mux = &alc662_capture_source,
1119 },
1120 [ALC662_LENOVO_101E] = {
1121 .mixers = { alc662_lenovo_101e_mixer },
1122 .init_verbs = { alc662_init_verbs,
1123 alc662_eapd_init_verbs,
1124 alc662_sue_init_verbs },
1125 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1126 .dac_nids = alc662_dac_nids,
1127 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1128 .channel_mode = alc662_3ST_2ch_modes,
1129 .input_mux = &alc662_lenovo_101e_capture_source,
1130 .unsol_event = alc_sku_unsol_event,
1131 .setup = alc662_lenovo_101e_setup,
1132 .init_hook = alc_inithook,
1133 },
1134 [ALC662_ASUS_EEEPC_P701] = {
1135 .mixers = { alc662_eeepc_p701_mixer },
1136 .init_verbs = { alc662_init_verbs,
1137 alc662_eapd_init_verbs,
1138 alc662_eeepc_sue_init_verbs },
1139 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1140 .dac_nids = alc662_dac_nids,
1141 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1142 .channel_mode = alc662_3ST_2ch_modes,
1143 .unsol_event = alc_sku_unsol_event,
1144 .setup = alc662_eeepc_setup,
1145 .init_hook = alc_inithook,
1146 },
1147 [ALC662_ASUS_EEEPC_EP20] = {
1148 .mixers = { alc662_eeepc_ep20_mixer,
1149 alc662_chmode_mixer },
1150 .init_verbs = { alc662_init_verbs,
1151 alc662_eapd_init_verbs,
1152 alc662_eeepc_ep20_sue_init_verbs },
1153 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1154 .dac_nids = alc662_dac_nids,
1155 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1156 .channel_mode = alc662_3ST_6ch_modes,
1157 .input_mux = &alc662_lenovo_101e_capture_source,
1158 .unsol_event = alc_sku_unsol_event,
1159 .setup = alc662_eeepc_ep20_setup,
1160 .init_hook = alc_inithook,
1161 },
1162 [ALC662_ECS] = {
1163 .mixers = { alc662_ecs_mixer },
1164 .init_verbs = { alc662_init_verbs,
1165 alc662_eapd_init_verbs,
1166 alc662_ecs_init_verbs },
1167 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1168 .dac_nids = alc662_dac_nids,
1169 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1170 .channel_mode = alc662_3ST_2ch_modes,
1171 .unsol_event = alc_sku_unsol_event,
1172 .setup = alc662_eeepc_setup,
1173 .init_hook = alc_inithook,
1174 },
1175 [ALC663_ASUS_M51VA] = {
1176 .mixers = { alc663_m51va_mixer },
1177 .init_verbs = { alc662_init_verbs,
1178 alc662_eapd_init_verbs,
1179 alc663_m51va_init_verbs },
1180 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1181 .dac_nids = alc662_dac_nids,
1182 .dig_out_nid = ALC662_DIGOUT_NID,
1183 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1184 .channel_mode = alc662_3ST_2ch_modes,
1185 .unsol_event = alc_sku_unsol_event,
1186 .setup = alc663_m51va_setup,
1187 .init_hook = alc_inithook,
1188 },
1189 [ALC663_ASUS_G71V] = {
1190 .mixers = { alc663_g71v_mixer },
1191 .init_verbs = { alc662_init_verbs,
1192 alc662_eapd_init_verbs,
1193 alc663_g71v_init_verbs },
1194 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1195 .dac_nids = alc662_dac_nids,
1196 .dig_out_nid = ALC662_DIGOUT_NID,
1197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1198 .channel_mode = alc662_3ST_2ch_modes,
1199 .unsol_event = alc_sku_unsol_event,
1200 .setup = alc663_g71v_setup,
1201 .init_hook = alc_inithook,
1202 },
1203 [ALC663_ASUS_H13] = {
1204 .mixers = { alc663_m51va_mixer },
1205 .init_verbs = { alc662_init_verbs,
1206 alc662_eapd_init_verbs,
1207 alc663_m51va_init_verbs },
1208 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1209 .dac_nids = alc662_dac_nids,
1210 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1211 .channel_mode = alc662_3ST_2ch_modes,
1212 .setup = alc663_m51va_setup,
1213 .unsol_event = alc_sku_unsol_event,
1214 .init_hook = alc_inithook,
1215 },
1216 [ALC663_ASUS_G50V] = {
1217 .mixers = { alc663_g50v_mixer },
1218 .init_verbs = { alc662_init_verbs,
1219 alc662_eapd_init_verbs,
1220 alc663_g50v_init_verbs },
1221 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1222 .dac_nids = alc662_dac_nids,
1223 .dig_out_nid = ALC662_DIGOUT_NID,
1224 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
1225 .channel_mode = alc662_3ST_6ch_modes,
1226 .input_mux = &alc663_capture_source,
1227 .unsol_event = alc_sku_unsol_event,
1228 .setup = alc663_g50v_setup,
1229 .init_hook = alc_inithook,
1230 },
1231 [ALC663_ASUS_MODE1] = {
1232 .mixers = { alc663_m51va_mixer },
1233 .cap_mixer = alc662_auto_capture_mixer,
1234 .init_verbs = { alc662_init_verbs,
1235 alc662_eapd_init_verbs,
1236 alc663_21jd_amic_init_verbs },
1237 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1238 .hp_nid = 0x03,
1239 .dac_nids = alc662_dac_nids,
1240 .dig_out_nid = ALC662_DIGOUT_NID,
1241 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1242 .channel_mode = alc662_3ST_2ch_modes,
1243 .unsol_event = alc_sku_unsol_event,
1244 .setup = alc663_mode1_setup,
1245 .init_hook = alc_inithook,
1246 },
1247 [ALC662_ASUS_MODE2] = {
1248 .mixers = { alc662_1bjd_mixer },
1249 .cap_mixer = alc662_auto_capture_mixer,
1250 .init_verbs = { alc662_init_verbs,
1251 alc662_eapd_init_verbs,
1252 alc662_1bjd_amic_init_verbs },
1253 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1254 .dac_nids = alc662_dac_nids,
1255 .dig_out_nid = ALC662_DIGOUT_NID,
1256 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1257 .channel_mode = alc662_3ST_2ch_modes,
1258 .unsol_event = alc_sku_unsol_event,
1259 .setup = alc662_mode2_setup,
1260 .init_hook = alc_inithook,
1261 },
1262 [ALC663_ASUS_MODE3] = {
1263 .mixers = { alc663_two_hp_m1_mixer },
1264 .cap_mixer = alc662_auto_capture_mixer,
1265 .init_verbs = { alc662_init_verbs,
1266 alc662_eapd_init_verbs,
1267 alc663_two_hp_amic_m1_init_verbs },
1268 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1269 .hp_nid = 0x03,
1270 .dac_nids = alc662_dac_nids,
1271 .dig_out_nid = ALC662_DIGOUT_NID,
1272 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1273 .channel_mode = alc662_3ST_2ch_modes,
1274 .unsol_event = alc_sku_unsol_event,
1275 .setup = alc663_mode3_setup,
1276 .init_hook = alc_inithook,
1277 },
1278 [ALC663_ASUS_MODE4] = {
1279 .mixers = { alc663_asus_21jd_clfe_mixer },
1280 .cap_mixer = alc662_auto_capture_mixer,
1281 .init_verbs = { alc662_init_verbs,
1282 alc662_eapd_init_verbs,
1283 alc663_21jd_amic_init_verbs},
1284 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1285 .hp_nid = 0x03,
1286 .dac_nids = alc662_dac_nids,
1287 .dig_out_nid = ALC662_DIGOUT_NID,
1288 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1289 .channel_mode = alc662_3ST_2ch_modes,
1290 .unsol_event = alc_sku_unsol_event,
1291 .setup = alc663_mode4_setup,
1292 .init_hook = alc_inithook,
1293 },
1294 [ALC663_ASUS_MODE5] = {
1295 .mixers = { alc663_asus_15jd_clfe_mixer },
1296 .cap_mixer = alc662_auto_capture_mixer,
1297 .init_verbs = { alc662_init_verbs,
1298 alc662_eapd_init_verbs,
1299 alc663_15jd_amic_init_verbs },
1300 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1301 .hp_nid = 0x03,
1302 .dac_nids = alc662_dac_nids,
1303 .dig_out_nid = ALC662_DIGOUT_NID,
1304 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1305 .channel_mode = alc662_3ST_2ch_modes,
1306 .unsol_event = alc_sku_unsol_event,
1307 .setup = alc663_mode5_setup,
1308 .init_hook = alc_inithook,
1309 },
1310 [ALC663_ASUS_MODE6] = {
1311 .mixers = { alc663_two_hp_m2_mixer },
1312 .cap_mixer = alc662_auto_capture_mixer,
1313 .init_verbs = { alc662_init_verbs,
1314 alc662_eapd_init_verbs,
1315 alc663_two_hp_amic_m2_init_verbs },
1316 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1317 .hp_nid = 0x03,
1318 .dac_nids = alc662_dac_nids,
1319 .dig_out_nid = ALC662_DIGOUT_NID,
1320 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1321 .channel_mode = alc662_3ST_2ch_modes,
1322 .unsol_event = alc_sku_unsol_event,
1323 .setup = alc663_mode6_setup,
1324 .init_hook = alc_inithook,
1325 },
1326 [ALC663_ASUS_MODE7] = {
1327 .mixers = { alc663_mode7_mixer },
1328 .cap_mixer = alc662_auto_capture_mixer,
1329 .init_verbs = { alc662_init_verbs,
1330 alc662_eapd_init_verbs,
1331 alc663_mode7_init_verbs },
1332 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1333 .hp_nid = 0x03,
1334 .dac_nids = alc662_dac_nids,
1335 .dig_out_nid = ALC662_DIGOUT_NID,
1336 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1337 .channel_mode = alc662_3ST_2ch_modes,
1338 .unsol_event = alc_sku_unsol_event,
1339 .setup = alc663_mode7_setup,
1340 .init_hook = alc_inithook,
1341 },
1342 [ALC663_ASUS_MODE8] = {
1343 .mixers = { alc663_mode8_mixer },
1344 .cap_mixer = alc662_auto_capture_mixer,
1345 .init_verbs = { alc662_init_verbs,
1346 alc662_eapd_init_verbs,
1347 alc663_mode8_init_verbs },
1348 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
1349 .hp_nid = 0x03,
1350 .dac_nids = alc662_dac_nids,
1351 .dig_out_nid = ALC662_DIGOUT_NID,
1352 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1353 .channel_mode = alc662_3ST_2ch_modes,
1354 .unsol_event = alc_sku_unsol_event,
1355 .setup = alc663_mode8_setup,
1356 .init_hook = alc_inithook,
1357 },
1358 [ALC272_DELL] = {
1359 .mixers = { alc663_m51va_mixer },
1360 .cap_mixer = alc272_auto_capture_mixer,
1361 .init_verbs = { alc662_init_verbs,
1362 alc662_eapd_init_verbs,
1363 alc272_dell_init_verbs },
1364 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1365 .dac_nids = alc272_dac_nids,
1366 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1367 .adc_nids = alc272_adc_nids,
1368 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
1369 .capsrc_nids = alc272_capsrc_nids,
1370 .channel_mode = alc662_3ST_2ch_modes,
1371 .unsol_event = alc_sku_unsol_event,
1372 .setup = alc663_m51va_setup,
1373 .init_hook = alc_inithook,
1374 },
1375 [ALC272_DELL_ZM1] = {
1376 .mixers = { alc663_m51va_mixer },
1377 .cap_mixer = alc662_auto_capture_mixer,
1378 .init_verbs = { alc662_init_verbs,
1379 alc662_eapd_init_verbs,
1380 alc272_dell_zm1_init_verbs },
1381 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1382 .dac_nids = alc272_dac_nids,
1383 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1384 .adc_nids = alc662_adc_nids,
1385 .num_adc_nids = 1,
1386 .capsrc_nids = alc662_capsrc_nids,
1387 .channel_mode = alc662_3ST_2ch_modes,
1388 .unsol_event = alc_sku_unsol_event,
1389 .setup = alc663_m51va_setup,
1390 .init_hook = alc_inithook,
1391 },
1392 [ALC272_SAMSUNG_NC10] = {
1393 .mixers = { alc272_nc10_mixer },
1394 .init_verbs = { alc662_init_verbs,
1395 alc662_eapd_init_verbs,
1396 alc663_21jd_amic_init_verbs },
1397 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1398 .dac_nids = alc272_dac_nids,
1399 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
1400 .channel_mode = alc662_3ST_2ch_modes,
1401 /*.input_mux = &alc272_nc10_capture_source,*/
1402 .unsol_event = alc_sku_unsol_event,
1403 .setup = alc663_mode4_setup,
1404 .init_hook = alc_inithook,
1405 },
1406};
1407
1408
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c
new file mode 100644
index 000000000000..0eeb227c7bc2
--- /dev/null
+++ b/sound/pci/hda/alc680_quirks.c
@@ -0,0 +1,222 @@
1/*
2 * ALC680 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC680 models */
7enum {
8 ALC680_AUTO,
9 ALC680_BASE,
10 ALC680_MODEL_LAST,
11};
12
13#define ALC680_DIGIN_NID ALC880_DIGIN_NID
14#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
15#define alc680_modes alc260_modes
16
17static const hda_nid_t alc680_dac_nids[3] = {
18 /* Lout1, Lout2, hp */
19 0x02, 0x03, 0x04
20};
21
22static const hda_nid_t alc680_adc_nids[3] = {
23 /* ADC0-2 */
24 /* DMIC, MIC, Line-in*/
25 0x07, 0x08, 0x09
26};
27
28/*
29 * Analog capture ADC cgange
30 */
31static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
32{
33 static hda_nid_t pins[] = {0x18, 0x19};
34 static hda_nid_t adcs[] = {0x08, 0x09};
35 int i;
36
37 for (i = 0; i < ARRAY_SIZE(pins); i++) {
38 if (!is_jack_detectable(codec, pins[i]))
39 continue;
40 if (snd_hda_jack_detect(codec, pins[i]))
41 return adcs[i];
42 }
43 return 0x07;
44}
45
46static void alc680_rec_autoswitch(struct hda_codec *codec)
47{
48 struct alc_spec *spec = codec->spec;
49 hda_nid_t nid = alc680_get_cur_adc(codec);
50 if (spec->cur_adc && nid != spec->cur_adc) {
51 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
52 spec->cur_adc = nid;
53 snd_hda_codec_setup_stream(codec, nid,
54 spec->cur_adc_stream_tag, 0,
55 spec->cur_adc_format);
56 }
57}
58
59static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
60 struct hda_codec *codec,
61 unsigned int stream_tag,
62 unsigned int format,
63 struct snd_pcm_substream *substream)
64{
65 struct alc_spec *spec = codec->spec;
66 hda_nid_t nid = alc680_get_cur_adc(codec);
67
68 spec->cur_adc = nid;
69 spec->cur_adc_stream_tag = stream_tag;
70 spec->cur_adc_format = format;
71 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
72 return 0;
73}
74
75static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
76 struct hda_codec *codec,
77 struct snd_pcm_substream *substream)
78{
79 struct alc_spec *spec = codec->spec;
80 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
81 spec->cur_adc = 0;
82 return 0;
83}
84
85static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
86 .substreams = 1, /* can be overridden */
87 .channels_min = 2,
88 .channels_max = 2,
89 /* NID is set in alc_build_pcms */
90 .ops = {
91 .prepare = alc680_capture_pcm_prepare,
92 .cleanup = alc680_capture_pcm_cleanup
93 },
94};
95
96static const struct snd_kcontrol_new alc680_base_mixer[] = {
97 /* output mixer control */
98 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
99 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
101 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
102 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
104 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
105 { }
106};
107
108static const struct hda_bind_ctls alc680_bind_cap_vol = {
109 .ops = &snd_hda_bind_vol,
110 .values = {
111 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
112 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
113 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
114 0
115 },
116};
117
118static const struct hda_bind_ctls alc680_bind_cap_switch = {
119 .ops = &snd_hda_bind_sw,
120 .values = {
121 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
122 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
123 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
124 0
125 },
126};
127
128static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
129 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
130 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
131 { } /* end */
132};
133
134/*
135 * generic initialization of ADC, input mixers and output mixers
136 */
137static const struct hda_verb alc680_init_verbs[] = {
138 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
140 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
141
142 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
143 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
146 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
148
149 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
150 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
151 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
152 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
153 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
154
155 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
156 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
157 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
158
159 { }
160};
161
162/* toggle speaker-output according to the hp-jack state */
163static void alc680_base_setup(struct hda_codec *codec)
164{
165 struct alc_spec *spec = codec->spec;
166
167 spec->autocfg.hp_pins[0] = 0x16;
168 spec->autocfg.speaker_pins[0] = 0x14;
169 spec->autocfg.speaker_pins[1] = 0x15;
170 spec->autocfg.num_inputs = 2;
171 spec->autocfg.inputs[0].pin = 0x18;
172 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
173 spec->autocfg.inputs[1].pin = 0x19;
174 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
175 spec->automute = 1;
176 spec->automute_mode = ALC_AUTOMUTE_AMP;
177}
178
179static void alc680_unsol_event(struct hda_codec *codec,
180 unsigned int res)
181{
182 if ((res >> 26) == ALC_HP_EVENT)
183 alc_hp_automute(codec);
184 if ((res >> 26) == ALC_MIC_EVENT)
185 alc680_rec_autoswitch(codec);
186}
187
188static void alc680_inithook(struct hda_codec *codec)
189{
190 alc_hp_automute(codec);
191 alc680_rec_autoswitch(codec);
192}
193
194/*
195 * configuration and preset
196 */
197static const char * const alc680_models[ALC680_MODEL_LAST] = {
198 [ALC680_BASE] = "base",
199 [ALC680_AUTO] = "auto",
200};
201
202static const struct snd_pci_quirk alc680_cfg_tbl[] = {
203 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
204 {}
205};
206
207static const struct alc_config_preset alc680_presets[] = {
208 [ALC680_BASE] = {
209 .mixers = { alc680_base_mixer },
210 .cap_mixer = alc680_master_capture_mixer,
211 .init_verbs = { alc680_init_verbs },
212 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
213 .dac_nids = alc680_dac_nids,
214 .dig_out_nid = ALC680_DIGOUT_NID,
215 .num_channel_mode = ARRAY_SIZE(alc680_modes),
216 .channel_mode = alc680_modes,
217 .unsol_event = alc680_unsol_event,
218 .setup = alc680_base_setup,
219 .init_hook = alc680_inithook,
220
221 },
222};
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c
new file mode 100644
index 000000000000..d719ec6350eb
--- /dev/null
+++ b/sound/pci/hda/alc861_quirks.c
@@ -0,0 +1,725 @@
1/*
2 * ALC660/ALC861 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861 models */
7enum {
8 ALC861_AUTO,
9 ALC861_3ST,
10 ALC660_3ST,
11 ALC861_3ST_DIG,
12 ALC861_6ST_DIG,
13 ALC861_UNIWILL_M31,
14 ALC861_TOSHIBA,
15 ALC861_ASUS,
16 ALC861_ASUS_LAPTOP,
17 ALC861_MODEL_LAST,
18};
19
20/*
21 * ALC861 channel source setting (2/6 channel selection for 3-stack)
22 */
23
24/*
25 * set the path ways for 2 channel output
26 * need to set the codec line out and mic 1 pin widgets to inputs
27 */
28static const struct hda_verb alc861_threestack_ch2_init[] = {
29 /* set pin widget 1Ah (line in) for input */
30 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
31 /* set pin widget 18h (mic1/2) for input, for mic also enable
32 * the vref
33 */
34 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
35
36 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
37#if 0
38 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
39 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
40#endif
41 { } /* end */
42};
43/*
44 * 6ch mode
45 * need to set the codec line out and mic 1 pin widgets to outputs
46 */
47static const struct hda_verb alc861_threestack_ch6_init[] = {
48 /* set pin widget 1Ah (line in) for output (Back Surround)*/
49 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
50 /* set pin widget 18h (mic1) for output (CLFE)*/
51 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
52
53 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
54 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
55
56 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
57#if 0
58 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
59 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
60#endif
61 { } /* end */
62};
63
64static const struct hda_channel_mode alc861_threestack_modes[2] = {
65 { 2, alc861_threestack_ch2_init },
66 { 6, alc861_threestack_ch6_init },
67};
68/* Set mic1 as input and unmute the mixer */
69static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
70 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
71 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
72 { } /* end */
73};
74/* Set mic1 as output and mute mixer */
75static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
76 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
77 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
78 { } /* end */
79};
80
81static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
82 { 2, alc861_uniwill_m31_ch2_init },
83 { 4, alc861_uniwill_m31_ch4_init },
84};
85
86/* Set mic1 and line-in as input and unmute the mixer */
87static const struct hda_verb alc861_asus_ch2_init[] = {
88 /* set pin widget 1Ah (line in) for input */
89 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
90 /* set pin widget 18h (mic1/2) for input, for mic also enable
91 * the vref
92 */
93 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
94
95 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
96#if 0
97 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
98 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
99#endif
100 { } /* end */
101};
102/* Set mic1 nad line-in as output and mute mixer */
103static const struct hda_verb alc861_asus_ch6_init[] = {
104 /* set pin widget 1Ah (line in) for output (Back Surround)*/
105 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
106 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
107 /* set pin widget 18h (mic1) for output (CLFE)*/
108 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
109 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
110 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
111 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
112
113 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
114#if 0
115 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
116 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
117#endif
118 { } /* end */
119};
120
121static const struct hda_channel_mode alc861_asus_modes[2] = {
122 { 2, alc861_asus_ch2_init },
123 { 6, alc861_asus_ch6_init },
124};
125
126/* patch-ALC861 */
127
128static const struct snd_kcontrol_new alc861_base_mixer[] = {
129 /* output mixer control */
130 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
131 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
132 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
133 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
134 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
135
136 /*Input mixer control */
137 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
138 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
139 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
140 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
141 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
142 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
145 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
147
148 { } /* end */
149};
150
151static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
152 /* output mixer control */
153 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
154 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
155 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
156 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
157 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
158
159 /* Input mixer control */
160 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
161 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
162 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
163 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
164 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
165 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
170
171 {
172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
173 .name = "Channel Mode",
174 .info = alc_ch_mode_info,
175 .get = alc_ch_mode_get,
176 .put = alc_ch_mode_put,
177 .private_value = ARRAY_SIZE(alc861_threestack_modes),
178 },
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
183 /* output mixer control */
184 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
186 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
187
188 { } /* end */
189};
190
191static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
192 /* output mixer control */
193 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
194 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
195 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
196 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
197 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
198
199 /* Input mixer control */
200 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
201 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
202 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
203 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
204 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
205 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
206 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
207 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
208 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
210
211 {
212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
213 .name = "Channel Mode",
214 .info = alc_ch_mode_info,
215 .get = alc_ch_mode_get,
216 .put = alc_ch_mode_put,
217 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
218 },
219 { } /* end */
220};
221
222static const struct snd_kcontrol_new alc861_asus_mixer[] = {
223 /* output mixer control */
224 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
225 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
226 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
227 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
228 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
229
230 /* Input mixer control */
231 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
232 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
233 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
234 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
235 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
236 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
237 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
238 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
240 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
241
242 {
243 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
244 .name = "Channel Mode",
245 .info = alc_ch_mode_info,
246 .get = alc_ch_mode_get,
247 .put = alc_ch_mode_put,
248 .private_value = ARRAY_SIZE(alc861_asus_modes),
249 },
250 { }
251};
252
253/* additional mixer */
254static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
255 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
256 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
257 { }
258};
259
260/*
261 * generic initialization of ADC, input mixers and output mixers
262 */
263static const struct hda_verb alc861_base_init_verbs[] = {
264 /*
265 * Unmute ADC0 and set the default input to mic-in
266 */
267 /* port-A for surround (rear panel) */
268 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
269 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
270 /* port-B for mic-in (rear panel) with vref */
271 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
272 /* port-C for line-in (rear panel) */
273 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
274 /* port-D for Front */
275 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
276 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
277 /* port-E for HP out (front panel) */
278 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
279 /* route front PCM to HP */
280 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
281 /* port-F for mic-in (front panel) with vref */
282 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
283 /* port-G for CLFE (rear panel) */
284 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
285 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
286 /* port-H for side (rear panel) */
287 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
288 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
289 /* CD-in */
290 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
291 /* route front mic to ADC1*/
292 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
293 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
294
295 /* Unmute DAC0~3 & spdif out*/
296 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
297 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
298 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
300 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
301
302 /* Unmute Mixer 14 (mic) 1c (Line in)*/
303 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
304 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
305 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
306 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
307
308 /* Unmute Stereo Mixer 15 */
309 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
310 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
311 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
312 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
313
314 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
315 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
318 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
319 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
320 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
321 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
322 /* hp used DAC 3 (Front) */
323 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
325
326 { }
327};
328
329static const struct hda_verb alc861_threestack_init_verbs[] = {
330 /*
331 * Unmute ADC0 and set the default input to mic-in
332 */
333 /* port-A for surround (rear panel) */
334 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
335 /* port-B for mic-in (rear panel) with vref */
336 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
337 /* port-C for line-in (rear panel) */
338 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
339 /* port-D for Front */
340 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
341 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
342 /* port-E for HP out (front panel) */
343 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
344 /* route front PCM to HP */
345 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
346 /* port-F for mic-in (front panel) with vref */
347 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
348 /* port-G for CLFE (rear panel) */
349 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
350 /* port-H for side (rear panel) */
351 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
352 /* CD-in */
353 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
354 /* route front mic to ADC1*/
355 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
356 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
357 /* Unmute DAC0~3 & spdif out*/
358 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
359 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
360 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
361 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
363
364 /* Unmute Mixer 14 (mic) 1c (Line in)*/
365 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
366 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
367 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369
370 /* Unmute Stereo Mixer 15 */
371 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
373 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
375
376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
377 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
378 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
379 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
380 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
381 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
382 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
383 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
384 /* hp used DAC 3 (Front) */
385 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
386 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
387 { }
388};
389
390static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
391 /*
392 * Unmute ADC0 and set the default input to mic-in
393 */
394 /* port-A for surround (rear panel) */
395 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
396 /* port-B for mic-in (rear panel) with vref */
397 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
398 /* port-C for line-in (rear panel) */
399 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
400 /* port-D for Front */
401 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
402 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
403 /* port-E for HP out (front panel) */
404 /* this has to be set to VREF80 */
405 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
406 /* route front PCM to HP */
407 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
408 /* port-F for mic-in (front panel) with vref */
409 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
410 /* port-G for CLFE (rear panel) */
411 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
412 /* port-H for side (rear panel) */
413 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
414 /* CD-in */
415 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
416 /* route front mic to ADC1*/
417 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
418 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
419 /* Unmute DAC0~3 & spdif out*/
420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
423 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
425
426 /* Unmute Mixer 14 (mic) 1c (Line in)*/
427 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
428 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
429 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
430 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
431
432 /* Unmute Stereo Mixer 15 */
433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
434 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
435 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
436 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
437
438 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
439 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
440 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
441 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
442 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
443 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
444 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
445 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
446 /* hp used DAC 3 (Front) */
447 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
448 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
449 { }
450};
451
452static const struct hda_verb alc861_asus_init_verbs[] = {
453 /*
454 * Unmute ADC0 and set the default input to mic-in
455 */
456 /* port-A for surround (rear panel)
457 * according to codec#0 this is the HP jack
458 */
459 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
460 /* route front PCM to HP */
461 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
462 /* port-B for mic-in (rear panel) with vref */
463 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
464 /* port-C for line-in (rear panel) */
465 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
466 /* port-D for Front */
467 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
468 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
469 /* port-E for HP out (front panel) */
470 /* this has to be set to VREF80 */
471 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
472 /* route front PCM to HP */
473 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
474 /* port-F for mic-in (front panel) with vref */
475 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
476 /* port-G for CLFE (rear panel) */
477 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
478 /* port-H for side (rear panel) */
479 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
480 /* CD-in */
481 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
482 /* route front mic to ADC1*/
483 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
485 /* Unmute DAC0~3 & spdif out*/
486 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
488 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
489 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
490 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
491 /* Unmute Mixer 14 (mic) 1c (Line in)*/
492 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
493 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
494 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
495 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
496
497 /* Unmute Stereo Mixer 15 */
498 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
500 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
502
503 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
504 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
507 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
509 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
511 /* hp used DAC 3 (Front) */
512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
513 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
514 { }
515};
516
517/* additional init verbs for ASUS laptops */
518static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
519 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
520 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
521 { }
522};
523
524static const struct hda_verb alc861_toshiba_init_verbs[] = {
525 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
526
527 { }
528};
529
530/* toggle speaker-output according to the hp-jack state */
531static void alc861_toshiba_automute(struct hda_codec *codec)
532{
533 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
534
535 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
536 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
537 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
538 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
539}
540
541static void alc861_toshiba_unsol_event(struct hda_codec *codec,
542 unsigned int res)
543{
544 if ((res >> 26) == ALC_HP_EVENT)
545 alc861_toshiba_automute(codec);
546}
547
548#define ALC861_DIGOUT_NID 0x07
549
550static const struct hda_channel_mode alc861_8ch_modes[1] = {
551 { 8, NULL }
552};
553
554static const hda_nid_t alc861_dac_nids[4] = {
555 /* front, surround, clfe, side */
556 0x03, 0x06, 0x05, 0x04
557};
558
559static const hda_nid_t alc660_dac_nids[3] = {
560 /* front, clfe, surround */
561 0x03, 0x05, 0x06
562};
563
564static const hda_nid_t alc861_adc_nids[1] = {
565 /* ADC0-2 */
566 0x08,
567};
568
569static const struct hda_input_mux alc861_capture_source = {
570 .num_items = 5,
571 .items = {
572 { "Mic", 0x0 },
573 { "Front Mic", 0x3 },
574 { "Line", 0x1 },
575 { "CD", 0x4 },
576 { "Mixer", 0x5 },
577 },
578};
579
580/*
581 * configuration and preset
582 */
583static const char * const alc861_models[ALC861_MODEL_LAST] = {
584 [ALC861_3ST] = "3stack",
585 [ALC660_3ST] = "3stack-660",
586 [ALC861_3ST_DIG] = "3stack-dig",
587 [ALC861_6ST_DIG] = "6stack-dig",
588 [ALC861_UNIWILL_M31] = "uniwill-m31",
589 [ALC861_TOSHIBA] = "toshiba",
590 [ALC861_ASUS] = "asus",
591 [ALC861_ASUS_LAPTOP] = "asus-laptop",
592 [ALC861_AUTO] = "auto",
593};
594
595static const struct snd_pci_quirk alc861_cfg_tbl[] = {
596 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
597 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
598 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
599 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
600 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
601 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
602 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
603 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
604 * Any other models that need this preset?
605 */
606 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
607 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
608 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
609 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
610 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
611 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
612 /* FIXME: the below seems conflict */
613 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
614 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
615 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
616 {}
617};
618
619static const struct alc_config_preset alc861_presets[] = {
620 [ALC861_3ST] = {
621 .mixers = { alc861_3ST_mixer },
622 .init_verbs = { alc861_threestack_init_verbs },
623 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
624 .dac_nids = alc861_dac_nids,
625 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
626 .channel_mode = alc861_threestack_modes,
627 .need_dac_fix = 1,
628 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
629 .adc_nids = alc861_adc_nids,
630 .input_mux = &alc861_capture_source,
631 },
632 [ALC861_3ST_DIG] = {
633 .mixers = { alc861_base_mixer },
634 .init_verbs = { alc861_threestack_init_verbs },
635 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
636 .dac_nids = alc861_dac_nids,
637 .dig_out_nid = ALC861_DIGOUT_NID,
638 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
639 .channel_mode = alc861_threestack_modes,
640 .need_dac_fix = 1,
641 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
642 .adc_nids = alc861_adc_nids,
643 .input_mux = &alc861_capture_source,
644 },
645 [ALC861_6ST_DIG] = {
646 .mixers = { alc861_base_mixer },
647 .init_verbs = { alc861_base_init_verbs },
648 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
649 .dac_nids = alc861_dac_nids,
650 .dig_out_nid = ALC861_DIGOUT_NID,
651 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
652 .channel_mode = alc861_8ch_modes,
653 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
654 .adc_nids = alc861_adc_nids,
655 .input_mux = &alc861_capture_source,
656 },
657 [ALC660_3ST] = {
658 .mixers = { alc861_3ST_mixer },
659 .init_verbs = { alc861_threestack_init_verbs },
660 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
661 .dac_nids = alc660_dac_nids,
662 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
663 .channel_mode = alc861_threestack_modes,
664 .need_dac_fix = 1,
665 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
666 .adc_nids = alc861_adc_nids,
667 .input_mux = &alc861_capture_source,
668 },
669 [ALC861_UNIWILL_M31] = {
670 .mixers = { alc861_uniwill_m31_mixer },
671 .init_verbs = { alc861_uniwill_m31_init_verbs },
672 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
673 .dac_nids = alc861_dac_nids,
674 .dig_out_nid = ALC861_DIGOUT_NID,
675 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
676 .channel_mode = alc861_uniwill_m31_modes,
677 .need_dac_fix = 1,
678 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
679 .adc_nids = alc861_adc_nids,
680 .input_mux = &alc861_capture_source,
681 },
682 [ALC861_TOSHIBA] = {
683 .mixers = { alc861_toshiba_mixer },
684 .init_verbs = { alc861_base_init_verbs,
685 alc861_toshiba_init_verbs },
686 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
687 .dac_nids = alc861_dac_nids,
688 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
689 .channel_mode = alc883_3ST_2ch_modes,
690 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
691 .adc_nids = alc861_adc_nids,
692 .input_mux = &alc861_capture_source,
693 .unsol_event = alc861_toshiba_unsol_event,
694 .init_hook = alc861_toshiba_automute,
695 },
696 [ALC861_ASUS] = {
697 .mixers = { alc861_asus_mixer },
698 .init_verbs = { alc861_asus_init_verbs },
699 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
700 .dac_nids = alc861_dac_nids,
701 .dig_out_nid = ALC861_DIGOUT_NID,
702 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
703 .channel_mode = alc861_asus_modes,
704 .need_dac_fix = 1,
705 .hp_nid = 0x06,
706 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
707 .adc_nids = alc861_adc_nids,
708 .input_mux = &alc861_capture_source,
709 },
710 [ALC861_ASUS_LAPTOP] = {
711 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
712 .init_verbs = { alc861_asus_init_verbs,
713 alc861_asus_laptop_init_verbs },
714 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
715 .dac_nids = alc861_dac_nids,
716 .dig_out_nid = ALC861_DIGOUT_NID,
717 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
718 .channel_mode = alc883_3ST_2ch_modes,
719 .need_dac_fix = 1,
720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
721 .adc_nids = alc861_adc_nids,
722 .input_mux = &alc861_capture_source,
723 },
724};
725
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c
new file mode 100644
index 000000000000..8f28450f41f8
--- /dev/null
+++ b/sound/pci/hda/alc861vd_quirks.c
@@ -0,0 +1,605 @@
1/*
2 * ALC660-VD/ALC861-VD quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC861-VD models */
7enum {
8 ALC861VD_AUTO,
9 ALC660VD_3ST,
10 ALC660VD_3ST_DIG,
11 ALC660VD_ASUS_V1S,
12 ALC861VD_3ST,
13 ALC861VD_3ST_DIG,
14 ALC861VD_6ST_DIG,
15 ALC861VD_LENOVO,
16 ALC861VD_DALLAS,
17 ALC861VD_HP,
18 ALC861VD_MODEL_LAST,
19};
20
21#define ALC861VD_DIGOUT_NID 0x06
22
23static const hda_nid_t alc861vd_dac_nids[4] = {
24 /* front, surr, clfe, side surr */
25 0x02, 0x03, 0x04, 0x05
26};
27
28/* dac_nids for ALC660vd are in a different order - according to
29 * Realtek's driver.
30 * This should probably result in a different mixer for 6stack models
31 * of ALC660vd codecs, but for now there is only 3stack mixer
32 * - and it is the same as in 861vd.
33 * adc_nids in ALC660vd are (is) the same as in 861vd
34 */
35static const hda_nid_t alc660vd_dac_nids[3] = {
36 /* front, rear, clfe, rear_surr */
37 0x02, 0x04, 0x03
38};
39
40static const hda_nid_t alc861vd_adc_nids[1] = {
41 /* ADC0 */
42 0x09,
43};
44
45static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
46
47/* input MUX */
48/* FIXME: should be a matrix-type input source selection */
49static const struct hda_input_mux alc861vd_capture_source = {
50 .num_items = 4,
51 .items = {
52 { "Mic", 0x0 },
53 { "Front Mic", 0x1 },
54 { "Line", 0x2 },
55 { "CD", 0x4 },
56 },
57};
58
59static const struct hda_input_mux alc861vd_dallas_capture_source = {
60 .num_items = 2,
61 .items = {
62 { "Mic", 0x0 },
63 { "Internal Mic", 0x1 },
64 },
65};
66
67static const struct hda_input_mux alc861vd_hp_capture_source = {
68 .num_items = 2,
69 .items = {
70 { "Front Mic", 0x0 },
71 { "ATAPI Mic", 0x1 },
72 },
73};
74
75/*
76 * 2ch mode
77 */
78static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
79 { 2, NULL }
80};
81
82/*
83 * 6ch mode
84 */
85static const struct hda_verb alc861vd_6stack_ch6_init[] = {
86 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
87 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
88 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
89 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
90 { } /* end */
91};
92
93/*
94 * 8ch mode
95 */
96static const struct hda_verb alc861vd_6stack_ch8_init[] = {
97 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
99 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
100 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { } /* end */
102};
103
104static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
105 { 6, alc861vd_6stack_ch6_init },
106 { 8, alc861vd_6stack_ch8_init },
107};
108
109static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
110 {
111 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
112 .name = "Channel Mode",
113 .info = alc_ch_mode_info,
114 .get = alc_ch_mode_get,
115 .put = alc_ch_mode_put,
116 },
117 { } /* end */
118};
119
120/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
121 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
122 */
123static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
124 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
125 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
126
127 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
128 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
129
130 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
131 HDA_OUTPUT),
132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
133 HDA_OUTPUT),
134 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
135 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
136
137 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
138 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
139
140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
141
142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
145
146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
149
150 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
152
153 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
154 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
155
156 { } /* end */
157};
158
159static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
160 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
161 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
162
163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
164
165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
166 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
167 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
168
169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
172
173 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
174 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
175
176 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
177 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
178
179 { } /* end */
180};
181
182static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
183 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
184 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
185 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
186
187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
188
189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
192
193 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
196
197 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
198 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
199
200 { } /* end */
201};
202
203/* Pin assignment: Speaker=0x14, HP = 0x15,
204 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
205 */
206static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
209 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
210 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
214 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
215 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
216 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
217 { } /* end */
218};
219
220/* Pin assignment: Speaker=0x14, Line-out = 0x15,
221 * Front Mic=0x18, ATAPI Mic = 0x19,
222 */
223static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
224 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
225 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
226 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
227 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
228 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
229 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
230 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
231 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
232
233 { } /* end */
234};
235
236/*
237 * generic initialization of ADC, input mixers and output mixers
238 */
239static const struct hda_verb alc861vd_volume_init_verbs[] = {
240 /*
241 * Unmute ADC0 and set the default input to mic-in
242 */
243 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
244 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
245
246 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
247 * the analog-loopback mixer widget
248 */
249 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
250 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
251 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
252 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
253 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
254 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
255
256 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
257 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
259 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
261
262 /*
263 * Set up output mixers (0x02 - 0x05)
264 */
265 /* set vol=0 to output mixers */
266 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
267 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
268 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
269 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
270
271 /* set up input amps for analog loopback */
272 /* Amp Indices: DAC = 0, mixer = 1 */
273 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
274 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
275 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
276 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
277 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
278 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
279 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
280 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
281
282 { }
283};
284
285/*
286 * 3-stack pin configuration:
287 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
288 */
289static const struct hda_verb alc861vd_3stack_init_verbs[] = {
290 /*
291 * Set pin mode and muting
292 */
293 /* set front pin widgets 0x14 for output */
294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
296 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
297
298 /* Mic (rear) pin: input vref at 80% */
299 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
300 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
301 /* Front Mic pin: input vref at 80% */
302 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
303 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
304 /* Line In pin: input */
305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
306 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
307 /* Line-2 In: Headphone output (output 0 - 0x0c) */
308 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
309 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
310 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
311 /* CD pin widget for input */
312 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
313
314 { }
315};
316
317/*
318 * 6-stack pin configuration:
319 */
320static const struct hda_verb alc861vd_6stack_init_verbs[] = {
321 /*
322 * Set pin mode and muting
323 */
324 /* set front pin widgets 0x14 for output */
325 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
326 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
327 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
328
329 /* Rear Pin: output 1 (0x0d) */
330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
333 /* CLFE Pin: output 2 (0x0e) */
334 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
335 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
336 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
337 /* Side Pin: output 3 (0x0f) */
338 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
339 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
340 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
341
342 /* Mic (rear) pin: input vref at 80% */
343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
344 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
345 /* Front Mic pin: input vref at 80% */
346 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
347 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
348 /* Line In pin: input */
349 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
350 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
351 /* Line-2 In: Headphone output (output 0 - 0x0c) */
352 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
353 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
354 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
355 /* CD pin widget for input */
356 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
357
358 { }
359};
360
361static const struct hda_verb alc861vd_eapd_verbs[] = {
362 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
363 { }
364};
365
366static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
369 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
370 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
371 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
372 {}
373};
374
375static void alc861vd_lenovo_setup(struct hda_codec *codec)
376{
377 struct alc_spec *spec = codec->spec;
378 spec->autocfg.hp_pins[0] = 0x1b;
379 spec->autocfg.speaker_pins[0] = 0x14;
380 spec->automute = 1;
381 spec->automute_mode = ALC_AUTOMUTE_AMP;
382}
383
384static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
385{
386 alc_hp_automute(codec);
387 alc88x_simple_mic_automute(codec);
388}
389
390static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
391 unsigned int res)
392{
393 switch (res >> 26) {
394 case ALC_MIC_EVENT:
395 alc88x_simple_mic_automute(codec);
396 break;
397 default:
398 alc_sku_unsol_event(codec, res);
399 break;
400 }
401}
402
403static const struct hda_verb alc861vd_dallas_verbs[] = {
404 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
405 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
406 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
407 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
408
409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
412 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
413 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
414 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
415 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
417
418 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
419 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
421 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
422 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
425 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
426
427 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
428 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
429 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
430 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
431 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
432 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
433 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
434 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
435
436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
438 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
439 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
440
441 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
444
445 { } /* end */
446};
447
448/* toggle speaker-output according to the hp-jack state */
449static void alc861vd_dallas_setup(struct hda_codec *codec)
450{
451 struct alc_spec *spec = codec->spec;
452
453 spec->autocfg.hp_pins[0] = 0x15;
454 spec->autocfg.speaker_pins[0] = 0x14;
455 spec->automute = 1;
456 spec->automute_mode = ALC_AUTOMUTE_AMP;
457}
458
459/*
460 * configuration and preset
461 */
462static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
463 [ALC660VD_3ST] = "3stack-660",
464 [ALC660VD_3ST_DIG] = "3stack-660-digout",
465 [ALC660VD_ASUS_V1S] = "asus-v1s",
466 [ALC861VD_3ST] = "3stack",
467 [ALC861VD_3ST_DIG] = "3stack-digout",
468 [ALC861VD_6ST_DIG] = "6stack-digout",
469 [ALC861VD_LENOVO] = "lenovo",
470 [ALC861VD_DALLAS] = "dallas",
471 [ALC861VD_HP] = "hp",
472 [ALC861VD_AUTO] = "auto",
473};
474
475static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
476 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
477 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
478 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
479 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
480 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
481 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
482 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
483 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
484 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
485 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
486 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
487 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
488 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
489 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
490 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
491 {}
492};
493
494static const struct alc_config_preset alc861vd_presets[] = {
495 [ALC660VD_3ST] = {
496 .mixers = { alc861vd_3st_mixer },
497 .init_verbs = { alc861vd_volume_init_verbs,
498 alc861vd_3stack_init_verbs },
499 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
500 .dac_nids = alc660vd_dac_nids,
501 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
502 .channel_mode = alc861vd_3stack_2ch_modes,
503 .input_mux = &alc861vd_capture_source,
504 },
505 [ALC660VD_3ST_DIG] = {
506 .mixers = { alc861vd_3st_mixer },
507 .init_verbs = { alc861vd_volume_init_verbs,
508 alc861vd_3stack_init_verbs },
509 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
510 .dac_nids = alc660vd_dac_nids,
511 .dig_out_nid = ALC861VD_DIGOUT_NID,
512 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
513 .channel_mode = alc861vd_3stack_2ch_modes,
514 .input_mux = &alc861vd_capture_source,
515 },
516 [ALC861VD_3ST] = {
517 .mixers = { alc861vd_3st_mixer },
518 .init_verbs = { alc861vd_volume_init_verbs,
519 alc861vd_3stack_init_verbs },
520 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
521 .dac_nids = alc861vd_dac_nids,
522 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
523 .channel_mode = alc861vd_3stack_2ch_modes,
524 .input_mux = &alc861vd_capture_source,
525 },
526 [ALC861VD_3ST_DIG] = {
527 .mixers = { alc861vd_3st_mixer },
528 .init_verbs = { alc861vd_volume_init_verbs,
529 alc861vd_3stack_init_verbs },
530 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
531 .dac_nids = alc861vd_dac_nids,
532 .dig_out_nid = ALC861VD_DIGOUT_NID,
533 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
534 .channel_mode = alc861vd_3stack_2ch_modes,
535 .input_mux = &alc861vd_capture_source,
536 },
537 [ALC861VD_6ST_DIG] = {
538 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
539 .init_verbs = { alc861vd_volume_init_verbs,
540 alc861vd_6stack_init_verbs },
541 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
542 .dac_nids = alc861vd_dac_nids,
543 .dig_out_nid = ALC861VD_DIGOUT_NID,
544 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
545 .channel_mode = alc861vd_6stack_modes,
546 .input_mux = &alc861vd_capture_source,
547 },
548 [ALC861VD_LENOVO] = {
549 .mixers = { alc861vd_lenovo_mixer },
550 .init_verbs = { alc861vd_volume_init_verbs,
551 alc861vd_3stack_init_verbs,
552 alc861vd_eapd_verbs,
553 alc861vd_lenovo_unsol_verbs },
554 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
555 .dac_nids = alc660vd_dac_nids,
556 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
557 .channel_mode = alc861vd_3stack_2ch_modes,
558 .input_mux = &alc861vd_capture_source,
559 .unsol_event = alc861vd_lenovo_unsol_event,
560 .setup = alc861vd_lenovo_setup,
561 .init_hook = alc861vd_lenovo_init_hook,
562 },
563 [ALC861VD_DALLAS] = {
564 .mixers = { alc861vd_dallas_mixer },
565 .init_verbs = { alc861vd_dallas_verbs },
566 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
567 .dac_nids = alc861vd_dac_nids,
568 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
569 .channel_mode = alc861vd_3stack_2ch_modes,
570 .input_mux = &alc861vd_dallas_capture_source,
571 .unsol_event = alc_sku_unsol_event,
572 .setup = alc861vd_dallas_setup,
573 .init_hook = alc_hp_automute,
574 },
575 [ALC861VD_HP] = {
576 .mixers = { alc861vd_hp_mixer },
577 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
578 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
579 .dac_nids = alc861vd_dac_nids,
580 .dig_out_nid = ALC861VD_DIGOUT_NID,
581 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
582 .channel_mode = alc861vd_3stack_2ch_modes,
583 .input_mux = &alc861vd_hp_capture_source,
584 .unsol_event = alc_sku_unsol_event,
585 .setup = alc861vd_dallas_setup,
586 .init_hook = alc_hp_automute,
587 },
588 [ALC660VD_ASUS_V1S] = {
589 .mixers = { alc861vd_lenovo_mixer },
590 .init_verbs = { alc861vd_volume_init_verbs,
591 alc861vd_3stack_init_verbs,
592 alc861vd_eapd_verbs,
593 alc861vd_lenovo_unsol_verbs },
594 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
595 .dac_nids = alc660vd_dac_nids,
596 .dig_out_nid = ALC861VD_DIGOUT_NID,
597 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
598 .channel_mode = alc861vd_3stack_2ch_modes,
599 .input_mux = &alc861vd_capture_source,
600 .unsol_event = alc861vd_lenovo_unsol_event,
601 .setup = alc861vd_lenovo_setup,
602 .init_hook = alc861vd_lenovo_init_hook,
603 },
604};
605
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c
new file mode 100644
index 000000000000..c844d2b59988
--- /dev/null
+++ b/sound/pci/hda/alc880_quirks.c
@@ -0,0 +1,1898 @@
1/*
2 * ALC880 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC880 board config type */
7enum {
8 ALC880_AUTO,
9 ALC880_3ST,
10 ALC880_3ST_DIG,
11 ALC880_5ST,
12 ALC880_5ST_DIG,
13 ALC880_W810,
14 ALC880_Z71V,
15 ALC880_6ST,
16 ALC880_6ST_DIG,
17 ALC880_F1734,
18 ALC880_ASUS,
19 ALC880_ASUS_DIG,
20 ALC880_ASUS_W1V,
21 ALC880_ASUS_DIG2,
22 ALC880_FUJITSU,
23 ALC880_UNIWILL_DIG,
24 ALC880_UNIWILL,
25 ALC880_UNIWILL_P53,
26 ALC880_CLEVO,
27 ALC880_TCL_S700,
28 ALC880_LG,
29 ALC880_LG_LW,
30 ALC880_MEDION_RIM,
31#ifdef CONFIG_SND_DEBUG
32 ALC880_TEST,
33#endif
34 ALC880_MODEL_LAST /* last tag */
35};
36
37/*
38 * ALC880 3-stack model
39 *
40 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
41 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
42 * F-Mic = 0x1b, HP = 0x19
43 */
44
45static const hda_nid_t alc880_dac_nids[4] = {
46 /* front, rear, clfe, rear_surr */
47 0x02, 0x05, 0x04, 0x03
48};
49
50static const hda_nid_t alc880_adc_nids[3] = {
51 /* ADC0-2 */
52 0x07, 0x08, 0x09,
53};
54
55/* The datasheet says the node 0x07 is connected from inputs,
56 * but it shows zero connection in the real implementation on some devices.
57 * Note: this is a 915GAV bug, fixed on 915GLV
58 */
59static const hda_nid_t alc880_adc_nids_alt[2] = {
60 /* ADC1-2 */
61 0x08, 0x09,
62};
63
64#define ALC880_DIGOUT_NID 0x06
65#define ALC880_DIGIN_NID 0x0a
66#define ALC880_PIN_CD_NID 0x1c
67
68static const struct hda_input_mux alc880_capture_source = {
69 .num_items = 4,
70 .items = {
71 { "Mic", 0x0 },
72 { "Front Mic", 0x3 },
73 { "Line", 0x2 },
74 { "CD", 0x4 },
75 },
76};
77
78/* channel source setting (2/6 channel selection for 3-stack) */
79/* 2ch mode */
80static const struct hda_verb alc880_threestack_ch2_init[] = {
81 /* set line-in to input, mute it */
82 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
83 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84 /* set mic-in to input vref 80%, mute it */
85 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
86 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
87 { } /* end */
88};
89
90/* 6ch mode */
91static const struct hda_verb alc880_threestack_ch6_init[] = {
92 /* set line-in to output, unmute it */
93 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
94 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
95 /* set mic-in to output, unmute it */
96 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
97 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
98 { } /* end */
99};
100
101static const struct hda_channel_mode alc880_threestack_modes[2] = {
102 { 2, alc880_threestack_ch2_init },
103 { 6, alc880_threestack_ch6_init },
104};
105
106static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
109 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
110 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
111 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
112 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
113 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
114 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
115 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
116 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
118 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
121 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
122 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
124 {
125 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
126 .name = "Channel Mode",
127 .info = alc_ch_mode_info,
128 .get = alc_ch_mode_get,
129 .put = alc_ch_mode_put,
130 },
131 { } /* end */
132};
133
134/*
135 * ALC880 5-stack model
136 *
137 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
138 * Side = 0x02 (0xd)
139 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
140 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
141 */
142
143/* additional mixers to alc880_three_stack_mixer */
144static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
145 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
146 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
147 { } /* end */
148};
149
150/* channel source setting (6/8 channel selection for 5-stack) */
151/* 6ch mode */
152static const struct hda_verb alc880_fivestack_ch6_init[] = {
153 /* set line-in to input, mute it */
154 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
155 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
156 { } /* end */
157};
158
159/* 8ch mode */
160static const struct hda_verb alc880_fivestack_ch8_init[] = {
161 /* set line-in to output, unmute it */
162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
164 { } /* end */
165};
166
167static const struct hda_channel_mode alc880_fivestack_modes[2] = {
168 { 6, alc880_fivestack_ch6_init },
169 { 8, alc880_fivestack_ch8_init },
170};
171
172
173/*
174 * ALC880 6-stack model
175 *
176 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
177 * Side = 0x05 (0x0f)
178 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
179 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
180 */
181
182static const hda_nid_t alc880_6st_dac_nids[4] = {
183 /* front, rear, clfe, rear_surr */
184 0x02, 0x03, 0x04, 0x05
185};
186
187static const struct hda_input_mux alc880_6stack_capture_source = {
188 .num_items = 4,
189 .items = {
190 { "Mic", 0x0 },
191 { "Front Mic", 0x1 },
192 { "Line", 0x2 },
193 { "CD", 0x4 },
194 },
195};
196
197/* fixed 8-channels */
198static const struct hda_channel_mode alc880_sixstack_modes[1] = {
199 { 8, NULL },
200};
201
202static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
203 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
204 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
205 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
206 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
207 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
211 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
212 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
213 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
214 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
220 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
221 {
222 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
223 .name = "Channel Mode",
224 .info = alc_ch_mode_info,
225 .get = alc_ch_mode_get,
226 .put = alc_ch_mode_put,
227 },
228 { } /* end */
229};
230
231
232/*
233 * ALC880 W810 model
234 *
235 * W810 has rear IO for:
236 * Front (DAC 02)
237 * Surround (DAC 03)
238 * Center/LFE (DAC 04)
239 * Digital out (06)
240 *
241 * The system also has a pair of internal speakers, and a headphone jack.
242 * These are both connected to Line2 on the codec, hence to DAC 02.
243 *
244 * There is a variable resistor to control the speaker or headphone
245 * volume. This is a hardware-only device without a software API.
246 *
247 * Plugging headphones in will disable the internal speakers. This is
248 * implemented in hardware, not via the driver using jack sense. In
249 * a similar fashion, plugging into the rear socket marked "front" will
250 * disable both the speakers and headphones.
251 *
252 * For input, there's a microphone jack, and an "audio in" jack.
253 * These may not do anything useful with this driver yet, because I
254 * haven't setup any initialization verbs for these yet...
255 */
256
257static const hda_nid_t alc880_w810_dac_nids[3] = {
258 /* front, rear/surround, clfe */
259 0x02, 0x03, 0x04
260};
261
262/* fixed 6 channels */
263static const struct hda_channel_mode alc880_w810_modes[1] = {
264 { 6, NULL }
265};
266
267/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
268static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
269 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
270 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
271 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
272 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
273 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
274 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
275 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
276 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
278 { } /* end */
279};
280
281
282/*
283 * Z710V model
284 *
285 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
286 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
287 * Line = 0x1a
288 */
289
290static const hda_nid_t alc880_z71v_dac_nids[1] = {
291 0x02
292};
293#define ALC880_Z71V_HP_DAC 0x03
294
295/* fixed 2 channels */
296static const struct hda_channel_mode alc880_2_jack_modes[1] = {
297 { 2, NULL }
298};
299
300static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
301 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
302 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
303 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
304 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
305 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
306 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
307 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
308 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
309 { } /* end */
310};
311
312
313/*
314 * ALC880 F1734 model
315 *
316 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
317 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
318 */
319
320static const hda_nid_t alc880_f1734_dac_nids[1] = {
321 0x03
322};
323#define ALC880_F1734_HP_DAC 0x02
324
325static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
326 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
327 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
328 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
329 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
332 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
334 { } /* end */
335};
336
337static const struct hda_input_mux alc880_f1734_capture_source = {
338 .num_items = 2,
339 .items = {
340 { "Mic", 0x1 },
341 { "CD", 0x4 },
342 },
343};
344
345
346/*
347 * ALC880 ASUS model
348 *
349 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
350 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
351 * Mic = 0x18, Line = 0x1a
352 */
353
354#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
355#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
356
357static const struct snd_kcontrol_new alc880_asus_mixer[] = {
358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
361 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
363 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
364 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
365 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
366 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
367 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
372 {
373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
374 .name = "Channel Mode",
375 .info = alc_ch_mode_info,
376 .get = alc_ch_mode_get,
377 .put = alc_ch_mode_put,
378 },
379 { } /* end */
380};
381
382/*
383 * ALC880 ASUS W1V model
384 *
385 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
386 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
387 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
388 */
389
390/* additional mixers to alc880_asus_mixer */
391static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
392 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
393 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
394 { } /* end */
395};
396
397/* TCL S700 */
398static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
400 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
402 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
403 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
405 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
406 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
407 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
408 { } /* end */
409};
410
411/* Uniwill */
412static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
413 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
414 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
415 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
416 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
418 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
419 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
420 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
421 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
422 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
423 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
424 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
425 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
426 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
427 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
428 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
429 {
430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
431 .name = "Channel Mode",
432 .info = alc_ch_mode_info,
433 .get = alc_ch_mode_get,
434 .put = alc_ch_mode_put,
435 },
436 { } /* end */
437};
438
439static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
441 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
442 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
443 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
444 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
445 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
449 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
450 { } /* end */
451};
452
453static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
454 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
457 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
458 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
459 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
460 { } /* end */
461};
462
463/*
464 * initialize the codec volumes, etc
465 */
466
467/*
468 * generic initialization of ADC, input mixers and output mixers
469 */
470static const struct hda_verb alc880_volume_init_verbs[] = {
471 /*
472 * Unmute ADC0-2 and set the default input to mic-in
473 */
474 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
475 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
476 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
477 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
478 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
479 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
480
481 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
482 * mixer widget
483 * Note: PASD motherboards uses the Line In 2 as the input for front
484 * panel mic (mic 2)
485 */
486 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
489 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
490 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
491 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
492 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
493 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
494
495 /*
496 * Set up output mixers (0x0c - 0x0f)
497 */
498 /* set vol=0 to output mixers */
499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
500 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
501 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
502 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
503 /* set up input amps for analog loopback */
504 /* Amp Indices: DAC = 0, mixer = 1 */
505 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
507 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
508 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
509 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
510 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
512 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
513
514 { }
515};
516
517/*
518 * 3-stack pin configuration:
519 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
520 */
521static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
522 /*
523 * preset connection lists of input pins
524 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
525 */
526 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
527 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
528 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
529
530 /*
531 * Set pin mode and muting
532 */
533 /* set front pin widgets 0x14 for output */
534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
536 /* Mic1 (rear panel) pin widget for input and vref at 80% */
537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
538 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
539 /* Mic2 (as headphone out) for HP output */
540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
542 /* Line In pin widget for input */
543 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
545 /* Line2 (as front mic) pin widget for input and vref at 80% */
546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
547 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
548 /* CD pin widget for input */
549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
550
551 { }
552};
553
554/*
555 * 5-stack pin configuration:
556 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
557 * line-in/side = 0x1a, f-mic = 0x1b
558 */
559static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
560 /*
561 * preset connection lists of input pins
562 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
563 */
564 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
565 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
566
567 /*
568 * Set pin mode and muting
569 */
570 /* set pin widgets 0x14-0x17 for output */
571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
573 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
574 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
575 /* unmute pins for output (no gain on this amp) */
576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
579 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
580
581 /* Mic1 (rear panel) pin widget for input and vref at 80% */
582 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
584 /* Mic2 (as headphone out) for HP output */
585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
587 /* Line In pin widget for input */
588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
590 /* Line2 (as front mic) pin widget for input and vref at 80% */
591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
593 /* CD pin widget for input */
594 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
595
596 { }
597};
598
599/*
600 * W810 pin configuration:
601 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
602 */
603static const struct hda_verb alc880_pin_w810_init_verbs[] = {
604 /* hphone/speaker input selector: front DAC */
605 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
606
607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
608 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
610 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
611 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
612 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
613
614 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
615 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
616
617 { }
618};
619
620/*
621 * Z71V pin configuration:
622 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
623 */
624static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
627 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
628 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
629
630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
633 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
634
635 { }
636};
637
638/*
639 * 6-stack pin configuration:
640 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
641 * f-mic = 0x19, line = 0x1a, HP = 0x1b
642 */
643static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
644 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
645
646 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
647 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
648 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
650 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
652 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
654
655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
661 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
662 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
664
665 { }
666};
667
668/*
669 * Uniwill pin configuration:
670 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
671 * line = 0x1a
672 */
673static const struct hda_verb alc880_uniwill_init_verbs[] = {
674 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
675
676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
677 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
680 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
681 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
682 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
683 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
690
691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
697 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
698 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
699 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
700
701 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
702 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT},
703
704 { }
705};
706
707/*
708* Uniwill P53
709* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
710 */
711static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
712 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
713
714 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
715 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
716 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
717 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
718 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
719 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
720 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
721 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
722 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
723 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
724 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
725 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
726
727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
733
734 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
735 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_DCVOL_EVENT},
736
737 { }
738};
739
740static const struct hda_verb alc880_beep_init_verbs[] = {
741 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
742 { }
743};
744
745static void alc880_uniwill_setup(struct hda_codec *codec)
746{
747 struct alc_spec *spec = codec->spec;
748
749 spec->autocfg.hp_pins[0] = 0x14;
750 spec->autocfg.speaker_pins[0] = 0x15;
751 spec->autocfg.speaker_pins[0] = 0x16;
752 spec->automute = 1;
753 spec->automute_mode = ALC_AUTOMUTE_AMP;
754}
755
756static void alc880_uniwill_init_hook(struct hda_codec *codec)
757{
758 alc_hp_automute(codec);
759 alc88x_simple_mic_automute(codec);
760}
761
762static void alc880_uniwill_unsol_event(struct hda_codec *codec,
763 unsigned int res)
764{
765 /* Looks like the unsol event is incompatible with the standard
766 * definition. 4bit tag is placed at 28 bit!
767 */
768 switch (res >> 28) {
769 case ALC_MIC_EVENT:
770 alc88x_simple_mic_automute(codec);
771 break;
772 default:
773 alc_sku_unsol_event(codec, res);
774 break;
775 }
776}
777
778static void alc880_uniwill_p53_setup(struct hda_codec *codec)
779{
780 struct alc_spec *spec = codec->spec;
781
782 spec->autocfg.hp_pins[0] = 0x14;
783 spec->autocfg.speaker_pins[0] = 0x15;
784 spec->automute = 1;
785 spec->automute_mode = ALC_AUTOMUTE_AMP;
786}
787
788static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
789{
790 unsigned int present;
791
792 present = snd_hda_codec_read(codec, 0x21, 0,
793 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
794 present &= HDA_AMP_VOLMASK;
795 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
796 HDA_AMP_VOLMASK, present);
797 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
798 HDA_AMP_VOLMASK, present);
799}
800
801static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
802 unsigned int res)
803{
804 /* Looks like the unsol event is incompatible with the standard
805 * definition. 4bit tag is placed at 28 bit!
806 */
807 if ((res >> 28) == ALC_DCVOL_EVENT)
808 alc880_uniwill_p53_dcvol_automute(codec);
809 else
810 alc_sku_unsol_event(codec, res);
811}
812
813/*
814 * F1734 pin configuration:
815 * HP = 0x14, speaker-out = 0x15, mic = 0x18
816 */
817static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
818 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
819 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
820 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
821 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
822 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
823
824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
826 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
828
829 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
830 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
832 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
834 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
835 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
836 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
837 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
838
839 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT},
840 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_DCVOL_EVENT},
841
842 { }
843};
844
845/*
846 * ASUS pin configuration:
847 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
848 */
849static const struct hda_verb alc880_pin_asus_init_verbs[] = {
850 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
851 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
852 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
853 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
854
855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
856 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
859 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
861 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
862 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
863
864 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
865 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
866 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
867 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
869 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
870 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
871 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
872 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
873
874 { }
875};
876
877/* Enable GPIO mask and set output */
878#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
879#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
880#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
881
882/* Clevo m520g init */
883static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
884 /* headphone output */
885 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
886 /* line-out */
887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
889 /* Line-in */
890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
892 /* CD */
893 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
894 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
895 /* Mic1 (rear panel) */
896 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
897 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
898 /* Mic2 (front panel) */
899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
900 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
901 /* headphone */
902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
904 /* change to EAPD mode */
905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
906 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
907
908 { }
909};
910
911static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
912 /* change to EAPD mode */
913 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
914 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
915
916 /* Headphone output */
917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
918 /* Front output*/
919 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
920 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
921
922 /* Line In pin widget for input */
923 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
924 /* CD pin widget for input */
925 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
926 /* Mic1 (rear panel) pin widget for input and vref at 80% */
927 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
928
929 /* change to EAPD mode */
930 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
931 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
932
933 { }
934};
935
936/*
937 * LG m1 express dual
938 *
939 * Pin assignment:
940 * Rear Line-In/Out (blue): 0x14
941 * Build-in Mic-In: 0x15
942 * Speaker-out: 0x17
943 * HP-Out (green): 0x1b
944 * Mic-In/Out (red): 0x19
945 * SPDIF-Out: 0x1e
946 */
947
948/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
949static const hda_nid_t alc880_lg_dac_nids[3] = {
950 0x05, 0x02, 0x03
951};
952
953/* seems analog CD is not working */
954static const struct hda_input_mux alc880_lg_capture_source = {
955 .num_items = 3,
956 .items = {
957 { "Mic", 0x1 },
958 { "Line", 0x5 },
959 { "Internal Mic", 0x6 },
960 },
961};
962
963/* 2,4,6 channel modes */
964static const struct hda_verb alc880_lg_ch2_init[] = {
965 /* set line-in and mic-in to input */
966 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
967 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
968 { }
969};
970
971static const struct hda_verb alc880_lg_ch4_init[] = {
972 /* set line-in to out and mic-in to input */
973 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
974 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
975 { }
976};
977
978static const struct hda_verb alc880_lg_ch6_init[] = {
979 /* set line-in and mic-in to output */
980 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
981 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
982 { }
983};
984
985static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
986 { 2, alc880_lg_ch2_init },
987 { 4, alc880_lg_ch4_init },
988 { 6, alc880_lg_ch6_init },
989};
990
991static const struct snd_kcontrol_new alc880_lg_mixer[] = {
992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
993 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
995 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
1000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
1003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
1004 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
1005 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
1006 {
1007 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1008 .name = "Channel Mode",
1009 .info = alc_ch_mode_info,
1010 .get = alc_ch_mode_get,
1011 .put = alc_ch_mode_put,
1012 },
1013 { } /* end */
1014};
1015
1016static const struct hda_verb alc880_lg_init_verbs[] = {
1017 /* set capture source to mic-in */
1018 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1020 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1021 /* mute all amp mixer inputs */
1022 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
1023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
1024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1025 /* line-in to input */
1026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1028 /* built-in mic */
1029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1030 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1031 /* speaker-out */
1032 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1033 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1034 /* mic-in to input */
1035 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
1036 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1037 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1038 /* HP-out */
1039 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
1040 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1041 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1042 /* jack sense */
1043 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1044 { }
1045};
1046
1047/* toggle speaker-output according to the hp-jack state */
1048static void alc880_lg_setup(struct hda_codec *codec)
1049{
1050 struct alc_spec *spec = codec->spec;
1051
1052 spec->autocfg.hp_pins[0] = 0x1b;
1053 spec->autocfg.speaker_pins[0] = 0x17;
1054 spec->automute = 1;
1055 spec->automute_mode = ALC_AUTOMUTE_AMP;
1056}
1057
1058/*
1059 * LG LW20
1060 *
1061 * Pin assignment:
1062 * Speaker-out: 0x14
1063 * Mic-In: 0x18
1064 * Built-in Mic-In: 0x19
1065 * Line-In: 0x1b
1066 * HP-Out: 0x1a
1067 * SPDIF-Out: 0x1e
1068 */
1069
1070static const struct hda_input_mux alc880_lg_lw_capture_source = {
1071 .num_items = 3,
1072 .items = {
1073 { "Mic", 0x0 },
1074 { "Internal Mic", 0x1 },
1075 { "Line In", 0x2 },
1076 },
1077};
1078
1079#define alc880_lg_lw_modes alc880_threestack_modes
1080
1081static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
1082 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1083 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1084 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1085 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
1086 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1087 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1088 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1089 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1090 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1091 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1093 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1094 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1095 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1096 {
1097 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1098 .name = "Channel Mode",
1099 .info = alc_ch_mode_info,
1100 .get = alc_ch_mode_get,
1101 .put = alc_ch_mode_put,
1102 },
1103 { } /* end */
1104};
1105
1106static const struct hda_verb alc880_lg_lw_init_verbs[] = {
1107 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1108 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1109 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
1110
1111 /* set capture source to mic-in */
1112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1113 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1114 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1115 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1116 /* speaker-out */
1117 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1118 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1119 /* HP-out */
1120 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1122 /* mic-in to input */
1123 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1124 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1125 /* built-in mic */
1126 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1127 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1128 /* jack sense */
1129 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1130 { }
1131};
1132
1133/* toggle speaker-output according to the hp-jack state */
1134static void alc880_lg_lw_setup(struct hda_codec *codec)
1135{
1136 struct alc_spec *spec = codec->spec;
1137
1138 spec->autocfg.hp_pins[0] = 0x1b;
1139 spec->autocfg.speaker_pins[0] = 0x14;
1140 spec->automute = 1;
1141 spec->automute_mode = ALC_AUTOMUTE_AMP;
1142}
1143
1144static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
1145 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1146 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
1147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1148 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1150 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
1151 { } /* end */
1152};
1153
1154static const struct hda_input_mux alc880_medion_rim_capture_source = {
1155 .num_items = 2,
1156 .items = {
1157 { "Mic", 0x0 },
1158 { "Internal Mic", 0x1 },
1159 },
1160};
1161
1162static const struct hda_verb alc880_medion_rim_init_verbs[] = {
1163 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1164
1165 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1166 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1167
1168 /* Mic1 (rear panel) pin widget for input and vref at 80% */
1169 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1170 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1171 /* Mic2 (as headphone out) for HP output */
1172 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1174 /* Internal Speaker */
1175 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1176 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1177
1178 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1179 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1180
1181 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1182 { }
1183};
1184
1185/* toggle speaker-output according to the hp-jack state */
1186static void alc880_medion_rim_automute(struct hda_codec *codec)
1187{
1188 struct alc_spec *spec = codec->spec;
1189 alc_hp_automute(codec);
1190 /* toggle EAPD */
1191 if (spec->jack_present)
1192 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
1193 else
1194 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
1195}
1196
1197static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
1198 unsigned int res)
1199{
1200 /* Looks like the unsol event is incompatible with the standard
1201 * definition. 4bit tag is placed at 28 bit!
1202 */
1203 if ((res >> 28) == ALC_HP_EVENT)
1204 alc880_medion_rim_automute(codec);
1205}
1206
1207static void alc880_medion_rim_setup(struct hda_codec *codec)
1208{
1209 struct alc_spec *spec = codec->spec;
1210
1211 spec->autocfg.hp_pins[0] = 0x14;
1212 spec->autocfg.speaker_pins[0] = 0x1b;
1213 spec->automute = 1;
1214 spec->automute_mode = ALC_AUTOMUTE_AMP;
1215}
1216
1217#ifdef CONFIG_SND_HDA_POWER_SAVE
1218static const struct hda_amp_list alc880_lg_loopbacks[] = {
1219 { 0x0b, HDA_INPUT, 1 },
1220 { 0x0b, HDA_INPUT, 6 },
1221 { 0x0b, HDA_INPUT, 7 },
1222 { } /* end */
1223};
1224#endif
1225
1226/*
1227 * Test configuration for debugging
1228 *
1229 * Almost all inputs/outputs are enabled. I/O pins can be configured via
1230 * enum controls.
1231 */
1232#ifdef CONFIG_SND_DEBUG
1233static const hda_nid_t alc880_test_dac_nids[4] = {
1234 0x02, 0x03, 0x04, 0x05
1235};
1236
1237static const struct hda_input_mux alc880_test_capture_source = {
1238 .num_items = 7,
1239 .items = {
1240 { "In-1", 0x0 },
1241 { "In-2", 0x1 },
1242 { "In-3", 0x2 },
1243 { "In-4", 0x3 },
1244 { "CD", 0x4 },
1245 { "Front", 0x5 },
1246 { "Surround", 0x6 },
1247 },
1248};
1249
1250static const struct hda_channel_mode alc880_test_modes[4] = {
1251 { 2, NULL },
1252 { 4, NULL },
1253 { 6, NULL },
1254 { 8, NULL },
1255};
1256
1257static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
1258 struct snd_ctl_elem_info *uinfo)
1259{
1260 static const char * const texts[] = {
1261 "N/A", "Line Out", "HP Out",
1262 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
1263 };
1264 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1265 uinfo->count = 1;
1266 uinfo->value.enumerated.items = 8;
1267 if (uinfo->value.enumerated.item >= 8)
1268 uinfo->value.enumerated.item = 7;
1269 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1270 return 0;
1271}
1272
1273static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
1274 struct snd_ctl_elem_value *ucontrol)
1275{
1276 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1277 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1278 unsigned int pin_ctl, item = 0;
1279
1280 pin_ctl = snd_hda_codec_read(codec, nid, 0,
1281 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1282 if (pin_ctl & AC_PINCTL_OUT_EN) {
1283 if (pin_ctl & AC_PINCTL_HP_EN)
1284 item = 2;
1285 else
1286 item = 1;
1287 } else if (pin_ctl & AC_PINCTL_IN_EN) {
1288 switch (pin_ctl & AC_PINCTL_VREFEN) {
1289 case AC_PINCTL_VREF_HIZ: item = 3; break;
1290 case AC_PINCTL_VREF_50: item = 4; break;
1291 case AC_PINCTL_VREF_GRD: item = 5; break;
1292 case AC_PINCTL_VREF_80: item = 6; break;
1293 case AC_PINCTL_VREF_100: item = 7; break;
1294 }
1295 }
1296 ucontrol->value.enumerated.item[0] = item;
1297 return 0;
1298}
1299
1300static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
1301 struct snd_ctl_elem_value *ucontrol)
1302{
1303 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1304 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1305 static const unsigned int ctls[] = {
1306 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
1307 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
1308 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
1309 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
1310 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
1311 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
1312 };
1313 unsigned int old_ctl, new_ctl;
1314
1315 old_ctl = snd_hda_codec_read(codec, nid, 0,
1316 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1317 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
1318 if (old_ctl != new_ctl) {
1319 int val;
1320 snd_hda_codec_write_cache(codec, nid, 0,
1321 AC_VERB_SET_PIN_WIDGET_CONTROL,
1322 new_ctl);
1323 val = ucontrol->value.enumerated.item[0] >= 3 ?
1324 HDA_AMP_MUTE : 0;
1325 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1326 HDA_AMP_MUTE, val);
1327 return 1;
1328 }
1329 return 0;
1330}
1331
1332static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
1333 struct snd_ctl_elem_info *uinfo)
1334{
1335 static const char * const texts[] = {
1336 "Front", "Surround", "CLFE", "Side"
1337 };
1338 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1339 uinfo->count = 1;
1340 uinfo->value.enumerated.items = 4;
1341 if (uinfo->value.enumerated.item >= 4)
1342 uinfo->value.enumerated.item = 3;
1343 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1344 return 0;
1345}
1346
1347static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
1348 struct snd_ctl_elem_value *ucontrol)
1349{
1350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1351 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1352 unsigned int sel;
1353
1354 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
1355 ucontrol->value.enumerated.item[0] = sel & 3;
1356 return 0;
1357}
1358
1359static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
1360 struct snd_ctl_elem_value *ucontrol)
1361{
1362 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1363 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
1364 unsigned int sel;
1365
1366 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
1367 if (ucontrol->value.enumerated.item[0] != sel) {
1368 sel = ucontrol->value.enumerated.item[0] & 3;
1369 snd_hda_codec_write_cache(codec, nid, 0,
1370 AC_VERB_SET_CONNECT_SEL, sel);
1371 return 1;
1372 }
1373 return 0;
1374}
1375
1376#define PIN_CTL_TEST(xname,nid) { \
1377 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1378 .name = xname, \
1379 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1380 .info = alc_test_pin_ctl_info, \
1381 .get = alc_test_pin_ctl_get, \
1382 .put = alc_test_pin_ctl_put, \
1383 .private_value = nid \
1384 }
1385
1386#define PIN_SRC_TEST(xname,nid) { \
1387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1388 .name = xname, \
1389 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
1390 .info = alc_test_pin_src_info, \
1391 .get = alc_test_pin_src_get, \
1392 .put = alc_test_pin_src_put, \
1393 .private_value = nid \
1394 }
1395
1396static const struct snd_kcontrol_new alc880_test_mixer[] = {
1397 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1398 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1399 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
1400 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1402 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1403 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
1404 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1405 PIN_CTL_TEST("Front Pin Mode", 0x14),
1406 PIN_CTL_TEST("Surround Pin Mode", 0x15),
1407 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
1408 PIN_CTL_TEST("Side Pin Mode", 0x17),
1409 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
1410 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
1411 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
1412 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
1413 PIN_SRC_TEST("In-1 Pin Source", 0x18),
1414 PIN_SRC_TEST("In-2 Pin Source", 0x19),
1415 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
1416 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
1417 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
1418 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
1419 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
1420 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
1421 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
1422 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
1423 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
1424 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
1425 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
1426 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
1427 {
1428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1429 .name = "Channel Mode",
1430 .info = alc_ch_mode_info,
1431 .get = alc_ch_mode_get,
1432 .put = alc_ch_mode_put,
1433 },
1434 { } /* end */
1435};
1436
1437static const struct hda_verb alc880_test_init_verbs[] = {
1438 /* Unmute inputs of 0x0c - 0x0f */
1439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1441 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1442 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1443 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1444 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1445 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1446 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1447 /* Vol output for 0x0c-0x0f */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1450 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1451 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1452 /* Set output pins 0x14-0x17 */
1453 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1454 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1455 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1456 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1457 /* Unmute output pins 0x14-0x17 */
1458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1460 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1461 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1462 /* Set input pins 0x18-0x1c */
1463 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1464 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1465 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1467 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1468 /* Mute input pins 0x18-0x1b */
1469 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1470 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1471 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1472 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1473 /* ADC set up */
1474 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1475 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1476 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1477 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1478 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1479 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1480 /* Analog input/passthru */
1481 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1482 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1483 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1484 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1485 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1486 { }
1487};
1488#endif
1489
1490/*
1491 */
1492
1493static const char * const alc880_models[ALC880_MODEL_LAST] = {
1494 [ALC880_3ST] = "3stack",
1495 [ALC880_TCL_S700] = "tcl",
1496 [ALC880_3ST_DIG] = "3stack-digout",
1497 [ALC880_CLEVO] = "clevo",
1498 [ALC880_5ST] = "5stack",
1499 [ALC880_5ST_DIG] = "5stack-digout",
1500 [ALC880_W810] = "w810",
1501 [ALC880_Z71V] = "z71v",
1502 [ALC880_6ST] = "6stack",
1503 [ALC880_6ST_DIG] = "6stack-digout",
1504 [ALC880_ASUS] = "asus",
1505 [ALC880_ASUS_W1V] = "asus-w1v",
1506 [ALC880_ASUS_DIG] = "asus-dig",
1507 [ALC880_ASUS_DIG2] = "asus-dig2",
1508 [ALC880_UNIWILL_DIG] = "uniwill",
1509 [ALC880_UNIWILL_P53] = "uniwill-p53",
1510 [ALC880_FUJITSU] = "fujitsu",
1511 [ALC880_F1734] = "F1734",
1512 [ALC880_LG] = "lg",
1513 [ALC880_LG_LW] = "lg-lw",
1514 [ALC880_MEDION_RIM] = "medion",
1515#ifdef CONFIG_SND_DEBUG
1516 [ALC880_TEST] = "test",
1517#endif
1518 [ALC880_AUTO] = "auto",
1519};
1520
1521static const struct snd_pci_quirk alc880_cfg_tbl[] = {
1522 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
1523 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
1524 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
1525 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
1526 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
1527 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
1528 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
1529 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
1530 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
1531 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
1532 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
1533 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
1534 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
1535 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
1536 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
1537 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
1538 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
1539 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
1540 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
1541 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
1542 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
1543 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
1544 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
1545 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
1546 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
1547 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
1548 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
1549 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
1550 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
1551 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
1552 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
1553 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
1554 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
1555 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
1556 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
1557 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
1558 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
1559 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
1560 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
1561 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
1562 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
1563 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
1564 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
1565 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
1566 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
1567 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
1568 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1569 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
1570 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
1571 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
1572 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
1573 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
1574 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
1575 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
1576 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
1577 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
1578 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
1579 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
1580 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
1581 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
1582 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
1583 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
1584 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
1585 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
1586 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
1587 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
1588 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
1589 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
1590 /* default Intel */
1591 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
1592 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
1593 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1594 {}
1595};
1596
1597/*
1598 * ALC880 codec presets
1599 */
1600static const struct alc_config_preset alc880_presets[] = {
1601 [ALC880_3ST] = {
1602 .mixers = { alc880_three_stack_mixer },
1603 .init_verbs = { alc880_volume_init_verbs,
1604 alc880_pin_3stack_init_verbs },
1605 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1606 .dac_nids = alc880_dac_nids,
1607 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1608 .channel_mode = alc880_threestack_modes,
1609 .need_dac_fix = 1,
1610 .input_mux = &alc880_capture_source,
1611 },
1612 [ALC880_3ST_DIG] = {
1613 .mixers = { alc880_three_stack_mixer },
1614 .init_verbs = { alc880_volume_init_verbs,
1615 alc880_pin_3stack_init_verbs },
1616 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1617 .dac_nids = alc880_dac_nids,
1618 .dig_out_nid = ALC880_DIGOUT_NID,
1619 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1620 .channel_mode = alc880_threestack_modes,
1621 .need_dac_fix = 1,
1622 .input_mux = &alc880_capture_source,
1623 },
1624 [ALC880_TCL_S700] = {
1625 .mixers = { alc880_tcl_s700_mixer },
1626 .init_verbs = { alc880_volume_init_verbs,
1627 alc880_pin_tcl_S700_init_verbs,
1628 alc880_gpio2_init_verbs },
1629 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1630 .dac_nids = alc880_dac_nids,
1631 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
1632 .num_adc_nids = 1, /* single ADC */
1633 .hp_nid = 0x03,
1634 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1635 .channel_mode = alc880_2_jack_modes,
1636 .input_mux = &alc880_capture_source,
1637 },
1638 [ALC880_5ST] = {
1639 .mixers = { alc880_three_stack_mixer,
1640 alc880_five_stack_mixer},
1641 .init_verbs = { alc880_volume_init_verbs,
1642 alc880_pin_5stack_init_verbs },
1643 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1644 .dac_nids = alc880_dac_nids,
1645 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1646 .channel_mode = alc880_fivestack_modes,
1647 .input_mux = &alc880_capture_source,
1648 },
1649 [ALC880_5ST_DIG] = {
1650 .mixers = { alc880_three_stack_mixer,
1651 alc880_five_stack_mixer },
1652 .init_verbs = { alc880_volume_init_verbs,
1653 alc880_pin_5stack_init_verbs },
1654 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1655 .dac_nids = alc880_dac_nids,
1656 .dig_out_nid = ALC880_DIGOUT_NID,
1657 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
1658 .channel_mode = alc880_fivestack_modes,
1659 .input_mux = &alc880_capture_source,
1660 },
1661 [ALC880_6ST] = {
1662 .mixers = { alc880_six_stack_mixer },
1663 .init_verbs = { alc880_volume_init_verbs,
1664 alc880_pin_6stack_init_verbs },
1665 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1666 .dac_nids = alc880_6st_dac_nids,
1667 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1668 .channel_mode = alc880_sixstack_modes,
1669 .input_mux = &alc880_6stack_capture_source,
1670 },
1671 [ALC880_6ST_DIG] = {
1672 .mixers = { alc880_six_stack_mixer },
1673 .init_verbs = { alc880_volume_init_verbs,
1674 alc880_pin_6stack_init_verbs },
1675 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
1676 .dac_nids = alc880_6st_dac_nids,
1677 .dig_out_nid = ALC880_DIGOUT_NID,
1678 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
1679 .channel_mode = alc880_sixstack_modes,
1680 .input_mux = &alc880_6stack_capture_source,
1681 },
1682 [ALC880_W810] = {
1683 .mixers = { alc880_w810_base_mixer },
1684 .init_verbs = { alc880_volume_init_verbs,
1685 alc880_pin_w810_init_verbs,
1686 alc880_gpio2_init_verbs },
1687 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
1688 .dac_nids = alc880_w810_dac_nids,
1689 .dig_out_nid = ALC880_DIGOUT_NID,
1690 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1691 .channel_mode = alc880_w810_modes,
1692 .input_mux = &alc880_capture_source,
1693 },
1694 [ALC880_Z71V] = {
1695 .mixers = { alc880_z71v_mixer },
1696 .init_verbs = { alc880_volume_init_verbs,
1697 alc880_pin_z71v_init_verbs },
1698 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
1699 .dac_nids = alc880_z71v_dac_nids,
1700 .dig_out_nid = ALC880_DIGOUT_NID,
1701 .hp_nid = 0x03,
1702 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1703 .channel_mode = alc880_2_jack_modes,
1704 .input_mux = &alc880_capture_source,
1705 },
1706 [ALC880_F1734] = {
1707 .mixers = { alc880_f1734_mixer },
1708 .init_verbs = { alc880_volume_init_verbs,
1709 alc880_pin_f1734_init_verbs },
1710 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
1711 .dac_nids = alc880_f1734_dac_nids,
1712 .hp_nid = 0x02,
1713 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1714 .channel_mode = alc880_2_jack_modes,
1715 .input_mux = &alc880_f1734_capture_source,
1716 .unsol_event = alc880_uniwill_p53_unsol_event,
1717 .setup = alc880_uniwill_p53_setup,
1718 .init_hook = alc_hp_automute,
1719 },
1720 [ALC880_ASUS] = {
1721 .mixers = { alc880_asus_mixer },
1722 .init_verbs = { alc880_volume_init_verbs,
1723 alc880_pin_asus_init_verbs,
1724 alc880_gpio1_init_verbs },
1725 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1726 .dac_nids = alc880_asus_dac_nids,
1727 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1728 .channel_mode = alc880_asus_modes,
1729 .need_dac_fix = 1,
1730 .input_mux = &alc880_capture_source,
1731 },
1732 [ALC880_ASUS_DIG] = {
1733 .mixers = { alc880_asus_mixer },
1734 .init_verbs = { alc880_volume_init_verbs,
1735 alc880_pin_asus_init_verbs,
1736 alc880_gpio1_init_verbs },
1737 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1738 .dac_nids = alc880_asus_dac_nids,
1739 .dig_out_nid = ALC880_DIGOUT_NID,
1740 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1741 .channel_mode = alc880_asus_modes,
1742 .need_dac_fix = 1,
1743 .input_mux = &alc880_capture_source,
1744 },
1745 [ALC880_ASUS_DIG2] = {
1746 .mixers = { alc880_asus_mixer },
1747 .init_verbs = { alc880_volume_init_verbs,
1748 alc880_pin_asus_init_verbs,
1749 alc880_gpio2_init_verbs }, /* use GPIO2 */
1750 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1751 .dac_nids = alc880_asus_dac_nids,
1752 .dig_out_nid = ALC880_DIGOUT_NID,
1753 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1754 .channel_mode = alc880_asus_modes,
1755 .need_dac_fix = 1,
1756 .input_mux = &alc880_capture_source,
1757 },
1758 [ALC880_ASUS_W1V] = {
1759 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
1760 .init_verbs = { alc880_volume_init_verbs,
1761 alc880_pin_asus_init_verbs,
1762 alc880_gpio1_init_verbs },
1763 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1764 .dac_nids = alc880_asus_dac_nids,
1765 .dig_out_nid = ALC880_DIGOUT_NID,
1766 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1767 .channel_mode = alc880_asus_modes,
1768 .need_dac_fix = 1,
1769 .input_mux = &alc880_capture_source,
1770 },
1771 [ALC880_UNIWILL_DIG] = {
1772 .mixers = { alc880_asus_mixer },
1773 .init_verbs = { alc880_volume_init_verbs,
1774 alc880_pin_asus_init_verbs },
1775 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1776 .dac_nids = alc880_asus_dac_nids,
1777 .dig_out_nid = ALC880_DIGOUT_NID,
1778 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
1779 .channel_mode = alc880_asus_modes,
1780 .need_dac_fix = 1,
1781 .input_mux = &alc880_capture_source,
1782 },
1783 [ALC880_UNIWILL] = {
1784 .mixers = { alc880_uniwill_mixer },
1785 .init_verbs = { alc880_volume_init_verbs,
1786 alc880_uniwill_init_verbs },
1787 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1788 .dac_nids = alc880_asus_dac_nids,
1789 .dig_out_nid = ALC880_DIGOUT_NID,
1790 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1791 .channel_mode = alc880_threestack_modes,
1792 .need_dac_fix = 1,
1793 .input_mux = &alc880_capture_source,
1794 .unsol_event = alc880_uniwill_unsol_event,
1795 .setup = alc880_uniwill_setup,
1796 .init_hook = alc880_uniwill_init_hook,
1797 },
1798 [ALC880_UNIWILL_P53] = {
1799 .mixers = { alc880_uniwill_p53_mixer },
1800 .init_verbs = { alc880_volume_init_verbs,
1801 alc880_uniwill_p53_init_verbs },
1802 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
1803 .dac_nids = alc880_asus_dac_nids,
1804 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
1805 .channel_mode = alc880_threestack_modes,
1806 .input_mux = &alc880_capture_source,
1807 .unsol_event = alc880_uniwill_p53_unsol_event,
1808 .setup = alc880_uniwill_p53_setup,
1809 .init_hook = alc_hp_automute,
1810 },
1811 [ALC880_FUJITSU] = {
1812 .mixers = { alc880_fujitsu_mixer },
1813 .init_verbs = { alc880_volume_init_verbs,
1814 alc880_uniwill_p53_init_verbs,
1815 alc880_beep_init_verbs },
1816 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1817 .dac_nids = alc880_dac_nids,
1818 .dig_out_nid = ALC880_DIGOUT_NID,
1819 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1820 .channel_mode = alc880_2_jack_modes,
1821 .input_mux = &alc880_capture_source,
1822 .unsol_event = alc880_uniwill_p53_unsol_event,
1823 .setup = alc880_uniwill_p53_setup,
1824 .init_hook = alc_hp_automute,
1825 },
1826 [ALC880_CLEVO] = {
1827 .mixers = { alc880_three_stack_mixer },
1828 .init_verbs = { alc880_volume_init_verbs,
1829 alc880_pin_clevo_init_verbs },
1830 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1831 .dac_nids = alc880_dac_nids,
1832 .hp_nid = 0x03,
1833 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
1834 .channel_mode = alc880_threestack_modes,
1835 .need_dac_fix = 1,
1836 .input_mux = &alc880_capture_source,
1837 },
1838 [ALC880_LG] = {
1839 .mixers = { alc880_lg_mixer },
1840 .init_verbs = { alc880_volume_init_verbs,
1841 alc880_lg_init_verbs },
1842 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
1843 .dac_nids = alc880_lg_dac_nids,
1844 .dig_out_nid = ALC880_DIGOUT_NID,
1845 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
1846 .channel_mode = alc880_lg_ch_modes,
1847 .need_dac_fix = 1,
1848 .input_mux = &alc880_lg_capture_source,
1849 .unsol_event = alc_sku_unsol_event,
1850 .setup = alc880_lg_setup,
1851 .init_hook = alc_hp_automute,
1852#ifdef CONFIG_SND_HDA_POWER_SAVE
1853 .loopbacks = alc880_lg_loopbacks,
1854#endif
1855 },
1856 [ALC880_LG_LW] = {
1857 .mixers = { alc880_lg_lw_mixer },
1858 .init_verbs = { alc880_volume_init_verbs,
1859 alc880_lg_lw_init_verbs },
1860 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1861 .dac_nids = alc880_dac_nids,
1862 .dig_out_nid = ALC880_DIGOUT_NID,
1863 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
1864 .channel_mode = alc880_lg_lw_modes,
1865 .input_mux = &alc880_lg_lw_capture_source,
1866 .unsol_event = alc_sku_unsol_event,
1867 .setup = alc880_lg_lw_setup,
1868 .init_hook = alc_hp_automute,
1869 },
1870 [ALC880_MEDION_RIM] = {
1871 .mixers = { alc880_medion_rim_mixer },
1872 .init_verbs = { alc880_volume_init_verbs,
1873 alc880_medion_rim_init_verbs,
1874 alc_gpio2_init_verbs },
1875 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
1876 .dac_nids = alc880_dac_nids,
1877 .dig_out_nid = ALC880_DIGOUT_NID,
1878 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
1879 .channel_mode = alc880_2_jack_modes,
1880 .input_mux = &alc880_medion_rim_capture_source,
1881 .unsol_event = alc880_medion_rim_unsol_event,
1882 .setup = alc880_medion_rim_setup,
1883 .init_hook = alc880_medion_rim_automute,
1884 },
1885#ifdef CONFIG_SND_DEBUG
1886 [ALC880_TEST] = {
1887 .mixers = { alc880_test_mixer },
1888 .init_verbs = { alc880_test_init_verbs },
1889 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
1890 .dac_nids = alc880_test_dac_nids,
1891 .dig_out_nid = ALC880_DIGOUT_NID,
1892 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
1893 .channel_mode = alc880_test_modes,
1894 .input_mux = &alc880_test_capture_source,
1895 },
1896#endif
1897};
1898
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c
new file mode 100644
index 000000000000..617d04723b82
--- /dev/null
+++ b/sound/pci/hda/alc882_quirks.c
@@ -0,0 +1,3755 @@
1/*
2 * ALC882/ALC883/ALC888/ALC889 quirk models
3 * included by patch_realtek.c
4 */
5
6/* ALC882 models */
7enum {
8 ALC882_AUTO,
9 ALC882_3ST_DIG,
10 ALC882_6ST_DIG,
11 ALC882_ARIMA,
12 ALC882_W2JC,
13 ALC882_TARGA,
14 ALC882_ASUS_A7J,
15 ALC882_ASUS_A7M,
16 ALC885_MACPRO,
17 ALC885_MBA21,
18 ALC885_MBP3,
19 ALC885_MB5,
20 ALC885_MACMINI3,
21 ALC885_IMAC24,
22 ALC885_IMAC91,
23 ALC883_3ST_2ch_DIG,
24 ALC883_3ST_6ch_DIG,
25 ALC883_3ST_6ch,
26 ALC883_6ST_DIG,
27 ALC883_TARGA_DIG,
28 ALC883_TARGA_2ch_DIG,
29 ALC883_TARGA_8ch_DIG,
30 ALC883_ACER,
31 ALC883_ACER_ASPIRE,
32 ALC888_ACER_ASPIRE_4930G,
33 ALC888_ACER_ASPIRE_6530G,
34 ALC888_ACER_ASPIRE_8930G,
35 ALC888_ACER_ASPIRE_7730G,
36 ALC883_MEDION,
37 ALC883_MEDION_WIM2160,
38 ALC883_LAPTOP_EAPD,
39 ALC883_LENOVO_101E_2ch,
40 ALC883_LENOVO_NB0763,
41 ALC888_LENOVO_MS7195_DIG,
42 ALC888_LENOVO_SKY,
43 ALC883_HAIER_W66,
44 ALC888_3ST_HP,
45 ALC888_6ST_DELL,
46 ALC883_MITAC,
47 ALC883_CLEVO_M540R,
48 ALC883_CLEVO_M720,
49 ALC883_FUJITSU_PI2515,
50 ALC888_FUJITSU_XA3530,
51 ALC883_3ST_6ch_INTEL,
52 ALC889A_INTEL,
53 ALC889_INTEL,
54 ALC888_ASUS_M90V,
55 ALC888_ASUS_EEE1601,
56 ALC889A_MB31,
57 ALC1200_ASUS_P5Q,
58 ALC883_SONY_VAIO_TT,
59 ALC882_MODEL_LAST,
60};
61
62/*
63 * 2ch mode
64 */
65static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
66/* Mic-in jack as mic in */
67 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
68 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
69/* Line-in jack as Line in */
70 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
71 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
72/* Line-Out as Front */
73 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
74 { } /* end */
75};
76
77/*
78 * 4ch mode
79 */
80static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
81/* Mic-in jack as mic in */
82 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
83 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
84/* Line-in jack as Surround */
85 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
86 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87/* Line-Out as Front */
88 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
89 { } /* end */
90};
91
92/*
93 * 6ch mode
94 */
95static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
96/* Mic-in jack as CLFE */
97 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
98 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
99/* Line-in jack as Surround */
100 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
101 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
102/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
103 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
104 { } /* end */
105};
106
107/*
108 * 8ch mode
109 */
110static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
111/* Mic-in jack as CLFE */
112 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
113 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
114/* Line-in jack as Surround */
115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
117/* Line-Out as Side */
118 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
119 { } /* end */
120};
121
122static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
123 { 2, alc888_4ST_ch2_intel_init },
124 { 4, alc888_4ST_ch4_intel_init },
125 { 6, alc888_4ST_ch6_intel_init },
126 { 8, alc888_4ST_ch8_intel_init },
127};
128
129/*
130 * ALC888 Fujitsu Siemens Amillo xa3530
131 */
132
133static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
134/* Front Mic: set to PIN_IN (empty by default) */
135 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
136/* Connect Internal HP to Front */
137 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
138 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
139 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
140/* Connect Bass HP to Front */
141 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
142 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
143 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
144/* Connect Line-Out side jack (SPDIF) to Side */
145 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
146 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
147 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
148/* Connect Mic jack to CLFE */
149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
150 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
151 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
152/* Connect Line-in jack to Surround */
153 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
154 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
155 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
156/* Connect HP out jack to Front */
157 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
158 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
159 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
160/* Enable unsolicited event for HP jack and Line-out jack */
161 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
162 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
163 {}
164};
165
166static void alc889_automute_setup(struct hda_codec *codec)
167{
168 struct alc_spec *spec = codec->spec;
169
170 spec->autocfg.hp_pins[0] = 0x15;
171 spec->autocfg.speaker_pins[0] = 0x14;
172 spec->autocfg.speaker_pins[1] = 0x16;
173 spec->autocfg.speaker_pins[2] = 0x17;
174 spec->autocfg.speaker_pins[3] = 0x19;
175 spec->autocfg.speaker_pins[4] = 0x1a;
176 spec->automute = 1;
177 spec->automute_mode = ALC_AUTOMUTE_AMP;
178}
179
180static void alc889_intel_init_hook(struct hda_codec *codec)
181{
182 alc889_coef_init(codec);
183 alc_hp_automute(codec);
184}
185
186static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
187{
188 struct alc_spec *spec = codec->spec;
189
190 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
191 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
192 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
193 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
194 spec->automute = 1;
195 spec->automute_mode = ALC_AUTOMUTE_AMP;
196}
197
198/*
199 * ALC888 Acer Aspire 4930G model
200 */
201
202static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
203/* Front Mic: set to PIN_IN (empty by default) */
204 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
205/* Unselect Front Mic by default in input mixer 3 */
206 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
207/* Enable unsolicited event for HP jack */
208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
209/* Connect Internal HP to front */
210 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
211 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
212 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
213/* Connect HP out to front */
214 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
215 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
216 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
217 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
218 { }
219};
220
221/*
222 * ALC888 Acer Aspire 6530G model
223 */
224
225static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
226/* Route to built-in subwoofer as well as speakers */
227 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
228 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
229 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
230 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
231/* Bias voltage on for external mic port */
232 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
233/* Front Mic: set to PIN_IN (empty by default) */
234 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
235/* Unselect Front Mic by default in input mixer 3 */
236 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
237/* Enable unsolicited event for HP jack */
238 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
239/* Enable speaker output */
240 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
241 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
242 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
243/* Enable headphone output */
244 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
245 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
246 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
247 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
248 { }
249};
250
251/*
252 *ALC888 Acer Aspire 7730G model
253 */
254
255static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
256/* Bias voltage on for external mic port */
257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
258/* Front Mic: set to PIN_IN (empty by default) */
259 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
260/* Unselect Front Mic by default in input mixer 3 */
261 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
262/* Enable unsolicited event for HP jack */
263 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
264/* Enable speaker output */
265 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
266 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
267 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
268/* Enable headphone output */
269 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
270 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
271 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
272 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
273/*Enable internal subwoofer */
274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
276 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
277 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
278 { }
279};
280
281/*
282 * ALC889 Acer Aspire 8930G model
283 */
284
285static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
286/* Front Mic: set to PIN_IN (empty by default) */
287 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
288/* Unselect Front Mic by default in input mixer 3 */
289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
290/* Enable unsolicited event for HP jack */
291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
292/* Connect Internal Front to Front */
293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
296/* Connect Internal Rear to Rear */
297 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
298 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
299 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
300/* Connect Internal CLFE to CLFE */
301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
303 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
304/* Connect HP out to Front */
305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
308/* Enable all DACs */
309/* DAC DISABLE/MUTE 1? */
310/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
311 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
312 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
313/* DAC DISABLE/MUTE 2? */
314/* some bit here disables the other DACs. Init=0x4900 */
315 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
316 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
317/* DMIC fix
318 * This laptop has a stereo digital microphone. The mics are only 1cm apart
319 * which makes the stereo useless. However, either the mic or the ALC889
320 * makes the signal become a difference/sum signal instead of standard
321 * stereo, which is annoying. So instead we flip this bit which makes the
322 * codec replicate the sum signal to both channels, turning it into a
323 * normal mono mic.
324 */
325/* DMIC_CONTROL? Init value = 0x0001 */
326 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
327 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
328 { }
329};
330
331static const struct hda_input_mux alc888_2_capture_sources[2] = {
332 /* Front mic only available on one ADC */
333 {
334 .num_items = 4,
335 .items = {
336 { "Mic", 0x0 },
337 { "Line", 0x2 },
338 { "CD", 0x4 },
339 { "Front Mic", 0xb },
340 },
341 },
342 {
343 .num_items = 3,
344 .items = {
345 { "Mic", 0x0 },
346 { "Line", 0x2 },
347 { "CD", 0x4 },
348 },
349 }
350};
351
352static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
353 /* Interal mic only available on one ADC */
354 {
355 .num_items = 5,
356 .items = {
357 { "Mic", 0x0 },
358 { "Line In", 0x2 },
359 { "CD", 0x4 },
360 { "Input Mix", 0xa },
361 { "Internal Mic", 0xb },
362 },
363 },
364 {
365 .num_items = 4,
366 .items = {
367 { "Mic", 0x0 },
368 { "Line In", 0x2 },
369 { "CD", 0x4 },
370 { "Input Mix", 0xa },
371 },
372 }
373};
374
375static const struct hda_input_mux alc889_capture_sources[3] = {
376 /* Digital mic only available on first "ADC" */
377 {
378 .num_items = 5,
379 .items = {
380 { "Mic", 0x0 },
381 { "Line", 0x2 },
382 { "CD", 0x4 },
383 { "Front Mic", 0xb },
384 { "Input Mix", 0xa },
385 },
386 },
387 {
388 .num_items = 4,
389 .items = {
390 { "Mic", 0x0 },
391 { "Line", 0x2 },
392 { "CD", 0x4 },
393 { "Input Mix", 0xa },
394 },
395 },
396 {
397 .num_items = 4,
398 .items = {
399 { "Mic", 0x0 },
400 { "Line", 0x2 },
401 { "CD", 0x4 },
402 { "Input Mix", 0xa },
403 },
404 }
405};
406
407static const struct snd_kcontrol_new alc888_base_mixer[] = {
408 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
409 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
410 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
411 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
412 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
413 HDA_OUTPUT),
414 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
416 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
417 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
418 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
419 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
420 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
421 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
422 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
424 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
425 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
426 { } /* end */
427};
428
429static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
435 HDA_OUTPUT),
436 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
437 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
438 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
439 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
440 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
441 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
442 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
446 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
448 { } /* end */
449};
450
451static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
453 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
455 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
456 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
457 HDA_OUTPUT),
458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
459 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
466 { } /* end */
467};
468
469
470static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
471{
472 struct alc_spec *spec = codec->spec;
473
474 spec->autocfg.hp_pins[0] = 0x15;
475 spec->autocfg.speaker_pins[0] = 0x14;
476 spec->autocfg.speaker_pins[1] = 0x16;
477 spec->autocfg.speaker_pins[2] = 0x17;
478 spec->automute = 1;
479 spec->automute_mode = ALC_AUTOMUTE_AMP;
480}
481
482static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
483{
484 struct alc_spec *spec = codec->spec;
485
486 spec->autocfg.hp_pins[0] = 0x15;
487 spec->autocfg.speaker_pins[0] = 0x14;
488 spec->autocfg.speaker_pins[1] = 0x16;
489 spec->autocfg.speaker_pins[2] = 0x17;
490 spec->automute = 1;
491 spec->automute_mode = ALC_AUTOMUTE_AMP;
492}
493
494static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
495{
496 struct alc_spec *spec = codec->spec;
497
498 spec->autocfg.hp_pins[0] = 0x15;
499 spec->autocfg.speaker_pins[0] = 0x14;
500 spec->autocfg.speaker_pins[1] = 0x16;
501 spec->autocfg.speaker_pins[2] = 0x17;
502 spec->automute = 1;
503 spec->automute_mode = ALC_AUTOMUTE_AMP;
504}
505
506static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
507{
508 struct alc_spec *spec = codec->spec;
509
510 spec->autocfg.hp_pins[0] = 0x15;
511 spec->autocfg.speaker_pins[0] = 0x14;
512 spec->autocfg.speaker_pins[1] = 0x16;
513 spec->autocfg.speaker_pins[2] = 0x1b;
514 spec->automute = 1;
515 spec->automute_mode = ALC_AUTOMUTE_AMP;
516}
517
518#define ALC882_DIGOUT_NID 0x06
519#define ALC882_DIGIN_NID 0x0a
520#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
521#define ALC883_DIGIN_NID ALC882_DIGIN_NID
522#define ALC1200_DIGOUT_NID 0x10
523
524
525static const struct hda_channel_mode alc882_ch_modes[1] = {
526 { 8, NULL }
527};
528
529/* DACs */
530static const hda_nid_t alc882_dac_nids[4] = {
531 /* front, rear, clfe, rear_surr */
532 0x02, 0x03, 0x04, 0x05
533};
534#define alc883_dac_nids alc882_dac_nids
535
536/* ADCs */
537#define alc882_adc_nids alc880_adc_nids
538#define alc882_adc_nids_alt alc880_adc_nids_alt
539#define alc883_adc_nids alc882_adc_nids_alt
540static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
541static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
542#define alc889_adc_nids alc880_adc_nids
543
544static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
545static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
546#define alc883_capsrc_nids alc882_capsrc_nids_alt
547static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
548#define alc889_capsrc_nids alc882_capsrc_nids
549
550/* input MUX */
551/* FIXME: should be a matrix-type input source selection */
552
553static const struct hda_input_mux alc882_capture_source = {
554 .num_items = 4,
555 .items = {
556 { "Mic", 0x0 },
557 { "Front Mic", 0x1 },
558 { "Line", 0x2 },
559 { "CD", 0x4 },
560 },
561};
562
563#define alc883_capture_source alc882_capture_source
564
565static const struct hda_input_mux alc889_capture_source = {
566 .num_items = 3,
567 .items = {
568 { "Front Mic", 0x0 },
569 { "Mic", 0x3 },
570 { "Line", 0x2 },
571 },
572};
573
574static const struct hda_input_mux mb5_capture_source = {
575 .num_items = 3,
576 .items = {
577 { "Mic", 0x1 },
578 { "Line", 0x7 },
579 { "CD", 0x4 },
580 },
581};
582
583static const struct hda_input_mux macmini3_capture_source = {
584 .num_items = 2,
585 .items = {
586 { "Line", 0x2 },
587 { "CD", 0x4 },
588 },
589};
590
591static const struct hda_input_mux alc883_3stack_6ch_intel = {
592 .num_items = 4,
593 .items = {
594 { "Mic", 0x1 },
595 { "Front Mic", 0x0 },
596 { "Line", 0x2 },
597 { "CD", 0x4 },
598 },
599};
600
601static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
602 .num_items = 2,
603 .items = {
604 { "Mic", 0x1 },
605 { "Line", 0x2 },
606 },
607};
608
609static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
610 .num_items = 4,
611 .items = {
612 { "Mic", 0x0 },
613 { "Internal Mic", 0x1 },
614 { "Line", 0x2 },
615 { "CD", 0x4 },
616 },
617};
618
619static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
620 .num_items = 2,
621 .items = {
622 { "Mic", 0x0 },
623 { "Internal Mic", 0x1 },
624 },
625};
626
627static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
628 .num_items = 3,
629 .items = {
630 { "Mic", 0x0 },
631 { "Front Mic", 0x1 },
632 { "Line", 0x4 },
633 },
634};
635
636static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
637 .num_items = 2,
638 .items = {
639 { "Mic", 0x0 },
640 { "Line", 0x2 },
641 },
642};
643
644static const struct hda_input_mux alc889A_mb31_capture_source = {
645 .num_items = 2,
646 .items = {
647 { "Mic", 0x0 },
648 /* Front Mic (0x01) unused */
649 { "Line", 0x2 },
650 /* Line 2 (0x03) unused */
651 /* CD (0x04) unused? */
652 },
653};
654
655static const struct hda_input_mux alc889A_imac91_capture_source = {
656 .num_items = 2,
657 .items = {
658 { "Mic", 0x01 },
659 { "Line", 0x2 }, /* Not sure! */
660 },
661};
662
663/*
664 * 2ch mode
665 */
666static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
667 { 2, NULL }
668};
669
670/*
671 * 2ch mode
672 */
673static const struct hda_verb alc882_3ST_ch2_init[] = {
674 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
675 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
676 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
677 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
678 { } /* end */
679};
680
681/*
682 * 4ch mode
683 */
684static const struct hda_verb alc882_3ST_ch4_init[] = {
685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
689 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
690 { } /* end */
691};
692
693/*
694 * 6ch mode
695 */
696static const struct hda_verb alc882_3ST_ch6_init[] = {
697 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
698 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
699 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
700 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
701 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
702 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
703 { } /* end */
704};
705
706static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
707 { 2, alc882_3ST_ch2_init },
708 { 4, alc882_3ST_ch4_init },
709 { 6, alc882_3ST_ch6_init },
710};
711
712#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
713
714/*
715 * 2ch mode
716 */
717static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
718 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
719 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
720 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
721 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
722 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
723 { } /* end */
724};
725
726/*
727 * 4ch mode
728 */
729static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
730 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
733 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
734 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
735 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
736 { } /* end */
737};
738
739/*
740 * 6ch mode
741 */
742static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
743 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
746 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
749 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
750 { } /* end */
751};
752
753static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
754 { 2, alc883_3ST_ch2_clevo_init },
755 { 4, alc883_3ST_ch4_clevo_init },
756 { 6, alc883_3ST_ch6_clevo_init },
757};
758
759
760/*
761 * 6ch mode
762 */
763static const struct hda_verb alc882_sixstack_ch6_init[] = {
764 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
765 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
766 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
767 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
768 { } /* end */
769};
770
771/*
772 * 8ch mode
773 */
774static const struct hda_verb alc882_sixstack_ch8_init[] = {
775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
779 { } /* end */
780};
781
782static const struct hda_channel_mode alc882_sixstack_modes[2] = {
783 { 6, alc882_sixstack_ch6_init },
784 { 8, alc882_sixstack_ch8_init },
785};
786
787
788/* Macbook Air 2,1 */
789
790static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
791 { 2, NULL },
792};
793
794/*
795 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
796 */
797
798/*
799 * 2ch mode
800 */
801static const struct hda_verb alc885_mbp_ch2_init[] = {
802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
803 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
804 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
805 { } /* end */
806};
807
808/*
809 * 4ch mode
810 */
811static const struct hda_verb alc885_mbp_ch4_init[] = {
812 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
813 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
814 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
816 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
817 { } /* end */
818};
819
820static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
821 { 2, alc885_mbp_ch2_init },
822 { 4, alc885_mbp_ch4_init },
823};
824
825/*
826 * 2ch
827 * Speakers/Woofer/HP = Front
828 * LineIn = Input
829 */
830static const struct hda_verb alc885_mb5_ch2_init[] = {
831 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
832 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
833 { } /* end */
834};
835
836/*
837 * 6ch mode
838 * Speakers/HP = Front
839 * Woofer = LFE
840 * LineIn = Surround
841 */
842static const struct hda_verb alc885_mb5_ch6_init[] = {
843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
845 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
846 { } /* end */
847};
848
849static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
850 { 2, alc885_mb5_ch2_init },
851 { 6, alc885_mb5_ch6_init },
852};
853
854#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
855
856/*
857 * 2ch mode
858 */
859static const struct hda_verb alc883_4ST_ch2_init[] = {
860 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
861 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
862 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
863 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
866 { } /* end */
867};
868
869/*
870 * 4ch mode
871 */
872static const struct hda_verb alc883_4ST_ch4_init[] = {
873 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
874 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
875 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
876 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
877 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
878 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
879 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
880 { } /* end */
881};
882
883/*
884 * 6ch mode
885 */
886static const struct hda_verb alc883_4ST_ch6_init[] = {
887 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
888 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
889 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
890 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
891 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
892 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
893 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
894 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
895 { } /* end */
896};
897
898/*
899 * 8ch mode
900 */
901static const struct hda_verb alc883_4ST_ch8_init[] = {
902 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
903 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
904 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
905 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
906 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
907 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
910 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
911 { } /* end */
912};
913
914static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
915 { 2, alc883_4ST_ch2_init },
916 { 4, alc883_4ST_ch4_init },
917 { 6, alc883_4ST_ch6_init },
918 { 8, alc883_4ST_ch8_init },
919};
920
921
922/*
923 * 2ch mode
924 */
925static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
926 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
927 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
930 { } /* end */
931};
932
933/*
934 * 4ch mode
935 */
936static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
941 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
942 { } /* end */
943};
944
945/*
946 * 6ch mode
947 */
948static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
950 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
951 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
952 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
953 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
954 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
955 { } /* end */
956};
957
958static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
959 { 2, alc883_3ST_ch2_intel_init },
960 { 4, alc883_3ST_ch4_intel_init },
961 { 6, alc883_3ST_ch6_intel_init },
962};
963
964/*
965 * 2ch mode
966 */
967static const struct hda_verb alc889_ch2_intel_init[] = {
968 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
969 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
970 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
971 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
972 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
973 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
974 { } /* end */
975};
976
977/*
978 * 6ch mode
979 */
980static const struct hda_verb alc889_ch6_intel_init[] = {
981 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
982 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
983 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
984 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
985 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
986 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
987 { } /* end */
988};
989
990/*
991 * 8ch mode
992 */
993static const struct hda_verb alc889_ch8_intel_init[] = {
994 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
995 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
996 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
997 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
998 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
999 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1000 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1001 { } /* end */
1002};
1003
1004static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
1005 { 2, alc889_ch2_intel_init },
1006 { 6, alc889_ch6_intel_init },
1007 { 8, alc889_ch8_intel_init },
1008};
1009
1010/*
1011 * 6ch mode
1012 */
1013static const struct hda_verb alc883_sixstack_ch6_init[] = {
1014 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
1015 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1016 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1017 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1018 { } /* end */
1019};
1020
1021/*
1022 * 8ch mode
1023 */
1024static const struct hda_verb alc883_sixstack_ch8_init[] = {
1025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1029 { } /* end */
1030};
1031
1032static const struct hda_channel_mode alc883_sixstack_modes[2] = {
1033 { 6, alc883_sixstack_ch6_init },
1034 { 8, alc883_sixstack_ch8_init },
1035};
1036
1037
1038/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
1039 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
1040 */
1041static const struct snd_kcontrol_new alc882_base_mixer[] = {
1042 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1043 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1044 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1045 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1046 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1047 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1048 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1049 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1050 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1051 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1052 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1058 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1059 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1060 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1061 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1062 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1063 { } /* end */
1064};
1065
1066/* Macbook Air 2,1 same control for HP and internal Speaker */
1067
1068static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
1069 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1070 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
1071 { }
1072};
1073
1074
1075static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
1076 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1077 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1079 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
1080 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1081 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1082 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
1084 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
1085 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
1086 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
1087 { } /* end */
1088};
1089
1090static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
1091 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1092 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1093 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1094 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1095 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1096 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1098 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1100 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
1102 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
1103 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1104 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
1105 { } /* end */
1106};
1107
1108static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
1109 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1110 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
1111 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
1112 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
1113 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
1114 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
1115 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
1116 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
1117 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
1118 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
1119 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
1120 { } /* end */
1121};
1122
1123static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
1124 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1125 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
1126 { } /* end */
1127};
1128
1129
1130static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
1131 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1132 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1133 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1134 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1135 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1136 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1140 { } /* end */
1141};
1142
1143static const struct snd_kcontrol_new alc882_targa_mixer[] = {
1144 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1145 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1149 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1150 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1151 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1152 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1154 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1155 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1156 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1157 { } /* end */
1158};
1159
1160/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
1161 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
1162 */
1163static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
1164 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1165 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
1166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1167 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
1168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1172 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
1173 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
1174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1175 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1176 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1177 { } /* end */
1178};
1179
1180static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
1181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1182 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1191 { } /* end */
1192};
1193
1194static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
1195 {
1196 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1197 .name = "Channel Mode",
1198 .info = alc_ch_mode_info,
1199 .get = alc_ch_mode_get,
1200 .put = alc_ch_mode_put,
1201 },
1202 { } /* end */
1203};
1204
1205static const struct hda_verb alc882_base_init_verbs[] = {
1206 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1207 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1208 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1209 /* Rear mixer */
1210 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1211 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1212 /* CLFE mixer */
1213 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1214 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1215 /* Side mixer */
1216 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1217 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1218
1219 /* Front Pin: output 0 (0x0c) */
1220 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1221 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1222 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1223 /* Rear Pin: output 1 (0x0d) */
1224 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1226 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
1227 /* CLFE Pin: output 2 (0x0e) */
1228 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1230 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1231 /* Side Pin: output 3 (0x0f) */
1232 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1233 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1234 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1235 /* Mic (rear) pin: input vref at 80% */
1236 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1237 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1238 /* Front Mic pin: input vref at 80% */
1239 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1240 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1241 /* Line In pin: input */
1242 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1243 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1244 /* Line-2 In: Headphone output (output 0 - 0x0c) */
1245 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1246 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1247 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1248 /* CD pin widget for input */
1249 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1250
1251 /* FIXME: use matrix-type input source selection */
1252 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1253 /* Input mixer2 */
1254 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1255 /* Input mixer3 */
1256 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1257 /* ADC2: mute amp left and right */
1258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1259 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1260 /* ADC3: mute amp left and right */
1261 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1262 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1263
1264 { }
1265};
1266
1267static const struct hda_verb alc882_adc1_init_verbs[] = {
1268 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1269 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1270 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1271 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1272 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1273 /* ADC1: mute amp left and right */
1274 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1275 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1276 { }
1277};
1278
1279static const struct hda_verb alc882_eapd_verbs[] = {
1280 /* change to EAPD mode */
1281 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1282 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
1283 { }
1284};
1285
1286static const struct hda_verb alc889_eapd_verbs[] = {
1287 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
1288 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1289 { }
1290};
1291
1292static const struct hda_verb alc_hp15_unsol_verbs[] = {
1293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
1294 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1295 {}
1296};
1297
1298static const struct hda_verb alc885_init_verbs[] = {
1299 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1301 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1302 /* Rear mixer */
1303 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1304 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1305 /* CLFE mixer */
1306 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1307 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1308 /* Side mixer */
1309 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1310 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1311
1312 /* Front HP Pin: output 0 (0x0c) */
1313 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1314 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1316 /* Front Pin: output 0 (0x0c) */
1317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1319 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1320 /* Rear Pin: output 1 (0x0d) */
1321 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1322 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1323 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
1324 /* CLFE Pin: output 2 (0x0e) */
1325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1326 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1327 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
1328 /* Side Pin: output 3 (0x0f) */
1329 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1330 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1331 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1332 /* Mic (rear) pin: input vref at 80% */
1333 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1334 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1335 /* Front Mic pin: input vref at 80% */
1336 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1338 /* Line In pin: input */
1339 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1340 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1341
1342 /* Mixer elements: 0x18, , 0x1a, 0x1b */
1343 /* Input mixer1 */
1344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1345 /* Input mixer2 */
1346 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1347 /* Input mixer3 */
1348 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1349 /* ADC2: mute amp left and right */
1350 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1351 /* ADC3: mute amp left and right */
1352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1353
1354 { }
1355};
1356
1357static const struct hda_verb alc885_init_input_verbs[] = {
1358 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1359 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1360 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1361 { }
1362};
1363
1364
1365/* Unmute Selector 24h and set the default input to front mic */
1366static const struct hda_verb alc889_init_input_verbs[] = {
1367 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
1368 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1369 { }
1370};
1371
1372
1373#define alc883_init_verbs alc882_base_init_verbs
1374
1375/* Mac Pro test */
1376static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
1377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1379 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
1380 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
1381 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
1382 /* FIXME: this looks suspicious...
1383 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
1384 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
1385 */
1386 { } /* end */
1387};
1388
1389static const struct hda_verb alc882_macpro_init_verbs[] = {
1390 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1391 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1394 /* Front Pin: output 0 (0x0c) */
1395 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1397 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1398 /* Front Mic pin: input vref at 80% */
1399 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1400 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1401 /* Speaker: output */
1402 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1403 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1404 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
1405 /* Headphone output (output 0 - 0x0c) */
1406 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1407 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1408 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1409
1410 /* FIXME: use matrix-type input source selection */
1411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1412 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1413 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1414 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1415 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1416 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1417 /* Input mixer2 */
1418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1421 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1422 /* Input mixer3 */
1423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1427 /* ADC1: mute amp left and right */
1428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1429 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1430 /* ADC2: mute amp left and right */
1431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1432 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1433 /* ADC3: mute amp left and right */
1434 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1435 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1436
1437 { }
1438};
1439
1440/* Macbook 5,1 */
1441static const struct hda_verb alc885_mb5_init_verbs[] = {
1442 /* DACs */
1443 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1444 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1445 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1446 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1447 /* Front mixer */
1448 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1449 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1450 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1451 /* Surround mixer */
1452 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1454 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1455 /* LFE mixer */
1456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1457 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1458 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1459 /* HP mixer */
1460 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1461 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1462 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1463 /* Front Pin (0x0c) */
1464 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1465 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1466 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1467 /* LFE Pin (0x0e) */
1468 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1469 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1470 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1471 /* HP Pin (0x0f) */
1472 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1474 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1475 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1476 /* Front Mic pin: input vref at 80% */
1477 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1478 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1479 /* Line In pin */
1480 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1481 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1482
1483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
1484 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
1485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
1486 { }
1487};
1488
1489/* Macmini 3,1 */
1490static const struct hda_verb alc885_macmini3_init_verbs[] = {
1491 /* DACs */
1492 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1493 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1494 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1495 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1496 /* Front mixer */
1497 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1498 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1499 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1500 /* Surround mixer */
1501 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1502 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1503 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1504 /* LFE mixer */
1505 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1506 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1507 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1508 /* HP mixer */
1509 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1511 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1512 /* Front Pin (0x0c) */
1513 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1514 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1515 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1516 /* LFE Pin (0x0e) */
1517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
1518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1519 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
1520 /* HP Pin (0x0f) */
1521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1523 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
1524 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1525 /* Line In pin */
1526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1527 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1528
1529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1533 { }
1534};
1535
1536
1537static const struct hda_verb alc885_mba21_init_verbs[] = {
1538 /*Internal and HP Speaker Mixer*/
1539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1541 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1542 /*Internal Speaker Pin (0x0c)*/
1543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1545 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1546 /* HP Pin: output 0 (0x0e) */
1547 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1548 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1549 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1550 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1551 /* Line in (is hp when jack connected)*/
1552 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1553 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1554
1555 { }
1556 };
1557
1558
1559/* Macbook Pro rev3 */
1560static const struct hda_verb alc885_mbp3_init_verbs[] = {
1561 /* Front mixer: unmute input/output amp left and right (volume = 0) */
1562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1565 /* Rear mixer */
1566 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1569 /* HP mixer */
1570 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1573 /* Front Pin: output 0 (0x0c) */
1574 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1575 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1576 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1577 /* HP Pin: output 0 (0x0e) */
1578 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
1579 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1580 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
1581 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1582 /* Mic (rear) pin: input vref at 80% */
1583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1585 /* Front Mic pin: input vref at 80% */
1586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1587 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1588 /* Line In pin: use output 1 when in LineOut mode */
1589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1591 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1592
1593 /* FIXME: use matrix-type input source selection */
1594 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1595 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
1596 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1598 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1600 /* Input mixer2 */
1601 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1605 /* Input mixer3 */
1606 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1610 /* ADC1: mute amp left and right */
1611 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1612 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1613 /* ADC2: mute amp left and right */
1614 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1615 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1616 /* ADC3: mute amp left and right */
1617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1618 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1619
1620 { }
1621};
1622
1623/* iMac 9,1 */
1624static const struct hda_verb alc885_imac91_init_verbs[] = {
1625 /* Internal Speaker Pin (0x0c) */
1626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
1630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1631 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1632 /* HP Pin: Rear */
1633 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1634 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1635 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC_HP_EVENT | AC_USRSP_EN)},
1637 /* Line in Rear */
1638 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
1639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1640 /* Front Mic pin: input vref at 80% */
1641 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1642 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1643 /* Rear mixer */
1644 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1645 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1647 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
1648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1650 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1651 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1652 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1653 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1654 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1655 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1656 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1657 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1658 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1659 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1660 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1661 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
1662 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1663 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
1664 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
1665 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1666 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1667 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1668 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
1669 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1670 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1671 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
1672 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
1673 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1674 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1675 { }
1676};
1677
1678/* iMac 24 mixer. */
1679static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
1680 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
1681 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
1682 { } /* end */
1683};
1684
1685/* iMac 24 init verbs. */
1686static const struct hda_verb alc885_imac24_init_verbs[] = {
1687 /* Internal speakers: output 0 (0x0c) */
1688 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1689 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1690 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
1691 /* Internal speakers: output 0 (0x0c) */
1692 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1693 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1694 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
1695 /* Headphone: output 0 (0x0c) */
1696 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1697 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1698 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1699 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1700 /* Front Mic: input vref at 80% */
1701 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1703 { }
1704};
1705
1706/* Toggle speaker-output according to the hp-jack state */
1707static void alc885_imac24_setup(struct hda_codec *codec)
1708{
1709 struct alc_spec *spec = codec->spec;
1710
1711 spec->autocfg.hp_pins[0] = 0x14;
1712 spec->autocfg.speaker_pins[0] = 0x18;
1713 spec->autocfg.speaker_pins[1] = 0x1a;
1714 spec->automute = 1;
1715 spec->automute_mode = ALC_AUTOMUTE_AMP;
1716}
1717
1718#define alc885_mb5_setup alc885_imac24_setup
1719#define alc885_macmini3_setup alc885_imac24_setup
1720
1721/* Macbook Air 2,1 */
1722static void alc885_mba21_setup(struct hda_codec *codec)
1723{
1724 struct alc_spec *spec = codec->spec;
1725
1726 spec->autocfg.hp_pins[0] = 0x14;
1727 spec->autocfg.speaker_pins[0] = 0x18;
1728 spec->automute = 1;
1729 spec->automute_mode = ALC_AUTOMUTE_AMP;
1730}
1731
1732
1733
1734static void alc885_mbp3_setup(struct hda_codec *codec)
1735{
1736 struct alc_spec *spec = codec->spec;
1737
1738 spec->autocfg.hp_pins[0] = 0x15;
1739 spec->autocfg.speaker_pins[0] = 0x14;
1740 spec->automute = 1;
1741 spec->automute_mode = ALC_AUTOMUTE_AMP;
1742}
1743
1744static void alc885_imac91_setup(struct hda_codec *codec)
1745{
1746 struct alc_spec *spec = codec->spec;
1747
1748 spec->autocfg.hp_pins[0] = 0x14;
1749 spec->autocfg.speaker_pins[0] = 0x18;
1750 spec->autocfg.speaker_pins[1] = 0x1a;
1751 spec->automute = 1;
1752 spec->automute_mode = ALC_AUTOMUTE_AMP;
1753}
1754
1755static const struct hda_verb alc882_targa_verbs[] = {
1756 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1757 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1758
1759 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1761
1762 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1763 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1764 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1765
1766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
1767 { } /* end */
1768};
1769
1770/* toggle speaker-output according to the hp-jack state */
1771static void alc882_targa_automute(struct hda_codec *codec)
1772{
1773 struct alc_spec *spec = codec->spec;
1774 alc_hp_automute(codec);
1775 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
1776 spec->jack_present ? 1 : 3);
1777}
1778
1779static void alc882_targa_setup(struct hda_codec *codec)
1780{
1781 struct alc_spec *spec = codec->spec;
1782
1783 spec->autocfg.hp_pins[0] = 0x14;
1784 spec->autocfg.speaker_pins[0] = 0x1b;
1785 spec->automute = 1;
1786 spec->automute_mode = ALC_AUTOMUTE_AMP;
1787}
1788
1789static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
1790{
1791 if ((res >> 26) == ALC_HP_EVENT)
1792 alc882_targa_automute(codec);
1793}
1794
1795static const struct hda_verb alc882_asus_a7j_verbs[] = {
1796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1798
1799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1802
1803 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1805 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1806
1807 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1808 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1809 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1810 { } /* end */
1811};
1812
1813static const struct hda_verb alc882_asus_a7m_verbs[] = {
1814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1816
1817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1819 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1820
1821 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1822 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1823 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
1824
1825 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
1826 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
1827 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1828 { } /* end */
1829};
1830
1831static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
1832{
1833 unsigned int gpiostate, gpiomask, gpiodir;
1834
1835 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
1836 AC_VERB_GET_GPIO_DATA, 0);
1837
1838 if (!muted)
1839 gpiostate |= (1 << pin);
1840 else
1841 gpiostate &= ~(1 << pin);
1842
1843 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
1844 AC_VERB_GET_GPIO_MASK, 0);
1845 gpiomask |= (1 << pin);
1846
1847 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
1848 AC_VERB_GET_GPIO_DIRECTION, 0);
1849 gpiodir |= (1 << pin);
1850
1851
1852 snd_hda_codec_write(codec, codec->afg, 0,
1853 AC_VERB_SET_GPIO_MASK, gpiomask);
1854 snd_hda_codec_write(codec, codec->afg, 0,
1855 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
1856
1857 msleep(1);
1858
1859 snd_hda_codec_write(codec, codec->afg, 0,
1860 AC_VERB_SET_GPIO_DATA, gpiostate);
1861}
1862
1863/* set up GPIO at initialization */
1864static void alc885_macpro_init_hook(struct hda_codec *codec)
1865{
1866 alc882_gpio_mute(codec, 0, 0);
1867 alc882_gpio_mute(codec, 1, 0);
1868}
1869
1870/* set up GPIO and update auto-muting at initialization */
1871static void alc885_imac24_init_hook(struct hda_codec *codec)
1872{
1873 alc885_macpro_init_hook(codec);
1874 alc_hp_automute(codec);
1875}
1876
1877/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
1878static const struct hda_verb alc889A_mb31_ch2_init[] = {
1879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1880 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1881 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1882 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1883 { } /* end */
1884};
1885
1886/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
1887static const struct hda_verb alc889A_mb31_ch4_init[] = {
1888 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
1889 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1890 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1892 { } /* end */
1893};
1894
1895/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
1896static const struct hda_verb alc889A_mb31_ch5_init[] = {
1897 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
1898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
1899 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
1900 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
1901 { } /* end */
1902};
1903
1904/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
1905static const struct hda_verb alc889A_mb31_ch6_init[] = {
1906 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
1907 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
1908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
1909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
1910 { } /* end */
1911};
1912
1913static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
1914 { 2, alc889A_mb31_ch2_init },
1915 { 4, alc889A_mb31_ch4_init },
1916 { 5, alc889A_mb31_ch5_init },
1917 { 6, alc889A_mb31_ch6_init },
1918};
1919
1920static const struct hda_verb alc883_medion_eapd_verbs[] = {
1921 /* eanable EAPD on medion laptop */
1922 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
1923 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
1924 { }
1925};
1926
1927#define alc883_base_mixer alc882_base_mixer
1928
1929static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
1930 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1931 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1932 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1933 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1934 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1935 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1936 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
1937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1938 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1941 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1942 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1943 { } /* end */
1944};
1945
1946static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
1947 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1948 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1949 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1950 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1951 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1952 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1953 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1954 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1955 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1956 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1957 { } /* end */
1958};
1959
1960static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
1961 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1962 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1963 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1964 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1966 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1968 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1969 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
1970 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1971 { } /* end */
1972};
1973
1974static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
1975 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1976 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1978 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1979 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1982 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1983 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1984 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1985 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1986 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1987 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1988 { } /* end */
1989};
1990
1991static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
1992 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1993 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1994 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1995 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1996 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2008 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2009 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2010 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2011 { } /* end */
2012};
2013
2014static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
2015 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2016 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2017 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2018 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2020 HDA_OUTPUT),
2021 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2022 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2023 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2024 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2025 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2026 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2030 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2033 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2035 { } /* end */
2036};
2037
2038static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
2039 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2044 HDA_OUTPUT),
2045 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2046 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2047 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2049 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
2050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2051 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2052 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2053 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2054 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
2055 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2056 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2057 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
2058 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2059 { } /* end */
2060};
2061
2062static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
2063 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2064 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2065 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2066 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2067 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2068 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2069 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2070 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2071 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2080 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2082 { } /* end */
2083};
2084
2085static const struct snd_kcontrol_new alc883_targa_mixer[] = {
2086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2087 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2089 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2090 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2091 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2092 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2093 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2094 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2095 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2096 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2097 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2098 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2103 { } /* end */
2104};
2105
2106static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
2107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2109 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2110 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2116 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2117 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2118 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2119 { } /* end */
2120};
2121
2122static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
2123 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2124 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2125 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2126 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
2127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2128 { } /* end */
2129};
2130
2131static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
2132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2133 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2138 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2139 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2140 { } /* end */
2141};
2142
2143static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
2144 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2145 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
2146 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2147 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2148 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2153 { } /* end */
2154};
2155
2156static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
2157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2159 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2160 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
2162 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
2163 { } /* end */
2164};
2165
2166static const struct hda_verb alc883_medion_wim2160_verbs[] = {
2167 /* Unmute front mixer */
2168 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2169 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2170
2171 /* Set speaker pin to front mixer */
2172 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2173
2174 /* Init headphone pin */
2175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2177 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2178 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2179
2180 { } /* end */
2181};
2182
2183/* toggle speaker-output according to the hp-jack state */
2184static void alc883_medion_wim2160_setup(struct hda_codec *codec)
2185{
2186 struct alc_spec *spec = codec->spec;
2187
2188 spec->autocfg.hp_pins[0] = 0x1a;
2189 spec->autocfg.speaker_pins[0] = 0x15;
2190 spec->automute = 1;
2191 spec->automute_mode = ALC_AUTOMUTE_AMP;
2192}
2193
2194static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
2195 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2196 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2203 { } /* end */
2204};
2205
2206static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
2207 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2208 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2211 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2212 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2216 { } /* end */
2217};
2218
2219static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
2220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
2223 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
2224 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
2225 0x0d, 1, 0x0, HDA_OUTPUT),
2226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
2227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
2228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
2229 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2230 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2239 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
2240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2241 { } /* end */
2242};
2243
2244static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
2245 /* Output mixers */
2246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
2247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
2248 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2249 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
2250 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
2251 HDA_OUTPUT),
2252 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
2253 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
2254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
2255 /* Output switches */
2256 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
2257 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
2258 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
2259 /* Boost mixers */
2260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
2261 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
2262 /* Input mixers */
2263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
2264 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
2265 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2266 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2267 { } /* end */
2268};
2269
2270static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
2271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2272 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2273 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
2274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2275 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
2276 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2277 { } /* end */
2278};
2279
2280static const struct hda_bind_ctls alc883_bind_cap_vol = {
2281 .ops = &snd_hda_bind_vol,
2282 .values = {
2283 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2284 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2285 0
2286 },
2287};
2288
2289static const struct hda_bind_ctls alc883_bind_cap_switch = {
2290 .ops = &snd_hda_bind_sw,
2291 .values = {
2292 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
2293 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
2294 0
2295 },
2296};
2297
2298static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
2299 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2300 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2307 { } /* end */
2308};
2309
2310static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
2311 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
2312 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
2313 {
2314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2315 /* .name = "Capture Source", */
2316 .name = "Input Source",
2317 .count = 1,
2318 .info = alc_mux_enum_info,
2319 .get = alc_mux_enum_get,
2320 .put = alc_mux_enum_put,
2321 },
2322 { } /* end */
2323};
2324
2325static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
2326 {
2327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2328 .name = "Channel Mode",
2329 .info = alc_ch_mode_info,
2330 .get = alc_ch_mode_get,
2331 .put = alc_ch_mode_put,
2332 },
2333 { } /* end */
2334};
2335
2336/* toggle speaker-output according to the hp-jack state */
2337static void alc883_mitac_setup(struct hda_codec *codec)
2338{
2339 struct alc_spec *spec = codec->spec;
2340
2341 spec->autocfg.hp_pins[0] = 0x15;
2342 spec->autocfg.speaker_pins[0] = 0x14;
2343 spec->autocfg.speaker_pins[1] = 0x17;
2344 spec->automute = 1;
2345 spec->automute_mode = ALC_AUTOMUTE_AMP;
2346}
2347
2348static const struct hda_verb alc883_mitac_verbs[] = {
2349 /* HP */
2350 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2351 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2352 /* Subwoofer */
2353 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2354 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355
2356 /* enable unsolicited event */
2357 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2358 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, */
2359
2360 { } /* end */
2361};
2362
2363static const struct hda_verb alc883_clevo_m540r_verbs[] = {
2364 /* HP */
2365 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2367 /* Int speaker */
2368 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
2369
2370 /* enable unsolicited event */
2371 /*
2372 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2373 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2374 */
2375
2376 { } /* end */
2377};
2378
2379static const struct hda_verb alc883_clevo_m720_verbs[] = {
2380 /* HP */
2381 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2383 /* Int speaker */
2384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
2385 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386
2387 /* enable unsolicited event */
2388 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2390
2391 { } /* end */
2392};
2393
2394static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
2395 /* HP */
2396 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2397 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2398 /* Subwoofer */
2399 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
2400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2401
2402 /* enable unsolicited event */
2403 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2404
2405 { } /* end */
2406};
2407
2408static const struct hda_verb alc883_targa_verbs[] = {
2409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2411
2412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2414
2415/* Connect Line-Out side jack (SPDIF) to Side */
2416 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2417 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2419/* Connect Mic jack to CLFE */
2420 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2421 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2422 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2423/* Connect Line-in jack to Surround */
2424 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2426 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2427/* Connect HP out jack to Front */
2428 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2429 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2430 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2431
2432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2433
2434 { } /* end */
2435};
2436
2437static const struct hda_verb alc883_lenovo_101e_verbs[] = {
2438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2439 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT|AC_USRSP_EN},
2440 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT|AC_USRSP_EN},
2441 { } /* end */
2442};
2443
2444static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
2445 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2446 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2447 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2449 { } /* end */
2450};
2451
2452static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
2453 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2454 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2456 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_FRONT_EVENT | AC_USRSP_EN},
2457 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2458 { } /* end */
2459};
2460
2461static const struct hda_verb alc883_haier_w66_verbs[] = {
2462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2464
2465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2466
2467 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2468 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2469 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2470 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2471 { } /* end */
2472};
2473
2474static const struct hda_verb alc888_lenovo_sky_verbs[] = {
2475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2477 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2479 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2480 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
2482 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2483 { } /* end */
2484};
2485
2486static const struct hda_verb alc888_6st_dell_verbs[] = {
2487 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2488 { }
2489};
2490
2491static const struct hda_verb alc883_vaiott_verbs[] = {
2492 /* HP */
2493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2494 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2495
2496 /* enable unsolicited event */
2497 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2498
2499 { } /* end */
2500};
2501
2502static void alc888_3st_hp_setup(struct hda_codec *codec)
2503{
2504 struct alc_spec *spec = codec->spec;
2505
2506 spec->autocfg.hp_pins[0] = 0x1b;
2507 spec->autocfg.speaker_pins[0] = 0x14;
2508 spec->autocfg.speaker_pins[1] = 0x16;
2509 spec->autocfg.speaker_pins[2] = 0x18;
2510 spec->automute = 1;
2511 spec->automute_mode = ALC_AUTOMUTE_AMP;
2512}
2513
2514static const struct hda_verb alc888_3st_hp_verbs[] = {
2515 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
2516 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
2517 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
2518 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2519 { } /* end */
2520};
2521
2522/*
2523 * 2ch mode
2524 */
2525static const struct hda_verb alc888_3st_hp_2ch_init[] = {
2526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2528 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2529 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2530 { } /* end */
2531};
2532
2533/*
2534 * 4ch mode
2535 */
2536static const struct hda_verb alc888_3st_hp_4ch_init[] = {
2537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2541 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2542 { } /* end */
2543};
2544
2545/*
2546 * 6ch mode
2547 */
2548static const struct hda_verb alc888_3st_hp_6ch_init[] = {
2549 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2550 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2551 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
2552 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2553 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2554 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
2555 { } /* end */
2556};
2557
2558static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
2559 { 2, alc888_3st_hp_2ch_init },
2560 { 4, alc888_3st_hp_4ch_init },
2561 { 6, alc888_3st_hp_6ch_init },
2562};
2563
2564static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
2565{
2566 struct alc_spec *spec = codec->spec;
2567
2568 spec->autocfg.hp_pins[0] = 0x1b;
2569 spec->autocfg.line_out_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[0] = 0x15;
2571 spec->automute = 1;
2572 spec->automute_mode = ALC_AUTOMUTE_AMP;
2573}
2574
2575/* toggle speaker-output according to the hp-jack state */
2576static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
2577{
2578 struct alc_spec *spec = codec->spec;
2579
2580 spec->autocfg.hp_pins[0] = 0x14;
2581 spec->autocfg.speaker_pins[0] = 0x15;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584}
2585
2586/* toggle speaker-output according to the hp-jack state */
2587#define alc883_targa_init_hook alc882_targa_init_hook
2588#define alc883_targa_unsol_event alc882_targa_unsol_event
2589
2590static void alc883_clevo_m720_setup(struct hda_codec *codec)
2591{
2592 struct alc_spec *spec = codec->spec;
2593
2594 spec->autocfg.hp_pins[0] = 0x15;
2595 spec->autocfg.speaker_pins[0] = 0x14;
2596 spec->automute = 1;
2597 spec->automute_mode = ALC_AUTOMUTE_AMP;
2598}
2599
2600static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
2601{
2602 alc_hp_automute(codec);
2603 alc88x_simple_mic_automute(codec);
2604}
2605
2606static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
2607 unsigned int res)
2608{
2609 switch (res >> 26) {
2610 case ALC_MIC_EVENT:
2611 alc88x_simple_mic_automute(codec);
2612 break;
2613 default:
2614 alc_sku_unsol_event(codec, res);
2615 break;
2616 }
2617}
2618
2619/* toggle speaker-output according to the hp-jack state */
2620static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
2621{
2622 struct alc_spec *spec = codec->spec;
2623
2624 spec->autocfg.hp_pins[0] = 0x14;
2625 spec->autocfg.speaker_pins[0] = 0x15;
2626 spec->automute = 1;
2627 spec->automute_mode = ALC_AUTOMUTE_AMP;
2628}
2629
2630static void alc883_haier_w66_setup(struct hda_codec *codec)
2631{
2632 struct alc_spec *spec = codec->spec;
2633
2634 spec->autocfg.hp_pins[0] = 0x1b;
2635 spec->autocfg.speaker_pins[0] = 0x14;
2636 spec->automute = 1;
2637 spec->automute_mode = ALC_AUTOMUTE_AMP;
2638}
2639
2640static void alc883_lenovo_101e_setup(struct hda_codec *codec)
2641{
2642 struct alc_spec *spec = codec->spec;
2643
2644 spec->autocfg.hp_pins[0] = 0x1b;
2645 spec->autocfg.line_out_pins[0] = 0x14;
2646 spec->autocfg.speaker_pins[0] = 0x15;
2647 spec->automute = 1;
2648 spec->detect_line = 1;
2649 spec->automute_lines = 1;
2650 spec->automute_mode = ALC_AUTOMUTE_AMP;
2651}
2652
2653/* toggle speaker-output according to the hp-jack state */
2654static void alc883_acer_aspire_setup(struct hda_codec *codec)
2655{
2656 struct alc_spec *spec = codec->spec;
2657
2658 spec->autocfg.hp_pins[0] = 0x14;
2659 spec->autocfg.speaker_pins[0] = 0x15;
2660 spec->autocfg.speaker_pins[1] = 0x16;
2661 spec->automute = 1;
2662 spec->automute_mode = ALC_AUTOMUTE_AMP;
2663}
2664
2665static const struct hda_verb alc883_acer_eapd_verbs[] = {
2666 /* HP Pin: output 0 (0x0c) */
2667 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2669 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2670 /* Front Pin: output 0 (0x0c) */
2671 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2673 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2674 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
2675 /* eanable EAPD on medion laptop */
2676 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
2677 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
2678 /* enable unsolicited event */
2679 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2680 { }
2681};
2682
2683static void alc888_6st_dell_setup(struct hda_codec *codec)
2684{
2685 struct alc_spec *spec = codec->spec;
2686
2687 spec->autocfg.hp_pins[0] = 0x1b;
2688 spec->autocfg.speaker_pins[0] = 0x14;
2689 spec->autocfg.speaker_pins[1] = 0x15;
2690 spec->autocfg.speaker_pins[2] = 0x16;
2691 spec->autocfg.speaker_pins[3] = 0x17;
2692 spec->automute = 1;
2693 spec->automute_mode = ALC_AUTOMUTE_AMP;
2694}
2695
2696static void alc888_lenovo_sky_setup(struct hda_codec *codec)
2697{
2698 struct alc_spec *spec = codec->spec;
2699
2700 spec->autocfg.hp_pins[0] = 0x1b;
2701 spec->autocfg.speaker_pins[0] = 0x14;
2702 spec->autocfg.speaker_pins[1] = 0x15;
2703 spec->autocfg.speaker_pins[2] = 0x16;
2704 spec->autocfg.speaker_pins[3] = 0x17;
2705 spec->autocfg.speaker_pins[4] = 0x1a;
2706 spec->automute = 1;
2707 spec->automute_mode = ALC_AUTOMUTE_AMP;
2708}
2709
2710static void alc883_vaiott_setup(struct hda_codec *codec)
2711{
2712 struct alc_spec *spec = codec->spec;
2713
2714 spec->autocfg.hp_pins[0] = 0x15;
2715 spec->autocfg.speaker_pins[0] = 0x14;
2716 spec->autocfg.speaker_pins[1] = 0x17;
2717 spec->automute = 1;
2718 spec->automute_mode = ALC_AUTOMUTE_AMP;
2719}
2720
2721static const struct hda_verb alc888_asus_m90v_verbs[] = {
2722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2723 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2724 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2725 /* enable unsolicited event */
2726 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2727 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN},
2728 { } /* end */
2729};
2730
2731static void alc883_mode2_setup(struct hda_codec *codec)
2732{
2733 struct alc_spec *spec = codec->spec;
2734
2735 spec->autocfg.hp_pins[0] = 0x1b;
2736 spec->autocfg.speaker_pins[0] = 0x14;
2737 spec->autocfg.speaker_pins[1] = 0x15;
2738 spec->autocfg.speaker_pins[2] = 0x16;
2739 spec->ext_mic_pin = 0x18;
2740 spec->int_mic_pin = 0x19;
2741 spec->auto_mic = 1;
2742 spec->automute = 1;
2743 spec->automute_mode = ALC_AUTOMUTE_AMP;
2744}
2745
2746static const struct hda_verb alc888_asus_eee1601_verbs[] = {
2747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2748 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2749 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2750 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2751 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2752 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2753 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
2754 /* enable unsolicited event */
2755 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2756 { } /* end */
2757};
2758
2759static void alc883_eee1601_inithook(struct hda_codec *codec)
2760{
2761 struct alc_spec *spec = codec->spec;
2762
2763 spec->autocfg.hp_pins[0] = 0x14;
2764 spec->autocfg.speaker_pins[0] = 0x1b;
2765 alc_hp_automute(codec);
2766}
2767
2768static const struct hda_verb alc889A_mb31_verbs[] = {
2769 /* Init rear pin (used as headphone output) */
2770 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
2771 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
2772 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN},
2773 /* Init line pin (used as output in 4ch and 6ch mode) */
2774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
2775 /* Init line 2 pin (used as headphone out by default) */
2776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
2777 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
2778 { } /* end */
2779};
2780
2781/* Mute speakers according to the headphone jack state */
2782static void alc889A_mb31_automute(struct hda_codec *codec)
2783{
2784 unsigned int present;
2785
2786 /* Mute only in 2ch or 4ch mode */
2787 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
2788 == 0x00) {
2789 present = snd_hda_jack_detect(codec, 0x15);
2790 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
2791 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2792 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
2793 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
2794 }
2795}
2796
2797static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
2798{
2799 if ((res >> 26) == ALC_HP_EVENT)
2800 alc889A_mb31_automute(codec);
2801}
2802
2803static const hda_nid_t alc883_slave_dig_outs[] = {
2804 ALC1200_DIGOUT_NID, 0,
2805};
2806
2807static const hda_nid_t alc1200_slave_dig_outs[] = {
2808 ALC883_DIGOUT_NID, 0,
2809};
2810
2811/*
2812 * configuration and preset
2813 */
2814static const char * const alc882_models[ALC882_MODEL_LAST] = {
2815 [ALC882_3ST_DIG] = "3stack-dig",
2816 [ALC882_6ST_DIG] = "6stack-dig",
2817 [ALC882_ARIMA] = "arima",
2818 [ALC882_W2JC] = "w2jc",
2819 [ALC882_TARGA] = "targa",
2820 [ALC882_ASUS_A7J] = "asus-a7j",
2821 [ALC882_ASUS_A7M] = "asus-a7m",
2822 [ALC885_MACPRO] = "macpro",
2823 [ALC885_MB5] = "mb5",
2824 [ALC885_MACMINI3] = "macmini3",
2825 [ALC885_MBA21] = "mba21",
2826 [ALC885_MBP3] = "mbp3",
2827 [ALC885_IMAC24] = "imac24",
2828 [ALC885_IMAC91] = "imac91",
2829 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
2830 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
2831 [ALC883_3ST_6ch] = "3stack-6ch",
2832 [ALC883_6ST_DIG] = "alc883-6stack-dig",
2833 [ALC883_TARGA_DIG] = "targa-dig",
2834 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
2835 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
2836 [ALC883_ACER] = "acer",
2837 [ALC883_ACER_ASPIRE] = "acer-aspire",
2838 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
2839 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
2840 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
2841 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
2842 [ALC883_MEDION] = "medion",
2843 [ALC883_MEDION_WIM2160] = "medion-wim2160",
2844 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
2845 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
2846 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
2847 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
2848 [ALC888_LENOVO_SKY] = "lenovo-sky",
2849 [ALC883_HAIER_W66] = "haier-w66",
2850 [ALC888_3ST_HP] = "3stack-hp",
2851 [ALC888_6ST_DELL] = "6stack-dell",
2852 [ALC883_MITAC] = "mitac",
2853 [ALC883_CLEVO_M540R] = "clevo-m540r",
2854 [ALC883_CLEVO_M720] = "clevo-m720",
2855 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
2856 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
2857 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
2858 [ALC889A_INTEL] = "intel-alc889a",
2859 [ALC889_INTEL] = "intel-x58",
2860 [ALC1200_ASUS_P5Q] = "asus-p5q",
2861 [ALC889A_MB31] = "mb31",
2862 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
2863 [ALC882_AUTO] = "auto",
2864};
2865
2866static const struct snd_pci_quirk alc882_cfg_tbl[] = {
2867 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
2868
2869 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
2870 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
2871 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
2872 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
2873 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
2874 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
2875 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
2876 ALC888_ACER_ASPIRE_4930G),
2877 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
2878 ALC888_ACER_ASPIRE_4930G),
2879 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
2880 ALC888_ACER_ASPIRE_8930G),
2881 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
2882 ALC888_ACER_ASPIRE_8930G),
2883 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
2884 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
2885 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
2886 ALC888_ACER_ASPIRE_6530G),
2887 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
2888 ALC888_ACER_ASPIRE_6530G),
2889 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
2890 ALC888_ACER_ASPIRE_7730G),
2891 /* default Acer -- disabled as it causes more problems.
2892 * model=auto should work fine now
2893 */
2894 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
2895
2896 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
2897
2898 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
2899 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
2900 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
2901 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
2902 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
2903 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
2904
2905 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
2906 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
2907 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
2908 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
2909 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
2910 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
2911 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
2912 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
2913 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
2914 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
2915 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
2916
2917 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
2918 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
2919 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2920 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
2921 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
2922 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
2923 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
2924 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
2925 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
2926
2927 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
2928 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
2929 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
2930 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2931 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
2932 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
2933 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
2934 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
2935 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
2936 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
2937 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
2938 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
2939 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
2940 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
2941 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
2942 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
2943 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
2944 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
2945 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
2946 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
2947 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
2948 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
2949 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
2950 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
2951 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
2952 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
2953 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
2954 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
2955 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
2956 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
2957 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
2958
2959 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
2960 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
2961 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
2962 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
2963 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
2964 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
2965 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
2966 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
2967 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
2968 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
2969 ALC883_FUJITSU_PI2515),
2970 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
2971 ALC888_FUJITSU_XA3530),
2972 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
2973 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2974 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2975 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
2976 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
2977 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
2978 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
2979 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
2980
2981 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
2982 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2983 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
2984 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
2985 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
2986 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
2987 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
2988
2989 {}
2990};
2991
2992/* codec SSID table for Intel Mac */
2993static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
2994 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
2995 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
2996 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
2997 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
2998 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
2999 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
3000 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
3001 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
3002 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
3003 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
3004 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
3005 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
3006 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
3007 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
3008 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
3009 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3010 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
3011 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
3012 * so apparently no perfect solution yet
3013 */
3014 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
3015 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
3016 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
3017 {} /* terminator */
3018};
3019
3020static const struct alc_config_preset alc882_presets[] = {
3021 [ALC882_3ST_DIG] = {
3022 .mixers = { alc882_base_mixer },
3023 .init_verbs = { alc882_base_init_verbs,
3024 alc882_adc1_init_verbs },
3025 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3026 .dac_nids = alc882_dac_nids,
3027 .dig_out_nid = ALC882_DIGOUT_NID,
3028 .dig_in_nid = ALC882_DIGIN_NID,
3029 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3030 .channel_mode = alc882_ch_modes,
3031 .need_dac_fix = 1,
3032 .input_mux = &alc882_capture_source,
3033 },
3034 [ALC882_6ST_DIG] = {
3035 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3036 .init_verbs = { alc882_base_init_verbs,
3037 alc882_adc1_init_verbs },
3038 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3039 .dac_nids = alc882_dac_nids,
3040 .dig_out_nid = ALC882_DIGOUT_NID,
3041 .dig_in_nid = ALC882_DIGIN_NID,
3042 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3043 .channel_mode = alc882_sixstack_modes,
3044 .input_mux = &alc882_capture_source,
3045 },
3046 [ALC882_ARIMA] = {
3047 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
3048 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3049 alc882_eapd_verbs },
3050 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3051 .dac_nids = alc882_dac_nids,
3052 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
3053 .channel_mode = alc882_sixstack_modes,
3054 .input_mux = &alc882_capture_source,
3055 },
3056 [ALC882_W2JC] = {
3057 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
3058 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3059 alc882_eapd_verbs, alc880_gpio1_init_verbs },
3060 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3061 .dac_nids = alc882_dac_nids,
3062 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3063 .channel_mode = alc880_threestack_modes,
3064 .need_dac_fix = 1,
3065 .input_mux = &alc882_capture_source,
3066 .dig_out_nid = ALC882_DIGOUT_NID,
3067 },
3068 [ALC885_MBA21] = {
3069 .mixers = { alc885_mba21_mixer },
3070 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
3071 .num_dacs = 2,
3072 .dac_nids = alc882_dac_nids,
3073 .channel_mode = alc885_mba21_ch_modes,
3074 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3075 .input_mux = &alc882_capture_source,
3076 .unsol_event = alc_sku_unsol_event,
3077 .setup = alc885_mba21_setup,
3078 .init_hook = alc_hp_automute,
3079 },
3080 [ALC885_MBP3] = {
3081 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
3082 .init_verbs = { alc885_mbp3_init_verbs,
3083 alc880_gpio1_init_verbs },
3084 .num_dacs = 2,
3085 .dac_nids = alc882_dac_nids,
3086 .hp_nid = 0x04,
3087 .channel_mode = alc885_mbp_4ch_modes,
3088 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
3089 .input_mux = &alc882_capture_source,
3090 .dig_out_nid = ALC882_DIGOUT_NID,
3091 .dig_in_nid = ALC882_DIGIN_NID,
3092 .unsol_event = alc_sku_unsol_event,
3093 .setup = alc885_mbp3_setup,
3094 .init_hook = alc_hp_automute,
3095 },
3096 [ALC885_MB5] = {
3097 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
3098 .init_verbs = { alc885_mb5_init_verbs,
3099 alc880_gpio1_init_verbs },
3100 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3101 .dac_nids = alc882_dac_nids,
3102 .channel_mode = alc885_mb5_6ch_modes,
3103 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
3104 .input_mux = &mb5_capture_source,
3105 .dig_out_nid = ALC882_DIGOUT_NID,
3106 .dig_in_nid = ALC882_DIGIN_NID,
3107 .unsol_event = alc_sku_unsol_event,
3108 .setup = alc885_mb5_setup,
3109 .init_hook = alc_hp_automute,
3110 },
3111 [ALC885_MACMINI3] = {
3112 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
3113 .init_verbs = { alc885_macmini3_init_verbs,
3114 alc880_gpio1_init_verbs },
3115 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3116 .dac_nids = alc882_dac_nids,
3117 .channel_mode = alc885_macmini3_6ch_modes,
3118 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
3119 .input_mux = &macmini3_capture_source,
3120 .dig_out_nid = ALC882_DIGOUT_NID,
3121 .dig_in_nid = ALC882_DIGIN_NID,
3122 .unsol_event = alc_sku_unsol_event,
3123 .setup = alc885_macmini3_setup,
3124 .init_hook = alc_hp_automute,
3125 },
3126 [ALC885_MACPRO] = {
3127 .mixers = { alc882_macpro_mixer },
3128 .init_verbs = { alc882_macpro_init_verbs },
3129 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3130 .dac_nids = alc882_dac_nids,
3131 .dig_out_nid = ALC882_DIGOUT_NID,
3132 .dig_in_nid = ALC882_DIGIN_NID,
3133 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3134 .channel_mode = alc882_ch_modes,
3135 .input_mux = &alc882_capture_source,
3136 .init_hook = alc885_macpro_init_hook,
3137 },
3138 [ALC885_IMAC24] = {
3139 .mixers = { alc885_imac24_mixer },
3140 .init_verbs = { alc885_imac24_init_verbs },
3141 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3142 .dac_nids = alc882_dac_nids,
3143 .dig_out_nid = ALC882_DIGOUT_NID,
3144 .dig_in_nid = ALC882_DIGIN_NID,
3145 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
3146 .channel_mode = alc882_ch_modes,
3147 .input_mux = &alc882_capture_source,
3148 .unsol_event = alc_sku_unsol_event,
3149 .setup = alc885_imac24_setup,
3150 .init_hook = alc885_imac24_init_hook,
3151 },
3152 [ALC885_IMAC91] = {
3153 .mixers = {alc885_imac91_mixer},
3154 .init_verbs = { alc885_imac91_init_verbs,
3155 alc880_gpio1_init_verbs },
3156 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3157 .dac_nids = alc882_dac_nids,
3158 .channel_mode = alc885_mba21_ch_modes,
3159 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
3160 .input_mux = &alc889A_imac91_capture_source,
3161 .dig_out_nid = ALC882_DIGOUT_NID,
3162 .dig_in_nid = ALC882_DIGIN_NID,
3163 .unsol_event = alc_sku_unsol_event,
3164 .setup = alc885_imac91_setup,
3165 .init_hook = alc_hp_automute,
3166 },
3167 [ALC882_TARGA] = {
3168 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
3169 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3170 alc880_gpio3_init_verbs, alc882_targa_verbs},
3171 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3172 .dac_nids = alc882_dac_nids,
3173 .dig_out_nid = ALC882_DIGOUT_NID,
3174 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3175 .adc_nids = alc882_adc_nids,
3176 .capsrc_nids = alc882_capsrc_nids,
3177 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3178 .channel_mode = alc882_3ST_6ch_modes,
3179 .need_dac_fix = 1,
3180 .input_mux = &alc882_capture_source,
3181 .unsol_event = alc_sku_unsol_event,
3182 .setup = alc882_targa_setup,
3183 .init_hook = alc882_targa_automute,
3184 },
3185 [ALC882_ASUS_A7J] = {
3186 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
3187 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3188 alc882_asus_a7j_verbs},
3189 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3190 .dac_nids = alc882_dac_nids,
3191 .dig_out_nid = ALC882_DIGOUT_NID,
3192 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
3193 .adc_nids = alc882_adc_nids,
3194 .capsrc_nids = alc882_capsrc_nids,
3195 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
3196 .channel_mode = alc882_3ST_6ch_modes,
3197 .need_dac_fix = 1,
3198 .input_mux = &alc882_capture_source,
3199 },
3200 [ALC882_ASUS_A7M] = {
3201 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
3202 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
3203 alc882_eapd_verbs, alc880_gpio1_init_verbs,
3204 alc882_asus_a7m_verbs },
3205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
3206 .dac_nids = alc882_dac_nids,
3207 .dig_out_nid = ALC882_DIGOUT_NID,
3208 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
3209 .channel_mode = alc880_threestack_modes,
3210 .need_dac_fix = 1,
3211 .input_mux = &alc882_capture_source,
3212 },
3213 [ALC883_3ST_2ch_DIG] = {
3214 .mixers = { alc883_3ST_2ch_mixer },
3215 .init_verbs = { alc883_init_verbs },
3216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3217 .dac_nids = alc883_dac_nids,
3218 .dig_out_nid = ALC883_DIGOUT_NID,
3219 .dig_in_nid = ALC883_DIGIN_NID,
3220 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3221 .channel_mode = alc883_3ST_2ch_modes,
3222 .input_mux = &alc883_capture_source,
3223 },
3224 [ALC883_3ST_6ch_DIG] = {
3225 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3226 .init_verbs = { alc883_init_verbs },
3227 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3228 .dac_nids = alc883_dac_nids,
3229 .dig_out_nid = ALC883_DIGOUT_NID,
3230 .dig_in_nid = ALC883_DIGIN_NID,
3231 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3232 .channel_mode = alc883_3ST_6ch_modes,
3233 .need_dac_fix = 1,
3234 .input_mux = &alc883_capture_source,
3235 },
3236 [ALC883_3ST_6ch] = {
3237 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3238 .init_verbs = { alc883_init_verbs },
3239 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3240 .dac_nids = alc883_dac_nids,
3241 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3242 .channel_mode = alc883_3ST_6ch_modes,
3243 .need_dac_fix = 1,
3244 .input_mux = &alc883_capture_source,
3245 },
3246 [ALC883_3ST_6ch_INTEL] = {
3247 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
3248 .init_verbs = { alc883_init_verbs },
3249 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3250 .dac_nids = alc883_dac_nids,
3251 .dig_out_nid = ALC883_DIGOUT_NID,
3252 .dig_in_nid = ALC883_DIGIN_NID,
3253 .slave_dig_outs = alc883_slave_dig_outs,
3254 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
3255 .channel_mode = alc883_3ST_6ch_intel_modes,
3256 .need_dac_fix = 1,
3257 .input_mux = &alc883_3stack_6ch_intel,
3258 },
3259 [ALC889A_INTEL] = {
3260 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3261 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
3262 alc_hp15_unsol_verbs },
3263 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3264 .dac_nids = alc883_dac_nids,
3265 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3266 .adc_nids = alc889_adc_nids,
3267 .dig_out_nid = ALC883_DIGOUT_NID,
3268 .dig_in_nid = ALC883_DIGIN_NID,
3269 .slave_dig_outs = alc883_slave_dig_outs,
3270 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3271 .channel_mode = alc889_8ch_intel_modes,
3272 .capsrc_nids = alc889_capsrc_nids,
3273 .input_mux = &alc889_capture_source,
3274 .setup = alc889_automute_setup,
3275 .init_hook = alc_hp_automute,
3276 .unsol_event = alc_sku_unsol_event,
3277 .need_dac_fix = 1,
3278 },
3279 [ALC889_INTEL] = {
3280 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
3281 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
3282 alc889_eapd_verbs, alc_hp15_unsol_verbs},
3283 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3284 .dac_nids = alc883_dac_nids,
3285 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3286 .adc_nids = alc889_adc_nids,
3287 .dig_out_nid = ALC883_DIGOUT_NID,
3288 .dig_in_nid = ALC883_DIGIN_NID,
3289 .slave_dig_outs = alc883_slave_dig_outs,
3290 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
3291 .channel_mode = alc889_8ch_intel_modes,
3292 .capsrc_nids = alc889_capsrc_nids,
3293 .input_mux = &alc889_capture_source,
3294 .setup = alc889_automute_setup,
3295 .init_hook = alc889_intel_init_hook,
3296 .unsol_event = alc_sku_unsol_event,
3297 .need_dac_fix = 1,
3298 },
3299 [ALC883_6ST_DIG] = {
3300 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3301 .init_verbs = { alc883_init_verbs },
3302 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3303 .dac_nids = alc883_dac_nids,
3304 .dig_out_nid = ALC883_DIGOUT_NID,
3305 .dig_in_nid = ALC883_DIGIN_NID,
3306 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3307 .channel_mode = alc883_sixstack_modes,
3308 .input_mux = &alc883_capture_source,
3309 },
3310 [ALC883_TARGA_DIG] = {
3311 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
3312 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3313 alc883_targa_verbs},
3314 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3315 .dac_nids = alc883_dac_nids,
3316 .dig_out_nid = ALC883_DIGOUT_NID,
3317 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3318 .channel_mode = alc883_3ST_6ch_modes,
3319 .need_dac_fix = 1,
3320 .input_mux = &alc883_capture_source,
3321 .unsol_event = alc883_targa_unsol_event,
3322 .setup = alc882_targa_setup,
3323 .init_hook = alc882_targa_automute,
3324 },
3325 [ALC883_TARGA_2ch_DIG] = {
3326 .mixers = { alc883_targa_2ch_mixer},
3327 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3328 alc883_targa_verbs},
3329 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3330 .dac_nids = alc883_dac_nids,
3331 .adc_nids = alc883_adc_nids_alt,
3332 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3333 .capsrc_nids = alc883_capsrc_nids,
3334 .dig_out_nid = ALC883_DIGOUT_NID,
3335 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3336 .channel_mode = alc883_3ST_2ch_modes,
3337 .input_mux = &alc883_capture_source,
3338 .unsol_event = alc883_targa_unsol_event,
3339 .setup = alc882_targa_setup,
3340 .init_hook = alc882_targa_automute,
3341 },
3342 [ALC883_TARGA_8ch_DIG] = {
3343 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
3344 alc883_chmode_mixer },
3345 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
3346 alc883_targa_verbs },
3347 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3348 .dac_nids = alc883_dac_nids,
3349 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3350 .adc_nids = alc883_adc_nids_rev,
3351 .capsrc_nids = alc883_capsrc_nids_rev,
3352 .dig_out_nid = ALC883_DIGOUT_NID,
3353 .dig_in_nid = ALC883_DIGIN_NID,
3354 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
3355 .channel_mode = alc883_4ST_8ch_modes,
3356 .need_dac_fix = 1,
3357 .input_mux = &alc883_capture_source,
3358 .unsol_event = alc883_targa_unsol_event,
3359 .setup = alc882_targa_setup,
3360 .init_hook = alc882_targa_automute,
3361 },
3362 [ALC883_ACER] = {
3363 .mixers = { alc883_base_mixer },
3364 /* On TravelMate laptops, GPIO 0 enables the internal speaker
3365 * and the headphone jack. Turn this on and rely on the
3366 * standard mute methods whenever the user wants to turn
3367 * these outputs off.
3368 */
3369 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
3370 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3371 .dac_nids = alc883_dac_nids,
3372 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3373 .channel_mode = alc883_3ST_2ch_modes,
3374 .input_mux = &alc883_capture_source,
3375 },
3376 [ALC883_ACER_ASPIRE] = {
3377 .mixers = { alc883_acer_aspire_mixer },
3378 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
3379 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3380 .dac_nids = alc883_dac_nids,
3381 .dig_out_nid = ALC883_DIGOUT_NID,
3382 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3383 .channel_mode = alc883_3ST_2ch_modes,
3384 .input_mux = &alc883_capture_source,
3385 .unsol_event = alc_sku_unsol_event,
3386 .setup = alc883_acer_aspire_setup,
3387 .init_hook = alc_hp_automute,
3388 },
3389 [ALC888_ACER_ASPIRE_4930G] = {
3390 .mixers = { alc888_acer_aspire_4930g_mixer,
3391 alc883_chmode_mixer },
3392 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3393 alc888_acer_aspire_4930g_verbs },
3394 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3395 .dac_nids = alc883_dac_nids,
3396 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3397 .adc_nids = alc883_adc_nids_rev,
3398 .capsrc_nids = alc883_capsrc_nids_rev,
3399 .dig_out_nid = ALC883_DIGOUT_NID,
3400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3401 .channel_mode = alc883_3ST_6ch_modes,
3402 .need_dac_fix = 1,
3403 .const_channel_count = 6,
3404 .num_mux_defs =
3405 ARRAY_SIZE(alc888_2_capture_sources),
3406 .input_mux = alc888_2_capture_sources,
3407 .unsol_event = alc_sku_unsol_event,
3408 .setup = alc888_acer_aspire_4930g_setup,
3409 .init_hook = alc_hp_automute,
3410 },
3411 [ALC888_ACER_ASPIRE_6530G] = {
3412 .mixers = { alc888_acer_aspire_6530_mixer },
3413 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3414 alc888_acer_aspire_6530g_verbs },
3415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3416 .dac_nids = alc883_dac_nids,
3417 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3418 .adc_nids = alc883_adc_nids_rev,
3419 .capsrc_nids = alc883_capsrc_nids_rev,
3420 .dig_out_nid = ALC883_DIGOUT_NID,
3421 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3422 .channel_mode = alc883_3ST_2ch_modes,
3423 .num_mux_defs =
3424 ARRAY_SIZE(alc888_2_capture_sources),
3425 .input_mux = alc888_acer_aspire_6530_sources,
3426 .unsol_event = alc_sku_unsol_event,
3427 .setup = alc888_acer_aspire_6530g_setup,
3428 .init_hook = alc_hp_automute,
3429 },
3430 [ALC888_ACER_ASPIRE_8930G] = {
3431 .mixers = { alc889_acer_aspire_8930g_mixer,
3432 alc883_chmode_mixer },
3433 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3434 alc889_acer_aspire_8930g_verbs,
3435 alc889_eapd_verbs},
3436 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3437 .dac_nids = alc883_dac_nids,
3438 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
3439 .adc_nids = alc889_adc_nids,
3440 .capsrc_nids = alc889_capsrc_nids,
3441 .dig_out_nid = ALC883_DIGOUT_NID,
3442 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3443 .channel_mode = alc883_3ST_6ch_modes,
3444 .need_dac_fix = 1,
3445 .const_channel_count = 6,
3446 .num_mux_defs =
3447 ARRAY_SIZE(alc889_capture_sources),
3448 .input_mux = alc889_capture_sources,
3449 .unsol_event = alc_sku_unsol_event,
3450 .setup = alc889_acer_aspire_8930g_setup,
3451 .init_hook = alc_hp_automute,
3452#ifdef CONFIG_SND_HDA_POWER_SAVE
3453 .power_hook = alc_power_eapd,
3454#endif
3455 },
3456 [ALC888_ACER_ASPIRE_7730G] = {
3457 .mixers = { alc883_3ST_6ch_mixer,
3458 alc883_chmode_mixer },
3459 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
3460 alc888_acer_aspire_7730G_verbs },
3461 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3462 .dac_nids = alc883_dac_nids,
3463 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3464 .adc_nids = alc883_adc_nids_rev,
3465 .capsrc_nids = alc883_capsrc_nids_rev,
3466 .dig_out_nid = ALC883_DIGOUT_NID,
3467 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3468 .channel_mode = alc883_3ST_6ch_modes,
3469 .need_dac_fix = 1,
3470 .const_channel_count = 6,
3471 .input_mux = &alc883_capture_source,
3472 .unsol_event = alc_sku_unsol_event,
3473 .setup = alc888_acer_aspire_7730g_setup,
3474 .init_hook = alc_hp_automute,
3475 },
3476 [ALC883_MEDION] = {
3477 .mixers = { alc883_fivestack_mixer,
3478 alc883_chmode_mixer },
3479 .init_verbs = { alc883_init_verbs,
3480 alc883_medion_eapd_verbs },
3481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3482 .dac_nids = alc883_dac_nids,
3483 .adc_nids = alc883_adc_nids_alt,
3484 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3485 .capsrc_nids = alc883_capsrc_nids,
3486 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3487 .channel_mode = alc883_sixstack_modes,
3488 .input_mux = &alc883_capture_source,
3489 },
3490 [ALC883_MEDION_WIM2160] = {
3491 .mixers = { alc883_medion_wim2160_mixer },
3492 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
3493 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3494 .dac_nids = alc883_dac_nids,
3495 .dig_out_nid = ALC883_DIGOUT_NID,
3496 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3497 .adc_nids = alc883_adc_nids,
3498 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3499 .channel_mode = alc883_3ST_2ch_modes,
3500 .input_mux = &alc883_capture_source,
3501 .unsol_event = alc_sku_unsol_event,
3502 .setup = alc883_medion_wim2160_setup,
3503 .init_hook = alc_hp_automute,
3504 },
3505 [ALC883_LAPTOP_EAPD] = {
3506 .mixers = { alc883_base_mixer },
3507 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
3508 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3509 .dac_nids = alc883_dac_nids,
3510 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3511 .channel_mode = alc883_3ST_2ch_modes,
3512 .input_mux = &alc883_capture_source,
3513 },
3514 [ALC883_CLEVO_M540R] = {
3515 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3516 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
3517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3518 .dac_nids = alc883_dac_nids,
3519 .dig_out_nid = ALC883_DIGOUT_NID,
3520 .dig_in_nid = ALC883_DIGIN_NID,
3521 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
3522 .channel_mode = alc883_3ST_6ch_clevo_modes,
3523 .need_dac_fix = 1,
3524 .input_mux = &alc883_capture_source,
3525 /* This machine has the hardware HP auto-muting, thus
3526 * we need no software mute via unsol event
3527 */
3528 },
3529 [ALC883_CLEVO_M720] = {
3530 .mixers = { alc883_clevo_m720_mixer },
3531 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
3532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3533 .dac_nids = alc883_dac_nids,
3534 .dig_out_nid = ALC883_DIGOUT_NID,
3535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3536 .channel_mode = alc883_3ST_2ch_modes,
3537 .input_mux = &alc883_capture_source,
3538 .unsol_event = alc883_clevo_m720_unsol_event,
3539 .setup = alc883_clevo_m720_setup,
3540 .init_hook = alc883_clevo_m720_init_hook,
3541 },
3542 [ALC883_LENOVO_101E_2ch] = {
3543 .mixers = { alc883_lenovo_101e_2ch_mixer},
3544 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
3545 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3546 .dac_nids = alc883_dac_nids,
3547 .adc_nids = alc883_adc_nids_alt,
3548 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
3549 .capsrc_nids = alc883_capsrc_nids,
3550 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3551 .channel_mode = alc883_3ST_2ch_modes,
3552 .input_mux = &alc883_lenovo_101e_capture_source,
3553 .setup = alc883_lenovo_101e_setup,
3554 .unsol_event = alc_sku_unsol_event,
3555 .init_hook = alc_inithook,
3556 },
3557 [ALC883_LENOVO_NB0763] = {
3558 .mixers = { alc883_lenovo_nb0763_mixer },
3559 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
3560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3561 .dac_nids = alc883_dac_nids,
3562 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3563 .channel_mode = alc883_3ST_2ch_modes,
3564 .need_dac_fix = 1,
3565 .input_mux = &alc883_lenovo_nb0763_capture_source,
3566 .unsol_event = alc_sku_unsol_event,
3567 .setup = alc883_lenovo_nb0763_setup,
3568 .init_hook = alc_hp_automute,
3569 },
3570 [ALC888_LENOVO_MS7195_DIG] = {
3571 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3572 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
3573 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3574 .dac_nids = alc883_dac_nids,
3575 .dig_out_nid = ALC883_DIGOUT_NID,
3576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3577 .channel_mode = alc883_3ST_6ch_modes,
3578 .need_dac_fix = 1,
3579 .input_mux = &alc883_capture_source,
3580 .unsol_event = alc_sku_unsol_event,
3581 .setup = alc888_lenovo_ms7195_setup,
3582 .init_hook = alc_inithook,
3583 },
3584 [ALC883_HAIER_W66] = {
3585 .mixers = { alc883_targa_2ch_mixer},
3586 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
3587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3588 .dac_nids = alc883_dac_nids,
3589 .dig_out_nid = ALC883_DIGOUT_NID,
3590 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3591 .channel_mode = alc883_3ST_2ch_modes,
3592 .input_mux = &alc883_capture_source,
3593 .unsol_event = alc_sku_unsol_event,
3594 .setup = alc883_haier_w66_setup,
3595 .init_hook = alc_hp_automute,
3596 },
3597 [ALC888_3ST_HP] = {
3598 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3599 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
3600 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3601 .dac_nids = alc883_dac_nids,
3602 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
3603 .channel_mode = alc888_3st_hp_modes,
3604 .need_dac_fix = 1,
3605 .input_mux = &alc883_capture_source,
3606 .unsol_event = alc_sku_unsol_event,
3607 .setup = alc888_3st_hp_setup,
3608 .init_hook = alc_hp_automute,
3609 },
3610 [ALC888_6ST_DELL] = {
3611 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3612 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
3613 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3614 .dac_nids = alc883_dac_nids,
3615 .dig_out_nid = ALC883_DIGOUT_NID,
3616 .dig_in_nid = ALC883_DIGIN_NID,
3617 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3618 .channel_mode = alc883_sixstack_modes,
3619 .input_mux = &alc883_capture_source,
3620 .unsol_event = alc_sku_unsol_event,
3621 .setup = alc888_6st_dell_setup,
3622 .init_hook = alc_hp_automute,
3623 },
3624 [ALC883_MITAC] = {
3625 .mixers = { alc883_mitac_mixer },
3626 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
3627 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3628 .dac_nids = alc883_dac_nids,
3629 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3630 .channel_mode = alc883_3ST_2ch_modes,
3631 .input_mux = &alc883_capture_source,
3632 .unsol_event = alc_sku_unsol_event,
3633 .setup = alc883_mitac_setup,
3634 .init_hook = alc_hp_automute,
3635 },
3636 [ALC883_FUJITSU_PI2515] = {
3637 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
3638 .init_verbs = { alc883_init_verbs,
3639 alc883_2ch_fujitsu_pi2515_verbs},
3640 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3641 .dac_nids = alc883_dac_nids,
3642 .dig_out_nid = ALC883_DIGOUT_NID,
3643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3644 .channel_mode = alc883_3ST_2ch_modes,
3645 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3646 .unsol_event = alc_sku_unsol_event,
3647 .setup = alc883_2ch_fujitsu_pi2515_setup,
3648 .init_hook = alc_hp_automute,
3649 },
3650 [ALC888_FUJITSU_XA3530] = {
3651 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
3652 .init_verbs = { alc883_init_verbs,
3653 alc888_fujitsu_xa3530_verbs },
3654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3655 .dac_nids = alc883_dac_nids,
3656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
3657 .adc_nids = alc883_adc_nids_rev,
3658 .capsrc_nids = alc883_capsrc_nids_rev,
3659 .dig_out_nid = ALC883_DIGOUT_NID,
3660 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
3661 .channel_mode = alc888_4ST_8ch_intel_modes,
3662 .num_mux_defs =
3663 ARRAY_SIZE(alc888_2_capture_sources),
3664 .input_mux = alc888_2_capture_sources,
3665 .unsol_event = alc_sku_unsol_event,
3666 .setup = alc888_fujitsu_xa3530_setup,
3667 .init_hook = alc_hp_automute,
3668 },
3669 [ALC888_LENOVO_SKY] = {
3670 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
3671 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
3672 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3673 .dac_nids = alc883_dac_nids,
3674 .dig_out_nid = ALC883_DIGOUT_NID,
3675 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3676 .channel_mode = alc883_sixstack_modes,
3677 .need_dac_fix = 1,
3678 .input_mux = &alc883_lenovo_sky_capture_source,
3679 .unsol_event = alc_sku_unsol_event,
3680 .setup = alc888_lenovo_sky_setup,
3681 .init_hook = alc_hp_automute,
3682 },
3683 [ALC888_ASUS_M90V] = {
3684 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
3685 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
3686 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3687 .dac_nids = alc883_dac_nids,
3688 .dig_out_nid = ALC883_DIGOUT_NID,
3689 .dig_in_nid = ALC883_DIGIN_NID,
3690 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
3691 .channel_mode = alc883_3ST_6ch_modes,
3692 .need_dac_fix = 1,
3693 .input_mux = &alc883_fujitsu_pi2515_capture_source,
3694 .unsol_event = alc_sku_unsol_event,
3695 .setup = alc883_mode2_setup,
3696 .init_hook = alc_inithook,
3697 },
3698 [ALC888_ASUS_EEE1601] = {
3699 .mixers = { alc883_asus_eee1601_mixer },
3700 .cap_mixer = alc883_asus_eee1601_cap_mixer,
3701 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
3702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3703 .dac_nids = alc883_dac_nids,
3704 .dig_out_nid = ALC883_DIGOUT_NID,
3705 .dig_in_nid = ALC883_DIGIN_NID,
3706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3707 .channel_mode = alc883_3ST_2ch_modes,
3708 .need_dac_fix = 1,
3709 .input_mux = &alc883_asus_eee1601_capture_source,
3710 .unsol_event = alc_sku_unsol_event,
3711 .init_hook = alc883_eee1601_inithook,
3712 },
3713 [ALC1200_ASUS_P5Q] = {
3714 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
3715 .init_verbs = { alc883_init_verbs },
3716 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3717 .dac_nids = alc883_dac_nids,
3718 .dig_out_nid = ALC1200_DIGOUT_NID,
3719 .dig_in_nid = ALC883_DIGIN_NID,
3720 .slave_dig_outs = alc1200_slave_dig_outs,
3721 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
3722 .channel_mode = alc883_sixstack_modes,
3723 .input_mux = &alc883_capture_source,
3724 },
3725 [ALC889A_MB31] = {
3726 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
3727 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
3728 alc880_gpio1_init_verbs },
3729 .adc_nids = alc883_adc_nids,
3730 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
3731 .capsrc_nids = alc883_capsrc_nids,
3732 .dac_nids = alc883_dac_nids,
3733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3734 .channel_mode = alc889A_mb31_6ch_modes,
3735 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
3736 .input_mux = &alc889A_mb31_capture_source,
3737 .dig_out_nid = ALC883_DIGOUT_NID,
3738 .unsol_event = alc889A_mb31_unsol_event,
3739 .init_hook = alc889A_mb31_automute,
3740 },
3741 [ALC883_SONY_VAIO_TT] = {
3742 .mixers = { alc883_vaiott_mixer },
3743 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
3744 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
3745 .dac_nids = alc883_dac_nids,
3746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
3747 .channel_mode = alc883_3ST_2ch_modes,
3748 .input_mux = &alc883_capture_source,
3749 .unsol_event = alc_sku_unsol_event,
3750 .setup = alc883_vaiott_setup,
3751 .init_hook = alc_hp_automute,
3752 },
3753};
3754
3755
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c
new file mode 100644
index 000000000000..2be1129cf458
--- /dev/null
+++ b/sound/pci/hda/alc_quirks.c
@@ -0,0 +1,467 @@
1/*
2 * Common codes for Realtek codec quirks
3 * included by patch_realtek.c
4 */
5
6/*
7 * configuration template - to be copied to the spec instance
8 */
9struct alc_config_preset {
10 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
11 * with spec
12 */
13 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
14 const struct hda_verb *init_verbs[5];
15 unsigned int num_dacs;
16 const hda_nid_t *dac_nids;
17 hda_nid_t dig_out_nid; /* optional */
18 hda_nid_t hp_nid; /* optional */
19 const hda_nid_t *slave_dig_outs;
20 unsigned int num_adc_nids;
21 const hda_nid_t *adc_nids;
22 const hda_nid_t *capsrc_nids;
23 hda_nid_t dig_in_nid;
24 unsigned int num_channel_mode;
25 const struct hda_channel_mode *channel_mode;
26 int need_dac_fix;
27 int const_channel_count;
28 unsigned int num_mux_defs;
29 const struct hda_input_mux *input_mux;
30 void (*unsol_event)(struct hda_codec *, unsigned int);
31 void (*setup)(struct hda_codec *);
32 void (*init_hook)(struct hda_codec *);
33#ifdef CONFIG_SND_HDA_POWER_SAVE
34 const struct hda_amp_list *loopbacks;
35 void (*power_hook)(struct hda_codec *codec);
36#endif
37};
38
39/*
40 * channel mode setting
41 */
42static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
43 struct snd_ctl_elem_info *uinfo)
44{
45 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
46 struct alc_spec *spec = codec->spec;
47 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
48 spec->num_channel_mode);
49}
50
51static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
52 struct snd_ctl_elem_value *ucontrol)
53{
54 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
55 struct alc_spec *spec = codec->spec;
56 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
57 spec->num_channel_mode,
58 spec->ext_channel_count);
59}
60
61static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
62 struct snd_ctl_elem_value *ucontrol)
63{
64 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
65 struct alc_spec *spec = codec->spec;
66 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
67 spec->num_channel_mode,
68 &spec->ext_channel_count);
69 if (err >= 0 && !spec->const_channel_count) {
70 spec->multiout.max_channels = spec->ext_channel_count;
71 if (spec->need_dac_fix)
72 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
73 }
74 return err;
75}
76
77/*
78 * Control the mode of pin widget settings via the mixer. "pc" is used
79 * instead of "%" to avoid consequences of accidentally treating the % as
80 * being part of a format specifier. Maximum allowed length of a value is
81 * 63 characters plus NULL terminator.
82 *
83 * Note: some retasking pin complexes seem to ignore requests for input
84 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
85 * are requested. Therefore order this list so that this behaviour will not
86 * cause problems when mixer clients move through the enum sequentially.
87 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
88 * March 2006.
89 */
90static const char * const alc_pin_mode_names[] = {
91 "Mic 50pc bias", "Mic 80pc bias",
92 "Line in", "Line out", "Headphone out",
93};
94static const unsigned char alc_pin_mode_values[] = {
95 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
96};
97/* The control can present all 5 options, or it can limit the options based
98 * in the pin being assumed to be exclusively an input or an output pin. In
99 * addition, "input" pins may or may not process the mic bias option
100 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
101 * accept requests for bias as of chip versions up to March 2006) and/or
102 * wiring in the computer.
103 */
104#define ALC_PIN_DIR_IN 0x00
105#define ALC_PIN_DIR_OUT 0x01
106#define ALC_PIN_DIR_INOUT 0x02
107#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
108#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
109
110/* Info about the pin modes supported by the different pin direction modes.
111 * For each direction the minimum and maximum values are given.
112 */
113static const signed char alc_pin_mode_dir_info[5][2] = {
114 { 0, 2 }, /* ALC_PIN_DIR_IN */
115 { 3, 4 }, /* ALC_PIN_DIR_OUT */
116 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
117 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
118 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
119};
120#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
121#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
122#define alc_pin_mode_n_items(_dir) \
123 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
124
125static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_info *uinfo)
127{
128 unsigned int item_num = uinfo->value.enumerated.item;
129 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
130
131 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
132 uinfo->count = 1;
133 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
134
135 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
136 item_num = alc_pin_mode_min(dir);
137 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
138 return 0;
139}
140
141static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
142 struct snd_ctl_elem_value *ucontrol)
143{
144 unsigned int i;
145 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
146 hda_nid_t nid = kcontrol->private_value & 0xffff;
147 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
148 long *valp = ucontrol->value.integer.value;
149 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
150 AC_VERB_GET_PIN_WIDGET_CONTROL,
151 0x00);
152
153 /* Find enumerated value for current pinctl setting */
154 i = alc_pin_mode_min(dir);
155 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
156 i++;
157 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
158 return 0;
159}
160
161static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
162 struct snd_ctl_elem_value *ucontrol)
163{
164 signed int change;
165 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
166 hda_nid_t nid = kcontrol->private_value & 0xffff;
167 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
168 long val = *ucontrol->value.integer.value;
169 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
170 AC_VERB_GET_PIN_WIDGET_CONTROL,
171 0x00);
172
173 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
174 val = alc_pin_mode_min(dir);
175
176 change = pinctl != alc_pin_mode_values[val];
177 if (change) {
178 /* Set pin mode to that requested */
179 snd_hda_codec_write_cache(codec, nid, 0,
180 AC_VERB_SET_PIN_WIDGET_CONTROL,
181 alc_pin_mode_values[val]);
182
183 /* Also enable the retasking pin's input/output as required
184 * for the requested pin mode. Enum values of 2 or less are
185 * input modes.
186 *
187 * Dynamically switching the input/output buffers probably
188 * reduces noise slightly (particularly on input) so we'll
189 * do it. However, having both input and output buffers
190 * enabled simultaneously doesn't seem to be problematic if
191 * this turns out to be necessary in the future.
192 */
193 if (val <= 2) {
194 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
195 HDA_AMP_MUTE, HDA_AMP_MUTE);
196 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
197 HDA_AMP_MUTE, 0);
198 } else {
199 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
200 HDA_AMP_MUTE, HDA_AMP_MUTE);
201 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
202 HDA_AMP_MUTE, 0);
203 }
204 }
205 return change;
206}
207
208#define ALC_PIN_MODE(xname, nid, dir) \
209 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
210 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
211 .info = alc_pin_mode_info, \
212 .get = alc_pin_mode_get, \
213 .put = alc_pin_mode_put, \
214 .private_value = nid | (dir<<16) }
215
216/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
217 * together using a mask with more than one bit set. This control is
218 * currently used only by the ALC260 test model. At this stage they are not
219 * needed for any "production" models.
220 */
221#ifdef CONFIG_SND_DEBUG
222#define alc_gpio_data_info snd_ctl_boolean_mono_info
223
224static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
225 struct snd_ctl_elem_value *ucontrol)
226{
227 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
228 hda_nid_t nid = kcontrol->private_value & 0xffff;
229 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
230 long *valp = ucontrol->value.integer.value;
231 unsigned int val = snd_hda_codec_read(codec, nid, 0,
232 AC_VERB_GET_GPIO_DATA, 0x00);
233
234 *valp = (val & mask) != 0;
235 return 0;
236}
237static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 signed int change;
241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
242 hda_nid_t nid = kcontrol->private_value & 0xffff;
243 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
244 long val = *ucontrol->value.integer.value;
245 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
246 AC_VERB_GET_GPIO_DATA,
247 0x00);
248
249 /* Set/unset the masked GPIO bit(s) as needed */
250 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
251 if (val == 0)
252 gpio_data &= ~mask;
253 else
254 gpio_data |= mask;
255 snd_hda_codec_write_cache(codec, nid, 0,
256 AC_VERB_SET_GPIO_DATA, gpio_data);
257
258 return change;
259}
260#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
261 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
262 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
263 .info = alc_gpio_data_info, \
264 .get = alc_gpio_data_get, \
265 .put = alc_gpio_data_put, \
266 .private_value = nid | (mask<<16) }
267#endif /* CONFIG_SND_DEBUG */
268
269/* A switch control to allow the enabling of the digital IO pins on the
270 * ALC260. This is incredibly simplistic; the intention of this control is
271 * to provide something in the test model allowing digital outputs to be
272 * identified if present. If models are found which can utilise these
273 * outputs a more complete mixer control can be devised for those models if
274 * necessary.
275 */
276#ifdef CONFIG_SND_DEBUG
277#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
278
279static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
280 struct snd_ctl_elem_value *ucontrol)
281{
282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
283 hda_nid_t nid = kcontrol->private_value & 0xffff;
284 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
285 long *valp = ucontrol->value.integer.value;
286 unsigned int val = snd_hda_codec_read(codec, nid, 0,
287 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
288
289 *valp = (val & mask) != 0;
290 return 0;
291}
292static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
293 struct snd_ctl_elem_value *ucontrol)
294{
295 signed int change;
296 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
297 hda_nid_t nid = kcontrol->private_value & 0xffff;
298 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
299 long val = *ucontrol->value.integer.value;
300 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
301 AC_VERB_GET_DIGI_CONVERT_1,
302 0x00);
303
304 /* Set/unset the masked control bit(s) as needed */
305 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
306 if (val==0)
307 ctrl_data &= ~mask;
308 else
309 ctrl_data |= mask;
310 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
311 ctrl_data);
312
313 return change;
314}
315#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
316 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
317 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
318 .info = alc_spdif_ctrl_info, \
319 .get = alc_spdif_ctrl_get, \
320 .put = alc_spdif_ctrl_put, \
321 .private_value = nid | (mask<<16) }
322#endif /* CONFIG_SND_DEBUG */
323
324/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
325 * Again, this is only used in the ALC26x test models to help identify when
326 * the EAPD line must be asserted for features to work.
327 */
328#ifdef CONFIG_SND_DEBUG
329#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
330
331static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
332 struct snd_ctl_elem_value *ucontrol)
333{
334 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
335 hda_nid_t nid = kcontrol->private_value & 0xffff;
336 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
337 long *valp = ucontrol->value.integer.value;
338 unsigned int val = snd_hda_codec_read(codec, nid, 0,
339 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
340
341 *valp = (val & mask) != 0;
342 return 0;
343}
344
345static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347{
348 int change;
349 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
350 hda_nid_t nid = kcontrol->private_value & 0xffff;
351 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
352 long val = *ucontrol->value.integer.value;
353 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_EAPD_BTLENABLE,
355 0x00);
356
357 /* Set/unset the masked control bit(s) as needed */
358 change = (!val ? 0 : mask) != (ctrl_data & mask);
359 if (!val)
360 ctrl_data &= ~mask;
361 else
362 ctrl_data |= mask;
363 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
364 ctrl_data);
365
366 return change;
367}
368
369#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
370 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
371 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
372 .info = alc_eapd_ctrl_info, \
373 .get = alc_eapd_ctrl_get, \
374 .put = alc_eapd_ctrl_put, \
375 .private_value = nid | (mask<<16) }
376#endif /* CONFIG_SND_DEBUG */
377
378static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
379{
380 struct alc_spec *spec = codec->spec;
381 struct auto_pin_cfg *cfg = &spec->autocfg;
382
383 if (!cfg->line_outs) {
384 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
385 cfg->line_out_pins[cfg->line_outs])
386 cfg->line_outs++;
387 }
388 if (!cfg->speaker_outs) {
389 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
390 cfg->speaker_pins[cfg->speaker_outs])
391 cfg->speaker_outs++;
392 }
393 if (!cfg->hp_outs) {
394 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
395 cfg->hp_pins[cfg->hp_outs])
396 cfg->hp_outs++;
397 }
398}
399
400/*
401 * set up from the preset table
402 */
403static void setup_preset(struct hda_codec *codec,
404 const struct alc_config_preset *preset)
405{
406 struct alc_spec *spec = codec->spec;
407 int i;
408
409 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
410 add_mixer(spec, preset->mixers[i]);
411 spec->cap_mixer = preset->cap_mixer;
412 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
413 i++)
414 add_verb(spec, preset->init_verbs[i]);
415
416 spec->channel_mode = preset->channel_mode;
417 spec->num_channel_mode = preset->num_channel_mode;
418 spec->need_dac_fix = preset->need_dac_fix;
419 spec->const_channel_count = preset->const_channel_count;
420
421 if (preset->const_channel_count)
422 spec->multiout.max_channels = preset->const_channel_count;
423 else
424 spec->multiout.max_channels = spec->channel_mode[0].channels;
425 spec->ext_channel_count = spec->channel_mode[0].channels;
426
427 spec->multiout.num_dacs = preset->num_dacs;
428 spec->multiout.dac_nids = preset->dac_nids;
429 spec->multiout.dig_out_nid = preset->dig_out_nid;
430 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
431 spec->multiout.hp_nid = preset->hp_nid;
432
433 spec->num_mux_defs = preset->num_mux_defs;
434 if (!spec->num_mux_defs)
435 spec->num_mux_defs = 1;
436 spec->input_mux = preset->input_mux;
437
438 spec->num_adc_nids = preset->num_adc_nids;
439 spec->adc_nids = preset->adc_nids;
440 spec->capsrc_nids = preset->capsrc_nids;
441 spec->dig_in_nid = preset->dig_in_nid;
442
443 spec->unsol_event = preset->unsol_event;
444 spec->init_hook = preset->init_hook;
445#ifdef CONFIG_SND_HDA_POWER_SAVE
446 spec->power_hook = preset->power_hook;
447 spec->loopback.amplist = preset->loopbacks;
448#endif
449
450 if (preset->setup)
451 preset->setup(codec);
452
453 alc_fixup_autocfg_pin_nums(codec);
454}
455
456
457/* auto-toggle front mic */
458static void alc88x_simple_mic_automute(struct hda_codec *codec)
459{
460 unsigned int present;
461 unsigned char bits;
462
463 present = snd_hda_jack_detect(codec, 0x18);
464 bits = present ? HDA_AMP_MUTE : 0;
465 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
466}
467
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index f26e487eca1c..9c27a3a4c4d5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -243,7 +243,8 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
243{ 243{
244 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); 244 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
245 unsigned int res; 245 unsigned int res;
246 codec_exec_verb(codec, cmd, &res); 246 if (codec_exec_verb(codec, cmd, &res))
247 return -1;
247 return res; 248 return res;
248} 249}
249EXPORT_SYMBOL_HDA(snd_hda_codec_read); 250EXPORT_SYMBOL_HDA(snd_hda_codec_read);
@@ -307,63 +308,107 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
307} 308}
308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); 309EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
309 310
310static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 311/* look up the cached results */
311 hda_nid_t *conn_list, int max_conns); 312static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid)
312static bool add_conn_list(struct snd_array *array, hda_nid_t nid); 313{
313static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 314 int i, len;
314 hda_nid_t *src, int len); 315 for (i = 0; i < array->used; ) {
316 hda_nid_t *p = snd_array_elem(array, i);
317 if (nid == *p)
318 return p;
319 len = p[1];
320 i += len + 2;
321 }
322 return NULL;
323}
315 324
316/** 325/**
317 * snd_hda_get_connections - get connection list 326 * snd_hda_get_conn_list - get connection list
318 * @codec: the HDA codec 327 * @codec: the HDA codec
319 * @nid: NID to parse 328 * @nid: NID to parse
320 * @conn_list: connection list array 329 * @listp: the pointer to store NID list
321 * @max_conns: max. number of connections to store
322 * 330 *
323 * Parses the connection list of the given widget and stores the list 331 * Parses the connection list of the given widget and stores the list
324 * of NIDs. 332 * of NIDs.
325 * 333 *
326 * Returns the number of connections, or a negative error code. 334 * Returns the number of connections, or a negative error code.
327 */ 335 */
328int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 336int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
329 hda_nid_t *conn_list, int max_conns) 337 const hda_nid_t **listp)
330{ 338{
331 struct snd_array *array = &codec->conn_lists; 339 struct snd_array *array = &codec->conn_lists;
332 int i, len, old_used; 340 int len, err;
333 hda_nid_t list[HDA_MAX_CONNECTIONS]; 341 hda_nid_t list[HDA_MAX_CONNECTIONS];
342 hda_nid_t *p;
343 bool added = false;
334 344
335 /* look up the cached results */ 345 again:
336 for (i = 0; i < array->used; ) { 346 /* if the connection-list is already cached, read it */
337 hda_nid_t *p = snd_array_elem(array, i); 347 p = lookup_conn_list(array, nid);
338 len = p[1]; 348 if (p) {
339 if (nid == *p) 349 if (listp)
340 return copy_conn_list(nid, conn_list, max_conns, 350 *listp = p + 2;
341 p + 2, len); 351 return p[1];
342 i += len + 2;
343 } 352 }
353 if (snd_BUG_ON(added))
354 return -EINVAL;
344 355
345 len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); 356 /* read the connection and add to the cache */
357 len = snd_hda_get_raw_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
346 if (len < 0) 358 if (len < 0)
347 return len; 359 return len;
360 err = snd_hda_override_conn_list(codec, nid, len, list);
361 if (err < 0)
362 return err;
363 added = true;
364 goto again;
365}
366EXPORT_SYMBOL_HDA(snd_hda_get_conn_list);
348 367
349 /* add to the cache */ 368/**
350 old_used = array->used; 369 * snd_hda_get_connections - copy connection list
351 if (!add_conn_list(array, nid) || !add_conn_list(array, len)) 370 * @codec: the HDA codec
352 goto error_add; 371 * @nid: NID to parse
353 for (i = 0; i < len; i++) 372 * @conn_list: connection list array
354 if (!add_conn_list(array, list[i])) 373 * @max_conns: max. number of connections to store
355 goto error_add; 374 *
375 * Parses the connection list of the given widget and stores the list
376 * of NIDs.
377 *
378 * Returns the number of connections, or a negative error code.
379 */
380int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
381 hda_nid_t *conn_list, int max_conns)
382{
383 const hda_nid_t *list;
384 int len = snd_hda_get_conn_list(codec, nid, &list);
356 385
357 return copy_conn_list(nid, conn_list, max_conns, list, len); 386 if (len <= 0)
358 387 return len;
359 error_add: 388 if (len > max_conns) {
360 array->used = old_used; 389 snd_printk(KERN_ERR "hda_codec: "
361 return -ENOMEM; 390 "Too many connections %d for NID 0x%x\n",
391 len, nid);
392 return -EINVAL;
393 }
394 memcpy(conn_list, list, len * sizeof(hda_nid_t));
395 return len;
362} 396}
363EXPORT_SYMBOL_HDA(snd_hda_get_connections); 397EXPORT_SYMBOL_HDA(snd_hda_get_connections);
364 398
365static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 399/**
366 hda_nid_t *conn_list, int max_conns) 400 * snd_hda_get_raw_connections - copy connection list without cache
401 * @codec: the HDA codec
402 * @nid: NID to parse
403 * @conn_list: connection list array
404 * @max_conns: max. number of connections to store
405 *
406 * Like snd_hda_get_connections(), copy the connection list but without
407 * checking through the connection-list cache.
408 * Currently called only from hda_proc.c, so not exported.
409 */
410int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
411 hda_nid_t *conn_list, int max_conns)
367{ 412{
368 unsigned int parm; 413 unsigned int parm;
369 int i, conn_len, conns; 414 int i, conn_len, conns;
@@ -376,11 +421,8 @@ static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
376 421
377 wcaps = get_wcaps(codec, nid); 422 wcaps = get_wcaps(codec, nid);
378 if (!(wcaps & AC_WCAP_CONN_LIST) && 423 if (!(wcaps & AC_WCAP_CONN_LIST) &&
379 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { 424 get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
380 snd_printk(KERN_WARNING "hda_codec: " 425 return 0;
381 "connection list not available for 0x%x\n", nid);
382 return -EINVAL;
383 }
384 426
385 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 427 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
386 if (parm & AC_CLIST_LONG) { 428 if (parm & AC_CLIST_LONG) {
@@ -470,18 +512,77 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
470 return true; 512 return true;
471} 513}
472 514
473static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 515/**
474 hda_nid_t *src, int len) 516 * snd_hda_override_conn_list - add/modify the connection-list to cache
517 * @codec: the HDA codec
518 * @nid: NID to parse
519 * @len: number of connection list entries
520 * @list: the list of connection entries
521 *
522 * Add or modify the given connection-list to the cache. If the corresponding
523 * cache already exists, invalidate it and append a new one.
524 *
525 * Returns zero or a negative error code.
526 */
527int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
528 const hda_nid_t *list)
529{
530 struct snd_array *array = &codec->conn_lists;
531 hda_nid_t *p;
532 int i, old_used;
533
534 p = lookup_conn_list(array, nid);
535 if (p)
536 *p = -1; /* invalidate the old entry */
537
538 old_used = array->used;
539 if (!add_conn_list(array, nid) || !add_conn_list(array, len))
540 goto error_add;
541 for (i = 0; i < len; i++)
542 if (!add_conn_list(array, list[i]))
543 goto error_add;
544 return 0;
545
546 error_add:
547 array->used = old_used;
548 return -ENOMEM;
549}
550EXPORT_SYMBOL_HDA(snd_hda_override_conn_list);
551
552/**
553 * snd_hda_get_conn_index - get the connection index of the given NID
554 * @codec: the HDA codec
555 * @mux: NID containing the list
556 * @nid: NID to select
557 * @recursive: 1 when searching NID recursively, otherwise 0
558 *
559 * Parses the connection list of the widget @mux and checks whether the
560 * widget @nid is present. If it is, return the connection index.
561 * Otherwise it returns -1.
562 */
563int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
564 hda_nid_t nid, int recursive)
475{ 565{
476 if (len > max_dst) { 566 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
477 snd_printk(KERN_ERR "hda_codec: " 567 int i, nums;
478 "Too many connections %d for NID 0x%x\n", 568
479 len, nid); 569 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
480 return -EINVAL; 570 for (i = 0; i < nums; i++)
571 if (conn[i] == nid)
572 return i;
573 if (!recursive)
574 return -1;
575 if (recursive > 5) {
576 snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
577 return -1;
481 } 578 }
482 memcpy(dst, src, len * sizeof(hda_nid_t)); 579 recursive++;
483 return len; 580 for (i = 0; i < nums; i++)
581 if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
582 return i;
583 return -1;
484} 584}
585EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
485 586
486/** 587/**
487 * snd_hda_queue_unsol_event - add an unsolicited event to queue 588 * snd_hda_queue_unsol_event - add an unsolicited event to queue
@@ -1083,6 +1184,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1083 snd_array_free(&codec->mixers); 1184 snd_array_free(&codec->mixers);
1084 snd_array_free(&codec->nids); 1185 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists); 1186 snd_array_free(&codec->conn_lists);
1187 snd_array_free(&codec->spdif_out);
1086 codec->bus->caddr_tbl[codec->addr] = NULL; 1188 codec->bus->caddr_tbl[codec->addr] = NULL;
1087 if (codec->patch_ops.free) 1189 if (codec->patch_ops.free)
1088 codec->patch_ops.free(codec); 1190 codec->patch_ops.free(codec);
@@ -1144,6 +1246,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1246 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1247 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); 1248 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1249 snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
1147 if (codec->bus->modelname) { 1250 if (codec->bus->modelname) {
1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1251 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1149 if (!codec->modelname) { 1252 if (!codec->modelname) {
@@ -2555,11 +2658,13 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2555 struct snd_ctl_elem_value *ucontrol) 2658 struct snd_ctl_elem_value *ucontrol)
2556{ 2659{
2557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2661 int idx = kcontrol->private_value;
2662 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2558 2663
2559 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff; 2664 ucontrol->value.iec958.status[0] = spdif->status & 0xff;
2560 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff; 2665 ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
2561 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff; 2666 ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
2562 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff; 2667 ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
2563 2668
2564 return 0; 2669 return 0;
2565} 2670}
@@ -2644,23 +2749,23 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2644 struct snd_ctl_elem_value *ucontrol) 2749 struct snd_ctl_elem_value *ucontrol)
2645{ 2750{
2646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2751 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2647 hda_nid_t nid = kcontrol->private_value; 2752 int idx = kcontrol->private_value;
2753 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2754 hda_nid_t nid = spdif->nid;
2648 unsigned short val; 2755 unsigned short val;
2649 int change; 2756 int change;
2650 2757
2651 mutex_lock(&codec->spdif_mutex); 2758 mutex_lock(&codec->spdif_mutex);
2652 codec->spdif_status = ucontrol->value.iec958.status[0] | 2759 spdif->status = ucontrol->value.iec958.status[0] |
2653 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 2760 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2654 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 2761 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2655 ((unsigned int)ucontrol->value.iec958.status[3] << 24); 2762 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2656 val = convert_from_spdif_status(codec->spdif_status); 2763 val = convert_from_spdif_status(spdif->status);
2657 val |= codec->spdif_ctls & 1; 2764 val |= spdif->ctls & 1;
2658 change = codec->spdif_ctls != val; 2765 change = spdif->ctls != val;
2659 codec->spdif_ctls = val; 2766 spdif->ctls = val;
2660 2767 if (change && nid != (u16)-1)
2661 if (change)
2662 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff); 2768 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
2663
2664 mutex_unlock(&codec->spdif_mutex); 2769 mutex_unlock(&codec->spdif_mutex);
2665 return change; 2770 return change;
2666} 2771}
@@ -2671,33 +2776,42 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2671 struct snd_ctl_elem_value *ucontrol) 2776 struct snd_ctl_elem_value *ucontrol)
2672{ 2777{
2673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2778 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2779 int idx = kcontrol->private_value;
2780 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2674 2781
2675 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; 2782 ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
2676 return 0; 2783 return 0;
2677} 2784}
2678 2785
2786static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
2787 int dig1, int dig2)
2788{
2789 set_dig_out_convert(codec, nid, dig1, dig2);
2790 /* unmute amp switch (if any) */
2791 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2792 (dig1 & AC_DIG1_ENABLE))
2793 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2794 HDA_AMP_MUTE, 0);
2795}
2796
2679static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, 2797static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2680 struct snd_ctl_elem_value *ucontrol) 2798 struct snd_ctl_elem_value *ucontrol)
2681{ 2799{
2682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2800 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2683 hda_nid_t nid = kcontrol->private_value; 2801 int idx = kcontrol->private_value;
2802 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2803 hda_nid_t nid = spdif->nid;
2684 unsigned short val; 2804 unsigned short val;
2685 int change; 2805 int change;
2686 2806
2687 mutex_lock(&codec->spdif_mutex); 2807 mutex_lock(&codec->spdif_mutex);
2688 val = codec->spdif_ctls & ~AC_DIG1_ENABLE; 2808 val = spdif->ctls & ~AC_DIG1_ENABLE;
2689 if (ucontrol->value.integer.value[0]) 2809 if (ucontrol->value.integer.value[0])
2690 val |= AC_DIG1_ENABLE; 2810 val |= AC_DIG1_ENABLE;
2691 change = codec->spdif_ctls != val; 2811 change = spdif->ctls != val;
2692 if (change) { 2812 spdif->ctls = val;
2693 codec->spdif_ctls = val; 2813 if (change && nid != (u16)-1)
2694 set_dig_out_convert(codec, nid, val & 0xff, -1); 2814 set_spdif_ctls(codec, nid, val & 0xff, -1);
2695 /* unmute amp switch (if any) */
2696 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2697 (val & AC_DIG1_ENABLE))
2698 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2699 HDA_AMP_MUTE, 0);
2700 }
2701 mutex_unlock(&codec->spdif_mutex); 2815 mutex_unlock(&codec->spdif_mutex);
2702 return change; 2816 return change;
2703} 2817}
@@ -2744,36 +2858,79 @@ static struct snd_kcontrol_new dig_mixes[] = {
2744 * 2858 *
2745 * Returns 0 if successful, or a negative error code. 2859 * Returns 0 if successful, or a negative error code.
2746 */ 2860 */
2747int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) 2861int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
2862 hda_nid_t associated_nid,
2863 hda_nid_t cvt_nid)
2748{ 2864{
2749 int err; 2865 int err;
2750 struct snd_kcontrol *kctl; 2866 struct snd_kcontrol *kctl;
2751 struct snd_kcontrol_new *dig_mix; 2867 struct snd_kcontrol_new *dig_mix;
2752 int idx; 2868 int idx;
2869 struct hda_spdif_out *spdif;
2753 2870
2754 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); 2871 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2755 if (idx < 0) { 2872 if (idx < 0) {
2756 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2873 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2757 return -EBUSY; 2874 return -EBUSY;
2758 } 2875 }
2876 spdif = snd_array_new(&codec->spdif_out);
2759 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 2877 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2760 kctl = snd_ctl_new1(dig_mix, codec); 2878 kctl = snd_ctl_new1(dig_mix, codec);
2761 if (!kctl) 2879 if (!kctl)
2762 return -ENOMEM; 2880 return -ENOMEM;
2763 kctl->id.index = idx; 2881 kctl->id.index = idx;
2764 kctl->private_value = nid; 2882 kctl->private_value = codec->spdif_out.used - 1;
2765 err = snd_hda_ctl_add(codec, nid, kctl); 2883 err = snd_hda_ctl_add(codec, associated_nid, kctl);
2766 if (err < 0) 2884 if (err < 0)
2767 return err; 2885 return err;
2768 } 2886 }
2769 codec->spdif_ctls = 2887 spdif->nid = cvt_nid;
2770 snd_hda_codec_read(codec, nid, 0, 2888 spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0,
2771 AC_VERB_GET_DIGI_CONVERT_1, 0); 2889 AC_VERB_GET_DIGI_CONVERT_1, 0);
2772 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 2890 spdif->status = convert_to_spdif_status(spdif->ctls);
2773 return 0; 2891 return 0;
2774} 2892}
2775EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); 2893EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
2776 2894
2895struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
2896 hda_nid_t nid)
2897{
2898 int i;
2899 for (i = 0; i < codec->spdif_out.used; i++) {
2900 struct hda_spdif_out *spdif =
2901 snd_array_elem(&codec->spdif_out, i);
2902 if (spdif->nid == nid)
2903 return spdif;
2904 }
2905 return NULL;
2906}
2907EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid);
2908
2909void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
2910{
2911 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2912
2913 mutex_lock(&codec->spdif_mutex);
2914 spdif->nid = (u16)-1;
2915 mutex_unlock(&codec->spdif_mutex);
2916}
2917EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign);
2918
2919void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
2920{
2921 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2922 unsigned short val;
2923
2924 mutex_lock(&codec->spdif_mutex);
2925 if (spdif->nid != nid) {
2926 spdif->nid = nid;
2927 val = spdif->ctls;
2928 set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
2929 }
2930 mutex_unlock(&codec->spdif_mutex);
2931}
2932EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_assign);
2933
2777/* 2934/*
2778 * SPDIF sharing with analog output 2935 * SPDIF sharing with analog output
2779 */ 2936 */
@@ -3356,7 +3513,7 @@ static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
3356 * 3513 *
3357 * Returns 0 if successful, otherwise a negative error code. 3514 * Returns 0 if successful, otherwise a negative error code.
3358 */ 3515 */
3359static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 3516int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3360 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 3517 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
3361{ 3518{
3362 unsigned int i, val, wcaps; 3519 unsigned int i, val, wcaps;
@@ -3448,6 +3605,7 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3448 3605
3449 return 0; 3606 return 0;
3450} 3607}
3608EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm);
3451 3609
3452/** 3610/**
3453 * snd_hda_is_supported_format - Check the validity of the format 3611 * snd_hda_is_supported_format - Check the validity of the format
@@ -4177,10 +4335,12 @@ EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
4177static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, 4335static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4178 unsigned int stream_tag, unsigned int format) 4336 unsigned int stream_tag, unsigned int format)
4179{ 4337{
4338 struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
4339
4180 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 4340 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
4181 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4341 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4182 set_dig_out_convert(codec, nid, 4342 set_dig_out_convert(codec, nid,
4183 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 4343 spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
4184 -1); 4344 -1);
4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4345 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4186 if (codec->slave_dig_outs) { 4346 if (codec->slave_dig_outs) {
@@ -4190,9 +4350,9 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4190 format); 4350 format);
4191 } 4351 }
4192 /* turn on again (if needed) */ 4352 /* turn on again (if needed) */
4193 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4353 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4194 set_dig_out_convert(codec, nid, 4354 set_dig_out_convert(codec, nid,
4195 codec->spdif_ctls & 0xff, -1); 4355 spdif->ctls & 0xff, -1);
4196} 4356}
4197 4357
4198static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) 4358static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
@@ -4348,6 +4508,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4348{ 4508{
4349 const hda_nid_t *nids = mout->dac_nids; 4509 const hda_nid_t *nids = mout->dac_nids;
4350 int chs = substream->runtime->channels; 4510 int chs = substream->runtime->channels;
4511 struct hda_spdif_out *spdif =
4512 snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
4351 int i; 4513 int i;
4352 4514
4353 mutex_lock(&codec->spdif_mutex); 4515 mutex_lock(&codec->spdif_mutex);
@@ -4356,7 +4518,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4356 if (chs == 2 && 4518 if (chs == 2 &&
4357 snd_hda_is_supported_format(codec, mout->dig_out_nid, 4519 snd_hda_is_supported_format(codec, mout->dig_out_nid,
4358 format) && 4520 format) &&
4359 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 4521 !(spdif->status & IEC958_AES0_NONAUDIO)) {
4360 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 4522 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
4361 setup_dig_out_stream(codec, mout->dig_out_nid, 4523 setup_dig_out_stream(codec, mout->dig_out_nid,
4362 stream_tag, format); 4524 stream_tag, format);
@@ -4528,7 +4690,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4528 unsigned int wid_caps = get_wcaps(codec, nid); 4690 unsigned int wid_caps = get_wcaps(codec, nid);
4529 unsigned int wid_type = get_wcaps_type(wid_caps); 4691 unsigned int wid_type = get_wcaps_type(wid_caps);
4530 unsigned int def_conf; 4692 unsigned int def_conf;
4531 short assoc, loc; 4693 short assoc, loc, conn, dev;
4532 4694
4533 /* read all default configuration for pin complex */ 4695 /* read all default configuration for pin complex */
4534 if (wid_type != AC_WID_PIN) 4696 if (wid_type != AC_WID_PIN)
@@ -4538,10 +4700,19 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4538 continue; 4700 continue;
4539 4701
4540 def_conf = snd_hda_codec_get_pincfg(codec, nid); 4702 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4541 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 4703 conn = get_defcfg_connect(def_conf);
4704 if (conn == AC_JACK_PORT_NONE)
4542 continue; 4705 continue;
4543 loc = get_defcfg_location(def_conf); 4706 loc = get_defcfg_location(def_conf);
4544 switch (get_defcfg_device(def_conf)) { 4707 dev = get_defcfg_device(def_conf);
4708
4709 /* workaround for buggy BIOS setups */
4710 if (dev == AC_JACK_LINE_OUT) {
4711 if (conn == AC_JACK_PORT_FIXED)
4712 dev = AC_JACK_SPEAKER;
4713 }
4714
4715 switch (dev) {
4545 case AC_JACK_LINE_OUT: 4716 case AC_JACK_LINE_OUT:
4546 seq = get_defcfg_sequence(def_conf); 4717 seq = get_defcfg_sequence(def_conf);
4547 assoc = get_defcfg_association(def_conf); 4718 assoc = get_defcfg_association(def_conf);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 59c97306c1de..f465e07a4879 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -829,8 +829,7 @@ struct hda_codec {
829 829
830 struct mutex spdif_mutex; 830 struct mutex spdif_mutex;
831 struct mutex control_mutex; 831 struct mutex control_mutex;
832 unsigned int spdif_status; /* IEC958 status bits */ 832 struct snd_array spdif_out;
833 unsigned short spdif_ctls; /* SPDIF control bits */
834 unsigned int spdif_in_enable; /* SPDIF input enable? */ 833 unsigned int spdif_in_enable; /* SPDIF input enable? */
835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 834 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
836 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 835 struct snd_array init_pins; /* initial (BIOS) pin configurations */
@@ -904,6 +903,16 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
904 hda_nid_t *start_id); 903 hda_nid_t *start_id);
905int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 904int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
906 hda_nid_t *conn_list, int max_conns); 905 hda_nid_t *conn_list, int max_conns);
906int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
907 hda_nid_t *conn_list, int max_conns);
908int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
909 const hda_nid_t **listp);
910int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
911 const hda_nid_t *list);
912int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
913 hda_nid_t nid, int recursive);
914int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
915 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
907 916
908struct hda_verb { 917struct hda_verb {
909 hda_nid_t nid; 918 hda_nid_t nid;
@@ -947,6 +956,17 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
947 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 956 hda_nid_t nid, unsigned int cfg); /* for hwdep */
948void snd_hda_shutup_pins(struct hda_codec *codec); 957void snd_hda_shutup_pins(struct hda_codec *codec);
949 958
959/* SPDIF controls */
960struct hda_spdif_out {
961 hda_nid_t nid; /* Converter nid values relate to */
962 unsigned int status; /* IEC958 status bits */
963 unsigned short ctls; /* SPDIF control bits */
964};
965struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
966 hda_nid_t nid);
967void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
968void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
969
950/* 970/*
951 * Mixer 971 * Mixer
952 */ 972 */
@@ -997,17 +1017,15 @@ int snd_hda_suspend(struct hda_bus *bus);
997int snd_hda_resume(struct hda_bus *bus); 1017int snd_hda_resume(struct hda_bus *bus);
998#endif 1018#endif
999 1019
1000#ifdef CONFIG_SND_HDA_POWER_SAVE
1001static inline 1020static inline
1002int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) 1021int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1003{ 1022{
1023#ifdef CONFIG_SND_HDA_POWER_SAVE
1004 if (codec->patch_ops.check_power_status) 1024 if (codec->patch_ops.check_power_status)
1005 return codec->patch_ops.check_power_status(codec, nid); 1025 return codec->patch_ops.check_power_status(codec, nid);
1026#endif
1006 return 0; 1027 return 0;
1007} 1028}
1008#else
1009#define hda_call_check_power_status(codec, nid) 0
1010#endif
1011 1029
1012/* 1030/*
1013 * get widget information 1031 * get widget information
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index e3e853153d14..28ce17d09c33 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -580,43 +580,45 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
580#endif /* CONFIG_PROC_FS */ 580#endif /* CONFIG_PROC_FS */
581 581
582/* update PCM info based on ELD */ 582/* update PCM info based on ELD */
583void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 583void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
584 struct hda_pcm_stream *codec_pars) 584 struct hda_pcm_stream *hinfo)
585{ 585{
586 u32 rates;
587 u64 formats;
588 unsigned int maxbps;
589 unsigned int channels_max;
586 int i; 590 int i;
587 591
588 /* assume basic audio support (the basic audio flag is not in ELD; 592 /* assume basic audio support (the basic audio flag is not in ELD;
589 * however, all audio capable sinks are required to support basic 593 * however, all audio capable sinks are required to support basic
590 * audio) */ 594 * audio) */
591 pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 595 rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
592 pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; 596 SNDRV_PCM_RATE_48000;
593 pcm->maxbps = 16; 597 formats = SNDRV_PCM_FMTBIT_S16_LE;
594 pcm->channels_max = 2; 598 maxbps = 16;
599 channels_max = 2;
595 for (i = 0; i < eld->sad_count; i++) { 600 for (i = 0; i < eld->sad_count; i++) {
596 struct cea_sad *a = &eld->sad[i]; 601 struct cea_sad *a = &eld->sad[i];
597 pcm->rates |= a->rates; 602 rates |= a->rates;
598 if (a->channels > pcm->channels_max) 603 if (a->channels > channels_max)
599 pcm->channels_max = a->channels; 604 channels_max = a->channels;
600 if (a->format == AUDIO_CODING_TYPE_LPCM) { 605 if (a->format == AUDIO_CODING_TYPE_LPCM) {
601 if (a->sample_bits & AC_SUPPCM_BITS_20) { 606 if (a->sample_bits & AC_SUPPCM_BITS_20) {
602 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 607 formats |= SNDRV_PCM_FMTBIT_S32_LE;
603 if (pcm->maxbps < 20) 608 if (maxbps < 20)
604 pcm->maxbps = 20; 609 maxbps = 20;
605 } 610 }
606 if (a->sample_bits & AC_SUPPCM_BITS_24) { 611 if (a->sample_bits & AC_SUPPCM_BITS_24) {
607 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 612 formats |= SNDRV_PCM_FMTBIT_S32_LE;
608 if (pcm->maxbps < 24) 613 if (maxbps < 24)
609 pcm->maxbps = 24; 614 maxbps = 24;
610 } 615 }
611 } 616 }
612 } 617 }
613 618
614 if (!codec_pars)
615 return;
616
617 /* restrict the parameters by the values the codec provides */ 619 /* restrict the parameters by the values the codec provides */
618 pcm->rates &= codec_pars->rates; 620 hinfo->rates &= rates;
619 pcm->formats &= codec_pars->formats; 621 hinfo->formats &= formats;
620 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 622 hinfo->maxbps = min(hinfo->maxbps, maxbps);
621 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 623 hinfo->channels_max = min(hinfo->channels_max, channels_max);
622} 624}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 5cc3d07f715f..be6982289c0d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -177,7 +177,8 @@ MODULE_DESCRIPTION("Intel HDA driver");
177#define ICH6_REG_INTCTL 0x20 177#define ICH6_REG_INTCTL 0x20
178#define ICH6_REG_INTSTS 0x24 178#define ICH6_REG_INTSTS 0x24
179#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */ 179#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
180#define ICH6_REG_SYNC 0x34 180#define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */
181#define ICH6_REG_SSYNC 0x38
181#define ICH6_REG_CORBLBASE 0x40 182#define ICH6_REG_CORBLBASE 0x40
182#define ICH6_REG_CORBUBASE 0x44 183#define ICH6_REG_CORBUBASE 0x44
183#define ICH6_REG_CORBWP 0x48 184#define ICH6_REG_CORBWP 0x48
@@ -479,6 +480,7 @@ enum {
479#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ 480#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
480#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ 481#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
481#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 482#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
483#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
482 484
483/* quirks for ATI SB / AMD Hudson */ 485/* quirks for ATI SB / AMD Hudson */
484#define AZX_DCAPS_PRESET_ATI_SB \ 486#define AZX_DCAPS_PRESET_ATI_SB \
@@ -1706,13 +1708,16 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1706 struct snd_pcm_runtime *runtime = substream->runtime; 1708 struct snd_pcm_runtime *runtime = substream->runtime;
1707 unsigned int bufsize, period_bytes, format_val, stream_tag; 1709 unsigned int bufsize, period_bytes, format_val, stream_tag;
1708 int err; 1710 int err;
1711 struct hda_spdif_out *spdif =
1712 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
1713 unsigned short ctls = spdif ? spdif->ctls : 0;
1709 1714
1710 azx_stream_reset(chip, azx_dev); 1715 azx_stream_reset(chip, azx_dev);
1711 format_val = snd_hda_calc_stream_format(runtime->rate, 1716 format_val = snd_hda_calc_stream_format(runtime->rate,
1712 runtime->channels, 1717 runtime->channels,
1713 runtime->format, 1718 runtime->format,
1714 hinfo->maxbps, 1719 hinfo->maxbps,
1715 apcm->codec->spdif_ctls); 1720 ctls);
1716 if (!format_val) { 1721 if (!format_val) {
1717 snd_printk(KERN_ERR SFX 1722 snd_printk(KERN_ERR SFX
1718 "invalid format_val, rate=%d, ch=%d, format=%d\n", 1723 "invalid format_val, rate=%d, ch=%d, format=%d\n",
@@ -1792,7 +1797,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1792 spin_lock(&chip->reg_lock); 1797 spin_lock(&chip->reg_lock);
1793 if (nsync > 1) { 1798 if (nsync > 1) {
1794 /* first, set SYNC bits of corresponding streams */ 1799 /* first, set SYNC bits of corresponding streams */
1795 azx_writel(chip, SYNC, azx_readl(chip, SYNC) | sbits); 1800 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1801 azx_writel(chip, OLD_SSYNC,
1802 azx_readl(chip, OLD_SSYNC) | sbits);
1803 else
1804 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
1796 } 1805 }
1797 snd_pcm_group_for_each_entry(s, substream) { 1806 snd_pcm_group_for_each_entry(s, substream) {
1798 if (s->pcm->card != substream->pcm->card) 1807 if (s->pcm->card != substream->pcm->card)
@@ -1848,7 +1857,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1848 if (nsync > 1) { 1857 if (nsync > 1) {
1849 spin_lock(&chip->reg_lock); 1858 spin_lock(&chip->reg_lock);
1850 /* reset SYNC bits */ 1859 /* reset SYNC bits */
1851 azx_writel(chip, SYNC, azx_readl(chip, SYNC) & ~sbits); 1860 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1861 azx_writel(chip, OLD_SSYNC,
1862 azx_readl(chip, OLD_SSYNC) & ~sbits);
1863 else
1864 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
1852 spin_unlock(&chip->reg_lock); 1865 spin_unlock(&chip->reg_lock);
1853 } 1866 }
1854 return 0; 1867 return 0;
@@ -1863,7 +1876,7 @@ static unsigned int azx_via_get_position(struct azx *chip,
1863 unsigned int fifo_size; 1876 unsigned int fifo_size;
1864 1877
1865 link_pos = azx_sd_readl(azx_dev, SD_LPIB); 1878 link_pos = azx_sd_readl(azx_dev, SD_LPIB);
1866 if (azx_dev->index >= 4) { 1879 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1867 /* Playback, no problem using link position */ 1880 /* Playback, no problem using link position */
1868 return link_pos; 1881 return link_pos;
1869 } 1882 }
@@ -1927,6 +1940,17 @@ static unsigned int azx_get_position(struct azx *chip,
1927 default: 1940 default:
1928 /* use the position buffer */ 1941 /* use the position buffer */
1929 pos = le32_to_cpu(*azx_dev->posbuf); 1942 pos = le32_to_cpu(*azx_dev->posbuf);
1943 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1944 if (!pos || pos == (u32)-1) {
1945 printk(KERN_WARNING
1946 "hda-intel: Invalid position buffer, "
1947 "using LPIB read method instead.\n");
1948 chip->position_fix[stream] = POS_FIX_LPIB;
1949 pos = azx_sd_readl(azx_dev, SD_LPIB);
1950 } else
1951 chip->position_fix[stream] = POS_FIX_POSBUF;
1952 }
1953 break;
1930 } 1954 }
1931 1955
1932 if (pos >= azx_dev->bufsize) 1956 if (pos >= azx_dev->bufsize)
@@ -1964,16 +1988,6 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1964 1988
1965 stream = azx_dev->substream->stream; 1989 stream = azx_dev->substream->stream;
1966 pos = azx_get_position(chip, azx_dev); 1990 pos = azx_get_position(chip, azx_dev);
1967 if (chip->position_fix[stream] == POS_FIX_AUTO) {
1968 if (!pos) {
1969 printk(KERN_WARNING
1970 "hda-intel: Invalid position buffer, "
1971 "using LPIB read method instead.\n");
1972 chip->position_fix[stream] = POS_FIX_LPIB;
1973 pos = azx_get_position(chip, azx_dev);
1974 } else
1975 chip->position_fix[stream] = POS_FIX_POSBUF;
1976 }
1977 1991
1978 if (WARN_ONCE(!azx_dev->period_bytes, 1992 if (WARN_ONCE(!azx_dev->period_bytes,
1979 "hda-intel: zero azx_dev->period_bytes")) 1993 "hda-intel: zero azx_dev->period_bytes"))
@@ -2061,6 +2075,8 @@ static void azx_pcm_free(struct snd_pcm *pcm)
2061 } 2075 }
2062} 2076}
2063 2077
2078#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
2079
2064static int 2080static int
2065azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, 2081azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2066 struct hda_pcm *cpcm) 2082 struct hda_pcm *cpcm)
@@ -2069,6 +2085,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2069 struct snd_pcm *pcm; 2085 struct snd_pcm *pcm;
2070 struct azx_pcm *apcm; 2086 struct azx_pcm *apcm;
2071 int pcm_dev = cpcm->device; 2087 int pcm_dev = cpcm->device;
2088 unsigned int size;
2072 int s, err; 2089 int s, err;
2073 2090
2074 if (pcm_dev >= HDA_MAX_PCMS) { 2091 if (pcm_dev >= HDA_MAX_PCMS) {
@@ -2104,9 +2121,12 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2104 snd_pcm_set_ops(pcm, s, &azx_pcm_ops); 2121 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
2105 } 2122 }
2106 /* buffer pre-allocation */ 2123 /* buffer pre-allocation */
2124 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
2125 if (size > MAX_PREALLOC_SIZE)
2126 size = MAX_PREALLOC_SIZE;
2107 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 2127 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
2108 snd_dma_pci_data(chip->pci), 2128 snd_dma_pci_data(chip->pci),
2109 1024 * 64, 32 * 1024 * 1024); 2129 size, MAX_PREALLOC_SIZE);
2110 return 0; 2130 return 0;
2111} 2131}
2112 2132
@@ -2347,28 +2367,20 @@ static int azx_dev_free(struct snd_device *device)
2347 * white/black-listing for position_fix 2367 * white/black-listing for position_fix
2348 */ 2368 */
2349static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2369static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2350 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
2351 SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
2352 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2370 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2353 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2371 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2354 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2355 SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
2356 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2372 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2357 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2373 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2358 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2374 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2359 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), 2375 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2360 SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB),
2361 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2376 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2362 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2377 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2363 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB),
2364 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), 2378 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
2365 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), 2379 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
2366 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2380 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2367 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2368 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), 2381 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2369 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), 2382 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
2370 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), 2383 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2371 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2372 {} 2384 {}
2373}; 2385};
2374 2386
@@ -2815,6 +2827,22 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2815 /* SCH */ 2827 /* SCH */
2816 { PCI_DEVICE(0x8086, 0x811b), 2828 { PCI_DEVICE(0x8086, 0x811b),
2817 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, 2829 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
2830 { PCI_DEVICE(0x8086, 0x2668),
2831 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */
2832 { PCI_DEVICE(0x8086, 0x27d8),
2833 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */
2834 { PCI_DEVICE(0x8086, 0x269a),
2835 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */
2836 { PCI_DEVICE(0x8086, 0x284b),
2837 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */
2838 { PCI_DEVICE(0x8086, 0x293e),
2839 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
2840 { PCI_DEVICE(0x8086, 0x293f),
2841 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
2842 { PCI_DEVICE(0x8086, 0x3a3e),
2843 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
2844 { PCI_DEVICE(0x8086, 0x3a6e),
2845 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
2818 /* Generic Intel */ 2846 /* Generic Intel */
2819 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), 2847 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2820 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2848 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 08ec073444e2..88b277e97409 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -212,7 +212,9 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
212/* 212/*
213 * SPDIF I/O 213 * SPDIF I/O
214 */ 214 */
215int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); 215int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
216 hda_nid_t associated_nid,
217 hda_nid_t cvt_nid);
216int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); 218int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
217 219
218/* 220/*
@@ -563,7 +565,6 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
563 * power-management 565 * power-management
564 */ 566 */
565 567
566#ifdef CONFIG_SND_HDA_POWER_SAVE
567void snd_hda_schedule_power_save(struct hda_codec *codec); 568void snd_hda_schedule_power_save(struct hda_codec *codec);
568 569
569struct hda_amp_list { 570struct hda_amp_list {
@@ -580,7 +581,6 @@ struct hda_loopback_check {
580int snd_hda_check_amp_list_power(struct hda_codec *codec, 581int snd_hda_check_amp_list_power(struct hda_codec *codec,
581 struct hda_loopback_check *check, 582 struct hda_loopback_check *check,
582 hda_nid_t nid); 583 hda_nid_t nid);
583#endif /* CONFIG_SND_HDA_POWER_SAVE */
584 584
585/* 585/*
586 * AMP control callbacks 586 * AMP control callbacks
@@ -639,8 +639,8 @@ struct hdmi_eld {
639int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 639int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
640int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t); 640int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
641void snd_hdmi_show_eld(struct hdmi_eld *eld); 641void snd_hdmi_show_eld(struct hdmi_eld *eld);
642void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 642void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
643 struct hda_pcm_stream *codec_pars); 643 struct hda_pcm_stream *hinfo);
644 644
645#ifdef CONFIG_PROC_FS 645#ifdef CONFIG_PROC_FS
646int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, 646int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index bfe74c2fb079..2be57b051aa2 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -636,7 +636,7 @@ static void print_codec_info(struct snd_info_entry *entry,
636 wid_caps |= AC_WCAP_CONN_LIST; 636 wid_caps |= AC_WCAP_CONN_LIST;
637 637
638 if (wid_caps & AC_WCAP_CONN_LIST) 638 if (wid_caps & AC_WCAP_CONN_LIST)
639 conn_len = snd_hda_get_connections(codec, nid, conn, 639 conn_len = snd_hda_get_raw_connections(codec, nid, conn,
640 HDA_MAX_CONNECTIONS); 640 HDA_MAX_CONNECTIONS);
641 641
642 if (wid_caps & AC_WCAP_IN_AMP) { 642 if (wid_caps & AC_WCAP_IN_AMP) {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d694e9d4921d..1362c8ba4d1f 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -213,7 +213,9 @@ static int ad198x_build_controls(struct hda_codec *codec)
213 return err; 213 return err;
214 } 214 }
215 if (spec->multiout.dig_out_nid) { 215 if (spec->multiout.dig_out_nid) {
216 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 216 err = snd_hda_create_spdif_out_ctls(codec,
217 spec->multiout.dig_out_nid,
218 spec->multiout.dig_out_nid);
217 if (err < 0) 219 if (err < 0)
218 return err; 220 return err;
219 err = snd_hda_create_spdif_share_sw(codec, 221 err = snd_hda_create_spdif_share_sw(codec,
@@ -1920,7 +1922,8 @@ static int patch_ad1981(struct hda_codec *codec)
1920 spec->mixers[0] = ad1981_hp_mixers; 1922 spec->mixers[0] = ad1981_hp_mixers;
1921 spec->num_init_verbs = 2; 1923 spec->num_init_verbs = 2;
1922 spec->init_verbs[1] = ad1981_hp_init_verbs; 1924 spec->init_verbs[1] = ad1981_hp_init_verbs;
1923 spec->multiout.dig_out_nid = 0; 1925 if (!is_jack_available(codec, 0x0a))
1926 spec->multiout.dig_out_nid = 0;
1924 spec->input_mux = &ad1981_hp_capture_source; 1927 spec->input_mux = &ad1981_hp_capture_source;
1925 1928
1926 codec->patch_ops.init = ad1981_hp_init; 1929 codec->patch_ops.init = ad1981_hp_init;
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 61b92634b161..6b406840846e 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -240,7 +240,8 @@ static int ca0110_build_controls(struct hda_codec *codec)
240 } 240 }
241 241
242 if (spec->dig_out) { 242 if (spec->dig_out) {
243 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out); 243 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
244 spec->dig_out);
244 if (err < 0) 245 if (err < 0)
245 return err; 246 return err;
246 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 247 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
new file mode 100644
index 000000000000..d9a2254ceef6
--- /dev/null
+++ b/sound/pci/hda/patch_ca0132.c
@@ -0,0 +1,1097 @@
1/*
2 * HD audio interface patch for Creative CA0132 chip
3 *
4 * Copyright (c) 2011, Creative Technology Ltd.
5 *
6 * Based on patch_ca0110.c
7 * Copyright (c) 2008 Takashi Iwai <tiwai@suse.de>
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/pci.h>
28#include <linux/mutex.h>
29#include <sound/core.h>
30#include "hda_codec.h"
31#include "hda_local.h"
32
33#define WIDGET_CHIP_CTRL 0x15
34#define WIDGET_DSP_CTRL 0x16
35
36#define WUH_MEM_CONNID 10
37#define DSP_MEM_CONNID 16
38
39enum hda_cmd_vendor_io {
40 /* for DspIO node */
41 VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
42 VENDOR_DSPIO_SCP_WRITE_DATA_HIGH = 0x100,
43
44 VENDOR_DSPIO_STATUS = 0xF01,
45 VENDOR_DSPIO_SCP_POST_READ_DATA = 0x702,
46 VENDOR_DSPIO_SCP_READ_DATA = 0xF02,
47 VENDOR_DSPIO_DSP_INIT = 0x703,
48 VENDOR_DSPIO_SCP_POST_COUNT_QUERY = 0x704,
49 VENDOR_DSPIO_SCP_READ_COUNT = 0xF04,
50
51 /* for ChipIO node */
52 VENDOR_CHIPIO_ADDRESS_LOW = 0x000,
53 VENDOR_CHIPIO_ADDRESS_HIGH = 0x100,
54 VENDOR_CHIPIO_STREAM_FORMAT = 0x200,
55 VENDOR_CHIPIO_DATA_LOW = 0x300,
56 VENDOR_CHIPIO_DATA_HIGH = 0x400,
57
58 VENDOR_CHIPIO_GET_PARAMETER = 0xF00,
59 VENDOR_CHIPIO_STATUS = 0xF01,
60 VENDOR_CHIPIO_HIC_POST_READ = 0x702,
61 VENDOR_CHIPIO_HIC_READ_DATA = 0xF03,
62
63 VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE = 0x70A,
64
65 VENDOR_CHIPIO_PLL_PMU_WRITE = 0x70C,
66 VENDOR_CHIPIO_PLL_PMU_READ = 0xF0C,
67 VENDOR_CHIPIO_8051_ADDRESS_LOW = 0x70D,
68 VENDOR_CHIPIO_8051_ADDRESS_HIGH = 0x70E,
69 VENDOR_CHIPIO_FLAG_SET = 0x70F,
70 VENDOR_CHIPIO_FLAGS_GET = 0xF0F,
71 VENDOR_CHIPIO_PARAMETER_SET = 0x710,
72 VENDOR_CHIPIO_PARAMETER_GET = 0xF10,
73
74 VENDOR_CHIPIO_PORT_ALLOC_CONFIG_SET = 0x711,
75 VENDOR_CHIPIO_PORT_ALLOC_SET = 0x712,
76 VENDOR_CHIPIO_PORT_ALLOC_GET = 0xF12,
77 VENDOR_CHIPIO_PORT_FREE_SET = 0x713,
78
79 VENDOR_CHIPIO_PARAMETER_EX_ID_GET = 0xF17,
80 VENDOR_CHIPIO_PARAMETER_EX_ID_SET = 0x717,
81 VENDOR_CHIPIO_PARAMETER_EX_VALUE_GET = 0xF18,
82 VENDOR_CHIPIO_PARAMETER_EX_VALUE_SET = 0x718
83};
84
85/*
86 * Control flag IDs
87 */
88enum control_flag_id {
89 /* Connection manager stream setup is bypassed/enabled */
90 CONTROL_FLAG_C_MGR = 0,
91 /* DSP DMA is bypassed/enabled */
92 CONTROL_FLAG_DMA = 1,
93 /* 8051 'idle' mode is disabled/enabled */
94 CONTROL_FLAG_IDLE_ENABLE = 2,
95 /* Tracker for the SPDIF-in path is bypassed/enabled */
96 CONTROL_FLAG_TRACKER = 3,
97 /* DigitalOut to Spdif2Out connection is disabled/enabled */
98 CONTROL_FLAG_SPDIF2OUT = 4,
99 /* Digital Microphone is disabled/enabled */
100 CONTROL_FLAG_DMIC = 5,
101 /* ADC_B rate is 48 kHz/96 kHz */
102 CONTROL_FLAG_ADC_B_96KHZ = 6,
103 /* ADC_C rate is 48 kHz/96 kHz */
104 CONTROL_FLAG_ADC_C_96KHZ = 7,
105 /* DAC rate is 48 kHz/96 kHz (affects all DACs) */
106 CONTROL_FLAG_DAC_96KHZ = 8,
107 /* DSP rate is 48 kHz/96 kHz */
108 CONTROL_FLAG_DSP_96KHZ = 9,
109 /* SRC clock is 98 MHz/196 MHz (196 MHz forces rate to 96 KHz) */
110 CONTROL_FLAG_SRC_CLOCK_196MHZ = 10,
111 /* SRC rate is 48 kHz/96 kHz (48 kHz disabled when clock is 196 MHz) */
112 CONTROL_FLAG_SRC_RATE_96KHZ = 11,
113 /* Decode Loop (DSP->SRC->DSP) is disabled/enabled */
114 CONTROL_FLAG_DECODE_LOOP = 12,
115 /* De-emphasis filter on DAC-1 disabled/enabled */
116 CONTROL_FLAG_DAC1_DEEMPHASIS = 13,
117 /* De-emphasis filter on DAC-2 disabled/enabled */
118 CONTROL_FLAG_DAC2_DEEMPHASIS = 14,
119 /* De-emphasis filter on DAC-3 disabled/enabled */
120 CONTROL_FLAG_DAC3_DEEMPHASIS = 15,
121 /* High-pass filter on ADC_B disabled/enabled */
122 CONTROL_FLAG_ADC_B_HIGH_PASS = 16,
123 /* High-pass filter on ADC_C disabled/enabled */
124 CONTROL_FLAG_ADC_C_HIGH_PASS = 17,
125 /* Common mode on Port_A disabled/enabled */
126 CONTROL_FLAG_PORT_A_COMMON_MODE = 18,
127 /* Common mode on Port_D disabled/enabled */
128 CONTROL_FLAG_PORT_D_COMMON_MODE = 19,
129 /* Impedance for ramp generator on Port_A 16 Ohm/10K Ohm */
130 CONTROL_FLAG_PORT_A_10KOHM_LOAD = 20,
131 /* Impedance for ramp generator on Port_D, 16 Ohm/10K Ohm */
132 CONTROL_FLAG_PORT_D_10K0HM_LOAD = 21,
133 /* ASI rate is 48kHz/96kHz */
134 CONTROL_FLAG_ASI_96KHZ = 22,
135 /* DAC power settings able to control attached ports no/yes */
136 CONTROL_FLAG_DACS_CONTROL_PORTS = 23,
137 /* Clock Stop OK reporting is disabled/enabled */
138 CONTROL_FLAG_CONTROL_STOP_OK_ENABLE = 24,
139 /* Number of control flags */
140 CONTROL_FLAGS_MAX = (CONTROL_FLAG_CONTROL_STOP_OK_ENABLE+1)
141};
142
143/*
144 * Control parameter IDs
145 */
146enum control_parameter_id {
147 /* 0: force HDA, 1: allow DSP if HDA Spdif1Out stream is idle */
148 CONTROL_PARAM_SPDIF1_SOURCE = 2,
149
150 /* Stream Control */
151
152 /* Select stream with the given ID */
153 CONTROL_PARAM_STREAM_ID = 24,
154 /* Source connection point for the selected stream */
155 CONTROL_PARAM_STREAM_SOURCE_CONN_POINT = 25,
156 /* Destination connection point for the selected stream */
157 CONTROL_PARAM_STREAM_DEST_CONN_POINT = 26,
158 /* Number of audio channels in the selected stream */
159 CONTROL_PARAM_STREAMS_CHANNELS = 27,
160 /*Enable control for the selected stream */
161 CONTROL_PARAM_STREAM_CONTROL = 28,
162
163 /* Connection Point Control */
164
165 /* Select connection point with the given ID */
166 CONTROL_PARAM_CONN_POINT_ID = 29,
167 /* Connection point sample rate */
168 CONTROL_PARAM_CONN_POINT_SAMPLE_RATE = 30,
169
170 /* Node Control */
171
172 /* Select HDA node with the given ID */
173 CONTROL_PARAM_NODE_ID = 31
174};
175
176/*
177 * Dsp Io Status codes
178 */
179enum hda_vendor_status_dspio {
180 /* Success */
181 VENDOR_STATUS_DSPIO_OK = 0x00,
182 /* Busy, unable to accept new command, the host must retry */
183 VENDOR_STATUS_DSPIO_BUSY = 0x01,
184 /* SCP command queue is full */
185 VENDOR_STATUS_DSPIO_SCP_COMMAND_QUEUE_FULL = 0x02,
186 /* SCP response queue is empty */
187 VENDOR_STATUS_DSPIO_SCP_RESPONSE_QUEUE_EMPTY = 0x03
188};
189
190/*
191 * Chip Io Status codes
192 */
193enum hda_vendor_status_chipio {
194 /* Success */
195 VENDOR_STATUS_CHIPIO_OK = 0x00,
196 /* Busy, unable to accept new command, the host must retry */
197 VENDOR_STATUS_CHIPIO_BUSY = 0x01
198};
199
200/*
201 * CA0132 sample rate
202 */
203enum ca0132_sample_rate {
204 SR_6_000 = 0x00,
205 SR_8_000 = 0x01,
206 SR_9_600 = 0x02,
207 SR_11_025 = 0x03,
208 SR_16_000 = 0x04,
209 SR_22_050 = 0x05,
210 SR_24_000 = 0x06,
211 SR_32_000 = 0x07,
212 SR_44_100 = 0x08,
213 SR_48_000 = 0x09,
214 SR_88_200 = 0x0A,
215 SR_96_000 = 0x0B,
216 SR_144_000 = 0x0C,
217 SR_176_400 = 0x0D,
218 SR_192_000 = 0x0E,
219 SR_384_000 = 0x0F,
220
221 SR_COUNT = 0x10,
222
223 SR_RATE_UNKNOWN = 0x1F
224};
225
226/*
227 * Scp Helper function
228 */
229enum get_set {
230 IS_SET = 0,
231 IS_GET = 1,
232};
233
234/*
235 * Duplicated from ca0110 codec
236 */
237
238static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac)
239{
240 if (pin) {
241 snd_hda_codec_write(codec, pin, 0,
242 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
243 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
244 snd_hda_codec_write(codec, pin, 0,
245 AC_VERB_SET_AMP_GAIN_MUTE,
246 AMP_OUT_UNMUTE);
247 }
248 if (dac)
249 snd_hda_codec_write(codec, dac, 0,
250 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO);
251}
252
253static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc)
254{
255 if (pin) {
256 snd_hda_codec_write(codec, pin, 0,
257 AC_VERB_SET_PIN_WIDGET_CONTROL,
258 PIN_VREF80);
259 if (get_wcaps(codec, pin) & AC_WCAP_IN_AMP)
260 snd_hda_codec_write(codec, pin, 0,
261 AC_VERB_SET_AMP_GAIN_MUTE,
262 AMP_IN_UNMUTE(0));
263 }
264 if (adc)
265 snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE,
266 AMP_IN_UNMUTE(0));
267}
268
269static char *dirstr[2] = { "Playback", "Capture" };
270
271static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
272 int chan, int dir)
273{
274 char namestr[44];
275 int type = dir ? HDA_INPUT : HDA_OUTPUT;
276 struct snd_kcontrol_new knew =
277 HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type);
278 sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
279 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
280}
281
282static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx,
283 int chan, int dir)
284{
285 char namestr[44];
286 int type = dir ? HDA_INPUT : HDA_OUTPUT;
287 struct snd_kcontrol_new knew =
288 HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type);
289 sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]);
290 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
291}
292
293#define add_out_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 0)
294#define add_out_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 0)
295#define add_in_switch(codec, nid, pfx) _add_switch(codec, nid, pfx, 3, 1)
296#define add_in_volume(codec, nid, pfx) _add_volume(codec, nid, pfx, 3, 1)
297#define add_mono_switch(codec, nid, pfx, chan) \
298 _add_switch(codec, nid, pfx, chan, 0)
299#define add_mono_volume(codec, nid, pfx, chan) \
300 _add_volume(codec, nid, pfx, chan, 0)
301#define add_in_mono_switch(codec, nid, pfx, chan) \
302 _add_switch(codec, nid, pfx, chan, 1)
303#define add_in_mono_volume(codec, nid, pfx, chan) \
304 _add_volume(codec, nid, pfx, chan, 1)
305
306
307/*
308 * CA0132 specific
309 */
310
311struct ca0132_spec {
312 struct auto_pin_cfg autocfg;
313 struct hda_multi_out multiout;
314 hda_nid_t out_pins[AUTO_CFG_MAX_OUTS];
315 hda_nid_t dacs[AUTO_CFG_MAX_OUTS];
316 hda_nid_t hp_dac;
317 hda_nid_t input_pins[AUTO_PIN_LAST];
318 hda_nid_t adcs[AUTO_PIN_LAST];
319 hda_nid_t dig_out;
320 hda_nid_t dig_in;
321 unsigned int num_inputs;
322 long curr_hp_switch;
323 long curr_hp_volume[2];
324 long curr_speaker_switch;
325 struct mutex chipio_mutex;
326 const char *input_labels[AUTO_PIN_LAST];
327 struct hda_pcm pcm_rec[2]; /* PCM information */
328};
329
330/* Chip access helper function */
331static int chipio_send(struct hda_codec *codec,
332 unsigned int reg,
333 unsigned int data)
334{
335 unsigned int res;
336 int retry = 50;
337
338 /* send bits of data specified by reg */
339 do {
340 res = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
341 reg, data);
342 if (res == VENDOR_STATUS_CHIPIO_OK)
343 return 0;
344 } while (--retry);
345 return -EIO;
346}
347
348/*
349 * Write chip address through the vendor widget -- NOT protected by the Mutex!
350 */
351static int chipio_write_address(struct hda_codec *codec,
352 unsigned int chip_addx)
353{
354 int res;
355
356 /* send low 16 bits of the address */
357 res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_LOW,
358 chip_addx & 0xffff);
359
360 if (res != -EIO) {
361 /* send high 16 bits of the address */
362 res = chipio_send(codec, VENDOR_CHIPIO_ADDRESS_HIGH,
363 chip_addx >> 16);
364 }
365
366 return res;
367}
368
369/*
370 * Write data through the vendor widget -- NOT protected by the Mutex!
371 */
372
373static int chipio_write_data(struct hda_codec *codec, unsigned int data)
374{
375 int res;
376
377 /* send low 16 bits of the data */
378 res = chipio_send(codec, VENDOR_CHIPIO_DATA_LOW, data & 0xffff);
379
380 if (res != -EIO) {
381 /* send high 16 bits of the data */
382 res = chipio_send(codec, VENDOR_CHIPIO_DATA_HIGH,
383 data >> 16);
384 }
385
386 return res;
387}
388
389/*
390 * Read data through the vendor widget -- NOT protected by the Mutex!
391 */
392static int chipio_read_data(struct hda_codec *codec, unsigned int *data)
393{
394 int res;
395
396 /* post read */
397 res = chipio_send(codec, VENDOR_CHIPIO_HIC_POST_READ, 0);
398
399 if (res != -EIO) {
400 /* read status */
401 res = chipio_send(codec, VENDOR_CHIPIO_STATUS, 0);
402 }
403
404 if (res != -EIO) {
405 /* read data */
406 *data = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
407 VENDOR_CHIPIO_HIC_READ_DATA,
408 0);
409 }
410
411 return res;
412}
413
414/*
415 * Write given value to the given address through the chip I/O widget.
416 * protected by the Mutex
417 */
418static int chipio_write(struct hda_codec *codec,
419 unsigned int chip_addx, const unsigned int data)
420{
421 struct ca0132_spec *spec = codec->spec;
422 int err;
423
424 mutex_lock(&spec->chipio_mutex);
425
426 /* write the address, and if successful proceed to write data */
427 err = chipio_write_address(codec, chip_addx);
428 if (err < 0)
429 goto exit;
430
431 err = chipio_write_data(codec, data);
432 if (err < 0)
433 goto exit;
434
435exit:
436 mutex_unlock(&spec->chipio_mutex);
437 return err;
438}
439
440/*
441 * Read the given address through the chip I/O widget
442 * protected by the Mutex
443 */
444static int chipio_read(struct hda_codec *codec,
445 unsigned int chip_addx, unsigned int *data)
446{
447 struct ca0132_spec *spec = codec->spec;
448 int err;
449
450 mutex_lock(&spec->chipio_mutex);
451
452 /* write the address, and if successful proceed to write data */
453 err = chipio_write_address(codec, chip_addx);
454 if (err < 0)
455 goto exit;
456
457 err = chipio_read_data(codec, data);
458 if (err < 0)
459 goto exit;
460
461exit:
462 mutex_unlock(&spec->chipio_mutex);
463 return err;
464}
465
466/*
467 * PCM stuffs
468 */
469static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid,
470 u32 stream_tag,
471 int channel_id, int format)
472{
473 unsigned int oldval, newval;
474
475 if (!nid)
476 return;
477
478 snd_printdd("ca0132_setup_stream: "
479 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
480 nid, stream_tag, channel_id, format);
481
482 /* update the format-id if changed */
483 oldval = snd_hda_codec_read(codec, nid, 0,
484 AC_VERB_GET_STREAM_FORMAT,
485 0);
486 if (oldval != format) {
487 msleep(20);
488 snd_hda_codec_write(codec, nid, 0,
489 AC_VERB_SET_STREAM_FORMAT,
490 format);
491 }
492
493 oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
494 newval = (stream_tag << 4) | channel_id;
495 if (oldval != newval) {
496 snd_hda_codec_write(codec, nid, 0,
497 AC_VERB_SET_CHANNEL_STREAMID,
498 newval);
499 }
500}
501
502static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
503{
504 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
505 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
506}
507
508/*
509 * PCM callbacks
510 */
511static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
512 struct hda_codec *codec,
513 unsigned int stream_tag,
514 unsigned int format,
515 struct snd_pcm_substream *substream)
516{
517 struct ca0132_spec *spec = codec->spec;
518
519 ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format);
520
521 return 0;
522}
523
524static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
525 struct hda_codec *codec,
526 struct snd_pcm_substream *substream)
527{
528 struct ca0132_spec *spec = codec->spec;
529
530 ca0132_cleanup_stream(codec, spec->dacs[0]);
531
532 return 0;
533}
534
535/*
536 * Digital out
537 */
538static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
539 struct hda_codec *codec,
540 unsigned int stream_tag,
541 unsigned int format,
542 struct snd_pcm_substream *substream)
543{
544 struct ca0132_spec *spec = codec->spec;
545
546 ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format);
547
548 return 0;
549}
550
551static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
552 struct hda_codec *codec,
553 struct snd_pcm_substream *substream)
554{
555 struct ca0132_spec *spec = codec->spec;
556
557 ca0132_cleanup_stream(codec, spec->dig_out);
558
559 return 0;
560}
561
562/*
563 * Analog capture
564 */
565static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
566 struct hda_codec *codec,
567 unsigned int stream_tag,
568 unsigned int format,
569 struct snd_pcm_substream *substream)
570{
571 struct ca0132_spec *spec = codec->spec;
572
573 ca0132_setup_stream(codec, spec->adcs[substream->number],
574 stream_tag, 0, format);
575
576 return 0;
577}
578
579static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
580 struct hda_codec *codec,
581 struct snd_pcm_substream *substream)
582{
583 struct ca0132_spec *spec = codec->spec;
584
585 ca0132_cleanup_stream(codec, spec->adcs[substream->number]);
586
587 return 0;
588}
589
590/*
591 * Digital capture
592 */
593static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
594 struct hda_codec *codec,
595 unsigned int stream_tag,
596 unsigned int format,
597 struct snd_pcm_substream *substream)
598{
599 struct ca0132_spec *spec = codec->spec;
600
601 ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format);
602
603 return 0;
604}
605
606static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
607 struct hda_codec *codec,
608 struct snd_pcm_substream *substream)
609{
610 struct ca0132_spec *spec = codec->spec;
611
612 ca0132_cleanup_stream(codec, spec->dig_in);
613
614 return 0;
615}
616
617/*
618 */
619static struct hda_pcm_stream ca0132_pcm_analog_playback = {
620 .substreams = 1,
621 .channels_min = 2,
622 .channels_max = 2,
623 .ops = {
624 .prepare = ca0132_playback_pcm_prepare,
625 .cleanup = ca0132_playback_pcm_cleanup
626 },
627};
628
629static struct hda_pcm_stream ca0132_pcm_analog_capture = {
630 .substreams = 1,
631 .channels_min = 2,
632 .channels_max = 2,
633 .ops = {
634 .prepare = ca0132_capture_pcm_prepare,
635 .cleanup = ca0132_capture_pcm_cleanup
636 },
637};
638
639static struct hda_pcm_stream ca0132_pcm_digital_playback = {
640 .substreams = 1,
641 .channels_min = 2,
642 .channels_max = 2,
643 .ops = {
644 .prepare = ca0132_dig_playback_pcm_prepare,
645 .cleanup = ca0132_dig_playback_pcm_cleanup
646 },
647};
648
649static struct hda_pcm_stream ca0132_pcm_digital_capture = {
650 .substreams = 1,
651 .channels_min = 2,
652 .channels_max = 2,
653 .ops = {
654 .prepare = ca0132_dig_capture_pcm_prepare,
655 .cleanup = ca0132_dig_capture_pcm_cleanup
656 },
657};
658
659static int ca0132_build_pcms(struct hda_codec *codec)
660{
661 struct ca0132_spec *spec = codec->spec;
662 struct hda_pcm *info = spec->pcm_rec;
663
664 codec->pcm_info = info;
665 codec->num_pcms = 0;
666
667 info->name = "CA0132 Analog";
668 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
669 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
670 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
671 spec->multiout.max_channels;
672 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
673 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_inputs;
674 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
675 codec->num_pcms++;
676
677 if (!spec->dig_out && !spec->dig_in)
678 return 0;
679
680 info++;
681 info->name = "CA0132 Digital";
682 info->pcm_type = HDA_PCM_TYPE_SPDIF;
683 if (spec->dig_out) {
684 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
685 ca0132_pcm_digital_playback;
686 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dig_out;
687 }
688 if (spec->dig_in) {
689 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
690 ca0132_pcm_digital_capture;
691 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
692 }
693 codec->num_pcms++;
694
695 return 0;
696}
697
698#define REG_CODEC_MUTE 0x18b014
699#define REG_CODEC_HP_VOL_L 0x18b070
700#define REG_CODEC_HP_VOL_R 0x18b074
701
702static int ca0132_hp_switch_get(struct snd_kcontrol *kcontrol,
703 struct snd_ctl_elem_value *ucontrol)
704{
705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
706 struct ca0132_spec *spec = codec->spec;
707 long *valp = ucontrol->value.integer.value;
708
709 *valp = spec->curr_hp_switch;
710 return 0;
711}
712
713static int ca0132_hp_switch_put(struct snd_kcontrol *kcontrol,
714 struct snd_ctl_elem_value *ucontrol)
715{
716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
717 struct ca0132_spec *spec = codec->spec;
718 long *valp = ucontrol->value.integer.value;
719 unsigned int data;
720 int err;
721
722 /* any change? */
723 if (spec->curr_hp_switch == *valp)
724 return 0;
725
726 snd_hda_power_up(codec);
727
728 err = chipio_read(codec, REG_CODEC_MUTE, &data);
729 if (err < 0)
730 return err;
731
732 /* *valp 0 is mute, 1 is unmute */
733 data = (data & 0x7f) | (*valp ? 0 : 0x80);
734 chipio_write(codec, REG_CODEC_MUTE, data);
735 if (err < 0)
736 return err;
737
738 spec->curr_hp_switch = *valp;
739
740 snd_hda_power_down(codec);
741 return 1;
742}
743
744static int ca0132_speaker_switch_get(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
746{
747 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
748 struct ca0132_spec *spec = codec->spec;
749 long *valp = ucontrol->value.integer.value;
750
751 *valp = spec->curr_speaker_switch;
752 return 0;
753}
754
755static int ca0132_speaker_switch_put(struct snd_kcontrol *kcontrol,
756 struct snd_ctl_elem_value *ucontrol)
757{
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 struct ca0132_spec *spec = codec->spec;
760 long *valp = ucontrol->value.integer.value;
761 unsigned int data;
762 int err;
763
764 /* any change? */
765 if (spec->curr_speaker_switch == *valp)
766 return 0;
767
768 snd_hda_power_up(codec);
769
770 err = chipio_read(codec, REG_CODEC_MUTE, &data);
771 if (err < 0)
772 return err;
773
774 /* *valp 0 is mute, 1 is unmute */
775 data = (data & 0xef) | (*valp ? 0 : 0x10);
776 chipio_write(codec, REG_CODEC_MUTE, data);
777 if (err < 0)
778 return err;
779
780 spec->curr_speaker_switch = *valp;
781
782 snd_hda_power_down(codec);
783 return 1;
784}
785
786static int ca0132_hp_volume_get(struct snd_kcontrol *kcontrol,
787 struct snd_ctl_elem_value *ucontrol)
788{
789 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
790 struct ca0132_spec *spec = codec->spec;
791 long *valp = ucontrol->value.integer.value;
792
793 *valp++ = spec->curr_hp_volume[0];
794 *valp = spec->curr_hp_volume[1];
795 return 0;
796}
797
798static int ca0132_hp_volume_put(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
802 struct ca0132_spec *spec = codec->spec;
803 long *valp = ucontrol->value.integer.value;
804 long left_vol, right_vol;
805 unsigned int data;
806 int val;
807 int err;
808
809 left_vol = *valp++;
810 right_vol = *valp;
811
812 /* any change? */
813 if ((spec->curr_hp_volume[0] == left_vol) &&
814 (spec->curr_hp_volume[1] == right_vol))
815 return 0;
816
817 snd_hda_power_up(codec);
818
819 err = chipio_read(codec, REG_CODEC_HP_VOL_L, &data);
820 if (err < 0)
821 return err;
822
823 val = 31 - left_vol;
824 data = (data & 0xe0) | val;
825 chipio_write(codec, REG_CODEC_HP_VOL_L, data);
826 if (err < 0)
827 return err;
828
829 val = 31 - right_vol;
830 data = (data & 0xe0) | val;
831 chipio_write(codec, REG_CODEC_HP_VOL_R, data);
832 if (err < 0)
833 return err;
834
835 spec->curr_hp_volume[0] = left_vol;
836 spec->curr_hp_volume[1] = right_vol;
837
838 snd_hda_power_down(codec);
839 return 1;
840}
841
842static int add_hp_switch(struct hda_codec *codec, hda_nid_t nid)
843{
844 struct snd_kcontrol_new knew =
845 HDA_CODEC_MUTE_MONO("Headphone Playback Switch",
846 nid, 1, 0, HDA_OUTPUT);
847 knew.get = ca0132_hp_switch_get;
848 knew.put = ca0132_hp_switch_put;
849 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
850}
851
852static int add_hp_volume(struct hda_codec *codec, hda_nid_t nid)
853{
854 struct snd_kcontrol_new knew =
855 HDA_CODEC_VOLUME_MONO("Headphone Playback Volume",
856 nid, 3, 0, HDA_OUTPUT);
857 knew.get = ca0132_hp_volume_get;
858 knew.put = ca0132_hp_volume_put;
859 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
860}
861
862static int add_speaker_switch(struct hda_codec *codec, hda_nid_t nid)
863{
864 struct snd_kcontrol_new knew =
865 HDA_CODEC_MUTE_MONO("Speaker Playback Switch",
866 nid, 1, 0, HDA_OUTPUT);
867 knew.get = ca0132_speaker_switch_get;
868 knew.put = ca0132_speaker_switch_put;
869 return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
870}
871
872static void ca0132_fix_hp_caps(struct hda_codec *codec)
873{
874 struct ca0132_spec *spec = codec->spec;
875 struct auto_pin_cfg *cfg = &spec->autocfg;
876 unsigned int caps;
877
878 /* set mute-capable, 1db step, 32 steps, ofs 6 */
879 caps = 0x80031f06;
880 snd_hda_override_amp_caps(codec, cfg->hp_pins[0], HDA_OUTPUT, caps);
881}
882
883static int ca0132_build_controls(struct hda_codec *codec)
884{
885 struct ca0132_spec *spec = codec->spec;
886 struct auto_pin_cfg *cfg = &spec->autocfg;
887 int i, err;
888
889 if (spec->multiout.num_dacs) {
890 err = add_speaker_switch(codec, spec->out_pins[0]);
891 if (err < 0)
892 return err;
893 }
894
895 if (cfg->hp_outs) {
896 ca0132_fix_hp_caps(codec);
897 err = add_hp_switch(codec, cfg->hp_pins[0]);
898 if (err < 0)
899 return err;
900 err = add_hp_volume(codec, cfg->hp_pins[0]);
901 if (err < 0)
902 return err;
903 }
904
905 for (i = 0; i < spec->num_inputs; i++) {
906 const char *label = spec->input_labels[i];
907
908 err = add_in_switch(codec, spec->adcs[i], label);
909 if (err < 0)
910 return err;
911 err = add_in_volume(codec, spec->adcs[i], label);
912 if (err < 0)
913 return err;
914 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
915 /* add Mic-Boost */
916 err = add_in_mono_volume(codec, spec->input_pins[i],
917 "Mic Boost", 1);
918 if (err < 0)
919 return err;
920 }
921 }
922
923 if (spec->dig_out) {
924 err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
925 spec->dig_out);
926 if (err < 0)
927 return err;
928 err = add_out_volume(codec, spec->dig_out, "IEC958");
929 if (err < 0)
930 return err;
931 }
932
933 if (spec->dig_in) {
934 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
935 if (err < 0)
936 return err;
937 err = add_in_volume(codec, spec->dig_in, "IEC958");
938 }
939 return 0;
940}
941
942
943static void ca0132_set_ct_ext(struct hda_codec *codec, int enable)
944{
945 /* Set Creative extension */
946 snd_printdd("SET CREATIVE EXTENSION\n");
947 snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
948 VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE,
949 enable);
950 msleep(20);
951}
952
953
954static void ca0132_config(struct hda_codec *codec)
955{
956 struct ca0132_spec *spec = codec->spec;
957 struct auto_pin_cfg *cfg = &spec->autocfg;
958
959 /* line-outs */
960 cfg->line_outs = 1;
961 cfg->line_out_pins[0] = 0x0b; /* front */
962 cfg->line_out_type = AUTO_PIN_LINE_OUT;
963
964 spec->dacs[0] = 0x02;
965 spec->out_pins[0] = 0x0b;
966 spec->multiout.dac_nids = spec->dacs;
967 spec->multiout.num_dacs = 1;
968 spec->multiout.max_channels = 2;
969
970 /* headphone */
971 cfg->hp_outs = 1;
972 cfg->hp_pins[0] = 0x0f;
973
974 spec->hp_dac = 0;
975 spec->multiout.hp_nid = 0;
976
977 /* inputs */
978 cfg->num_inputs = 2; /* Mic-in and line-in */
979 cfg->inputs[0].pin = 0x12;
980 cfg->inputs[0].type = AUTO_PIN_MIC;
981 cfg->inputs[1].pin = 0x11;
982 cfg->inputs[1].type = AUTO_PIN_LINE_IN;
983
984 /* Mic-in */
985 spec->input_pins[0] = 0x12;
986 spec->input_labels[0] = "Mic-In";
987 spec->adcs[0] = 0x07;
988
989 /* Line-In */
990 spec->input_pins[1] = 0x11;
991 spec->input_labels[1] = "Line-In";
992 spec->adcs[1] = 0x08;
993 spec->num_inputs = 2;
994}
995
996static void ca0132_init_chip(struct hda_codec *codec)
997{
998 struct ca0132_spec *spec = codec->spec;
999
1000 mutex_init(&spec->chipio_mutex);
1001}
1002
1003static void ca0132_exit_chip(struct hda_codec *codec)
1004{
1005 /* put any chip cleanup stuffs here. */
1006}
1007
1008static int ca0132_init(struct hda_codec *codec)
1009{
1010 struct ca0132_spec *spec = codec->spec;
1011 struct auto_pin_cfg *cfg = &spec->autocfg;
1012 int i;
1013
1014 for (i = 0; i < spec->multiout.num_dacs; i++) {
1015 init_output(codec, spec->out_pins[i],
1016 spec->multiout.dac_nids[i]);
1017 }
1018 init_output(codec, cfg->hp_pins[0], spec->hp_dac);
1019 init_output(codec, cfg->dig_out_pins[0], spec->dig_out);
1020
1021 for (i = 0; i < spec->num_inputs; i++)
1022 init_input(codec, spec->input_pins[i], spec->adcs[i]);
1023
1024 init_input(codec, cfg->dig_in_pin, spec->dig_in);
1025
1026 ca0132_set_ct_ext(codec, 1);
1027
1028 return 0;
1029}
1030
1031
1032static void ca0132_free(struct hda_codec *codec)
1033{
1034 ca0132_set_ct_ext(codec, 0);
1035 ca0132_exit_chip(codec);
1036 kfree(codec->spec);
1037}
1038
1039static struct hda_codec_ops ca0132_patch_ops = {
1040 .build_controls = ca0132_build_controls,
1041 .build_pcms = ca0132_build_pcms,
1042 .init = ca0132_init,
1043 .free = ca0132_free,
1044};
1045
1046
1047
1048static int patch_ca0132(struct hda_codec *codec)
1049{
1050 struct ca0132_spec *spec;
1051
1052 snd_printdd("patch_ca0132\n");
1053
1054 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1055 if (!spec)
1056 return -ENOMEM;
1057 codec->spec = spec;
1058
1059 ca0132_init_chip(codec);
1060
1061 ca0132_config(codec);
1062
1063 codec->patch_ops = ca0132_patch_ops;
1064
1065 return 0;
1066}
1067
1068/*
1069 * patch entries
1070 */
1071static struct hda_codec_preset snd_hda_preset_ca0132[] = {
1072 { .id = 0x11020011, .name = "CA0132", .patch = patch_ca0132 },
1073 {} /* terminator */
1074};
1075
1076MODULE_ALIAS("snd-hda-codec-id:11020011");
1077
1078MODULE_LICENSE("GPL");
1079MODULE_DESCRIPTION("Creative CA0132, CA0132 HD-audio codec");
1080
1081static struct hda_codec_preset_list ca0132_list = {
1082 .preset = snd_hda_preset_ca0132,
1083 .owner = THIS_MODULE,
1084};
1085
1086static int __init patch_ca0132_init(void)
1087{
1088 return snd_hda_add_codec_preset(&ca0132_list);
1089}
1090
1091static void __exit patch_ca0132_exit(void)
1092{
1093 snd_hda_delete_codec_preset(&ca0132_list);
1094}
1095
1096module_init(patch_ca0132_init)
1097module_exit(patch_ca0132_exit)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 26a1521045bb..7f93739b1e33 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -346,21 +346,15 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
346 346
347 nid = codec->start_nid; 347 nid = codec->start_nid;
348 for (i = 0; i < codec->num_nodes; i++, nid++) { 348 for (i = 0; i < codec->num_nodes; i++, nid++) {
349 hda_nid_t pins[2];
350 unsigned int type; 349 unsigned int type;
351 int j, nums; 350 int idx;
352 type = get_wcaps_type(get_wcaps(codec, nid)); 351 type = get_wcaps_type(get_wcaps(codec, nid));
353 if (type != AC_WID_AUD_IN) 352 if (type != AC_WID_AUD_IN)
354 continue; 353 continue;
355 nums = snd_hda_get_connections(codec, nid, pins, 354 idx = snd_hda_get_conn_index(codec, nid, pin, 0);
356 ARRAY_SIZE(pins)); 355 if (idx >= 0) {
357 if (nums <= 0) 356 *idxp = idx;
358 continue; 357 return nid;
359 for (j = 0; j < nums; j++) {
360 if (pins[j] == pin) {
361 *idxp = j;
362 return nid;
363 }
364 } 358 }
365 } 359 }
366 return 0; 360 return 0;
@@ -821,7 +815,8 @@ static int build_digital_output(struct hda_codec *codec)
821 if (!spec->multiout.dig_out_nid) 815 if (!spec->multiout.dig_out_nid)
822 return 0; 816 return 0;
823 817
824 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 818 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid,
819 spec->multiout.dig_out_nid);
825 if (err < 0) 820 if (err < 0)
826 return err; 821 return err;
827 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 822 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index ab3308daa960..cd2cf5e94e81 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -327,7 +327,9 @@ static int cmi9880_build_controls(struct hda_codec *codec)
327 return err; 327 return err;
328 } 328 }
329 if (spec->multiout.dig_out_nid) { 329 if (spec->multiout.dig_out_nid) {
330 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 330 err = snd_hda_create_spdif_out_ctls(codec,
331 spec->multiout.dig_out_nid,
332 spec->multiout.dig_out_nid);
331 if (err < 0) 333 if (err < 0)
332 return err; 334 return err;
333 err = snd_hda_create_spdif_share_sw(codec, 335 err = snd_hda_create_spdif_share_sw(codec,
@@ -396,12 +398,11 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
396{ 398{
397 struct cmi_spec *spec = codec->spec; 399 struct cmi_spec *spec = codec->spec;
398 hda_nid_t nid; 400 hda_nid_t nid;
399 int i, j, k, len; 401 int i, j, k;
400 402
401 /* clear the table, only one c-media dac assumed here */ 403 /* clear the table, only one c-media dac assumed here */
402 memset(spec->multi_init, 0, sizeof(spec->multi_init)); 404 memset(spec->multi_init, 0, sizeof(spec->multi_init));
403 for (j = 0, i = 0; i < cfg->line_outs; i++) { 405 for (j = 0, i = 0; i < cfg->line_outs; i++) {
404 hda_nid_t conn[4];
405 nid = cfg->line_out_pins[i]; 406 nid = cfg->line_out_pins[i];
406 /* set as output */ 407 /* set as output */
407 spec->multi_init[j].nid = nid; 408 spec->multi_init[j].nid = nid;
@@ -414,12 +415,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
414 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; 415 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
415 spec->multi_init[j].param = 0; 416 spec->multi_init[j].param = 0;
416 /* find the index in connect list */ 417 /* find the index in connect list */
417 len = snd_hda_get_connections(codec, nid, conn, 4); 418 k = snd_hda_get_conn_index(codec, nid,
418 for (k = 0; k < len; k++) 419 spec->dac_nids[i], 0);
419 if (conn[k] == spec->dac_nids[i]) { 420 if (k >= 0)
420 spec->multi_init[j].param = k; 421 spec->multi_init[j].param = k;
421 break;
422 }
423 j++; 422 j++;
424 } 423 }
425 } 424 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7bbc5f237a5e..884f67b8f4e0 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -155,6 +155,10 @@ struct conexant_spec {
155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
156 156
157 unsigned int beep_amp; 157 unsigned int beep_amp;
158
159 /* extra EAPD pins */
160 unsigned int num_eapds;
161 hda_nid_t eapds[4];
158}; 162};
159 163
160static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 164static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -510,6 +514,7 @@ static int conexant_build_controls(struct hda_codec *codec)
510 } 514 }
511 if (spec->multiout.dig_out_nid) { 515 if (spec->multiout.dig_out_nid) {
512 err = snd_hda_create_spdif_out_ctls(codec, 516 err = snd_hda_create_spdif_out_ctls(codec,
517 spec->multiout.dig_out_nid,
513 spec->multiout.dig_out_nid); 518 spec->multiout.dig_out_nid);
514 if (err < 0) 519 if (err < 0)
515 return err; 520 return err;
@@ -1123,10 +1128,8 @@ static int patch_cxt5045(struct hda_codec *codec)
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, 1128 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models, 1129 cxt5045_models,
1125 cxt5045_cfg_tbl); 1130 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0) 1131 if (board_config < 0)
1128 board_config = CXT5045_AUTO; 1132 board_config = CXT5045_AUTO; /* model=auto as default */
1129#endif
1130 if (board_config == CXT5045_AUTO) 1133 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec); 1134 return patch_conexant_auto(codec);
1132 1135
@@ -1564,10 +1567,8 @@ static int patch_cxt5047(struct hda_codec *codec)
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, 1567 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models, 1568 cxt5047_models,
1566 cxt5047_cfg_tbl); 1569 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0) 1570 if (board_config < 0)
1569 board_config = CXT5047_AUTO; 1571 board_config = CXT5047_AUTO; /* model=auto as default */
1570#endif
1571 if (board_config == CXT5047_AUTO) 1572 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec); 1573 return patch_conexant_auto(codec);
1573 1574
@@ -1993,10 +1994,8 @@ static int patch_cxt5051(struct hda_codec *codec)
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1994 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models, 1995 cxt5051_models,
1995 cxt5051_cfg_tbl); 1996 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0) 1997 if (board_config < 0)
1998 board_config = CXT5051_AUTO; 1998 board_config = CXT5051_AUTO; /* model=auto as default */
1999#endif
2000 if (board_config == CXT5051_AUTO) 1999 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec); 2000 return patch_conexant_auto(codec);
2002 2001
@@ -3114,10 +3113,8 @@ static int patch_cxt5066(struct hda_codec *codec)
3114 3113
3115 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, 3114 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3116 cxt5066_models, cxt5066_cfg_tbl); 3115 cxt5066_models, cxt5066_cfg_tbl);
3117#if 0 /* use the old method just for safety */
3118 if (board_config < 0) 3116 if (board_config < 0)
3119 board_config = CXT5066_AUTO; 3117 board_config = CXT5066_AUTO; /* model=auto as default */
3120#endif
3121 if (board_config == CXT5066_AUTO) 3118 if (board_config == CXT5066_AUTO)
3122 return patch_conexant_auto(codec); 3119 return patch_conexant_auto(codec);
3123 3120
@@ -3308,19 +3305,8 @@ static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3308 3305
3309static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3306static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3310 3307
3311/* get the connection index of @nid in the widget @mux */ 3308#define get_connection_index(codec, mux, nid)\
3312static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3309 snd_hda_get_conn_index(codec, mux, nid, 0)
3313 hda_nid_t nid)
3314{
3315 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3316 int i, nums;
3317
3318 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3319 for (i = 0; i < nums; i++)
3320 if (conn[i] == nid)
3321 return i;
3322 return -1;
3323}
3324 3310
3325/* get an unassigned DAC from the given list. 3311/* get an unassigned DAC from the given list.
3326 * Return the nid if found and reduce the DAC list, or return zero if 3312 * Return the nid if found and reduce the DAC list, or return zero if
@@ -3919,6 +3905,38 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3919#define cx_auto_parse_beep(codec) 3905#define cx_auto_parse_beep(codec)
3920#endif 3906#endif
3921 3907
3908static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
3909{
3910 int i;
3911 for (i = 0; i < nums; i++)
3912 if (list[i] == nid)
3913 return true;
3914 return false;
3915}
3916
3917/* parse extra-EAPD that aren't assigned to any pins */
3918static void cx_auto_parse_eapd(struct hda_codec *codec)
3919{
3920 struct conexant_spec *spec = codec->spec;
3921 struct auto_pin_cfg *cfg = &spec->autocfg;
3922 hda_nid_t nid, end_nid;
3923
3924 end_nid = codec->start_nid + codec->num_nodes;
3925 for (nid = codec->start_nid; nid < end_nid; nid++) {
3926 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3927 continue;
3928 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3929 continue;
3930 if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) ||
3931 found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) ||
3932 found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs))
3933 continue;
3934 spec->eapds[spec->num_eapds++] = nid;
3935 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3936 break;
3937 }
3938}
3939
3922static int cx_auto_parse_auto_config(struct hda_codec *codec) 3940static int cx_auto_parse_auto_config(struct hda_codec *codec)
3923{ 3941{
3924 struct conexant_spec *spec = codec->spec; 3942 struct conexant_spec *spec = codec->spec;
@@ -3932,6 +3950,7 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3932 cx_auto_parse_input(codec); 3950 cx_auto_parse_input(codec);
3933 cx_auto_parse_digital(codec); 3951 cx_auto_parse_digital(codec);
3934 cx_auto_parse_beep(codec); 3952 cx_auto_parse_beep(codec);
3953 cx_auto_parse_eapd(codec);
3935 return 0; 3954 return 0;
3936} 3955}
3937 3956
@@ -4019,6 +4038,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
4019 } 4038 }
4020 } 4039 }
4021 cx_auto_update_speakers(codec); 4040 cx_auto_update_speakers(codec);
4041 /* turn on/off extra EAPDs, too */
4042 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4022} 4043}
4023 4044
4024static void cx_auto_init_input(struct hda_codec *codec) 4045static void cx_auto_init_input(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index bd0ae697f9c4..19cb72db9c38 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -43,7 +43,7 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
43 43
44/* 44/*
45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device 45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
46 * could support two independent pipes, each of them can be connected to one or 46 * could support N independent pipes, each of them can be connected to one or
47 * more ports (DVI, HDMI or DisplayPort). 47 * more ports (DVI, HDMI or DisplayPort).
48 * 48 *
49 * The HDA correspondence of pipes/ports are converter/pin nodes. 49 * The HDA correspondence of pipes/ports are converter/pin nodes.
@@ -51,30 +51,33 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
51#define MAX_HDMI_CVTS 4 51#define MAX_HDMI_CVTS 4
52#define MAX_HDMI_PINS 4 52#define MAX_HDMI_PINS 4
53 53
54struct hdmi_spec { 54struct hdmi_spec_per_cvt {
55 int num_cvts; 55 hda_nid_t cvt_nid;
56 int num_pins; 56 int assigned;
57 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */ 57 unsigned int channels_min;
58 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */ 58 unsigned int channels_max;
59 u32 rates;
60 u64 formats;
61 unsigned int maxbps;
62};
59 63
60 /* 64struct hdmi_spec_per_pin {
61 * source connection for each pin 65 hda_nid_t pin_nid;
62 */ 66 int num_mux_nids;
63 hda_nid_t pin_cvt[MAX_HDMI_PINS+1]; 67 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
68 struct hdmi_eld sink_eld;
69};
64 70
65 /* 71struct hdmi_spec {
66 * HDMI sink attached to each pin 72 int num_cvts;
67 */ 73 struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS];
68 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
69 74
70 /* 75 int num_pins;
71 * export one pcm per pipe 76 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
72 */ 77 struct hda_pcm pcm_rec[MAX_HDMI_PINS];
73 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
74 struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
75 78
76 /* 79 /*
77 * ati/nvhdmi specific 80 * Non-generic ATI/NVIDIA specific
78 */ 81 */
79 struct hda_multi_out multiout; 82 struct hda_multi_out multiout;
80 const struct hda_pcm_stream *pcm_playback; 83 const struct hda_pcm_stream *pcm_playback;
@@ -284,15 +287,40 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
284 * HDMI routines 287 * HDMI routines
285 */ 288 */
286 289
287static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) 290static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid)
288{ 291{
289 int i; 292 int pin_idx;
290 293
291 for (i = 0; nids[i]; i++) 294 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
292 if (nids[i] == nid) 295 if (spec->pins[pin_idx].pin_nid == pin_nid)
293 return i; 296 return pin_idx;
294 297
295 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid); 298 snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid);
299 return -EINVAL;
300}
301
302static int hinfo_to_pin_index(struct hdmi_spec *spec,
303 struct hda_pcm_stream *hinfo)
304{
305 int pin_idx;
306
307 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
308 if (&spec->pcm_rec[pin_idx].stream[0] == hinfo)
309 return pin_idx;
310
311 snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo);
312 return -EINVAL;
313}
314
315static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
316{
317 int cvt_idx;
318
319 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
320 if (spec->cvts[cvt_idx].cvt_nid == cvt_nid)
321 return cvt_idx;
322
323 snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid);
296 return -EINVAL; 324 return -EINVAL;
297} 325}
298 326
@@ -326,28 +354,28 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
326 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); 354 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
327} 355}
328 356
329static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid) 357static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
330{ 358{
331 /* Unmute */ 359 /* Unmute */
332 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) 360 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
333 snd_hda_codec_write(codec, pin_nid, 0, 361 snd_hda_codec_write(codec, pin_nid, 0,
334 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 362 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
335 /* Enable pin out */ 363 /* Disable pin out until stream is active*/
336 snd_hda_codec_write(codec, pin_nid, 0, 364 snd_hda_codec_write(codec, pin_nid, 0,
337 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 365 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
338} 366}
339 367
340static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid) 368static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
341{ 369{
342 return 1 + snd_hda_codec_read(codec, nid, 0, 370 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
343 AC_VERB_GET_CVT_CHAN_COUNT, 0); 371 AC_VERB_GET_CVT_CHAN_COUNT, 0);
344} 372}
345 373
346static void hdmi_set_channel_count(struct hda_codec *codec, 374static void hdmi_set_channel_count(struct hda_codec *codec,
347 hda_nid_t nid, int chs) 375 hda_nid_t cvt_nid, int chs)
348{ 376{
349 if (chs != hdmi_get_channel_count(codec, nid)) 377 if (chs != hdmi_get_channel_count(codec, cvt_nid))
350 snd_hda_codec_write(codec, nid, 0, 378 snd_hda_codec_write(codec, cvt_nid, 0,
351 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 379 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
352} 380}
353 381
@@ -384,11 +412,8 @@ static void init_channel_allocations(void)
384 * 412 *
385 * TODO: it could select the wrong CA from multiple candidates. 413 * TODO: it could select the wrong CA from multiple candidates.
386*/ 414*/
387static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid, 415static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
388 int channels)
389{ 416{
390 struct hdmi_spec *spec = codec->spec;
391 struct hdmi_eld *eld;
392 int i; 417 int i;
393 int ca = 0; 418 int ca = 0;
394 int spk_mask = 0; 419 int spk_mask = 0;
@@ -400,19 +425,6 @@ static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
400 if (channels <= 2) 425 if (channels <= 2)
401 return 0; 426 return 0;
402 427
403 i = hda_node_index(spec->pin_cvt, nid);
404 if (i < 0)
405 return 0;
406 eld = &spec->sink_eld[i];
407
408 /*
409 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
410 * in console or for audio devices. Assume the highest speakers
411 * configuration, to _not_ prohibit multi-channel audio playback.
412 */
413 if (!eld->spk_alloc)
414 eld->spk_alloc = 0xffff;
415
416 /* 428 /*
417 * expand ELD's speaker allocation mask 429 * expand ELD's speaker allocation mask
418 * 430 *
@@ -608,67 +620,63 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
608 return true; 620 return true;
609} 621}
610 622
611static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, 623static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
612 struct snd_pcm_substream *substream) 624 struct snd_pcm_substream *substream)
613{ 625{
614 struct hdmi_spec *spec = codec->spec; 626 struct hdmi_spec *spec = codec->spec;
615 hda_nid_t pin_nid; 627 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
628 hda_nid_t pin_nid = per_pin->pin_nid;
616 int channels = substream->runtime->channels; 629 int channels = substream->runtime->channels;
630 struct hdmi_eld *eld;
617 int ca; 631 int ca;
618 int i;
619 union audio_infoframe ai; 632 union audio_infoframe ai;
620 633
621 ca = hdmi_channel_allocation(codec, nid, channels); 634 eld = &spec->pins[pin_idx].sink_eld;
622 635 if (!eld->monitor_present)
623 for (i = 0; i < spec->num_pins; i++) { 636 return;
624 if (spec->pin_cvt[i] != nid)
625 continue;
626 if (!spec->sink_eld[i].monitor_present)
627 continue;
628 637
629 pin_nid = spec->pin[i]; 638 ca = hdmi_channel_allocation(eld, channels);
630 639
631 memset(&ai, 0, sizeof(ai)); 640 memset(&ai, 0, sizeof(ai));
632 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ 641 if (eld->conn_type == 0) { /* HDMI */
633 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; 642 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
634 643
635 hdmi_ai->type = 0x84; 644 hdmi_ai->type = 0x84;
636 hdmi_ai->ver = 0x01; 645 hdmi_ai->ver = 0x01;
637 hdmi_ai->len = 0x0a; 646 hdmi_ai->len = 0x0a;
638 hdmi_ai->CC02_CT47 = channels - 1; 647 hdmi_ai->CC02_CT47 = channels - 1;
639 hdmi_ai->CA = ca; 648 hdmi_ai->CA = ca;
640 hdmi_checksum_audio_infoframe(hdmi_ai); 649 hdmi_checksum_audio_infoframe(hdmi_ai);
641 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ 650 } else if (eld->conn_type == 1) { /* DisplayPort */
642 struct dp_audio_infoframe *dp_ai = &ai.dp; 651 struct dp_audio_infoframe *dp_ai = &ai.dp;
643 652
644 dp_ai->type = 0x84; 653 dp_ai->type = 0x84;
645 dp_ai->len = 0x1b; 654 dp_ai->len = 0x1b;
646 dp_ai->ver = 0x11 << 2; 655 dp_ai->ver = 0x11 << 2;
647 dp_ai->CC02_CT47 = channels - 1; 656 dp_ai->CC02_CT47 = channels - 1;
648 dp_ai->CA = ca; 657 dp_ai->CA = ca;
649 } else { 658 } else {
650 snd_printd("HDMI: unknown connection type at pin %d\n", 659 snd_printd("HDMI: unknown connection type at pin %d\n",
651 pin_nid); 660 pin_nid);
652 continue; 661 return;
653 } 662 }
654 663
655 /* 664 /*
656 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or 665 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
657 * sizeof(*dp_ai) to avoid partial match/update problems when 666 * sizeof(*dp_ai) to avoid partial match/update problems when
658 * the user switches between HDMI/DP monitors. 667 * the user switches between HDMI/DP monitors.
659 */ 668 */
660 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, 669 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
661 sizeof(ai))) { 670 sizeof(ai))) {
662 snd_printdd("hdmi_setup_audio_infoframe: " 671 snd_printdd("hdmi_setup_audio_infoframe: "
663 "cvt=%d pin=%d channels=%d\n", 672 "pin=%d channels=%d\n",
664 nid, pin_nid, 673 pin_nid,
665 channels); 674 channels);
666 hdmi_setup_channel_mapping(codec, pin_nid, ca); 675 hdmi_setup_channel_mapping(codec, pin_nid, ca);
667 hdmi_stop_infoframe_trans(codec, pin_nid); 676 hdmi_stop_infoframe_trans(codec, pin_nid);
668 hdmi_fill_audio_infoframe(codec, pin_nid, 677 hdmi_fill_audio_infoframe(codec, pin_nid,
669 ai.bytes, sizeof(ai)); 678 ai.bytes, sizeof(ai));
670 hdmi_start_infoframe_trans(codec, pin_nid); 679 hdmi_start_infoframe_trans(codec, pin_nid);
671 }
672 } 680 }
673} 681}
674 682
@@ -686,17 +694,27 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
686 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; 694 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
687 int pd = !!(res & AC_UNSOL_RES_PD); 695 int pd = !!(res & AC_UNSOL_RES_PD);
688 int eldv = !!(res & AC_UNSOL_RES_ELDV); 696 int eldv = !!(res & AC_UNSOL_RES_ELDV);
689 int index; 697 int pin_idx;
698 struct hdmi_eld *eld;
690 699
691 printk(KERN_INFO 700 printk(KERN_INFO
692 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 701 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
693 pin_nid, pd, eldv); 702 codec->addr, pin_nid, pd, eldv);
694 703
695 index = hda_node_index(spec->pin, pin_nid); 704 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
696 if (index < 0) 705 if (pin_idx < 0)
697 return; 706 return;
707 eld = &spec->pins[pin_idx].sink_eld;
698 708
699 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); 709 hdmi_present_sense(codec, pin_nid, eld);
710
711 /*
712 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
713 * in console or for audio devices. Assume the highest speakers
714 * configuration, to _not_ prohibit multi-channel audio playback.
715 */
716 if (!eld->spk_alloc)
717 eld->spk_alloc = 0xffff;
700} 718}
701 719
702static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 720static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -707,7 +725,8 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
707 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); 725 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
708 726
709 printk(KERN_INFO 727 printk(KERN_INFO
710 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", 728 "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
729 codec->addr,
711 tag, 730 tag,
712 subtag, 731 subtag,
713 cp_state, 732 cp_state,
@@ -727,7 +746,7 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
727 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 746 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
728 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; 747 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
729 748
730 if (hda_node_index(spec->pin, tag) < 0) { 749 if (pin_nid_to_pin_index(spec, tag) < 0) {
731 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); 750 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
732 return; 751 return;
733 } 752 }
@@ -746,21 +765,14 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
746#define is_hbr_format(format) \ 765#define is_hbr_format(format) \
747 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) 766 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
748 767
749static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 768static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
750 u32 stream_tag, int format) 769 hda_nid_t pin_nid, u32 stream_tag, int format)
751{ 770{
752 struct hdmi_spec *spec = codec->spec;
753 int pinctl; 771 int pinctl;
754 int new_pinctl = 0; 772 int new_pinctl = 0;
755 int i;
756
757 for (i = 0; i < spec->num_pins; i++) {
758 if (spec->pin_cvt[i] != nid)
759 continue;
760 if (!(snd_hda_query_pin_caps(codec, spec->pin[i]) & AC_PINCAP_HBR))
761 continue;
762 773
763 pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, 774 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
775 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
764 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 776 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
765 777
766 new_pinctl = pinctl & ~AC_PINCTL_EPT; 778 new_pinctl = pinctl & ~AC_PINCTL_EPT;
@@ -771,22 +783,22 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
771 783
772 snd_printdd("hdmi_setup_stream: " 784 snd_printdd("hdmi_setup_stream: "
773 "NID=0x%x, %spinctl=0x%x\n", 785 "NID=0x%x, %spinctl=0x%x\n",
774 spec->pin[i], 786 pin_nid,
775 pinctl == new_pinctl ? "" : "new-", 787 pinctl == new_pinctl ? "" : "new-",
776 new_pinctl); 788 new_pinctl);
777 789
778 if (pinctl != new_pinctl) 790 if (pinctl != new_pinctl)
779 snd_hda_codec_write(codec, spec->pin[i], 0, 791 snd_hda_codec_write(codec, pin_nid, 0,
780 AC_VERB_SET_PIN_WIDGET_CONTROL, 792 AC_VERB_SET_PIN_WIDGET_CONTROL,
781 new_pinctl); 793 new_pinctl);
782 }
783 794
795 }
784 if (is_hbr_format(format) && !new_pinctl) { 796 if (is_hbr_format(format) && !new_pinctl) {
785 snd_printdd("hdmi_setup_stream: HBR is not supported\n"); 797 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
786 return -EINVAL; 798 return -EINVAL;
787 } 799 }
788 800
789 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 801 snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
790 return 0; 802 return 0;
791} 803}
792 804
@@ -798,37 +810,70 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
798 struct snd_pcm_substream *substream) 810 struct snd_pcm_substream *substream)
799{ 811{
800 struct hdmi_spec *spec = codec->spec; 812 struct hdmi_spec *spec = codec->spec;
801 struct hdmi_eld *eld;
802 struct hda_pcm_stream *codec_pars;
803 struct snd_pcm_runtime *runtime = substream->runtime; 813 struct snd_pcm_runtime *runtime = substream->runtime;
804 unsigned int idx; 814 int pin_idx, cvt_idx, mux_idx = 0;
815 struct hdmi_spec_per_pin *per_pin;
816 struct hdmi_eld *eld;
817 struct hdmi_spec_per_cvt *per_cvt = NULL;
818 int pinctl;
805 819
806 for (idx = 0; idx < spec->num_cvts; idx++) 820 /* Validate hinfo */
807 if (hinfo->nid == spec->cvt[idx]) 821 pin_idx = hinfo_to_pin_index(spec, hinfo);
808 break; 822 if (snd_BUG_ON(pin_idx < 0))
809 if (snd_BUG_ON(idx >= spec->num_cvts) ||
810 snd_BUG_ON(idx >= spec->num_pins))
811 return -EINVAL; 823 return -EINVAL;
824 per_pin = &spec->pins[pin_idx];
825 eld = &per_pin->sink_eld;
812 826
813 /* save the PCM info the codec provides */ 827 /* Dynamically assign converter to stream */
814 codec_pars = &spec->codec_pcm_pars[idx]; 828 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
815 if (!codec_pars->rates) 829 per_cvt = &spec->cvts[cvt_idx];
816 *codec_pars = *hinfo;
817 830
818 eld = &spec->sink_eld[idx]; 831 /* Must not already be assigned */
819 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) { 832 if (per_cvt->assigned)
820 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 833 continue;
834 /* Must be in pin's mux's list of converters */
835 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
836 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
837 break;
838 /* Not in mux list */
839 if (mux_idx == per_pin->num_mux_nids)
840 continue;
841 break;
842 }
843 /* No free converters */
844 if (cvt_idx == spec->num_cvts)
845 return -ENODEV;
846
847 /* Claim converter */
848 per_cvt->assigned = 1;
849 hinfo->nid = per_cvt->cvt_nid;
850
851 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
852 AC_VERB_SET_CONNECT_SEL,
853 mux_idx);
854 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
855 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
856 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
857 AC_VERB_SET_PIN_WIDGET_CONTROL,
858 pinctl | PIN_OUT);
859 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
860
861 /* Initially set the converter's capabilities */
862 hinfo->channels_min = per_cvt->channels_min;
863 hinfo->channels_max = per_cvt->channels_max;
864 hinfo->rates = per_cvt->rates;
865 hinfo->formats = per_cvt->formats;
866 hinfo->maxbps = per_cvt->maxbps;
867
868 /* Restrict capabilities by ELD if this isn't disabled */
869 if (!static_hdmi_pcm && eld->eld_valid) {
870 snd_hdmi_eld_update_pcm_info(eld, hinfo);
821 if (hinfo->channels_min > hinfo->channels_max || 871 if (hinfo->channels_min > hinfo->channels_max ||
822 !hinfo->rates || !hinfo->formats) 872 !hinfo->rates || !hinfo->formats)
823 return -ENODEV; 873 return -ENODEV;
824 } else {
825 /* fallback to the codec default */
826 hinfo->channels_max = codec_pars->channels_max;
827 hinfo->rates = codec_pars->rates;
828 hinfo->formats = codec_pars->formats;
829 hinfo->maxbps = codec_pars->maxbps;
830 } 874 }
831 /* store the updated parameters */ 875
876 /* Store the updated parameters */
832 runtime->hw.channels_min = hinfo->channels_min; 877 runtime->hw.channels_min = hinfo->channels_min;
833 runtime->hw.channels_max = hinfo->channels_max; 878 runtime->hw.channels_max = hinfo->channels_max;
834 runtime->hw.formats = hinfo->formats; 879 runtime->hw.formats = hinfo->formats;
@@ -842,12 +887,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
842/* 887/*
843 * HDA/HDMI auto parsing 888 * HDA/HDMI auto parsing
844 */ 889 */
845static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) 890static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
846{ 891{
847 struct hdmi_spec *spec = codec->spec; 892 struct hdmi_spec *spec = codec->spec;
848 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; 893 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
849 int conn_len, curr; 894 hda_nid_t pin_nid = per_pin->pin_nid;
850 int index;
851 895
852 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { 896 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
853 snd_printk(KERN_WARNING 897 snd_printk(KERN_WARNING
@@ -857,19 +901,9 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
857 return -EINVAL; 901 return -EINVAL;
858 } 902 }
859 903
860 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list, 904 per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid,
861 HDA_MAX_CONNECTIONS); 905 per_pin->mux_nids,
862 if (conn_len > 1) 906 HDA_MAX_CONNECTIONS);
863 curr = snd_hda_codec_read(codec, pin_nid, 0,
864 AC_VERB_GET_CONNECT_SEL, 0);
865 else
866 curr = 0;
867
868 index = hda_node_index(spec->pin, pin_nid);
869 if (index < 0)
870 return -EINVAL;
871
872 spec->pin_cvt[index] = conn_list[curr];
873 907
874 return 0; 908 return 0;
875} 909}
@@ -896,8 +930,8 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
896 eld->eld_valid = 0; 930 eld->eld_valid = 0;
897 931
898 printk(KERN_INFO 932 printk(KERN_INFO
899 "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 933 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
900 pin_nid, eld->monitor_present, eld->eld_valid); 934 codec->addr, pin_nid, eld->monitor_present, eld->eld_valid);
901 935
902 if (eld->eld_valid) 936 if (eld->eld_valid)
903 if (!snd_hdmi_get_eld(eld, codec, pin_nid)) 937 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
@@ -909,47 +943,75 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
909static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) 943static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
910{ 944{
911 struct hdmi_spec *spec = codec->spec; 945 struct hdmi_spec *spec = codec->spec;
946 unsigned int caps, config;
947 int pin_idx;
948 struct hdmi_spec_per_pin *per_pin;
949 struct hdmi_eld *eld;
912 int err; 950 int err;
913 951
914 if (spec->num_pins >= MAX_HDMI_PINS) { 952 caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
915 snd_printk(KERN_WARNING 953 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
916 "HDMI: no space for pin %d\n", pin_nid); 954 return 0;
955
956 config = snd_hda_codec_read(codec, pin_nid, 0,
957 AC_VERB_GET_CONFIG_DEFAULT, 0);
958 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
959 return 0;
960
961 if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS))
917 return -E2BIG; 962 return -E2BIG;
918 } 963
964 pin_idx = spec->num_pins;
965 per_pin = &spec->pins[pin_idx];
966 eld = &per_pin->sink_eld;
967
968 per_pin->pin_nid = pin_nid;
919 969
920 err = snd_hda_input_jack_add(codec, pin_nid, 970 err = snd_hda_input_jack_add(codec, pin_nid,
921 SND_JACK_VIDEOOUT, NULL); 971 SND_JACK_VIDEOOUT, NULL);
922 if (err < 0) 972 if (err < 0)
923 return err; 973 return err;
924 974
925 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 975 err = hdmi_read_pin_conn(codec, pin_idx);
976 if (err < 0)
977 return err;
926 978
927 spec->pin[spec->num_pins] = pin_nid;
928 spec->num_pins++; 979 spec->num_pins++;
929 980
930 return hdmi_read_pin_conn(codec, pin_nid); 981 hdmi_present_sense(codec, pin_nid, eld);
982
983 return 0;
931} 984}
932 985
933static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 986static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
934{ 987{
935 int i, found_pin = 0;
936 struct hdmi_spec *spec = codec->spec; 988 struct hdmi_spec *spec = codec->spec;
937 989 int cvt_idx;
938 for (i = 0; i < spec->num_pins; i++) 990 struct hdmi_spec_per_cvt *per_cvt;
939 if (nid == spec->pin_cvt[i]) { 991 unsigned int chans;
940 found_pin = 1; 992 int err;
941 break;
942 }
943
944 if (!found_pin) {
945 snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
946 return -EINVAL;
947 }
948 993
949 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) 994 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
950 return -E2BIG; 995 return -E2BIG;
951 996
952 spec->cvt[spec->num_cvts] = nid; 997 chans = get_wcaps(codec, cvt_nid);
998 chans = get_wcaps_channels(chans);
999
1000 cvt_idx = spec->num_cvts;
1001 per_cvt = &spec->cvts[cvt_idx];
1002
1003 per_cvt->cvt_nid = cvt_nid;
1004 per_cvt->channels_min = 2;
1005 if (chans <= 16)
1006 per_cvt->channels_max = chans;
1007
1008 err = snd_hda_query_supported_pcm(codec, cvt_nid,
1009 &per_cvt->rates,
1010 &per_cvt->formats,
1011 &per_cvt->maxbps);
1012 if (err < 0)
1013 return err;
1014
953 spec->num_cvts++; 1015 spec->num_cvts++;
954 1016
955 return 0; 1017 return 0;
@@ -959,8 +1021,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
959{ 1021{
960 hda_nid_t nid; 1022 hda_nid_t nid;
961 int i, nodes; 1023 int i, nodes;
962 int num_tmp_cvts = 0;
963 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
964 1024
965 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 1025 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
966 if (!nid || nodes < 0) { 1026 if (!nid || nodes < 0) {
@@ -971,7 +1031,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
971 for (i = 0; i < nodes; i++, nid++) { 1031 for (i = 0; i < nodes; i++, nid++) {
972 unsigned int caps; 1032 unsigned int caps;
973 unsigned int type; 1033 unsigned int type;
974 unsigned int config;
975 1034
976 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 1035 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
977 type = get_wcaps_type(caps); 1036 type = get_wcaps_type(caps);
@@ -981,32 +1040,14 @@ static int hdmi_parse_codec(struct hda_codec *codec)
981 1040
982 switch (type) { 1041 switch (type) {
983 case AC_WID_AUD_OUT: 1042 case AC_WID_AUD_OUT:
984 if (num_tmp_cvts >= MAX_HDMI_CVTS) { 1043 hdmi_add_cvt(codec, nid);
985 snd_printk(KERN_WARNING
986 "HDMI: no space for converter %d\n", nid);
987 continue;
988 }
989 tmp_cvt[num_tmp_cvts] = nid;
990 num_tmp_cvts++;
991 break; 1044 break;
992 case AC_WID_PIN: 1045 case AC_WID_PIN:
993 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
994 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
995 continue;
996
997 config = snd_hda_codec_read(codec, nid, 0,
998 AC_VERB_GET_CONFIG_DEFAULT, 0);
999 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
1000 continue;
1001
1002 hdmi_add_pin(codec, nid); 1046 hdmi_add_pin(codec, nid);
1003 break; 1047 break;
1004 } 1048 }
1005 } 1049 }
1006 1050
1007 for (i = 0; i < num_tmp_cvts; i++)
1008 hdmi_add_cvt(codec, tmp_cvt[i]);
1009
1010 /* 1051 /*
1011 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 1052 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
1012 * can be lost and presence sense verb will become inaccurate if the 1053 * can be lost and presence sense verb will become inaccurate if the
@@ -1023,7 +1064,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
1023 1064
1024/* 1065/*
1025 */ 1066 */
1026static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { 1067static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = {
1027 "HDMI 0", 1068 "HDMI 0",
1028 "HDMI 1", 1069 "HDMI 1",
1029 "HDMI 2", 1070 "HDMI 2",
@@ -1040,51 +1081,84 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1040 unsigned int format, 1081 unsigned int format,
1041 struct snd_pcm_substream *substream) 1082 struct snd_pcm_substream *substream)
1042{ 1083{
1043 hdmi_set_channel_count(codec, hinfo->nid, 1084 hda_nid_t cvt_nid = hinfo->nid;
1044 substream->runtime->channels); 1085 struct hdmi_spec *spec = codec->spec;
1086 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1087 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1088
1089 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1045 1090
1046 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); 1091 hdmi_setup_audio_infoframe(codec, pin_idx, substream);
1047 1092
1048 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 1093 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1049} 1094}
1050 1095
1051static const struct hda_pcm_stream generic_hdmi_pcm_playback = { 1096static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1052 .substreams = 1, 1097 struct hda_codec *codec,
1053 .channels_min = 2, 1098 struct snd_pcm_substream *substream)
1054 .ops = { 1099{
1055 .open = hdmi_pcm_open, 1100 struct hdmi_spec *spec = codec->spec;
1056 .prepare = generic_hdmi_playback_pcm_prepare, 1101 int cvt_idx, pin_idx;
1057 }, 1102 struct hdmi_spec_per_cvt *per_cvt;
1103 struct hdmi_spec_per_pin *per_pin;
1104 int pinctl;
1105
1106 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
1107
1108 if (hinfo->nid) {
1109 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
1110 if (snd_BUG_ON(cvt_idx < 0))
1111 return -EINVAL;
1112 per_cvt = &spec->cvts[cvt_idx];
1113
1114 snd_BUG_ON(!per_cvt->assigned);
1115 per_cvt->assigned = 0;
1116 hinfo->nid = 0;
1117
1118 pin_idx = hinfo_to_pin_index(spec, hinfo);
1119 if (snd_BUG_ON(pin_idx < 0))
1120 return -EINVAL;
1121 per_pin = &spec->pins[pin_idx];
1122
1123 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
1124 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1125 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
1126 AC_VERB_SET_PIN_WIDGET_CONTROL,
1127 pinctl & ~PIN_OUT);
1128 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1129 }
1130
1131 return 0;
1132}
1133
1134static const struct hda_pcm_ops generic_ops = {
1135 .open = hdmi_pcm_open,
1136 .prepare = generic_hdmi_playback_pcm_prepare,
1137 .cleanup = generic_hdmi_playback_pcm_cleanup,
1058}; 1138};
1059 1139
1060static int generic_hdmi_build_pcms(struct hda_codec *codec) 1140static int generic_hdmi_build_pcms(struct hda_codec *codec)
1061{ 1141{
1062 struct hdmi_spec *spec = codec->spec; 1142 struct hdmi_spec *spec = codec->spec;
1063 struct hda_pcm *info = spec->pcm_rec; 1143 int pin_idx;
1064 int i;
1065 1144
1066 codec->num_pcms = spec->num_cvts; 1145 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1067 codec->pcm_info = info; 1146 struct hda_pcm *info;
1068
1069 for (i = 0; i < codec->num_pcms; i++, info++) {
1070 unsigned int chans;
1071 struct hda_pcm_stream *pstr; 1147 struct hda_pcm_stream *pstr;
1072 1148
1073 chans = get_wcaps(codec, spec->cvt[i]); 1149 info = &spec->pcm_rec[pin_idx];
1074 chans = get_wcaps_channels(chans); 1150 info->name = generic_hdmi_pcm_names[pin_idx];
1075
1076 info->name = generic_hdmi_pcm_names[i];
1077 info->pcm_type = HDA_PCM_TYPE_HDMI; 1151 info->pcm_type = HDA_PCM_TYPE_HDMI;
1152
1078 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1153 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1079 if (spec->pcm_playback) 1154 pstr->substreams = 1;
1080 *pstr = *spec->pcm_playback; 1155 pstr->ops = generic_ops;
1081 else 1156 /* other pstr fields are set in open */
1082 *pstr = generic_hdmi_pcm_playback;
1083 pstr->nid = spec->cvt[i];
1084 if (pstr->channels_max <= 2 && chans && chans <= 16)
1085 pstr->channels_max = chans;
1086 } 1157 }
1087 1158
1159 codec->num_pcms = spec->num_pins;
1160 codec->pcm_info = spec->pcm_rec;
1161
1088 return 0; 1162 return 0;
1089} 1163}
1090 1164
@@ -1092,12 +1166,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1092{ 1166{
1093 struct hdmi_spec *spec = codec->spec; 1167 struct hdmi_spec *spec = codec->spec;
1094 int err; 1168 int err;
1095 int i; 1169 int pin_idx;
1096 1170
1097 for (i = 0; i < codec->num_pcms; i++) { 1171 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1098 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]); 1172 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1173 err = snd_hda_create_spdif_out_ctls(codec,
1174 per_pin->pin_nid,
1175 per_pin->mux_nids[0]);
1099 if (err < 0) 1176 if (err < 0)
1100 return err; 1177 return err;
1178 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1101 } 1179 }
1102 1180
1103 return 0; 1181 return 0;
@@ -1106,13 +1184,19 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1106static int generic_hdmi_init(struct hda_codec *codec) 1184static int generic_hdmi_init(struct hda_codec *codec)
1107{ 1185{
1108 struct hdmi_spec *spec = codec->spec; 1186 struct hdmi_spec *spec = codec->spec;
1109 int i; 1187 int pin_idx;
1110 1188
1111 for (i = 0; spec->pin[i]; i++) { 1189 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1112 hdmi_enable_output(codec, spec->pin[i]); 1190 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1113 snd_hda_codec_write(codec, spec->pin[i], 0, 1191 hda_nid_t pin_nid = per_pin->pin_nid;
1192 struct hdmi_eld *eld = &per_pin->sink_eld;
1193
1194 hdmi_init_pin(codec, pin_nid);
1195 snd_hda_codec_write(codec, pin_nid, 0,
1114 AC_VERB_SET_UNSOLICITED_ENABLE, 1196 AC_VERB_SET_UNSOLICITED_ENABLE,
1115 AC_USRSP_EN | spec->pin[i]); 1197 AC_USRSP_EN | pin_nid);
1198
1199 snd_hda_eld_proc_new(codec, eld, pin_idx);
1116 } 1200 }
1117 return 0; 1201 return 0;
1118} 1202}
@@ -1120,10 +1204,14 @@ static int generic_hdmi_init(struct hda_codec *codec)
1120static void generic_hdmi_free(struct hda_codec *codec) 1204static void generic_hdmi_free(struct hda_codec *codec)
1121{ 1205{
1122 struct hdmi_spec *spec = codec->spec; 1206 struct hdmi_spec *spec = codec->spec;
1123 int i; 1207 int pin_idx;
1208
1209 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1210 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1211 struct hdmi_eld *eld = &per_pin->sink_eld;
1124 1212
1125 for (i = 0; i < spec->num_pins; i++) 1213 snd_hda_eld_proc_free(codec, eld);
1126 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); 1214 }
1127 snd_hda_input_jack_free(codec); 1215 snd_hda_input_jack_free(codec);
1128 1216
1129 kfree(spec); 1217 kfree(spec);
@@ -1140,7 +1228,6 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
1140static int patch_generic_hdmi(struct hda_codec *codec) 1228static int patch_generic_hdmi(struct hda_codec *codec)
1141{ 1229{
1142 struct hdmi_spec *spec; 1230 struct hdmi_spec *spec;
1143 int i;
1144 1231
1145 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1232 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1146 if (spec == NULL) 1233 if (spec == NULL)
@@ -1154,15 +1241,69 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1154 } 1241 }
1155 codec->patch_ops = generic_hdmi_patch_ops; 1242 codec->patch_ops = generic_hdmi_patch_ops;
1156 1243
1157 for (i = 0; i < spec->num_pins; i++)
1158 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
1159
1160 init_channel_allocations(); 1244 init_channel_allocations();
1161 1245
1162 return 0; 1246 return 0;
1163} 1247}
1164 1248
1165/* 1249/*
1250 * Shared non-generic implementations
1251 */
1252
1253static int simple_playback_build_pcms(struct hda_codec *codec)
1254{
1255 struct hdmi_spec *spec = codec->spec;
1256 struct hda_pcm *info = spec->pcm_rec;
1257 int i;
1258
1259 codec->num_pcms = spec->num_cvts;
1260 codec->pcm_info = info;
1261
1262 for (i = 0; i < codec->num_pcms; i++, info++) {
1263 unsigned int chans;
1264 struct hda_pcm_stream *pstr;
1265
1266 chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
1267 chans = get_wcaps_channels(chans);
1268
1269 info->name = generic_hdmi_pcm_names[i];
1270 info->pcm_type = HDA_PCM_TYPE_HDMI;
1271 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1272 snd_BUG_ON(!spec->pcm_playback);
1273 *pstr = *spec->pcm_playback;
1274 pstr->nid = spec->cvts[i].cvt_nid;
1275 if (pstr->channels_max <= 2 && chans && chans <= 16)
1276 pstr->channels_max = chans;
1277 }
1278
1279 return 0;
1280}
1281
1282static int simple_playback_build_controls(struct hda_codec *codec)
1283{
1284 struct hdmi_spec *spec = codec->spec;
1285 int err;
1286 int i;
1287
1288 for (i = 0; i < codec->num_pcms; i++) {
1289 err = snd_hda_create_spdif_out_ctls(codec,
1290 spec->cvts[i].cvt_nid,
1291 spec->cvts[i].cvt_nid);
1292 if (err < 0)
1293 return err;
1294 }
1295
1296 return 0;
1297}
1298
1299static void simple_playback_free(struct hda_codec *codec)
1300{
1301 struct hdmi_spec *spec = codec->spec;
1302
1303 kfree(spec);
1304}
1305
1306/*
1166 * Nvidia specific implementations 1307 * Nvidia specific implementations
1167 */ 1308 */
1168 1309
@@ -1352,6 +1493,9 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1352 int chs; 1493 int chs;
1353 unsigned int dataDCC1, dataDCC2, channel_id; 1494 unsigned int dataDCC1, dataDCC2, channel_id;
1354 int i; 1495 int i;
1496 struct hdmi_spec *spec = codec->spec;
1497 struct hda_spdif_out *spdif =
1498 snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid);
1355 1499
1356 mutex_lock(&codec->spdif_mutex); 1500 mutex_lock(&codec->spdif_mutex);
1357 1501
@@ -1361,12 +1505,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1361 dataDCC2 = 0x2; 1505 dataDCC2 = 0x2;
1362 1506
1363 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 1507 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1364 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 1508 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
1365 snd_hda_codec_write(codec, 1509 snd_hda_codec_write(codec,
1366 nvhdmi_master_con_nid_7x, 1510 nvhdmi_master_con_nid_7x,
1367 0, 1511 0,
1368 AC_VERB_SET_DIGI_CONVERT_1, 1512 AC_VERB_SET_DIGI_CONVERT_1,
1369 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1513 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1370 1514
1371 /* set the stream id */ 1515 /* set the stream id */
1372 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 1516 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
@@ -1378,12 +1522,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1378 1522
1379 /* turn on again (if needed) */ 1523 /* turn on again (if needed) */
1380 /* enable and set the channel status audio/data flag */ 1524 /* enable and set the channel status audio/data flag */
1381 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1525 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
1382 snd_hda_codec_write(codec, 1526 snd_hda_codec_write(codec,
1383 nvhdmi_master_con_nid_7x, 1527 nvhdmi_master_con_nid_7x,
1384 0, 1528 0,
1385 AC_VERB_SET_DIGI_CONVERT_1, 1529 AC_VERB_SET_DIGI_CONVERT_1,
1386 codec->spdif_ctls & 0xff); 1530 spdif->ctls & 0xff);
1387 snd_hda_codec_write(codec, 1531 snd_hda_codec_write(codec,
1388 nvhdmi_master_con_nid_7x, 1532 nvhdmi_master_con_nid_7x,
1389 0, 1533 0,
@@ -1400,12 +1544,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1400 *otherwise the IEC958 bits won't be updated 1544 *otherwise the IEC958 bits won't be updated
1401 */ 1545 */
1402 if (codec->spdif_status_reset && 1546 if (codec->spdif_status_reset &&
1403 (codec->spdif_ctls & AC_DIG1_ENABLE)) 1547 (spdif->ctls & AC_DIG1_ENABLE))
1404 snd_hda_codec_write(codec, 1548 snd_hda_codec_write(codec,
1405 nvhdmi_con_nids_7x[i], 1549 nvhdmi_con_nids_7x[i],
1406 0, 1550 0,
1407 AC_VERB_SET_DIGI_CONVERT_1, 1551 AC_VERB_SET_DIGI_CONVERT_1,
1408 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1552 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1409 /* set the stream id */ 1553 /* set the stream id */
1410 snd_hda_codec_write(codec, 1554 snd_hda_codec_write(codec,
1411 nvhdmi_con_nids_7x[i], 1555 nvhdmi_con_nids_7x[i],
@@ -1421,12 +1565,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1421 /* turn on again (if needed) */ 1565 /* turn on again (if needed) */
1422 /* enable and set the channel status audio/data flag */ 1566 /* enable and set the channel status audio/data flag */
1423 if (codec->spdif_status_reset && 1567 if (codec->spdif_status_reset &&
1424 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1568 (spdif->ctls & AC_DIG1_ENABLE)) {
1425 snd_hda_codec_write(codec, 1569 snd_hda_codec_write(codec,
1426 nvhdmi_con_nids_7x[i], 1570 nvhdmi_con_nids_7x[i],
1427 0, 1571 0,
1428 AC_VERB_SET_DIGI_CONVERT_1, 1572 AC_VERB_SET_DIGI_CONVERT_1,
1429 codec->spdif_ctls & 0xff); 1573 spdif->ctls & 0xff);
1430 snd_hda_codec_write(codec, 1574 snd_hda_codec_write(codec,
1431 nvhdmi_con_nids_7x[i], 1575 nvhdmi_con_nids_7x[i],
1432 0, 1576 0,
@@ -1471,17 +1615,17 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1471}; 1615};
1472 1616
1473static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { 1617static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1474 .build_controls = generic_hdmi_build_controls, 1618 .build_controls = simple_playback_build_controls,
1475 .build_pcms = generic_hdmi_build_pcms, 1619 .build_pcms = simple_playback_build_pcms,
1476 .init = nvhdmi_7x_init, 1620 .init = nvhdmi_7x_init,
1477 .free = generic_hdmi_free, 1621 .free = simple_playback_free,
1478}; 1622};
1479 1623
1480static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { 1624static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1481 .build_controls = generic_hdmi_build_controls, 1625 .build_controls = simple_playback_build_controls,
1482 .build_pcms = generic_hdmi_build_pcms, 1626 .build_pcms = simple_playback_build_pcms,
1483 .init = nvhdmi_7x_init, 1627 .init = nvhdmi_7x_init,
1484 .free = generic_hdmi_free, 1628 .free = simple_playback_free,
1485}; 1629};
1486 1630
1487static int patch_nvhdmi_2ch(struct hda_codec *codec) 1631static int patch_nvhdmi_2ch(struct hda_codec *codec)
@@ -1498,7 +1642,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
1498 spec->multiout.max_channels = 2; 1642 spec->multiout.max_channels = 2;
1499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; 1643 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1500 spec->num_cvts = 1; 1644 spec->num_cvts = 1;
1501 spec->cvt[0] = nvhdmi_master_con_nid_7x; 1645 spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
1502 spec->pcm_playback = &nvhdmi_pcm_playback_2ch; 1646 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1503 1647
1504 codec->patch_ops = nvhdmi_patch_ops_2ch; 1648 codec->patch_ops = nvhdmi_patch_ops_2ch;
@@ -1549,11 +1693,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1549 substream); 1693 substream);
1550 if (err < 0) 1694 if (err < 0)
1551 return err; 1695 return err;
1552 snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT, 1696 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1553 chans - 1); 1697 AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
1554 /* FIXME: XXX */ 1698 /* FIXME: XXX */
1555 for (i = 0; i < chans; i++) { 1699 for (i = 0; i < chans; i++) {
1556 snd_hda_codec_write(codec, spec->cvt[0], 0, 1700 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1557 AC_VERB_SET_HDMI_CHAN_SLOT, 1701 AC_VERB_SET_HDMI_CHAN_SLOT,
1558 (i << 4) | i); 1702 (i << 4) | i);
1559 } 1703 }
@@ -1584,18 +1728,18 @@ static int atihdmi_init(struct hda_codec *codec)
1584 1728
1585 snd_hda_sequence_write(codec, atihdmi_basic_init); 1729 snd_hda_sequence_write(codec, atihdmi_basic_init);
1586 /* SI codec requires to unmute the pin */ 1730 /* SI codec requires to unmute the pin */
1587 if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP) 1731 if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP)
1588 snd_hda_codec_write(codec, spec->pin[0], 0, 1732 snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0,
1589 AC_VERB_SET_AMP_GAIN_MUTE, 1733 AC_VERB_SET_AMP_GAIN_MUTE,
1590 AMP_OUT_UNMUTE); 1734 AMP_OUT_UNMUTE);
1591 return 0; 1735 return 0;
1592} 1736}
1593 1737
1594static const struct hda_codec_ops atihdmi_patch_ops = { 1738static const struct hda_codec_ops atihdmi_patch_ops = {
1595 .build_controls = generic_hdmi_build_controls, 1739 .build_controls = simple_playback_build_controls,
1596 .build_pcms = generic_hdmi_build_pcms, 1740 .build_pcms = simple_playback_build_pcms,
1597 .init = atihdmi_init, 1741 .init = atihdmi_init,
1598 .free = generic_hdmi_free, 1742 .free = simple_playback_free,
1599}; 1743};
1600 1744
1601 1745
@@ -1613,8 +1757,8 @@ static int patch_atihdmi(struct hda_codec *codec)
1613 spec->multiout.max_channels = 2; 1757 spec->multiout.max_channels = 2;
1614 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; 1758 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1615 spec->num_cvts = 1; 1759 spec->num_cvts = 1;
1616 spec->cvt[0] = ATIHDMI_CVT_NID; 1760 spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
1617 spec->pin[0] = ATIHDMI_PIN_NID; 1761 spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
1618 spec->pcm_playback = &atihdmi_pcm_digital_playback; 1762 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1619 1763
1620 codec->patch_ops = atihdmi_patch_ops; 1764 codec->patch_ops = atihdmi_patch_ops;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b48fb43b5448..52ce07534e5b 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
@@ -276,14 +51,6 @@ enum {
276 ALC_INIT_GPIO3, 51 ALC_INIT_GPIO3,
277}; 52};
278 53
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
287struct alc_customize_define { 54struct alc_customize_define {
288 unsigned int sku_cfg; 55 unsigned int sku_cfg;
289 unsigned char port_connectivity; 56 unsigned char port_connectivity;
@@ -348,9 +115,9 @@ struct alc_spec {
348 const hda_nid_t *adc_nids; 115 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids; 116 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 117 hda_nid_t dig_in_nid; /* digital-in NID; optional */
118 hda_nid_t mixer_nid; /* analog-mixer NID */
351 119
352 /* capture setup for dynamic dual-adc switch */ 120 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc; 121 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag; 122 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format; 123 unsigned int cur_adc_format;
@@ -359,9 +126,9 @@ struct alc_spec {
359 unsigned int num_mux_defs; 126 unsigned int num_mux_defs;
360 const struct hda_input_mux *input_mux; 127 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3]; 128 unsigned int cur_mux[3];
362 struct alc_mic_route ext_mic; 129 hda_nid_t ext_mic_pin;
363 struct alc_mic_route dock_mic; 130 hda_nid_t dock_mic_pin;
364 struct alc_mic_route int_mic; 131 hda_nid_t int_mic_pin;
365 132
366 /* channel model */ 133 /* channel model */
367 const struct hda_channel_mode *channel_mode; 134 const struct hda_channel_mode *channel_mode;
@@ -381,6 +148,9 @@ struct alc_spec {
381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 148 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS]; 149 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS]; 150 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
151 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
152 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
153 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
384 154
385 /* hooks */ 155 /* hooks */
386 void (*init_hook)(struct hda_codec *codec); 156 void (*init_hook)(struct hda_codec *codec);
@@ -395,6 +165,7 @@ struct alc_spec {
395 unsigned int line_jack_present:1; 165 unsigned int line_jack_present:1;
396 unsigned int master_mute:1; 166 unsigned int master_mute:1;
397 unsigned int auto_mic:1; 167 unsigned int auto_mic:1;
168 unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
398 unsigned int automute:1; /* HP automute enabled */ 169 unsigned int automute:1; /* HP automute enabled */
399 unsigned int detect_line:1; /* Line-out detection enabled */ 170 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */ 171 unsigned int automute_lines:1; /* automute line-out as well */
@@ -402,8 +173,9 @@ struct alc_spec {
402 173
403 /* other flags */ 174 /* other flags */
404 unsigned int no_analog :1; /* digital I/O only */ 175 unsigned int no_analog :1; /* digital I/O only */
405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ 176 unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
406 unsigned int single_input_src:1; 177 unsigned int single_input_src:1;
178 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
407 179
408 /* auto-mute control */ 180 /* auto-mute control */
409 int automute_mode; 181 int automute_mode;
@@ -432,39 +204,23 @@ struct alc_spec {
432 struct alc_multi_io multi_io[4]; 204 struct alc_multi_io multi_io[4];
433}; 205};
434 206
435/* 207#define ALC_MODEL_AUTO 0 /* common for all chips */
436 * configuration template - to be copied to the spec instance
437 */
438struct alc_config_preset {
439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
440 * with spec
441 */
442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
443 const struct hda_verb *init_verbs[5];
444 unsigned int num_dacs;
445 const hda_nid_t *dac_nids;
446 hda_nid_t dig_out_nid; /* optional */
447 hda_nid_t hp_nid; /* optional */
448 const hda_nid_t *slave_dig_outs;
449 unsigned int num_adc_nids;
450 const hda_nid_t *adc_nids;
451 const hda_nid_t *capsrc_nids;
452 hda_nid_t dig_in_nid;
453 unsigned int num_channel_mode;
454 const struct hda_channel_mode *channel_mode;
455 int need_dac_fix;
456 int const_channel_count;
457 unsigned int num_mux_defs;
458 const struct hda_input_mux *input_mux;
459 void (*unsol_event)(struct hda_codec *, unsigned int);
460 void (*setup)(struct hda_codec *);
461 void (*init_hook)(struct hda_codec *);
462#ifdef CONFIG_SND_HDA_POWER_SAVE
463 const struct hda_amp_list *loopbacks;
464 void (*power_hook)(struct hda_codec *codec);
465#endif
466};
467 208
209static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
210 int dir, unsigned int bits)
211{
212 if (!nid)
213 return false;
214 if (get_wcaps(codec, nid) & (1 << (dir + 1)))
215 if (query_amp_caps(codec, nid, dir) & bits)
216 return true;
217 return false;
218}
219
220#define nid_has_mute(codec, nid, dir) \
221 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
222#define nid_has_volume(codec, nid, dir) \
223 check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
468 224
469/* 225/*
470 * input MUX handling 226 * input MUX handling
@@ -493,388 +249,83 @@ static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
493 return 0; 249 return 0;
494} 250}
495 251
496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol, 252static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
497 struct snd_ctl_elem_value *ucontrol) 253{
254 struct alc_spec *spec = codec->spec;
255 hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
256
257 if (spec->cur_adc && spec->cur_adc != new_adc) {
258 /* stream is running, let's swap the current ADC */
259 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
260 spec->cur_adc = new_adc;
261 snd_hda_codec_setup_stream(codec, new_adc,
262 spec->cur_adc_stream_tag, 0,
263 spec->cur_adc_format);
264 return true;
265 }
266 return false;
267}
268
269/* select the given imux item; either unmute exclusively or select the route */
270static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
271 unsigned int idx, bool force)
498{ 272{
499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500 struct alc_spec *spec = codec->spec; 273 struct alc_spec *spec = codec->spec;
501 const struct hda_input_mux *imux; 274 const struct hda_input_mux *imux;
502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
503 unsigned int mux_idx; 275 unsigned int mux_idx;
504 hda_nid_t nid = spec->capsrc_nids ? 276 int i, type;
505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 277 hda_nid_t nid;
506 unsigned int type;
507 278
508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 279 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509 imux = &spec->input_mux[mux_idx]; 280 imux = &spec->input_mux[mux_idx];
510 if (!imux->num_items && mux_idx > 0) 281 if (!imux->num_items && mux_idx > 0)
511 imux = &spec->input_mux[0]; 282 imux = &spec->input_mux[0];
512 283
284 if (idx >= imux->num_items)
285 idx = imux->num_items - 1;
286 if (spec->cur_mux[adc_idx] == idx && !force)
287 return 0;
288 spec->cur_mux[adc_idx] = idx;
289
290 if (spec->dyn_adc_switch) {
291 alc_dyn_adc_pcm_resetup(codec, idx);
292 adc_idx = spec->dyn_adc_idx[idx];
293 }
294
295 nid = spec->capsrc_nids ?
296 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
297
298 /* no selection? */
299 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
300 return 1;
301
513 type = get_wcaps_type(get_wcaps(codec, nid)); 302 type = get_wcaps_type(get_wcaps(codec, nid));
514 if (type == AC_WID_AUD_MIX) { 303 if (type == AC_WID_AUD_MIX) {
515 /* Matrix-mixer style (e.g. ALC882) */ 304 /* Matrix-mixer style (e.g. ALC882) */
516 unsigned int *cur_val = &spec->cur_mux[adc_idx];
517 unsigned int i, idx;
518
519 idx = ucontrol->value.enumerated.item[0];
520 if (idx >= imux->num_items)
521 idx = imux->num_items - 1;
522 if (*cur_val == idx)
523 return 0;
524 for (i = 0; i < imux->num_items; i++) { 305 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 306 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 307 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index, 308 imux->items[i].index,
528 HDA_AMP_MUTE, v); 309 HDA_AMP_MUTE, v);
529 } 310 }
530 *cur_val = idx;
531 return 1;
532 } else { 311 } else {
533 /* MUX style (e.g. ALC880) */ 312 /* MUX style (e.g. ALC880) */
534 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
535 &spec->cur_mux[adc_idx]);
536 }
537}
538
539/*
540 * channel mode setting
541 */
542static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_info *uinfo)
544{
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
547 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548 spec->num_channel_mode);
549}
550
551static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
553{
554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555 struct alc_spec *spec = codec->spec;
556 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
557 spec->num_channel_mode,
558 spec->ext_channel_count);
559}
560
561static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563{
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 struct alc_spec *spec = codec->spec;
566 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567 spec->num_channel_mode,
568 &spec->ext_channel_count);
569 if (err >= 0 && !spec->const_channel_count) {
570 spec->multiout.max_channels = spec->ext_channel_count;
571 if (spec->need_dac_fix)
572 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
573 }
574 return err;
575}
576
577/*
578 * Control the mode of pin widget settings via the mixer. "pc" is used
579 * instead of "%" to avoid consequences of accidentally treating the % as
580 * being part of a format specifier. Maximum allowed length of a value is
581 * 63 characters plus NULL terminator.
582 *
583 * Note: some retasking pin complexes seem to ignore requests for input
584 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
585 * are requested. Therefore order this list so that this behaviour will not
586 * cause problems when mixer clients move through the enum sequentially.
587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588 * March 2006.
589 */
590static const char * const alc_pin_mode_names[] = {
591 "Mic 50pc bias", "Mic 80pc bias",
592 "Line in", "Line out", "Headphone out",
593};
594static const unsigned char alc_pin_mode_values[] = {
595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
596};
597/* The control can present all 5 options, or it can limit the options based
598 * in the pin being assumed to be exclusively an input or an output pin. In
599 * addition, "input" pins may or may not process the mic bias option
600 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
601 * accept requests for bias as of chip versions up to March 2006) and/or
602 * wiring in the computer.
603 */
604#define ALC_PIN_DIR_IN 0x00
605#define ALC_PIN_DIR_OUT 0x01
606#define ALC_PIN_DIR_INOUT 0x02
607#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
608#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
609
610/* Info about the pin modes supported by the different pin direction modes.
611 * For each direction the minimum and maximum values are given.
612 */
613static const signed char alc_pin_mode_dir_info[5][2] = {
614 { 0, 2 }, /* ALC_PIN_DIR_IN */
615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
617 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
618 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
619};
620#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
621#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
622#define alc_pin_mode_n_items(_dir) \
623 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
624
625static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_info *uinfo)
627{
628 unsigned int item_num = uinfo->value.enumerated.item;
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630
631 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
632 uinfo->count = 1;
633 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
634
635 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
636 item_num = alc_pin_mode_min(dir);
637 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
638 return 0;
639}
640
641static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
643{
644 unsigned int i;
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
647 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
648 long *valp = ucontrol->value.integer.value;
649 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_PIN_WIDGET_CONTROL,
651 0x00);
652
653 /* Find enumerated value for current pinctl setting */
654 i = alc_pin_mode_min(dir);
655 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
656 i++;
657 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
658 return 0;
659}
660
661static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662 struct snd_ctl_elem_value *ucontrol)
663{
664 signed int change;
665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666 hda_nid_t nid = kcontrol->private_value & 0xffff;
667 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668 long val = *ucontrol->value.integer.value;
669 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_PIN_WIDGET_CONTROL,
671 0x00);
672
673 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
674 val = alc_pin_mode_min(dir);
675
676 change = pinctl != alc_pin_mode_values[val];
677 if (change) {
678 /* Set pin mode to that requested */
679 snd_hda_codec_write_cache(codec, nid, 0, 313 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL, 314 AC_VERB_SET_CONNECT_SEL,
681 alc_pin_mode_values[val]); 315 imux->items[idx].index);
682
683 /* Also enable the retasking pin's input/output as required
684 * for the requested pin mode. Enum values of 2 or less are
685 * input modes.
686 *
687 * Dynamically switching the input/output buffers probably
688 * reduces noise slightly (particularly on input) so we'll
689 * do it. However, having both input and output buffers
690 * enabled simultaneously doesn't seem to be problematic if
691 * this turns out to be necessary in the future.
692 */
693 if (val <= 2) {
694 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
695 HDA_AMP_MUTE, HDA_AMP_MUTE);
696 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
697 HDA_AMP_MUTE, 0);
698 } else {
699 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700 HDA_AMP_MUTE, HDA_AMP_MUTE);
701 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
702 HDA_AMP_MUTE, 0);
703 }
704 } 316 }
705 return change; 317 return 1;
706}
707
708#define ALC_PIN_MODE(xname, nid, dir) \
709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711 .info = alc_pin_mode_info, \
712 .get = alc_pin_mode_get, \
713 .put = alc_pin_mode_put, \
714 .private_value = nid | (dir<<16) }
715
716/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
717 * together using a mask with more than one bit set. This control is
718 * currently used only by the ALC260 test model. At this stage they are not
719 * needed for any "production" models.
720 */
721#ifdef CONFIG_SND_DEBUG
722#define alc_gpio_data_info snd_ctl_boolean_mono_info
723
724static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726{
727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
728 hda_nid_t nid = kcontrol->private_value & 0xffff;
729 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
730 long *valp = ucontrol->value.integer.value;
731 unsigned int val = snd_hda_codec_read(codec, nid, 0,
732 AC_VERB_GET_GPIO_DATA, 0x00);
733
734 *valp = (val & mask) != 0;
735 return 0;
736}
737static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
739{
740 signed int change;
741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
742 hda_nid_t nid = kcontrol->private_value & 0xffff;
743 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
744 long val = *ucontrol->value.integer.value;
745 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746 AC_VERB_GET_GPIO_DATA,
747 0x00);
748
749 /* Set/unset the masked GPIO bit(s) as needed */
750 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751 if (val == 0)
752 gpio_data &= ~mask;
753 else
754 gpio_data |= mask;
755 snd_hda_codec_write_cache(codec, nid, 0,
756 AC_VERB_SET_GPIO_DATA, gpio_data);
757
758 return change;
759}
760#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
761 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
762 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
763 .info = alc_gpio_data_info, \
764 .get = alc_gpio_data_get, \
765 .put = alc_gpio_data_put, \
766 .private_value = nid | (mask<<16) }
767#endif /* CONFIG_SND_DEBUG */
768
769/* A switch control to allow the enabling of the digital IO pins on the
770 * ALC260. This is incredibly simplistic; the intention of this control is
771 * to provide something in the test model allowing digital outputs to be
772 * identified if present. If models are found which can utilise these
773 * outputs a more complete mixer control can be devised for those models if
774 * necessary.
775 */
776#ifdef CONFIG_SND_DEBUG
777#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
778
779static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
781{
782 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783 hda_nid_t nid = kcontrol->private_value & 0xffff;
784 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785 long *valp = ucontrol->value.integer.value;
786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
787 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
788
789 *valp = (val & mask) != 0;
790 return 0;
791}
792static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794{
795 signed int change;
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long val = *ucontrol->value.integer.value;
800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_DIGI_CONVERT_1,
802 0x00);
803
804 /* Set/unset the masked control bit(s) as needed */
805 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
806 if (val==0)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811 ctrl_data);
812
813 return change;
814}
815#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
816 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
818 .info = alc_spdif_ctrl_info, \
819 .get = alc_spdif_ctrl_get, \
820 .put = alc_spdif_ctrl_put, \
821 .private_value = nid | (mask<<16) }
822#endif /* CONFIG_SND_DEBUG */
823
824/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
825 * Again, this is only used in the ALC26x test models to help identify when
826 * the EAPD line must be asserted for features to work.
827 */
828#ifdef CONFIG_SND_DEBUG
829#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
830
831static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
832 struct snd_ctl_elem_value *ucontrol)
833{
834 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
835 hda_nid_t nid = kcontrol->private_value & 0xffff;
836 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
837 long *valp = ucontrol->value.integer.value;
838 unsigned int val = snd_hda_codec_read(codec, nid, 0,
839 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
840
841 *valp = (val & mask) != 0;
842 return 0;
843} 318}
844 319
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 320static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol) 321 struct snd_ctl_elem_value *ucontrol)
847{ 322{
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff; 324 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 325 return alc_mux_select(codec, adc_idx,
852 long val = *ucontrol->value.integer.value; 326 ucontrol->value.enumerated.item[0], false);
853 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_EAPD_BTLENABLE,
855 0x00);
856
857 /* Set/unset the masked control bit(s) as needed */
858 change = (!val ? 0 : mask) != (ctrl_data & mask);
859 if (!val)
860 ctrl_data &= ~mask;
861 else
862 ctrl_data |= mask;
863 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864 ctrl_data);
865
866 return change;
867} 327}
868 328
869#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
871 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
872 .info = alc_eapd_ctrl_info, \
873 .get = alc_eapd_ctrl_get, \
874 .put = alc_eapd_ctrl_put, \
875 .private_value = nid | (mask<<16) }
876#endif /* CONFIG_SND_DEBUG */
877
878/* 329/*
879 * set up the input pin config (depending on the given auto-pin type) 330 * set up the input pin config (depending on the given auto-pin type)
880 */ 331 */
@@ -903,29 +354,10 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 354 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904} 355}
905 356
906static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907{
908 struct alc_spec *spec = codec->spec;
909 struct auto_pin_cfg *cfg = &spec->autocfg;
910
911 if (!cfg->line_outs) {
912 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913 cfg->line_out_pins[cfg->line_outs])
914 cfg->line_outs++;
915 }
916 if (!cfg->speaker_outs) {
917 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918 cfg->speaker_pins[cfg->speaker_outs])
919 cfg->speaker_outs++;
920 }
921 if (!cfg->hp_outs) {
922 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923 cfg->hp_pins[cfg->hp_outs])
924 cfg->hp_outs++;
925 }
926}
927
928/* 357/*
358 * Append the given mixer and verb elements for the later use
359 * The mixer array is referred in build_controls(), and init_verbs are
360 * called in init().
929 */ 361 */
930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 362static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931{ 363{
@@ -942,61 +374,8 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
942} 374}
943 375
944/* 376/*
945 * set up from the preset table 377 * GPIO setup tables, used in initialization
946 */ 378 */
947static void setup_preset(struct hda_codec *codec,
948 const struct alc_config_preset *preset)
949{
950 struct alc_spec *spec = codec->spec;
951 int i;
952
953 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
954 add_mixer(spec, preset->mixers[i]);
955 spec->cap_mixer = preset->cap_mixer;
956 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957 i++)
958 add_verb(spec, preset->init_verbs[i]);
959
960 spec->channel_mode = preset->channel_mode;
961 spec->num_channel_mode = preset->num_channel_mode;
962 spec->need_dac_fix = preset->need_dac_fix;
963 spec->const_channel_count = preset->const_channel_count;
964
965 if (preset->const_channel_count)
966 spec->multiout.max_channels = preset->const_channel_count;
967 else
968 spec->multiout.max_channels = spec->channel_mode[0].channels;
969 spec->ext_channel_count = spec->channel_mode[0].channels;
970
971 spec->multiout.num_dacs = preset->num_dacs;
972 spec->multiout.dac_nids = preset->dac_nids;
973 spec->multiout.dig_out_nid = preset->dig_out_nid;
974 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
975 spec->multiout.hp_nid = preset->hp_nid;
976
977 spec->num_mux_defs = preset->num_mux_defs;
978 if (!spec->num_mux_defs)
979 spec->num_mux_defs = 1;
980 spec->input_mux = preset->input_mux;
981
982 spec->num_adc_nids = preset->num_adc_nids;
983 spec->adc_nids = preset->adc_nids;
984 spec->capsrc_nids = preset->capsrc_nids;
985 spec->dig_in_nid = preset->dig_in_nid;
986
987 spec->unsol_event = preset->unsol_event;
988 spec->init_hook = preset->init_hook;
989#ifdef CONFIG_SND_HDA_POWER_SAVE
990 spec->power_hook = preset->power_hook;
991 spec->loopback.amplist = preset->loopbacks;
992#endif
993
994 if (preset->setup)
995 preset->setup(codec);
996
997 alc_fixup_autocfg_pin_nums(codec);
998}
999
1000/* Enable GPIO mask and set output */ 379/* Enable GPIO mask and set output */
1001static const struct hda_verb alc_gpio1_init_verbs[] = { 380static const struct hda_verb alc_gpio1_init_verbs[] = {
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 381 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
@@ -1051,14 +430,19 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1051 alc_fix_pll(codec); 430 alc_fix_pll(codec);
1052} 431}
1053 432
433/*
434 * Jack-reporting via input-jack layer
435 */
436
437/* initialization of jacks; currently checks only a few known pins */
1054static int alc_init_jacks(struct hda_codec *codec) 438static int alc_init_jacks(struct hda_codec *codec)
1055{ 439{
1056#ifdef CONFIG_SND_HDA_INPUT_JACK 440#ifdef CONFIG_SND_HDA_INPUT_JACK
1057 struct alc_spec *spec = codec->spec; 441 struct alc_spec *spec = codec->spec;
1058 int err; 442 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 443 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin; 444 unsigned int mic_nid = spec->ext_mic_pin;
1061 unsigned int dock_nid = spec->dock_mic.pin; 445 unsigned int dock_nid = spec->dock_mic_pin;
1062 446
1063 if (hp_nid) { 447 if (hp_nid) {
1064 err = snd_hda_input_jack_add(codec, hp_nid, 448 err = snd_hda_input_jack_add(codec, hp_nid,
@@ -1086,7 +470,12 @@ static int alc_init_jacks(struct hda_codec *codec)
1086 return 0; 470 return 0;
1087} 471}
1088 472
1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 473/*
474 * Jack detections for HP auto-mute and mic-switch
475 */
476
477/* check each pin in the given array; returns true if any of them is plugged */
478static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090{ 479{
1091 int i, present = 0; 480 int i, present = 0;
1092 481
@@ -1100,6 +489,7 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1100 return present; 489 return present;
1101} 490}
1102 491
492/* standard HP/line-out auto-mute helper */
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 493static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out) 494 bool mute, bool hp_out)
1105{ 495{
@@ -1170,6 +560,7 @@ static void update_speakers(struct hda_codec *codec)
1170 spec->autocfg.line_out_pins, on, false); 560 spec->autocfg.line_out_pins, on, false);
1171} 561}
1172 562
563/* standard HP-automute helper */
1173static void alc_hp_automute(struct hda_codec *codec) 564static void alc_hp_automute(struct hda_codec *codec)
1174{ 565{
1175 struct alc_spec *spec = codec->spec; 566 struct alc_spec *spec = codec->spec;
@@ -1182,6 +573,7 @@ static void alc_hp_automute(struct hda_codec *codec)
1182 update_speakers(codec); 573 update_speakers(codec);
1183} 574}
1184 575
576/* standard line-out-automute helper */
1185static void alc_line_automute(struct hda_codec *codec) 577static void alc_line_automute(struct hda_codec *codec)
1186{ 578{
1187 struct alc_spec *spec = codec->spec; 579 struct alc_spec *spec = codec->spec;
@@ -1194,106 +586,33 @@ static void alc_line_automute(struct hda_codec *codec)
1194 update_speakers(codec); 586 update_speakers(codec);
1195} 587}
1196 588
1197static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 589#define get_connection_index(codec, mux, nid) \
1198 hda_nid_t nid) 590 snd_hda_get_conn_index(codec, mux, nid, 0)
1199{
1200 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1201 int i, nums;
1202
1203 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1204 for (i = 0; i < nums; i++)
1205 if (conn[i] == nid)
1206 return i;
1207 return -1;
1208}
1209
1210/* switch the current ADC according to the jack state */
1211static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1212{
1213 struct alc_spec *spec = codec->spec;
1214 unsigned int present;
1215 hda_nid_t new_adc;
1216
1217 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1218 if (present)
1219 spec->cur_adc_idx = 1;
1220 else
1221 spec->cur_adc_idx = 0;
1222 new_adc = spec->adc_nids[spec->cur_adc_idx];
1223 if (spec->cur_adc && spec->cur_adc != new_adc) {
1224 /* stream is running, let's swap the current ADC */
1225 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1226 spec->cur_adc = new_adc;
1227 snd_hda_codec_setup_stream(codec, new_adc,
1228 spec->cur_adc_stream_tag, 0,
1229 spec->cur_adc_format);
1230 }
1231}
1232 591
592/* standard mic auto-switch helper */
1233static void alc_mic_automute(struct hda_codec *codec) 593static void alc_mic_automute(struct hda_codec *codec)
1234{ 594{
1235 struct alc_spec *spec = codec->spec; 595 struct alc_spec *spec = codec->spec;
1236 struct alc_mic_route *dead1, *dead2, *alive; 596 hda_nid_t *pins = spec->imux_pins;
1237 unsigned int present, type;
1238 hda_nid_t cap_nid;
1239 597
1240 if (!spec->auto_mic) 598 if (!spec->auto_mic || !spec->auto_mic_valid_imux)
1241 return;
1242 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243 return; 599 return;
1244 if (snd_BUG_ON(!spec->adc_nids)) 600 if (snd_BUG_ON(!spec->adc_nids))
1245 return; 601 return;
1246 602 if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0))
1247 if (spec->dual_adc_switch) {
1248 alc_dual_mic_adc_auto_switch(codec);
1249 return; 603 return;
1250 }
1251
1252 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1253
1254 alive = &spec->int_mic;
1255 dead1 = &spec->ext_mic;
1256 dead2 = &spec->dock_mic;
1257
1258 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1259 if (present) {
1260 alive = &spec->ext_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->dock_mic;
1263 }
1264 if (!present && spec->dock_mic.pin > 0) {
1265 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266 if (present) {
1267 alive = &spec->dock_mic;
1268 dead1 = &spec->int_mic;
1269 dead2 = &spec->ext_mic;
1270 }
1271 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1272 }
1273 604
1274 type = get_wcaps_type(get_wcaps(codec, cap_nid)); 605 if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
1275 if (type == AC_WID_AUD_MIX) { 606 alc_mux_select(codec, 0, spec->ext_mic_idx, false);
1276 /* Matrix-mixer style (e.g. ALC882) */ 607 else if (spec->dock_mic_idx >= 0 &&
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, 608 snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
1278 alive->mux_idx, 609 alc_mux_select(codec, 0, spec->dock_mic_idx, false);
1279 HDA_AMP_MUTE, 0); 610 else
1280 if (dead1->pin > 0) 611 alc_mux_select(codec, 0, spec->int_mic_idx, false);
1281 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282 dead1->mux_idx,
1283 HDA_AMP_MUTE, HDA_AMP_MUTE);
1284 if (dead2->pin > 0)
1285 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286 dead2->mux_idx,
1287 HDA_AMP_MUTE, HDA_AMP_MUTE);
1288 } else {
1289 /* MUX style (e.g. ALC880) */
1290 snd_hda_codec_write_cache(codec, cap_nid, 0,
1291 AC_VERB_SET_CONNECT_SEL,
1292 alive->mux_idx);
1293 }
1294 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1295 612
1296 /* FIXME: analog mixer */ 613 snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]);
614 if (spec->dock_mic_idx >= 0)
615 snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]);
1297} 616}
1298 617
1299/* unsolicited event for HP jack sensing */ 618/* unsolicited event for HP jack sensing */
@@ -1304,18 +623,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1304 else 623 else
1305 res >>= 26; 624 res >>= 26;
1306 switch (res) { 625 switch (res) {
1307 case ALC880_HP_EVENT: 626 case ALC_HP_EVENT:
1308 alc_hp_automute(codec); 627 alc_hp_automute(codec);
1309 break; 628 break;
1310 case ALC880_FRONT_EVENT: 629 case ALC_FRONT_EVENT:
1311 alc_line_automute(codec); 630 alc_line_automute(codec);
1312 break; 631 break;
1313 case ALC880_MIC_EVENT: 632 case ALC_MIC_EVENT:
1314 alc_mic_automute(codec); 633 alc_mic_automute(codec);
1315 break; 634 break;
1316 } 635 }
1317} 636}
1318 637
638/* call init functions of standard auto-mute helpers */
1319static void alc_inithook(struct hda_codec *codec) 639static void alc_inithook(struct hda_codec *codec)
1320{ 640{
1321 alc_hp_automute(codec); 641 alc_hp_automute(codec);
@@ -1341,6 +661,7 @@ static void alc888_coef_init(struct hda_codec *codec)
1341 AC_VERB_SET_PROC_COEF, 0x3030); 661 AC_VERB_SET_PROC_COEF, 0x3030);
1342} 662}
1343 663
664/* additional initialization for ALC889 variants */
1344static void alc889_coef_init(struct hda_codec *codec) 665static void alc889_coef_init(struct hda_codec *codec)
1345{ 666{
1346 unsigned int tmp; 667 unsigned int tmp;
@@ -1365,28 +686,12 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1365static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) 686static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366{ 687{
1367 /* We currently only handle front, HP */ 688 /* We currently only handle front, HP */
1368 switch (codec->vendor_id) { 689 static hda_nid_t pins[] = {
1369 case 0x10ec0260: 690 0x0f, 0x10, 0x14, 0x15, 0
1370 set_eapd(codec, 0x0f, on); 691 };
1371 set_eapd(codec, 0x10, on); 692 hda_nid_t *p;
1372 break; 693 for (p = pins; *p; p++)
1373 case 0x10ec0262: 694 set_eapd(codec, *p, on);
1374 case 0x10ec0267:
1375 case 0x10ec0268:
1376 case 0x10ec0269:
1377 case 0x10ec0270:
1378 case 0x10ec0272:
1379 case 0x10ec0660:
1380 case 0x10ec0662:
1381 case 0x10ec0663:
1382 case 0x10ec0665:
1383 case 0x10ec0862:
1384 case 0x10ec0889:
1385 case 0x10ec0892:
1386 set_eapd(codec, 0x14, on);
1387 set_eapd(codec, 0x15, on);
1388 break;
1389 }
1390} 695}
1391 696
1392/* generic shutup callback; 697/* generic shutup callback;
@@ -1398,10 +703,12 @@ static void alc_eapd_shutup(struct hda_codec *codec)
1398 msleep(200); 703 msleep(200);
1399} 704}
1400 705
706/* generic EAPD initialization */
1401static void alc_auto_init_amp(struct hda_codec *codec, int type) 707static void alc_auto_init_amp(struct hda_codec *codec, int type)
1402{ 708{
1403 unsigned int tmp; 709 unsigned int tmp;
1404 710
711 alc_auto_setup_eapd(codec, true);
1405 switch (type) { 712 switch (type) {
1406 case ALC_INIT_GPIO1: 713 case ALC_INIT_GPIO1:
1407 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 714 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
@@ -1413,7 +720,6 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1413 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 720 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414 break; 721 break;
1415 case ALC_INIT_DEFAULT: 722 case ALC_INIT_DEFAULT:
1416 alc_auto_setup_eapd(codec, true);
1417 switch (codec->vendor_id) { 723 switch (codec->vendor_id) {
1418 case 0x10ec0260: 724 case 0x10ec0260:
1419 snd_hda_codec_write(codec, 0x1a, 0, 725 snd_hda_codec_write(codec, 0x1a, 0,
@@ -1457,6 +763,9 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1457 } 763 }
1458} 764}
1459 765
766/*
767 * Auto-Mute mode mixer enum support
768 */
1460static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 769static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_info *uinfo) 770 struct snd_ctl_elem_info *uinfo)
1462{ 771{
@@ -1543,7 +852,11 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {
1543 .put = alc_automute_mode_put, 852 .put = alc_automute_mode_put,
1544}; 853};
1545 854
1546static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 855static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
856{
857 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
858 return snd_array_new(&spec->kctls);
859}
1547 860
1548static int alc_add_automute_mode_enum(struct hda_codec *codec) 861static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549{ 862{
@@ -1560,6 +873,10 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
1560 return 0; 873 return 0;
1561} 874}
1562 875
876/*
877 * Check the availability of HP/line-out auto-mute;
878 * Set up appropriately if really supported
879 */
1563static void alc_init_auto_hp(struct hda_codec *codec) 880static void alc_init_auto_hp(struct hda_codec *codec)
1564{ 881{
1565 struct alc_spec *spec = codec->spec; 882 struct alc_spec *spec = codec->spec;
@@ -1598,7 +915,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1598 nid); 915 nid);
1599 snd_hda_codec_write_cache(codec, nid, 0, 916 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE, 917 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_HP_EVENT); 918 AC_USRSP_EN | ALC_HP_EVENT);
1602 spec->automute = 1; 919 spec->automute = 1;
1603 spec->automute_mode = ALC_AUTOMUTE_PIN; 920 spec->automute_mode = ALC_AUTOMUTE_PIN;
1604 } 921 }
@@ -1613,7 +930,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1613 "on NID 0x%x\n", nid); 930 "on NID 0x%x\n", nid);
1614 snd_hda_codec_write_cache(codec, nid, 0, 931 snd_hda_codec_write_cache(codec, nid, 0,
1615 AC_VERB_SET_UNSOLICITED_ENABLE, 932 AC_VERB_SET_UNSOLICITED_ENABLE,
1616 AC_USRSP_EN | ALC880_FRONT_EVENT); 933 AC_USRSP_EN | ALC_FRONT_EVENT);
1617 spec->detect_line = 1; 934 spec->detect_line = 1;
1618 } 935 }
1619 spec->automute_lines = spec->detect_line; 936 spec->automute_lines = spec->detect_line;
@@ -1626,6 +943,132 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1626 } 943 }
1627} 944}
1628 945
946/* return the position of NID in the list, or -1 if not found */
947static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
948{
949 int i;
950 for (i = 0; i < nums; i++)
951 if (list[i] == nid)
952 return i;
953 return -1;
954}
955
956/* check whether dynamic ADC-switching is available */
957static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
958{
959 struct alc_spec *spec = codec->spec;
960 struct hda_input_mux *imux = &spec->private_imux[0];
961 int i, n, idx;
962 hda_nid_t cap, pin;
963
964 if (imux != spec->input_mux) /* no dynamic imux? */
965 return false;
966
967 for (n = 0; n < spec->num_adc_nids; n++) {
968 cap = spec->private_capsrc_nids[n];
969 for (i = 0; i < imux->num_items; i++) {
970 pin = spec->imux_pins[i];
971 if (!pin)
972 return false;
973 if (get_connection_index(codec, cap, pin) < 0)
974 break;
975 }
976 if (i >= imux->num_items)
977 return true; /* no ADC-switch is needed */
978 }
979
980 for (i = 0; i < imux->num_items; i++) {
981 pin = spec->imux_pins[i];
982 for (n = 0; n < spec->num_adc_nids; n++) {
983 cap = spec->private_capsrc_nids[n];
984 idx = get_connection_index(codec, cap, pin);
985 if (idx >= 0) {
986 imux->items[i].index = idx;
987 spec->dyn_adc_idx[i] = n;
988 break;
989 }
990 }
991 }
992
993 snd_printdd("realtek: enabling ADC switching\n");
994 spec->dyn_adc_switch = 1;
995 return true;
996}
997
998/* rebuild imux for matching with the given auto-mic pins (if not yet) */
999static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1000{
1001 struct alc_spec *spec = codec->spec;
1002 struct hda_input_mux *imux;
1003 static char * const texts[3] = {
1004 "Mic", "Internal Mic", "Dock Mic"
1005 };
1006 int i;
1007
1008 if (!spec->auto_mic)
1009 return false;
1010 imux = &spec->private_imux[0];
1011 if (spec->input_mux == imux)
1012 return true;
1013 spec->imux_pins[0] = spec->ext_mic_pin;
1014 spec->imux_pins[1] = spec->int_mic_pin;
1015 spec->imux_pins[2] = spec->dock_mic_pin;
1016 for (i = 0; i < 3; i++) {
1017 strcpy(imux->items[i].label, texts[i]);
1018 if (spec->imux_pins[i])
1019 imux->num_items = i + 1;
1020 }
1021 spec->num_mux_defs = 1;
1022 spec->input_mux = imux;
1023 return true;
1024}
1025
1026/* check whether all auto-mic pins are valid; setup indices if OK */
1027static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1028{
1029 struct alc_spec *spec = codec->spec;
1030 const struct hda_input_mux *imux;
1031
1032 if (!spec->auto_mic)
1033 return false;
1034 if (spec->auto_mic_valid_imux)
1035 return true; /* already checked */
1036
1037 /* fill up imux indices */
1038 if (!alc_check_dyn_adc_switch(codec)) {
1039 spec->auto_mic = 0;
1040 return false;
1041 }
1042
1043 imux = spec->input_mux;
1044 spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
1045 spec->imux_pins, imux->num_items);
1046 spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
1047 spec->imux_pins, imux->num_items);
1048 spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
1049 spec->imux_pins, imux->num_items);
1050 if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
1051 spec->auto_mic = 0;
1052 return false; /* no corresponding imux */
1053 }
1054
1055 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1056 AC_VERB_SET_UNSOLICITED_ENABLE,
1057 AC_USRSP_EN | ALC_MIC_EVENT);
1058 if (spec->dock_mic_pin)
1059 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1060 AC_VERB_SET_UNSOLICITED_ENABLE,
1061 AC_USRSP_EN | ALC_MIC_EVENT);
1062
1063 spec->auto_mic_valid_imux = 1;
1064 spec->auto_mic = 1;
1065 return true;
1066}
1067
1068/*
1069 * Check the availability of auto-mic switch;
1070 * Set up if really supported
1071 */
1629static void alc_init_auto_mic(struct hda_codec *codec) 1072static void alc_init_auto_mic(struct hda_codec *codec)
1630{ 1073{
1631 struct alc_spec *spec = codec->spec; 1074 struct alc_spec *spec = codec->spec;
@@ -1633,6 +1076,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1633 hda_nid_t fixed, ext, dock; 1076 hda_nid_t fixed, ext, dock;
1634 int i; 1077 int i;
1635 1078
1079 spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
1080
1636 fixed = ext = dock = 0; 1081 fixed = ext = dock = 0;
1637 for (i = 0; i < cfg->num_inputs; i++) { 1082 for (i = 0; i < cfg->num_inputs; i++) {
1638 hda_nid_t nid = cfg->inputs[i].pin; 1083 hda_nid_t nid = cfg->inputs[i].pin;
@@ -1674,21 +1119,32 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1674 return; /* no unsol support */ 1119 return; /* no unsol support */
1675 if (dock && !is_jack_detectable(codec, dock)) 1120 if (dock && !is_jack_detectable(codec, dock))
1676 return; /* no unsol support */ 1121 return; /* no unsol support */
1122
1123 /* check imux indices */
1124 spec->ext_mic_pin = ext;
1125 spec->int_mic_pin = fixed;
1126 spec->dock_mic_pin = dock;
1127
1128 spec->auto_mic = 1;
1129 if (!alc_auto_mic_check_imux(codec))
1130 return;
1131
1677 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1132 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1678 ext, fixed, dock); 1133 ext, fixed, dock);
1679 spec->ext_mic.pin = ext;
1680 spec->dock_mic.pin = dock;
1681 spec->int_mic.pin = fixed;
1682 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1683 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1684 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1685 spec->auto_mic = 1;
1686 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1687 AC_VERB_SET_UNSOLICITED_ENABLE,
1688 AC_USRSP_EN | ALC880_MIC_EVENT);
1689 spec->unsol_event = alc_sku_unsol_event; 1134 spec->unsol_event = alc_sku_unsol_event;
1690} 1135}
1691 1136
1137/* check the availabilities of auto-mute and auto-mic switches */
1138static void alc_auto_check_switches(struct hda_codec *codec)
1139{
1140 alc_init_auto_hp(codec);
1141 alc_init_auto_mic(codec);
1142}
1143
1144/*
1145 * Realtek SSID verification
1146 */
1147
1692/* Could be any non-zero and even value. When used as fixup, tells 1148/* Could be any non-zero and even value. When used as fixup, tells
1693 * the driver to ignore any present sku defines. 1149 * the driver to ignore any present sku defines.
1694 */ 1150 */
@@ -1759,6 +1215,12 @@ do_sku:
1759 return 0; 1215 return 0;
1760} 1216}
1761 1217
1218/* return true if the given NID is found in the list */
1219static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1220{
1221 return find_idx_in_nid_list(nid, list, nums) >= 0;
1222}
1223
1762/* check subsystem ID and set up device-specific initialization; 1224/* check subsystem ID and set up device-specific initialization;
1763 * return 1 if initialized, 0 if invalid SSID 1225 * return 1 if initialized, 0 if invalid SSID
1764 */ 1226 */
@@ -1868,27 +1330,24 @@ do_sku:
1868 nid = porti; 1330 nid = porti;
1869 else 1331 else
1870 return 1; 1332 return 1;
1871 for (i = 0; i < spec->autocfg.line_outs; i++) 1333 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1872 if (spec->autocfg.line_out_pins[i] == nid) 1334 spec->autocfg.line_outs))
1873 return 1; 1335 return 1;
1874 spec->autocfg.hp_pins[0] = nid; 1336 spec->autocfg.hp_pins[0] = nid;
1875 } 1337 }
1876 return 1; 1338 return 1;
1877} 1339}
1878 1340
1879static void alc_ssid_check(struct hda_codec *codec, 1341/* Check the validity of ALC subsystem-id
1880 hda_nid_t porta, hda_nid_t porte, 1342 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
1881 hda_nid_t portd, hda_nid_t porti) 1343static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
1882{ 1344{
1883 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1345 if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
1884 struct alc_spec *spec = codec->spec; 1346 struct alc_spec *spec = codec->spec;
1885 snd_printd("realtek: " 1347 snd_printd("realtek: "
1886 "Enable default setup for auto mode as fallback\n"); 1348 "Enable default setup for auto mode as fallback\n");
1887 spec->init_amp = ALC_INIT_DEFAULT; 1349 spec->init_amp = ALC_INIT_DEFAULT;
1888 } 1350 }
1889
1890 alc_init_auto_hp(codec);
1891 alc_init_auto_mic(codec);
1892} 1351}
1893 1352
1894/* 1353/*
@@ -2036,6 +1495,9 @@ static void alc_pick_fixup(struct hda_codec *codec,
2036 } 1495 }
2037} 1496}
2038 1497
1498/*
1499 * COEF access helper functions
1500 */
2039static int alc_read_coef_idx(struct hda_codec *codec, 1501static int alc_read_coef_idx(struct hda_codec *codec,
2040 unsigned int coef_idx) 1502 unsigned int coef_idx)
2041{ 1503{
@@ -2056,20 +1518,32 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2056 coef_val); 1518 coef_val);
2057} 1519}
2058 1520
1521/*
1522 * Digital I/O handling
1523 */
1524
2059/* set right pin controls for digital I/O */ 1525/* set right pin controls for digital I/O */
2060static void alc_auto_init_digital(struct hda_codec *codec) 1526static void alc_auto_init_digital(struct hda_codec *codec)
2061{ 1527{
2062 struct alc_spec *spec = codec->spec; 1528 struct alc_spec *spec = codec->spec;
2063 int i; 1529 int i;
2064 hda_nid_t pin; 1530 hda_nid_t pin, dac;
2065 1531
2066 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1532 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2067 pin = spec->autocfg.dig_out_pins[i]; 1533 pin = spec->autocfg.dig_out_pins[i];
2068 if (pin) { 1534 if (!pin)
2069 snd_hda_codec_write(codec, pin, 0, 1535 continue;
2070 AC_VERB_SET_PIN_WIDGET_CONTROL, 1536 snd_hda_codec_write(codec, pin, 0,
2071 PIN_OUT); 1537 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2072 } 1538 if (!i)
1539 dac = spec->multiout.dig_out_nid;
1540 else
1541 dac = spec->slave_dig_outs[i - 1];
1542 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
1543 continue;
1544 snd_hda_codec_write(codec, dac, 0,
1545 AC_VERB_SET_AMP_GAIN_MUTE,
1546 AMP_OUT_UNMUTE);
2073 } 1547 }
2074 pin = spec->autocfg.dig_in_pin; 1548 pin = spec->autocfg.dig_in_pin;
2075 if (pin) 1549 if (pin)
@@ -2087,11 +1561,13 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2087 1561
2088 /* support multiple SPDIFs; the secondary is set up as a slave */ 1562 /* support multiple SPDIFs; the secondary is set up as a slave */
2089 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1563 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1564 hda_nid_t conn[4];
2090 err = snd_hda_get_connections(codec, 1565 err = snd_hda_get_connections(codec,
2091 spec->autocfg.dig_out_pins[i], 1566 spec->autocfg.dig_out_pins[i],
2092 &dig_nid, 1); 1567 conn, ARRAY_SIZE(conn));
2093 if (err < 0) 1568 if (err < 0)
2094 continue; 1569 continue;
1570 dig_nid = conn[0]; /* assume the first element is audio-out */
2095 if (!i) { 1571 if (!i) {
2096 spec->multiout.dig_out_nid = dig_nid; 1572 spec->multiout.dig_out_nid = dig_nid;
2097 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1573 spec->dig_out_type = spec->autocfg.dig_out_type[0];
@@ -2124,572 +1600,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2124} 1600}
2125 1601
2126/* 1602/*
2127 * ALC888 1603 * capture mixer elements
2128 */
2129
2130/*
2131 * 2ch mode
2132 */ 1604 */
2133static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2134/* Mic-in jack as mic in */
2135 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2136 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2137/* Line-in jack as Line in */
2138 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2139 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2140/* Line-Out as Front */
2141 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2142 { } /* end */
2143};
2144
2145/*
2146 * 4ch mode
2147 */
2148static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2149/* Mic-in jack as mic in */
2150 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2151 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2152/* Line-in jack as Surround */
2153 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2154 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2155/* Line-Out as Front */
2156 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2157 { } /* end */
2158};
2159
2160/*
2161 * 6ch mode
2162 */
2163static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2164/* Mic-in jack as CLFE */
2165 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2166 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2167/* Line-in jack as Surround */
2168 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2169 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2170/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2171 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2172 { } /* end */
2173};
2174
2175/*
2176 * 8ch mode
2177 */
2178static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2179/* Mic-in jack as CLFE */
2180 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2181 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2182/* Line-in jack as Surround */
2183 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2184 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2185/* Line-Out as Side */
2186 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2187 { } /* end */
2188};
2189
2190static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2191 { 2, alc888_4ST_ch2_intel_init },
2192 { 4, alc888_4ST_ch4_intel_init },
2193 { 6, alc888_4ST_ch6_intel_init },
2194 { 8, alc888_4ST_ch8_intel_init },
2195};
2196
2197/*
2198 * ALC888 Fujitsu Siemens Amillo xa3530
2199 */
2200
2201static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2202/* Front Mic: set to PIN_IN (empty by default) */
2203 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2204/* Connect Internal HP to Front */
2205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2207 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2208/* Connect Bass HP to Front */
2209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2212/* Connect Line-Out side jack (SPDIF) to Side */
2213 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2214 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2215 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2216/* Connect Mic jack to CLFE */
2217 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2218 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2220/* Connect Line-in jack to Surround */
2221 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2224/* Connect HP out jack to Front */
2225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2228/* Enable unsolicited event for HP jack and Line-out jack */
2229 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2230 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2231 {}
2232};
2233
2234static void alc889_automute_setup(struct hda_codec *codec)
2235{
2236 struct alc_spec *spec = codec->spec;
2237
2238 spec->autocfg.hp_pins[0] = 0x15;
2239 spec->autocfg.speaker_pins[0] = 0x14;
2240 spec->autocfg.speaker_pins[1] = 0x16;
2241 spec->autocfg.speaker_pins[2] = 0x17;
2242 spec->autocfg.speaker_pins[3] = 0x19;
2243 spec->autocfg.speaker_pins[4] = 0x1a;
2244 spec->automute = 1;
2245 spec->automute_mode = ALC_AUTOMUTE_AMP;
2246}
2247
2248static void alc889_intel_init_hook(struct hda_codec *codec)
2249{
2250 alc889_coef_init(codec);
2251 alc_hp_automute(codec);
2252}
2253
2254static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2255{
2256 struct alc_spec *spec = codec->spec;
2257
2258 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2259 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2260 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2261 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2262 spec->automute = 1;
2263 spec->automute_mode = ALC_AUTOMUTE_AMP;
2264}
2265
2266/*
2267 * ALC888 Acer Aspire 4930G model
2268 */
2269
2270static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2271/* Front Mic: set to PIN_IN (empty by default) */
2272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2273/* Unselect Front Mic by default in input mixer 3 */
2274 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2275/* Enable unsolicited event for HP jack */
2276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2277/* Connect Internal HP to front */
2278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2281/* Connect HP out to front */
2282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2285 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2286 { }
2287};
2288
2289/*
2290 * ALC888 Acer Aspire 6530G model
2291 */
2292
2293static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2294/* Route to built-in subwoofer as well as speakers */
2295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2297 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299/* Bias voltage on for external mic port */
2300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2301/* Front Mic: set to PIN_IN (empty by default) */
2302 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2303/* Unselect Front Mic by default in input mixer 3 */
2304 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2305/* Enable unsolicited event for HP jack */
2306 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2307/* Enable speaker output */
2308 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2309 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2311/* Enable headphone output */
2312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2313 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2315 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2316 { }
2317};
2318
2319/*
2320 *ALC888 Acer Aspire 7730G model
2321 */
2322
2323static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2324/* Bias voltage on for external mic port */
2325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2326/* Front Mic: set to PIN_IN (empty by default) */
2327 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2328/* Unselect Front Mic by default in input mixer 3 */
2329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2330/* Enable unsolicited event for HP jack */
2331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2332/* Enable speaker output */
2333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2336/* Enable headphone output */
2337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2340 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2341/*Enable internal subwoofer */
2342 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2345 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2346 { }
2347};
2348
2349/*
2350 * ALC889 Acer Aspire 8930G model
2351 */
2352
2353static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2354/* Front Mic: set to PIN_IN (empty by default) */
2355 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2356/* Unselect Front Mic by default in input mixer 3 */
2357 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2358/* Enable unsolicited event for HP jack */
2359 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2360/* Connect Internal Front to Front */
2361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2364/* Connect Internal Rear to Rear */
2365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2368/* Connect Internal CLFE to CLFE */
2369 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2372/* Connect HP out to Front */
2373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2376/* Enable all DACs */
2377/* DAC DISABLE/MUTE 1? */
2378/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2379 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2380 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2381/* DAC DISABLE/MUTE 2? */
2382/* some bit here disables the other DACs. Init=0x4900 */
2383 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2384 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2385/* DMIC fix
2386 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2387 * which makes the stereo useless. However, either the mic or the ALC889
2388 * makes the signal become a difference/sum signal instead of standard
2389 * stereo, which is annoying. So instead we flip this bit which makes the
2390 * codec replicate the sum signal to both channels, turning it into a
2391 * normal mono mic.
2392 */
2393/* DMIC_CONTROL? Init value = 0x0001 */
2394 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2395 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2396 { }
2397};
2398
2399static const struct hda_input_mux alc888_2_capture_sources[2] = {
2400 /* Front mic only available on one ADC */
2401 {
2402 .num_items = 4,
2403 .items = {
2404 { "Mic", 0x0 },
2405 { "Line", 0x2 },
2406 { "CD", 0x4 },
2407 { "Front Mic", 0xb },
2408 },
2409 },
2410 {
2411 .num_items = 3,
2412 .items = {
2413 { "Mic", 0x0 },
2414 { "Line", 0x2 },
2415 { "CD", 0x4 },
2416 },
2417 }
2418};
2419
2420static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2421 /* Interal mic only available on one ADC */
2422 {
2423 .num_items = 5,
2424 .items = {
2425 { "Mic", 0x0 },
2426 { "Line In", 0x2 },
2427 { "CD", 0x4 },
2428 { "Input Mix", 0xa },
2429 { "Internal Mic", 0xb },
2430 },
2431 },
2432 {
2433 .num_items = 4,
2434 .items = {
2435 { "Mic", 0x0 },
2436 { "Line In", 0x2 },
2437 { "CD", 0x4 },
2438 { "Input Mix", 0xa },
2439 },
2440 }
2441};
2442
2443static const struct hda_input_mux alc889_capture_sources[3] = {
2444 /* Digital mic only available on first "ADC" */
2445 {
2446 .num_items = 5,
2447 .items = {
2448 { "Mic", 0x0 },
2449 { "Line", 0x2 },
2450 { "CD", 0x4 },
2451 { "Front Mic", 0xb },
2452 { "Input Mix", 0xa },
2453 },
2454 },
2455 {
2456 .num_items = 4,
2457 .items = {
2458 { "Mic", 0x0 },
2459 { "Line", 0x2 },
2460 { "CD", 0x4 },
2461 { "Input Mix", 0xa },
2462 },
2463 },
2464 {
2465 .num_items = 4,
2466 .items = {
2467 { "Mic", 0x0 },
2468 { "Line", 0x2 },
2469 { "CD", 0x4 },
2470 { "Input Mix", 0xa },
2471 },
2472 }
2473};
2474
2475static const struct snd_kcontrol_new alc888_base_mixer[] = {
2476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2481 HDA_OUTPUT),
2482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2486 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2488 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2489 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2490 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2494 { } /* end */
2495};
2496
2497static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2498 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2503 HDA_OUTPUT),
2504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2505 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2506 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2514 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2516 { } /* end */
2517};
2518
2519static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2525 HDA_OUTPUT),
2526 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2527 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2528 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2534 { } /* end */
2535};
2536
2537
2538static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2539{
2540 struct alc_spec *spec = codec->spec;
2541
2542 spec->autocfg.hp_pins[0] = 0x15;
2543 spec->autocfg.speaker_pins[0] = 0x14;
2544 spec->autocfg.speaker_pins[1] = 0x16;
2545 spec->autocfg.speaker_pins[2] = 0x17;
2546 spec->automute = 1;
2547 spec->automute_mode = ALC_AUTOMUTE_AMP;
2548}
2549
2550static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2551{
2552 struct alc_spec *spec = codec->spec;
2553
2554 spec->autocfg.hp_pins[0] = 0x15;
2555 spec->autocfg.speaker_pins[0] = 0x14;
2556 spec->autocfg.speaker_pins[1] = 0x16;
2557 spec->autocfg.speaker_pins[2] = 0x17;
2558 spec->automute = 1;
2559 spec->automute_mode = ALC_AUTOMUTE_AMP;
2560}
2561
2562static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2563{
2564 struct alc_spec *spec = codec->spec;
2565
2566 spec->autocfg.hp_pins[0] = 0x15;
2567 spec->autocfg.speaker_pins[0] = 0x14;
2568 spec->autocfg.speaker_pins[1] = 0x16;
2569 spec->autocfg.speaker_pins[2] = 0x17;
2570 spec->automute = 1;
2571 spec->automute_mode = ALC_AUTOMUTE_AMP;
2572}
2573
2574static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2575{
2576 struct alc_spec *spec = codec->spec;
2577
2578 spec->autocfg.hp_pins[0] = 0x15;
2579 spec->autocfg.speaker_pins[0] = 0x14;
2580 spec->autocfg.speaker_pins[1] = 0x16;
2581 spec->autocfg.speaker_pins[2] = 0x1b;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584}
2585
2586/*
2587 * ALC880 3-stack model
2588 *
2589 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2590 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2591 * F-Mic = 0x1b, HP = 0x19
2592 */
2593
2594static const hda_nid_t alc880_dac_nids[4] = {
2595 /* front, rear, clfe, rear_surr */
2596 0x02, 0x05, 0x04, 0x03
2597};
2598
2599static const hda_nid_t alc880_adc_nids[3] = {
2600 /* ADC0-2 */
2601 0x07, 0x08, 0x09,
2602};
2603
2604/* The datasheet says the node 0x07 is connected from inputs,
2605 * but it shows zero connection in the real implementation on some devices.
2606 * Note: this is a 915GAV bug, fixed on 915GLV
2607 */
2608static const hda_nid_t alc880_adc_nids_alt[2] = {
2609 /* ADC1-2 */
2610 0x08, 0x09,
2611};
2612
2613#define ALC880_DIGOUT_NID 0x06
2614#define ALC880_DIGIN_NID 0x0a
2615
2616static const struct hda_input_mux alc880_capture_source = {
2617 .num_items = 4,
2618 .items = {
2619 { "Mic", 0x0 },
2620 { "Front Mic", 0x3 },
2621 { "Line", 0x2 },
2622 { "CD", 0x4 },
2623 },
2624};
2625
2626/* channel source setting (2/6 channel selection for 3-stack) */
2627/* 2ch mode */
2628static const struct hda_verb alc880_threestack_ch2_init[] = {
2629 /* set line-in to input, mute it */
2630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2632 /* set mic-in to input vref 80%, mute it */
2633 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2634 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2635 { } /* end */
2636};
2637
2638/* 6ch mode */
2639static const struct hda_verb alc880_threestack_ch6_init[] = {
2640 /* set line-in to output, unmute it */
2641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2643 /* set mic-in to output, unmute it */
2644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2646 { } /* end */
2647};
2648
2649static const struct hda_channel_mode alc880_threestack_modes[2] = {
2650 { 2, alc880_threestack_ch2_init },
2651 { 6, alc880_threestack_ch6_init },
2652};
2653
2654static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2669 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2670 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2672 {
2673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674 .name = "Channel Mode",
2675 .info = alc_ch_mode_info,
2676 .get = alc_ch_mode_get,
2677 .put = alc_ch_mode_put,
2678 },
2679 { } /* end */
2680};
2681
2682/* capture mixer elements */
2683static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1605static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_info *uinfo) 1606 struct snd_ctl_elem_info *uinfo)
2685{ 1607{
2686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1608 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2687 struct alc_spec *spec = codec->spec; 1609 struct alc_spec *spec = codec->spec;
1610 unsigned long val;
2688 int err; 1611 int err;
2689 1612
2690 mutex_lock(&codec->control_mutex); 1613 mutex_lock(&codec->control_mutex);
2691 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1614 if (spec->vol_in_capsrc)
2692 HDA_INPUT); 1615 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1616 else
1617 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1618 kcontrol->private_value = val;
2693 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1619 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2694 mutex_unlock(&codec->control_mutex); 1620 mutex_unlock(&codec->control_mutex);
2695 return err; 1621 return err;
@@ -2700,11 +1626,15 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2700{ 1626{
2701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2702 struct alc_spec *spec = codec->spec; 1628 struct alc_spec *spec = codec->spec;
1629 unsigned long val;
2703 int err; 1630 int err;
2704 1631
2705 mutex_lock(&codec->control_mutex); 1632 mutex_lock(&codec->control_mutex);
2706 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1633 if (spec->vol_in_capsrc)
2707 HDA_INPUT); 1634 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1635 else
1636 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1637 kcontrol->private_value = val;
2708 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1638 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2709 mutex_unlock(&codec->control_mutex); 1639 mutex_unlock(&codec->control_mutex);
2710 return err; 1640 return err;
@@ -2722,7 +1652,7 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2722 int i, err = 0; 1652 int i, err = 0;
2723 1653
2724 mutex_lock(&codec->control_mutex); 1654 mutex_lock(&codec->control_mutex);
2725 if (check_adc_switch && spec->dual_adc_switch) { 1655 if (check_adc_switch && spec->dyn_adc_switch) {
2726 for (i = 0; i < spec->num_adc_nids; i++) { 1656 for (i = 0; i < spec->num_adc_nids; i++) {
2727 kcontrol->private_value = 1657 kcontrol->private_value =
2728 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1658 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
@@ -2733,9 +1663,14 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2733 } 1663 }
2734 } else { 1664 } else {
2735 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1665 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2736 kcontrol->private_value = 1666 if (spec->vol_in_capsrc)
2737 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1667 kcontrol->private_value =
2738 3, 0, HDA_INPUT); 1668 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
1669 3, 0, HDA_OUTPUT);
1670 else
1671 kcontrol->private_value =
1672 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1673 3, 0, HDA_INPUT);
2739 err = func(kcontrol, ucontrol); 1674 err = func(kcontrol, ucontrol);
2740 } 1675 }
2741 error: 1676 error:
@@ -2830,335 +1765,6 @@ DEFINE_CAPMIX_NOSRC(2);
2830DEFINE_CAPMIX_NOSRC(3); 1765DEFINE_CAPMIX_NOSRC(3);
2831 1766
2832/* 1767/*
2833 * ALC880 5-stack model
2834 *
2835 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2836 * Side = 0x02 (0xd)
2837 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2838 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2839 */
2840
2841/* additional mixers to alc880_three_stack_mixer */
2842static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2843 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2844 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2845 { } /* end */
2846};
2847
2848/* channel source setting (6/8 channel selection for 5-stack) */
2849/* 6ch mode */
2850static const struct hda_verb alc880_fivestack_ch6_init[] = {
2851 /* set line-in to input, mute it */
2852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2854 { } /* end */
2855};
2856
2857/* 8ch mode */
2858static const struct hda_verb alc880_fivestack_ch8_init[] = {
2859 /* set line-in to output, unmute it */
2860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2862 { } /* end */
2863};
2864
2865static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2866 { 6, alc880_fivestack_ch6_init },
2867 { 8, alc880_fivestack_ch8_init },
2868};
2869
2870
2871/*
2872 * ALC880 6-stack model
2873 *
2874 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2875 * Side = 0x05 (0x0f)
2876 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2877 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2878 */
2879
2880static const hda_nid_t alc880_6st_dac_nids[4] = {
2881 /* front, rear, clfe, rear_surr */
2882 0x02, 0x03, 0x04, 0x05
2883};
2884
2885static const struct hda_input_mux alc880_6stack_capture_source = {
2886 .num_items = 4,
2887 .items = {
2888 { "Mic", 0x0 },
2889 { "Front Mic", 0x1 },
2890 { "Line", 0x2 },
2891 { "CD", 0x4 },
2892 },
2893};
2894
2895/* fixed 8-channels */
2896static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2897 { 8, NULL },
2898};
2899
2900static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2901 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2902 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2903 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2904 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2905 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2906 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2907 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2908 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2909 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2910 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2911 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2912 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2913 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2914 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2915 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2916 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2917 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2918 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2919 {
2920 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2921 .name = "Channel Mode",
2922 .info = alc_ch_mode_info,
2923 .get = alc_ch_mode_get,
2924 .put = alc_ch_mode_put,
2925 },
2926 { } /* end */
2927};
2928
2929
2930/*
2931 * ALC880 W810 model
2932 *
2933 * W810 has rear IO for:
2934 * Front (DAC 02)
2935 * Surround (DAC 03)
2936 * Center/LFE (DAC 04)
2937 * Digital out (06)
2938 *
2939 * The system also has a pair of internal speakers, and a headphone jack.
2940 * These are both connected to Line2 on the codec, hence to DAC 02.
2941 *
2942 * There is a variable resistor to control the speaker or headphone
2943 * volume. This is a hardware-only device without a software API.
2944 *
2945 * Plugging headphones in will disable the internal speakers. This is
2946 * implemented in hardware, not via the driver using jack sense. In
2947 * a similar fashion, plugging into the rear socket marked "front" will
2948 * disable both the speakers and headphones.
2949 *
2950 * For input, there's a microphone jack, and an "audio in" jack.
2951 * These may not do anything useful with this driver yet, because I
2952 * haven't setup any initialization verbs for these yet...
2953 */
2954
2955static const hda_nid_t alc880_w810_dac_nids[3] = {
2956 /* front, rear/surround, clfe */
2957 0x02, 0x03, 0x04
2958};
2959
2960/* fixed 6 channels */
2961static const struct hda_channel_mode alc880_w810_modes[1] = {
2962 { 6, NULL }
2963};
2964
2965/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2966static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2968 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2970 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2976 { } /* end */
2977};
2978
2979
2980/*
2981 * Z710V model
2982 *
2983 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2984 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2985 * Line = 0x1a
2986 */
2987
2988static const hda_nid_t alc880_z71v_dac_nids[1] = {
2989 0x02
2990};
2991#define ALC880_Z71V_HP_DAC 0x03
2992
2993/* fixed 2 channels */
2994static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2995 { 2, NULL }
2996};
2997
2998static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3000 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3001 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3002 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3006 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3007 { } /* end */
3008};
3009
3010
3011/*
3012 * ALC880 F1734 model
3013 *
3014 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3015 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3016 */
3017
3018static const hda_nid_t alc880_f1734_dac_nids[1] = {
3019 0x03
3020};
3021#define ALC880_F1734_HP_DAC 0x02
3022
3023static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3024 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3025 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3026 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3027 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3028 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3029 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3030 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3032 { } /* end */
3033};
3034
3035static const struct hda_input_mux alc880_f1734_capture_source = {
3036 .num_items = 2,
3037 .items = {
3038 { "Mic", 0x1 },
3039 { "CD", 0x4 },
3040 },
3041};
3042
3043
3044/*
3045 * ALC880 ASUS model
3046 *
3047 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3048 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3049 * Mic = 0x18, Line = 0x1a
3050 */
3051
3052#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3053#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3054
3055static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3056 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3057 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3058 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3059 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3060 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3061 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3062 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3063 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3069 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3070 {
3071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3072 .name = "Channel Mode",
3073 .info = alc_ch_mode_info,
3074 .get = alc_ch_mode_get,
3075 .put = alc_ch_mode_put,
3076 },
3077 { } /* end */
3078};
3079
3080/*
3081 * ALC880 ASUS W1V model
3082 *
3083 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3084 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3085 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3086 */
3087
3088/* additional mixers to alc880_asus_mixer */
3089static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3090 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3091 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3092 { } /* end */
3093};
3094
3095/* TCL S700 */
3096static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3098 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3100 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3101 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3104 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3105 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3106 { } /* end */
3107};
3108
3109/* Uniwill */
3110static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3111 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3112 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3113 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3114 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3115 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3116 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3117 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3118 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3119 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3120 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3121 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3122 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3126 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3127 {
3128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3129 .name = "Channel Mode",
3130 .info = alc_ch_mode_info,
3131 .get = alc_ch_mode_get,
3132 .put = alc_ch_mode_put,
3133 },
3134 { } /* end */
3135};
3136
3137static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3138 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3139 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3140 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3141 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3142 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3143 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3146 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3147 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3148 { } /* end */
3149};
3150
3151static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3153 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3154 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3155 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3158 { } /* end */
3159};
3160
3161/*
3162 * virtual master controls 1768 * virtual master controls
3163 */ 1769 */
3164 1770
@@ -3237,6 +1843,7 @@ static int alc_build_controls(struct hda_codec *codec)
3237 } 1843 }
3238 if (spec->multiout.dig_out_nid) { 1844 if (spec->multiout.dig_out_nid) {
3239 err = snd_hda_create_spdif_out_ctls(codec, 1845 err = snd_hda_create_spdif_out_ctls(codec,
1846 spec->multiout.dig_out_nid,
3240 spec->multiout.dig_out_nid); 1847 spec->multiout.dig_out_nid);
3241 if (err < 0) 1848 if (err < 0)
3242 return err; 1849 return err;
@@ -3368,789 +1975,6 @@ static int alc_build_controls(struct hda_codec *codec)
3368 1975
3369 1976
3370/* 1977/*
3371 * initialize the codec volumes, etc
3372 */
3373
3374/*
3375 * generic initialization of ADC, input mixers and output mixers
3376 */
3377static const struct hda_verb alc880_volume_init_verbs[] = {
3378 /*
3379 * Unmute ADC0-2 and set the default input to mic-in
3380 */
3381 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3382 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3383 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3384 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3385 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3386 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3387
3388 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3389 * mixer widget
3390 * Note: PASD motherboards uses the Line In 2 as the input for front
3391 * panel mic (mic 2)
3392 */
3393 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3394 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3395 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3401
3402 /*
3403 * Set up output mixers (0x0c - 0x0f)
3404 */
3405 /* set vol=0 to output mixers */
3406 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3407 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3408 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3410 /* set up input amps for analog loopback */
3411 /* Amp Indices: DAC = 0, mixer = 1 */
3412 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3415 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3416 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3417 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3418 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3419 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3420
3421 { }
3422};
3423
3424/*
3425 * 3-stack pin configuration:
3426 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3427 */
3428static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3429 /*
3430 * preset connection lists of input pins
3431 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3432 */
3433 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3434 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3435 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3436
3437 /*
3438 * Set pin mode and muting
3439 */
3440 /* set front pin widgets 0x14 for output */
3441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3442 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3443 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3444 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3445 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3446 /* Mic2 (as headphone out) for HP output */
3447 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3448 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3449 /* Line In pin widget for input */
3450 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3451 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3452 /* Line2 (as front mic) pin widget for input and vref at 80% */
3453 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3454 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3455 /* CD pin widget for input */
3456 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3457
3458 { }
3459};
3460
3461/*
3462 * 5-stack pin configuration:
3463 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3464 * line-in/side = 0x1a, f-mic = 0x1b
3465 */
3466static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3467 /*
3468 * preset connection lists of input pins
3469 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3470 */
3471 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3472 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3473
3474 /*
3475 * Set pin mode and muting
3476 */
3477 /* set pin widgets 0x14-0x17 for output */
3478 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3480 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3481 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3482 /* unmute pins for output (no gain on this amp) */
3483 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3484 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3485 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3486 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3487
3488 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3491 /* Mic2 (as headphone out) for HP output */
3492 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3493 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494 /* Line In pin widget for input */
3495 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3497 /* Line2 (as front mic) pin widget for input and vref at 80% */
3498 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3499 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3500 /* CD pin widget for input */
3501 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3502
3503 { }
3504};
3505
3506/*
3507 * W810 pin configuration:
3508 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3509 */
3510static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3511 /* hphone/speaker input selector: front DAC */
3512 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3513
3514 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3515 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3517 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3518 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3519 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3520
3521 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3522 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3523
3524 { }
3525};
3526
3527/*
3528 * Z71V pin configuration:
3529 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3530 */
3531static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3535 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3536
3537 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3538 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3540 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3541
3542 { }
3543};
3544
3545/*
3546 * 6-stack pin configuration:
3547 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3548 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3549 */
3550static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3551 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3552
3553 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3554 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3556 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3557 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3558 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3560 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3561
3562 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3563 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3564 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3565 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3566 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3567 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3568 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3569 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3571
3572 { }
3573};
3574
3575/*
3576 * Uniwill pin configuration:
3577 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3578 * line = 0x1a
3579 */
3580static const struct hda_verb alc880_uniwill_init_verbs[] = {
3581 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3582
3583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3584 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3585 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3587 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3589 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3591 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3592 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3593 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3594 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3595 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3596 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3597
3598 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3599 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3600 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3601 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3602 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3603 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3604 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3605 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3606 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3607
3608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3609 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3610
3611 { }
3612};
3613
3614/*
3615* Uniwill P53
3616* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3617 */
3618static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3619 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3620
3621 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3622 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3623 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3624 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3625 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3626 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3631 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3633
3634 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3635 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3636 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3637 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3638 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3639 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3640
3641 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3642 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3643
3644 { }
3645};
3646
3647static const struct hda_verb alc880_beep_init_verbs[] = {
3648 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3649 { }
3650};
3651
3652/* auto-toggle front mic */
3653static void alc88x_simple_mic_automute(struct hda_codec *codec)
3654{
3655 unsigned int present;
3656 unsigned char bits;
3657
3658 present = snd_hda_jack_detect(codec, 0x18);
3659 bits = present ? HDA_AMP_MUTE : 0;
3660 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3661}
3662
3663static void alc880_uniwill_setup(struct hda_codec *codec)
3664{
3665 struct alc_spec *spec = codec->spec;
3666
3667 spec->autocfg.hp_pins[0] = 0x14;
3668 spec->autocfg.speaker_pins[0] = 0x15;
3669 spec->autocfg.speaker_pins[0] = 0x16;
3670 spec->automute = 1;
3671 spec->automute_mode = ALC_AUTOMUTE_AMP;
3672}
3673
3674static void alc880_uniwill_init_hook(struct hda_codec *codec)
3675{
3676 alc_hp_automute(codec);
3677 alc88x_simple_mic_automute(codec);
3678}
3679
3680static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3681 unsigned int res)
3682{
3683 /* Looks like the unsol event is incompatible with the standard
3684 * definition. 4bit tag is placed at 28 bit!
3685 */
3686 switch (res >> 28) {
3687 case ALC880_MIC_EVENT:
3688 alc88x_simple_mic_automute(codec);
3689 break;
3690 default:
3691 alc_sku_unsol_event(codec, res);
3692 break;
3693 }
3694}
3695
3696static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3697{
3698 struct alc_spec *spec = codec->spec;
3699
3700 spec->autocfg.hp_pins[0] = 0x14;
3701 spec->autocfg.speaker_pins[0] = 0x15;
3702 spec->automute = 1;
3703 spec->automute_mode = ALC_AUTOMUTE_AMP;
3704}
3705
3706static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3707{
3708 unsigned int present;
3709
3710 present = snd_hda_codec_read(codec, 0x21, 0,
3711 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3712 present &= HDA_AMP_VOLMASK;
3713 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3714 HDA_AMP_VOLMASK, present);
3715 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3716 HDA_AMP_VOLMASK, present);
3717}
3718
3719static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3720 unsigned int res)
3721{
3722 /* Looks like the unsol event is incompatible with the standard
3723 * definition. 4bit tag is placed at 28 bit!
3724 */
3725 if ((res >> 28) == ALC880_DCVOL_EVENT)
3726 alc880_uniwill_p53_dcvol_automute(codec);
3727 else
3728 alc_sku_unsol_event(codec, res);
3729}
3730
3731/*
3732 * F1734 pin configuration:
3733 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3734 */
3735static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3736 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3737 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3738 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3739 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3740 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3741
3742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3744 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3745 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3746
3747 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3748 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3753 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3754 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3755 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3756
3757 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3758 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3759
3760 { }
3761};
3762
3763/*
3764 * ASUS pin configuration:
3765 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3766 */
3767static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3768 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3769 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3770 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3771 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3772
3773 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3774 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3775 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3778 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3779 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3780 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3781
3782 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3784 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3788 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3789 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3791
3792 { }
3793};
3794
3795/* Enable GPIO mask and set output */
3796#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3797#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3798#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3799
3800/* Clevo m520g init */
3801static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3802 /* headphone output */
3803 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3804 /* line-out */
3805 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3806 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3807 /* Line-in */
3808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810 /* CD */
3811 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3812 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3813 /* Mic1 (rear panel) */
3814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3816 /* Mic2 (front panel) */
3817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3818 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3819 /* headphone */
3820 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3821 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3822 /* change to EAPD mode */
3823 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3824 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3825
3826 { }
3827};
3828
3829static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3830 /* change to EAPD mode */
3831 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3832 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3833
3834 /* Headphone output */
3835 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3836 /* Front output*/
3837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3838 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3839
3840 /* Line In pin widget for input */
3841 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3842 /* CD pin widget for input */
3843 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3844 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3845 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3846
3847 /* change to EAPD mode */
3848 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3849 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3850
3851 { }
3852};
3853
3854/*
3855 * LG m1 express dual
3856 *
3857 * Pin assignment:
3858 * Rear Line-In/Out (blue): 0x14
3859 * Build-in Mic-In: 0x15
3860 * Speaker-out: 0x17
3861 * HP-Out (green): 0x1b
3862 * Mic-In/Out (red): 0x19
3863 * SPDIF-Out: 0x1e
3864 */
3865
3866/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3867static const hda_nid_t alc880_lg_dac_nids[3] = {
3868 0x05, 0x02, 0x03
3869};
3870
3871/* seems analog CD is not working */
3872static const struct hda_input_mux alc880_lg_capture_source = {
3873 .num_items = 3,
3874 .items = {
3875 { "Mic", 0x1 },
3876 { "Line", 0x5 },
3877 { "Internal Mic", 0x6 },
3878 },
3879};
3880
3881/* 2,4,6 channel modes */
3882static const struct hda_verb alc880_lg_ch2_init[] = {
3883 /* set line-in and mic-in to input */
3884 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3885 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3886 { }
3887};
3888
3889static const struct hda_verb alc880_lg_ch4_init[] = {
3890 /* set line-in to out and mic-in to input */
3891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3893 { }
3894};
3895
3896static const struct hda_verb alc880_lg_ch6_init[] = {
3897 /* set line-in and mic-in to output */
3898 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3899 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3900 { }
3901};
3902
3903static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3904 { 2, alc880_lg_ch2_init },
3905 { 4, alc880_lg_ch4_init },
3906 { 6, alc880_lg_ch6_init },
3907};
3908
3909static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3911 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3913 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3918 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3919 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3920 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3921 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3924 {
3925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3926 .name = "Channel Mode",
3927 .info = alc_ch_mode_info,
3928 .get = alc_ch_mode_get,
3929 .put = alc_ch_mode_put,
3930 },
3931 { } /* end */
3932};
3933
3934static const struct hda_verb alc880_lg_init_verbs[] = {
3935 /* set capture source to mic-in */
3936 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3937 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3938 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3939 /* mute all amp mixer inputs */
3940 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3941 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3942 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3943 /* line-in to input */
3944 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3945 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3946 /* built-in mic */
3947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3948 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3949 /* speaker-out */
3950 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3951 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3952 /* mic-in to input */
3953 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956 /* HP-out */
3957 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3958 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3959 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3960 /* jack sense */
3961 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3962 { }
3963};
3964
3965/* toggle speaker-output according to the hp-jack state */
3966static void alc880_lg_setup(struct hda_codec *codec)
3967{
3968 struct alc_spec *spec = codec->spec;
3969
3970 spec->autocfg.hp_pins[0] = 0x1b;
3971 spec->autocfg.speaker_pins[0] = 0x17;
3972 spec->automute = 1;
3973 spec->automute_mode = ALC_AUTOMUTE_AMP;
3974}
3975
3976/*
3977 * LG LW20
3978 *
3979 * Pin assignment:
3980 * Speaker-out: 0x14
3981 * Mic-In: 0x18
3982 * Built-in Mic-In: 0x19
3983 * Line-In: 0x1b
3984 * HP-Out: 0x1a
3985 * SPDIF-Out: 0x1e
3986 */
3987
3988static const struct hda_input_mux alc880_lg_lw_capture_source = {
3989 .num_items = 3,
3990 .items = {
3991 { "Mic", 0x0 },
3992 { "Internal Mic", 0x1 },
3993 { "Line In", 0x2 },
3994 },
3995};
3996
3997#define alc880_lg_lw_modes alc880_threestack_modes
3998
3999static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4000 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4001 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4003 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4004 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4005 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4006 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4007 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4008 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4009 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4012 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4013 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4014 {
4015 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4016 .name = "Channel Mode",
4017 .info = alc_ch_mode_info,
4018 .get = alc_ch_mode_get,
4019 .put = alc_ch_mode_put,
4020 },
4021 { } /* end */
4022};
4023
4024static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4025 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4026 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4027 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4028
4029 /* set capture source to mic-in */
4030 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4031 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4033 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4034 /* speaker-out */
4035 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4037 /* HP-out */
4038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4040 /* mic-in to input */
4041 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4042 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4043 /* built-in mic */
4044 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4045 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4046 /* jack sense */
4047 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4048 { }
4049};
4050
4051/* toggle speaker-output according to the hp-jack state */
4052static void alc880_lg_lw_setup(struct hda_codec *codec)
4053{
4054 struct alc_spec *spec = codec->spec;
4055
4056 spec->autocfg.hp_pins[0] = 0x1b;
4057 spec->autocfg.speaker_pins[0] = 0x14;
4058 spec->automute = 1;
4059 spec->automute_mode = ALC_AUTOMUTE_AMP;
4060}
4061
4062static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4063 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4064 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4067 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4068 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4069 { } /* end */
4070};
4071
4072static const struct hda_input_mux alc880_medion_rim_capture_source = {
4073 .num_items = 2,
4074 .items = {
4075 { "Mic", 0x0 },
4076 { "Internal Mic", 0x1 },
4077 },
4078};
4079
4080static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4081 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4082
4083 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4084 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4085
4086 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4087 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4088 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4089 /* Mic2 (as headphone out) for HP output */
4090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4091 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4092 /* Internal Speaker */
4093 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4094 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4095
4096 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4097 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4098
4099 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4100 { }
4101};
4102
4103/* toggle speaker-output according to the hp-jack state */
4104static void alc880_medion_rim_automute(struct hda_codec *codec)
4105{
4106 struct alc_spec *spec = codec->spec;
4107 alc_hp_automute(codec);
4108 /* toggle EAPD */
4109 if (spec->jack_present)
4110 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4111 else
4112 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4113}
4114
4115static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4116 unsigned int res)
4117{
4118 /* Looks like the unsol event is incompatible with the standard
4119 * definition. 4bit tag is placed at 28 bit!
4120 */
4121 if ((res >> 28) == ALC880_HP_EVENT)
4122 alc880_medion_rim_automute(codec);
4123}
4124
4125static void alc880_medion_rim_setup(struct hda_codec *codec)
4126{
4127 struct alc_spec *spec = codec->spec;
4128
4129 spec->autocfg.hp_pins[0] = 0x14;
4130 spec->autocfg.speaker_pins[0] = 0x1b;
4131 spec->automute = 1;
4132 spec->automute_mode = ALC_AUTOMUTE_AMP;
4133}
4134
4135#ifdef CONFIG_SND_HDA_POWER_SAVE
4136static const struct hda_amp_list alc880_loopbacks[] = {
4137 { 0x0b, HDA_INPUT, 0 },
4138 { 0x0b, HDA_INPUT, 1 },
4139 { 0x0b, HDA_INPUT, 2 },
4140 { 0x0b, HDA_INPUT, 3 },
4141 { 0x0b, HDA_INPUT, 4 },
4142 { } /* end */
4143};
4144
4145static const struct hda_amp_list alc880_lg_loopbacks[] = {
4146 { 0x0b, HDA_INPUT, 1 },
4147 { 0x0b, HDA_INPUT, 6 },
4148 { 0x0b, HDA_INPUT, 7 },
4149 { } /* end */
4150};
4151#endif
4152
4153/*
4154 * Common callbacks 1978 * Common callbacks
4155 */ 1979 */
4156 1980
@@ -4196,7 +2020,7 @@ static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4196/* 2020/*
4197 * Analog playback callbacks 2021 * Analog playback callbacks
4198 */ 2022 */
4199static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2023static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
4200 struct hda_codec *codec, 2024 struct hda_codec *codec,
4201 struct snd_pcm_substream *substream) 2025 struct snd_pcm_substream *substream)
4202{ 2026{
@@ -4205,7 +2029,7 @@ static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4205 hinfo); 2029 hinfo);
4206} 2030}
4207 2031
4208static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2032static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4209 struct hda_codec *codec, 2033 struct hda_codec *codec,
4210 unsigned int stream_tag, 2034 unsigned int stream_tag,
4211 unsigned int format, 2035 unsigned int format,
@@ -4216,7 +2040,7 @@ static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4216 stream_tag, format, substream); 2040 stream_tag, format, substream);
4217} 2041}
4218 2042
4219static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2043static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4220 struct hda_codec *codec, 2044 struct hda_codec *codec,
4221 struct snd_pcm_substream *substream) 2045 struct snd_pcm_substream *substream)
4222{ 2046{
@@ -4227,7 +2051,7 @@ static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4227/* 2051/*
4228 * Digital out 2052 * Digital out
4229 */ 2053 */
4230static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2054static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4231 struct hda_codec *codec, 2055 struct hda_codec *codec,
4232 struct snd_pcm_substream *substream) 2056 struct snd_pcm_substream *substream)
4233{ 2057{
@@ -4235,7 +2059,7 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4235 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2059 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4236} 2060}
4237 2061
4238static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2062static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4239 struct hda_codec *codec, 2063 struct hda_codec *codec,
4240 unsigned int stream_tag, 2064 unsigned int stream_tag,
4241 unsigned int format, 2065 unsigned int format,
@@ -4246,7 +2070,7 @@ static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4246 stream_tag, format, substream); 2070 stream_tag, format, substream);
4247} 2071}
4248 2072
4249static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2073static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4250 struct hda_codec *codec, 2074 struct hda_codec *codec,
4251 struct snd_pcm_substream *substream) 2075 struct snd_pcm_substream *substream)
4252{ 2076{
@@ -4254,7 +2078,7 @@ static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4254 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 2078 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4255} 2079}
4256 2080
4257static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2081static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4258 struct hda_codec *codec, 2082 struct hda_codec *codec,
4259 struct snd_pcm_substream *substream) 2083 struct snd_pcm_substream *substream)
4260{ 2084{
@@ -4265,7 +2089,7 @@ static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4265/* 2089/*
4266 * Analog capture 2090 * Analog capture
4267 */ 2091 */
4268static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2092static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4269 struct hda_codec *codec, 2093 struct hda_codec *codec,
4270 unsigned int stream_tag, 2094 unsigned int stream_tag,
4271 unsigned int format, 2095 unsigned int format,
@@ -4278,7 +2102,7 @@ static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4278 return 0; 2102 return 0;
4279} 2103}
4280 2104
4281static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2105static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4282 struct hda_codec *codec, 2106 struct hda_codec *codec,
4283 struct snd_pcm_substream *substream) 2107 struct snd_pcm_substream *substream)
4284{ 2108{
@@ -4290,21 +2114,21 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4290} 2114}
4291 2115
4292/* analog capture with dynamic dual-adc changes */ 2116/* analog capture with dynamic dual-adc changes */
4293static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2117static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4294 struct hda_codec *codec, 2118 struct hda_codec *codec,
4295 unsigned int stream_tag, 2119 unsigned int stream_tag,
4296 unsigned int format, 2120 unsigned int format,
4297 struct snd_pcm_substream *substream) 2121 struct snd_pcm_substream *substream)
4298{ 2122{
4299 struct alc_spec *spec = codec->spec; 2123 struct alc_spec *spec = codec->spec;
4300 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 2124 spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
4301 spec->cur_adc_stream_tag = stream_tag; 2125 spec->cur_adc_stream_tag = stream_tag;
4302 spec->cur_adc_format = format; 2126 spec->cur_adc_format = format;
4303 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 2127 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4304 return 0; 2128 return 0;
4305} 2129}
4306 2130
4307static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2131static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4308 struct hda_codec *codec, 2132 struct hda_codec *codec,
4309 struct snd_pcm_substream *substream) 2133 struct snd_pcm_substream *substream)
4310{ 2134{
@@ -4314,70 +2138,70 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4314 return 0; 2138 return 0;
4315} 2139}
4316 2140
4317static const struct hda_pcm_stream dualmic_pcm_analog_capture = { 2141static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
4318 .substreams = 1, 2142 .substreams = 1,
4319 .channels_min = 2, 2143 .channels_min = 2,
4320 .channels_max = 2, 2144 .channels_max = 2,
4321 .nid = 0, /* fill later */ 2145 .nid = 0, /* fill later */
4322 .ops = { 2146 .ops = {
4323 .prepare = dualmic_capture_pcm_prepare, 2147 .prepare = dyn_adc_capture_pcm_prepare,
4324 .cleanup = dualmic_capture_pcm_cleanup 2148 .cleanup = dyn_adc_capture_pcm_cleanup
4325 }, 2149 },
4326}; 2150};
4327 2151
4328/* 2152/*
4329 */ 2153 */
4330static const struct hda_pcm_stream alc880_pcm_analog_playback = { 2154static const struct hda_pcm_stream alc_pcm_analog_playback = {
4331 .substreams = 1, 2155 .substreams = 1,
4332 .channels_min = 2, 2156 .channels_min = 2,
4333 .channels_max = 8, 2157 .channels_max = 8,
4334 /* NID is set in alc_build_pcms */ 2158 /* NID is set in alc_build_pcms */
4335 .ops = { 2159 .ops = {
4336 .open = alc880_playback_pcm_open, 2160 .open = alc_playback_pcm_open,
4337 .prepare = alc880_playback_pcm_prepare, 2161 .prepare = alc_playback_pcm_prepare,
4338 .cleanup = alc880_playback_pcm_cleanup 2162 .cleanup = alc_playback_pcm_cleanup
4339 }, 2163 },
4340}; 2164};
4341 2165
4342static const struct hda_pcm_stream alc880_pcm_analog_capture = { 2166static const struct hda_pcm_stream alc_pcm_analog_capture = {
4343 .substreams = 1, 2167 .substreams = 1,
4344 .channels_min = 2, 2168 .channels_min = 2,
4345 .channels_max = 2, 2169 .channels_max = 2,
4346 /* NID is set in alc_build_pcms */ 2170 /* NID is set in alc_build_pcms */
4347}; 2171};
4348 2172
4349static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 2173static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
4350 .substreams = 1, 2174 .substreams = 1,
4351 .channels_min = 2, 2175 .channels_min = 2,
4352 .channels_max = 2, 2176 .channels_max = 2,
4353 /* NID is set in alc_build_pcms */ 2177 /* NID is set in alc_build_pcms */
4354}; 2178};
4355 2179
4356static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 2180static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
4357 .substreams = 2, /* can be overridden */ 2181 .substreams = 2, /* can be overridden */
4358 .channels_min = 2, 2182 .channels_min = 2,
4359 .channels_max = 2, 2183 .channels_max = 2,
4360 /* NID is set in alc_build_pcms */ 2184 /* NID is set in alc_build_pcms */
4361 .ops = { 2185 .ops = {
4362 .prepare = alc880_alt_capture_pcm_prepare, 2186 .prepare = alc_alt_capture_pcm_prepare,
4363 .cleanup = alc880_alt_capture_pcm_cleanup 2187 .cleanup = alc_alt_capture_pcm_cleanup
4364 }, 2188 },
4365}; 2189};
4366 2190
4367static const struct hda_pcm_stream alc880_pcm_digital_playback = { 2191static const struct hda_pcm_stream alc_pcm_digital_playback = {
4368 .substreams = 1, 2192 .substreams = 1,
4369 .channels_min = 2, 2193 .channels_min = 2,
4370 .channels_max = 2, 2194 .channels_max = 2,
4371 /* NID is set in alc_build_pcms */ 2195 /* NID is set in alc_build_pcms */
4372 .ops = { 2196 .ops = {
4373 .open = alc880_dig_playback_pcm_open, 2197 .open = alc_dig_playback_pcm_open,
4374 .close = alc880_dig_playback_pcm_close, 2198 .close = alc_dig_playback_pcm_close,
4375 .prepare = alc880_dig_playback_pcm_prepare, 2199 .prepare = alc_dig_playback_pcm_prepare,
4376 .cleanup = alc880_dig_playback_pcm_cleanup 2200 .cleanup = alc_dig_playback_pcm_cleanup
4377 }, 2201 },
4378}; 2202};
4379 2203
4380static const struct hda_pcm_stream alc880_pcm_digital_capture = { 2204static const struct hda_pcm_stream alc_pcm_digital_capture = {
4381 .substreams = 1, 2205 .substreams = 1,
4382 .channels_min = 2, 2206 .channels_min = 2,
4383 .channels_max = 2, 2207 .channels_max = 2,
@@ -4395,6 +2219,7 @@ static int alc_build_pcms(struct hda_codec *codec)
4395{ 2219{
4396 struct alc_spec *spec = codec->spec; 2220 struct alc_spec *spec = codec->spec;
4397 struct hda_pcm *info = spec->pcm_rec; 2221 struct hda_pcm *info = spec->pcm_rec;
2222 const struct hda_pcm_stream *p;
4398 int i; 2223 int i;
4399 2224
4400 codec->num_pcms = 1; 2225 codec->num_pcms = 1;
@@ -4407,16 +2232,22 @@ static int alc_build_pcms(struct hda_codec *codec)
4407 "%s Analog", codec->chip_name); 2232 "%s Analog", codec->chip_name);
4408 info->name = spec->stream_name_analog; 2233 info->name = spec->stream_name_analog;
4409 2234
4410 if (spec->stream_analog_playback) { 2235 if (spec->multiout.dac_nids > 0) {
4411 if (snd_BUG_ON(!spec->multiout.dac_nids)) 2236 p = spec->stream_analog_playback;
4412 return -EINVAL; 2237 if (!p)
4413 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2238 p = &alc_pcm_analog_playback;
2239 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2240 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4415 } 2241 }
4416 if (spec->stream_analog_capture) { 2242 if (spec->adc_nids) {
4417 if (snd_BUG_ON(!spec->adc_nids)) 2243 p = spec->stream_analog_capture;
4418 return -EINVAL; 2244 if (!p) {
4419 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2245 if (spec->dyn_adc_switch)
2246 p = &dyn_adc_pcm_analog_capture;
2247 else
2248 p = &alc_pcm_analog_capture;
2249 }
2250 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4420 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2251 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4421 } 2252 }
4422 2253
@@ -4443,14 +2274,18 @@ static int alc_build_pcms(struct hda_codec *codec)
4443 info->pcm_type = spec->dig_out_type; 2274 info->pcm_type = spec->dig_out_type;
4444 else 2275 else
4445 info->pcm_type = HDA_PCM_TYPE_SPDIF; 2276 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4446 if (spec->multiout.dig_out_nid && 2277 if (spec->multiout.dig_out_nid) {
4447 spec->stream_digital_playback) { 2278 p = spec->stream_digital_playback;
4448 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2279 if (!p)
2280 p = &alc_pcm_digital_playback;
2281 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4449 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2282 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4450 } 2283 }
4451 if (spec->dig_in_nid && 2284 if (spec->dig_in_nid) {
4452 spec->stream_digital_capture) { 2285 p = spec->stream_digital_capture;
4453 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2286 if (!p)
2287 p = &alc_pcm_digital_capture;
2288 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4454 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2289 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4455 } 2290 }
4456 /* FIXME: do we need this for all Realtek codec models? */ 2291 /* FIXME: do we need this for all Realtek codec models? */
@@ -4464,14 +2299,15 @@ static int alc_build_pcms(struct hda_codec *codec)
4464 * model, configure a second analog capture-only PCM. 2299 * model, configure a second analog capture-only PCM.
4465 */ 2300 */
4466 /* Additional Analaog capture for index #2 */ 2301 /* Additional Analaog capture for index #2 */
4467 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 2302 if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
4468 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4469 codec->num_pcms = 3; 2303 codec->num_pcms = 3;
4470 info = spec->pcm_rec + 2; 2304 info = spec->pcm_rec + 2;
4471 info->name = spec->stream_name_analog; 2305 info->name = spec->stream_name_analog;
4472 if (spec->alt_dac_nid) { 2306 if (spec->alt_dac_nid) {
4473 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 2307 p = spec->stream_analog_alt_playback;
4474 *spec->stream_analog_alt_playback; 2308 if (!p)
2309 p = &alc_pcm_analog_alt_playback;
2310 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4475 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 2311 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4476 spec->alt_dac_nid; 2312 spec->alt_dac_nid;
4477 } else { 2313 } else {
@@ -4479,9 +2315,11 @@ static int alc_build_pcms(struct hda_codec *codec)
4479 alc_pcm_null_stream; 2315 alc_pcm_null_stream;
4480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2316 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4481 } 2317 }
4482 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { 2318 if (spec->num_adc_nids > 1) {
4483 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 2319 p = spec->stream_analog_alt_capture;
4484 *spec->stream_analog_alt_capture; 2320 if (!p)
2321 p = &alc_pcm_analog_alt_capture;
2322 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 2323 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4486 spec->adc_nids[1]; 2324 spec->adc_nids[1];
4487 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 2325 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
@@ -4591,679 +2429,6 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4591} 2429}
4592 2430
4593/* 2431/*
4594 * Test configuration for debugging
4595 *
4596 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4597 * enum controls.
4598 */
4599#ifdef CONFIG_SND_DEBUG
4600static const hda_nid_t alc880_test_dac_nids[4] = {
4601 0x02, 0x03, 0x04, 0x05
4602};
4603
4604static const struct hda_input_mux alc880_test_capture_source = {
4605 .num_items = 7,
4606 .items = {
4607 { "In-1", 0x0 },
4608 { "In-2", 0x1 },
4609 { "In-3", 0x2 },
4610 { "In-4", 0x3 },
4611 { "CD", 0x4 },
4612 { "Front", 0x5 },
4613 { "Surround", 0x6 },
4614 },
4615};
4616
4617static const struct hda_channel_mode alc880_test_modes[4] = {
4618 { 2, NULL },
4619 { 4, NULL },
4620 { 6, NULL },
4621 { 8, NULL },
4622};
4623
4624static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4625 struct snd_ctl_elem_info *uinfo)
4626{
4627 static const char * const texts[] = {
4628 "N/A", "Line Out", "HP Out",
4629 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4630 };
4631 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4632 uinfo->count = 1;
4633 uinfo->value.enumerated.items = 8;
4634 if (uinfo->value.enumerated.item >= 8)
4635 uinfo->value.enumerated.item = 7;
4636 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4637 return 0;
4638}
4639
4640static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4641 struct snd_ctl_elem_value *ucontrol)
4642{
4643 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4644 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4645 unsigned int pin_ctl, item = 0;
4646
4647 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4648 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4649 if (pin_ctl & AC_PINCTL_OUT_EN) {
4650 if (pin_ctl & AC_PINCTL_HP_EN)
4651 item = 2;
4652 else
4653 item = 1;
4654 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4655 switch (pin_ctl & AC_PINCTL_VREFEN) {
4656 case AC_PINCTL_VREF_HIZ: item = 3; break;
4657 case AC_PINCTL_VREF_50: item = 4; break;
4658 case AC_PINCTL_VREF_GRD: item = 5; break;
4659 case AC_PINCTL_VREF_80: item = 6; break;
4660 case AC_PINCTL_VREF_100: item = 7; break;
4661 }
4662 }
4663 ucontrol->value.enumerated.item[0] = item;
4664 return 0;
4665}
4666
4667static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4668 struct snd_ctl_elem_value *ucontrol)
4669{
4670 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4671 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4672 static const unsigned int ctls[] = {
4673 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4674 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4675 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4676 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4677 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4678 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4679 };
4680 unsigned int old_ctl, new_ctl;
4681
4682 old_ctl = snd_hda_codec_read(codec, nid, 0,
4683 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4684 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4685 if (old_ctl != new_ctl) {
4686 int val;
4687 snd_hda_codec_write_cache(codec, nid, 0,
4688 AC_VERB_SET_PIN_WIDGET_CONTROL,
4689 new_ctl);
4690 val = ucontrol->value.enumerated.item[0] >= 3 ?
4691 HDA_AMP_MUTE : 0;
4692 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4693 HDA_AMP_MUTE, val);
4694 return 1;
4695 }
4696 return 0;
4697}
4698
4699static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4700 struct snd_ctl_elem_info *uinfo)
4701{
4702 static const char * const texts[] = {
4703 "Front", "Surround", "CLFE", "Side"
4704 };
4705 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4706 uinfo->count = 1;
4707 uinfo->value.enumerated.items = 4;
4708 if (uinfo->value.enumerated.item >= 4)
4709 uinfo->value.enumerated.item = 3;
4710 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4711 return 0;
4712}
4713
4714static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4715 struct snd_ctl_elem_value *ucontrol)
4716{
4717 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4718 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4719 unsigned int sel;
4720
4721 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4722 ucontrol->value.enumerated.item[0] = sel & 3;
4723 return 0;
4724}
4725
4726static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4727 struct snd_ctl_elem_value *ucontrol)
4728{
4729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4730 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4731 unsigned int sel;
4732
4733 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4734 if (ucontrol->value.enumerated.item[0] != sel) {
4735 sel = ucontrol->value.enumerated.item[0] & 3;
4736 snd_hda_codec_write_cache(codec, nid, 0,
4737 AC_VERB_SET_CONNECT_SEL, sel);
4738 return 1;
4739 }
4740 return 0;
4741}
4742
4743#define PIN_CTL_TEST(xname,nid) { \
4744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4745 .name = xname, \
4746 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4747 .info = alc_test_pin_ctl_info, \
4748 .get = alc_test_pin_ctl_get, \
4749 .put = alc_test_pin_ctl_put, \
4750 .private_value = nid \
4751 }
4752
4753#define PIN_SRC_TEST(xname,nid) { \
4754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4755 .name = xname, \
4756 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4757 .info = alc_test_pin_src_info, \
4758 .get = alc_test_pin_src_get, \
4759 .put = alc_test_pin_src_put, \
4760 .private_value = nid \
4761 }
4762
4763static const struct snd_kcontrol_new alc880_test_mixer[] = {
4764 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4765 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4766 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4767 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4768 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4769 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4770 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4771 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4772 PIN_CTL_TEST("Front Pin Mode", 0x14),
4773 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4774 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4775 PIN_CTL_TEST("Side Pin Mode", 0x17),
4776 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4777 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4778 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4779 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4780 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4781 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4782 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4783 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4784 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4785 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4786 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4787 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4788 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4789 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4790 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4791 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4792 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4793 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4794 {
4795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4796 .name = "Channel Mode",
4797 .info = alc_ch_mode_info,
4798 .get = alc_ch_mode_get,
4799 .put = alc_ch_mode_put,
4800 },
4801 { } /* end */
4802};
4803
4804static const struct hda_verb alc880_test_init_verbs[] = {
4805 /* Unmute inputs of 0x0c - 0x0f */
4806 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4810 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4811 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4812 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4813 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4814 /* Vol output for 0x0c-0x0f */
4815 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4817 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4818 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4819 /* Set output pins 0x14-0x17 */
4820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4821 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4822 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4823 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4824 /* Unmute output pins 0x14-0x17 */
4825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4829 /* Set input pins 0x18-0x1c */
4830 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4831 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4832 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4833 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4834 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4835 /* Mute input pins 0x18-0x1b */
4836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4839 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4840 /* ADC set up */
4841 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4842 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4843 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4844 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4845 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4846 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4847 /* Analog input/passthru */
4848 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4849 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4850 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4851 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4852 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4853 { }
4854};
4855#endif
4856
4857/*
4858 */
4859
4860static const char * const alc880_models[ALC880_MODEL_LAST] = {
4861 [ALC880_3ST] = "3stack",
4862 [ALC880_TCL_S700] = "tcl",
4863 [ALC880_3ST_DIG] = "3stack-digout",
4864 [ALC880_CLEVO] = "clevo",
4865 [ALC880_5ST] = "5stack",
4866 [ALC880_5ST_DIG] = "5stack-digout",
4867 [ALC880_W810] = "w810",
4868 [ALC880_Z71V] = "z71v",
4869 [ALC880_6ST] = "6stack",
4870 [ALC880_6ST_DIG] = "6stack-digout",
4871 [ALC880_ASUS] = "asus",
4872 [ALC880_ASUS_W1V] = "asus-w1v",
4873 [ALC880_ASUS_DIG] = "asus-dig",
4874 [ALC880_ASUS_DIG2] = "asus-dig2",
4875 [ALC880_UNIWILL_DIG] = "uniwill",
4876 [ALC880_UNIWILL_P53] = "uniwill-p53",
4877 [ALC880_FUJITSU] = "fujitsu",
4878 [ALC880_F1734] = "F1734",
4879 [ALC880_LG] = "lg",
4880 [ALC880_LG_LW] = "lg-lw",
4881 [ALC880_MEDION_RIM] = "medion",
4882#ifdef CONFIG_SND_DEBUG
4883 [ALC880_TEST] = "test",
4884#endif
4885 [ALC880_AUTO] = "auto",
4886};
4887
4888static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4889 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4890 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4891 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4892 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4893 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4894 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4895 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4896 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4897 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4898 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4899 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4900 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4901 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4902 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4903 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4904 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4905 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4906 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4907 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4908 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4909 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4910 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4911 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4912 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4913 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4914 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4915 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4916 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4917 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4918 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4919 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4920 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4921 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4922 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4923 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4924 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4925 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4926 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4927 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4928 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4929 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4930 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4931 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4932 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4933 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4934 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4935 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4936 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4937 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4938 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4939 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4940 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4941 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4942 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4943 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4944 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4945 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4946 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4947 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4948 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4949 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4950 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4951 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4952 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4953 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4954 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4955 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4956 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4957 /* default Intel */
4958 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4959 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4960 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4961 {}
4962};
4963
4964/*
4965 * ALC880 codec presets
4966 */
4967static const struct alc_config_preset alc880_presets[] = {
4968 [ALC880_3ST] = {
4969 .mixers = { alc880_three_stack_mixer },
4970 .init_verbs = { alc880_volume_init_verbs,
4971 alc880_pin_3stack_init_verbs },
4972 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4973 .dac_nids = alc880_dac_nids,
4974 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4975 .channel_mode = alc880_threestack_modes,
4976 .need_dac_fix = 1,
4977 .input_mux = &alc880_capture_source,
4978 },
4979 [ALC880_3ST_DIG] = {
4980 .mixers = { alc880_three_stack_mixer },
4981 .init_verbs = { alc880_volume_init_verbs,
4982 alc880_pin_3stack_init_verbs },
4983 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4984 .dac_nids = alc880_dac_nids,
4985 .dig_out_nid = ALC880_DIGOUT_NID,
4986 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4987 .channel_mode = alc880_threestack_modes,
4988 .need_dac_fix = 1,
4989 .input_mux = &alc880_capture_source,
4990 },
4991 [ALC880_TCL_S700] = {
4992 .mixers = { alc880_tcl_s700_mixer },
4993 .init_verbs = { alc880_volume_init_verbs,
4994 alc880_pin_tcl_S700_init_verbs,
4995 alc880_gpio2_init_verbs },
4996 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4997 .dac_nids = alc880_dac_nids,
4998 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4999 .num_adc_nids = 1, /* single ADC */
5000 .hp_nid = 0x03,
5001 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5002 .channel_mode = alc880_2_jack_modes,
5003 .input_mux = &alc880_capture_source,
5004 },
5005 [ALC880_5ST] = {
5006 .mixers = { alc880_three_stack_mixer,
5007 alc880_five_stack_mixer},
5008 .init_verbs = { alc880_volume_init_verbs,
5009 alc880_pin_5stack_init_verbs },
5010 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5011 .dac_nids = alc880_dac_nids,
5012 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5013 .channel_mode = alc880_fivestack_modes,
5014 .input_mux = &alc880_capture_source,
5015 },
5016 [ALC880_5ST_DIG] = {
5017 .mixers = { alc880_three_stack_mixer,
5018 alc880_five_stack_mixer },
5019 .init_verbs = { alc880_volume_init_verbs,
5020 alc880_pin_5stack_init_verbs },
5021 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5022 .dac_nids = alc880_dac_nids,
5023 .dig_out_nid = ALC880_DIGOUT_NID,
5024 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5025 .channel_mode = alc880_fivestack_modes,
5026 .input_mux = &alc880_capture_source,
5027 },
5028 [ALC880_6ST] = {
5029 .mixers = { alc880_six_stack_mixer },
5030 .init_verbs = { alc880_volume_init_verbs,
5031 alc880_pin_6stack_init_verbs },
5032 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5033 .dac_nids = alc880_6st_dac_nids,
5034 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5035 .channel_mode = alc880_sixstack_modes,
5036 .input_mux = &alc880_6stack_capture_source,
5037 },
5038 [ALC880_6ST_DIG] = {
5039 .mixers = { alc880_six_stack_mixer },
5040 .init_verbs = { alc880_volume_init_verbs,
5041 alc880_pin_6stack_init_verbs },
5042 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5043 .dac_nids = alc880_6st_dac_nids,
5044 .dig_out_nid = ALC880_DIGOUT_NID,
5045 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5046 .channel_mode = alc880_sixstack_modes,
5047 .input_mux = &alc880_6stack_capture_source,
5048 },
5049 [ALC880_W810] = {
5050 .mixers = { alc880_w810_base_mixer },
5051 .init_verbs = { alc880_volume_init_verbs,
5052 alc880_pin_w810_init_verbs,
5053 alc880_gpio2_init_verbs },
5054 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5055 .dac_nids = alc880_w810_dac_nids,
5056 .dig_out_nid = ALC880_DIGOUT_NID,
5057 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5058 .channel_mode = alc880_w810_modes,
5059 .input_mux = &alc880_capture_source,
5060 },
5061 [ALC880_Z71V] = {
5062 .mixers = { alc880_z71v_mixer },
5063 .init_verbs = { alc880_volume_init_verbs,
5064 alc880_pin_z71v_init_verbs },
5065 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5066 .dac_nids = alc880_z71v_dac_nids,
5067 .dig_out_nid = ALC880_DIGOUT_NID,
5068 .hp_nid = 0x03,
5069 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5070 .channel_mode = alc880_2_jack_modes,
5071 .input_mux = &alc880_capture_source,
5072 },
5073 [ALC880_F1734] = {
5074 .mixers = { alc880_f1734_mixer },
5075 .init_verbs = { alc880_volume_init_verbs,
5076 alc880_pin_f1734_init_verbs },
5077 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5078 .dac_nids = alc880_f1734_dac_nids,
5079 .hp_nid = 0x02,
5080 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5081 .channel_mode = alc880_2_jack_modes,
5082 .input_mux = &alc880_f1734_capture_source,
5083 .unsol_event = alc880_uniwill_p53_unsol_event,
5084 .setup = alc880_uniwill_p53_setup,
5085 .init_hook = alc_hp_automute,
5086 },
5087 [ALC880_ASUS] = {
5088 .mixers = { alc880_asus_mixer },
5089 .init_verbs = { alc880_volume_init_verbs,
5090 alc880_pin_asus_init_verbs,
5091 alc880_gpio1_init_verbs },
5092 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5093 .dac_nids = alc880_asus_dac_nids,
5094 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5095 .channel_mode = alc880_asus_modes,
5096 .need_dac_fix = 1,
5097 .input_mux = &alc880_capture_source,
5098 },
5099 [ALC880_ASUS_DIG] = {
5100 .mixers = { alc880_asus_mixer },
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_asus_init_verbs,
5103 alc880_gpio1_init_verbs },
5104 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5105 .dac_nids = alc880_asus_dac_nids,
5106 .dig_out_nid = ALC880_DIGOUT_NID,
5107 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5108 .channel_mode = alc880_asus_modes,
5109 .need_dac_fix = 1,
5110 .input_mux = &alc880_capture_source,
5111 },
5112 [ALC880_ASUS_DIG2] = {
5113 .mixers = { alc880_asus_mixer },
5114 .init_verbs = { alc880_volume_init_verbs,
5115 alc880_pin_asus_init_verbs,
5116 alc880_gpio2_init_verbs }, /* use GPIO2 */
5117 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5118 .dac_nids = alc880_asus_dac_nids,
5119 .dig_out_nid = ALC880_DIGOUT_NID,
5120 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5121 .channel_mode = alc880_asus_modes,
5122 .need_dac_fix = 1,
5123 .input_mux = &alc880_capture_source,
5124 },
5125 [ALC880_ASUS_W1V] = {
5126 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5127 .init_verbs = { alc880_volume_init_verbs,
5128 alc880_pin_asus_init_verbs,
5129 alc880_gpio1_init_verbs },
5130 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5131 .dac_nids = alc880_asus_dac_nids,
5132 .dig_out_nid = ALC880_DIGOUT_NID,
5133 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5134 .channel_mode = alc880_asus_modes,
5135 .need_dac_fix = 1,
5136 .input_mux = &alc880_capture_source,
5137 },
5138 [ALC880_UNIWILL_DIG] = {
5139 .mixers = { alc880_asus_mixer },
5140 .init_verbs = { alc880_volume_init_verbs,
5141 alc880_pin_asus_init_verbs },
5142 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5143 .dac_nids = alc880_asus_dac_nids,
5144 .dig_out_nid = ALC880_DIGOUT_NID,
5145 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5146 .channel_mode = alc880_asus_modes,
5147 .need_dac_fix = 1,
5148 .input_mux = &alc880_capture_source,
5149 },
5150 [ALC880_UNIWILL] = {
5151 .mixers = { alc880_uniwill_mixer },
5152 .init_verbs = { alc880_volume_init_verbs,
5153 alc880_uniwill_init_verbs },
5154 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5155 .dac_nids = alc880_asus_dac_nids,
5156 .dig_out_nid = ALC880_DIGOUT_NID,
5157 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5158 .channel_mode = alc880_threestack_modes,
5159 .need_dac_fix = 1,
5160 .input_mux = &alc880_capture_source,
5161 .unsol_event = alc880_uniwill_unsol_event,
5162 .setup = alc880_uniwill_setup,
5163 .init_hook = alc880_uniwill_init_hook,
5164 },
5165 [ALC880_UNIWILL_P53] = {
5166 .mixers = { alc880_uniwill_p53_mixer },
5167 .init_verbs = { alc880_volume_init_verbs,
5168 alc880_uniwill_p53_init_verbs },
5169 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5170 .dac_nids = alc880_asus_dac_nids,
5171 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5172 .channel_mode = alc880_threestack_modes,
5173 .input_mux = &alc880_capture_source,
5174 .unsol_event = alc880_uniwill_p53_unsol_event,
5175 .setup = alc880_uniwill_p53_setup,
5176 .init_hook = alc_hp_automute,
5177 },
5178 [ALC880_FUJITSU] = {
5179 .mixers = { alc880_fujitsu_mixer },
5180 .init_verbs = { alc880_volume_init_verbs,
5181 alc880_uniwill_p53_init_verbs,
5182 alc880_beep_init_verbs },
5183 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5184 .dac_nids = alc880_dac_nids,
5185 .dig_out_nid = ALC880_DIGOUT_NID,
5186 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5187 .channel_mode = alc880_2_jack_modes,
5188 .input_mux = &alc880_capture_source,
5189 .unsol_event = alc880_uniwill_p53_unsol_event,
5190 .setup = alc880_uniwill_p53_setup,
5191 .init_hook = alc_hp_automute,
5192 },
5193 [ALC880_CLEVO] = {
5194 .mixers = { alc880_three_stack_mixer },
5195 .init_verbs = { alc880_volume_init_verbs,
5196 alc880_pin_clevo_init_verbs },
5197 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5198 .dac_nids = alc880_dac_nids,
5199 .hp_nid = 0x03,
5200 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5201 .channel_mode = alc880_threestack_modes,
5202 .need_dac_fix = 1,
5203 .input_mux = &alc880_capture_source,
5204 },
5205 [ALC880_LG] = {
5206 .mixers = { alc880_lg_mixer },
5207 .init_verbs = { alc880_volume_init_verbs,
5208 alc880_lg_init_verbs },
5209 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5210 .dac_nids = alc880_lg_dac_nids,
5211 .dig_out_nid = ALC880_DIGOUT_NID,
5212 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5213 .channel_mode = alc880_lg_ch_modes,
5214 .need_dac_fix = 1,
5215 .input_mux = &alc880_lg_capture_source,
5216 .unsol_event = alc_sku_unsol_event,
5217 .setup = alc880_lg_setup,
5218 .init_hook = alc_hp_automute,
5219#ifdef CONFIG_SND_HDA_POWER_SAVE
5220 .loopbacks = alc880_lg_loopbacks,
5221#endif
5222 },
5223 [ALC880_LG_LW] = {
5224 .mixers = { alc880_lg_lw_mixer },
5225 .init_verbs = { alc880_volume_init_verbs,
5226 alc880_lg_lw_init_verbs },
5227 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5228 .dac_nids = alc880_dac_nids,
5229 .dig_out_nid = ALC880_DIGOUT_NID,
5230 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5231 .channel_mode = alc880_lg_lw_modes,
5232 .input_mux = &alc880_lg_lw_capture_source,
5233 .unsol_event = alc_sku_unsol_event,
5234 .setup = alc880_lg_lw_setup,
5235 .init_hook = alc_hp_automute,
5236 },
5237 [ALC880_MEDION_RIM] = {
5238 .mixers = { alc880_medion_rim_mixer },
5239 .init_verbs = { alc880_volume_init_verbs,
5240 alc880_medion_rim_init_verbs,
5241 alc_gpio2_init_verbs },
5242 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5243 .dac_nids = alc880_dac_nids,
5244 .dig_out_nid = ALC880_DIGOUT_NID,
5245 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5246 .channel_mode = alc880_2_jack_modes,
5247 .input_mux = &alc880_medion_rim_capture_source,
5248 .unsol_event = alc880_medion_rim_unsol_event,
5249 .setup = alc880_medion_rim_setup,
5250 .init_hook = alc880_medion_rim_automute,
5251 },
5252#ifdef CONFIG_SND_DEBUG
5253 [ALC880_TEST] = {
5254 .mixers = { alc880_test_mixer },
5255 .init_verbs = { alc880_test_init_verbs },
5256 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5257 .dac_nids = alc880_test_dac_nids,
5258 .dig_out_nid = ALC880_DIGOUT_NID,
5259 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5260 .channel_mode = alc880_test_modes,
5261 .input_mux = &alc880_test_capture_source,
5262 },
5263#endif
5264};
5265
5266/*
5267 * Automatic parse of I/O pins from the BIOS configuration 2432 * Automatic parse of I/O pins from the BIOS configuration
5268 */ 2433 */
5269 2434
@@ -5272,18 +2437,12 @@ enum {
5272 ALC_CTL_WIDGET_MUTE, 2437 ALC_CTL_WIDGET_MUTE,
5273 ALC_CTL_BIND_MUTE, 2438 ALC_CTL_BIND_MUTE,
5274}; 2439};
5275static const struct snd_kcontrol_new alc880_control_templates[] = { 2440static const struct snd_kcontrol_new alc_control_templates[] = {
5276 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2441 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5277 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2442 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5278 HDA_BIND_MUTE(NULL, 0, 0, 0), 2443 HDA_BIND_MUTE(NULL, 0, 0, 0),
5279}; 2444};
5280 2445
5281static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5282{
5283 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5284 return snd_array_new(&spec->kctls);
5285}
5286
5287/* add dynamic controls */ 2446/* add dynamic controls */
5288static int add_control(struct alc_spec *spec, int type, const char *name, 2447static int add_control(struct alc_spec *spec, int type, const char *name,
5289 int cidx, unsigned long val) 2448 int cidx, unsigned long val)
@@ -5293,7 +2452,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
5293 knew = alc_kcontrol_new(spec); 2452 knew = alc_kcontrol_new(spec);
5294 if (!knew) 2453 if (!knew)
5295 return -ENOMEM; 2454 return -ENOMEM;
5296 *knew = alc880_control_templates[type]; 2455 *knew = alc_control_templates[type];
5297 knew->name = kstrdup(name, GFP_KERNEL); 2456 knew->name = kstrdup(name, GFP_KERNEL);
5298 if (!knew->name) 2457 if (!knew->name)
5299 return -ENOMEM; 2458 return -ENOMEM;
@@ -5322,60 +2481,15 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
5322#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2481#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5323 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2482 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5324 2483
5325#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 2484static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5326#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 2485 bool can_be_master, int *index)
5327#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5328#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5329#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5330#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5331#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5332#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5333#define ALC880_PIN_CD_NID 0x1c
5334
5335/* fill in the dac_nids table from the parsed pin configuration */
5336static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5337 const struct auto_pin_cfg *cfg)
5338{
5339 hda_nid_t nid;
5340 int assigned[4];
5341 int i, j;
5342
5343 memset(assigned, 0, sizeof(assigned));
5344 spec->multiout.dac_nids = spec->private_dac_nids;
5345
5346 /* check the pins hardwired to audio widget */
5347 for (i = 0; i < cfg->line_outs; i++) {
5348 nid = cfg->line_out_pins[i];
5349 if (alc880_is_fixed_pin(nid)) {
5350 int idx = alc880_fixed_pin_idx(nid);
5351 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5352 assigned[idx] = 1;
5353 }
5354 }
5355 /* left pins can be connect to any audio widget */
5356 for (i = 0; i < cfg->line_outs; i++) {
5357 nid = cfg->line_out_pins[i];
5358 if (alc880_is_fixed_pin(nid))
5359 continue;
5360 /* search for an empty channel */
5361 for (j = 0; j < cfg->line_outs; j++) {
5362 if (!assigned[j]) {
5363 spec->private_dac_nids[i] =
5364 alc880_idx_to_dac(j);
5365 assigned[j] = 1;
5366 break;
5367 }
5368 }
5369 }
5370 spec->multiout.num_dacs = cfg->line_outs;
5371 return 0;
5372}
5373
5374static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5375 bool can_be_master)
5376{ 2486{
5377 struct auto_pin_cfg *cfg = &spec->autocfg; 2487 struct auto_pin_cfg *cfg = &spec->autocfg;
2488 static const char * const chname[4] = {
2489 "Front", "Surround", NULL /*CLFE*/, "Side"
2490 };
5378 2491
2492 *index = 0;
5379 if (cfg->line_outs == 1 && !spec->multi_ios && 2493 if (cfg->line_outs == 1 && !spec->multi_ios &&
5380 !cfg->hp_outs && !cfg->speaker_outs && can_be_master) 2494 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5381 return "Master"; 2495 return "Master";
@@ -5386,120 +2500,17 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5386 return "Speaker"; 2500 return "Speaker";
5387 break; 2501 break;
5388 case AUTO_PIN_HP_OUT: 2502 case AUTO_PIN_HP_OUT:
2503 /* for multi-io case, only the primary out */
2504 if (ch && spec->multi_ios)
2505 break;
2506 *index = ch;
5389 return "Headphone"; 2507 return "Headphone";
5390 default: 2508 default:
5391 if (cfg->line_outs == 1 && !spec->multi_ios) 2509 if (cfg->line_outs == 1 && !spec->multi_ios)
5392 return "PCM"; 2510 return "PCM";
5393 break; 2511 break;
5394 } 2512 }
5395 return NULL; 2513 return chname[ch];
5396}
5397
5398/* add playback controls from the parsed DAC table */
5399static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5400 const struct auto_pin_cfg *cfg)
5401{
5402 static const char * const chname[4] = {
5403 "Front", "Surround", NULL /*CLFE*/, "Side"
5404 };
5405 const char *pfx = alc_get_line_out_pfx(spec, false);
5406 hda_nid_t nid;
5407 int i, err, noutputs;
5408
5409 noutputs = cfg->line_outs;
5410 if (spec->multi_ios > 0)
5411 noutputs += spec->multi_ios;
5412
5413 for (i = 0; i < noutputs; i++) {
5414 if (!spec->multiout.dac_nids[i])
5415 continue;
5416 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5417 if (!pfx && i == 2) {
5418 /* Center/LFE */
5419 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5420 "Center",
5421 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5422 HDA_OUTPUT));
5423 if (err < 0)
5424 return err;
5425 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5426 "LFE",
5427 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5428 HDA_OUTPUT));
5429 if (err < 0)
5430 return err;
5431 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5432 "Center",
5433 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5434 HDA_INPUT));
5435 if (err < 0)
5436 return err;
5437 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5438 "LFE",
5439 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5440 HDA_INPUT));
5441 if (err < 0)
5442 return err;
5443 } else {
5444 const char *name = pfx;
5445 int index = i;
5446 if (!name) {
5447 name = chname[i];
5448 index = 0;
5449 }
5450 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5451 name, index,
5452 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5453 HDA_OUTPUT));
5454 if (err < 0)
5455 return err;
5456 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5457 name, index,
5458 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5459 HDA_INPUT));
5460 if (err < 0)
5461 return err;
5462 }
5463 }
5464 return 0;
5465}
5466
5467/* add playback controls for speaker and HP outputs */
5468static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5469 const char *pfx)
5470{
5471 hda_nid_t nid;
5472 int err;
5473
5474 if (!pin)
5475 return 0;
5476
5477 if (alc880_is_fixed_pin(pin)) {
5478 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5479 /* specify the DAC as the extra output */
5480 if (!spec->multiout.hp_nid)
5481 spec->multiout.hp_nid = nid;
5482 else
5483 spec->multiout.extra_out_nid[0] = nid;
5484 /* control HP volume/switch on the output mixer amp */
5485 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5486 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5487 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5488 if (err < 0)
5489 return err;
5490 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5491 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5492 if (err < 0)
5493 return err;
5494 } else if (alc880_is_multi_pin(pin)) {
5495 /* set manual connection */
5496 /* we have only a switch on HP-out PIN */
5497 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5498 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5499 if (err < 0)
5500 return err;
5501 }
5502 return 0;
5503} 2514}
5504 2515
5505/* create input playback/capture controls for the given pin */ 2516/* create input playback/capture controls for the given pin */
@@ -5526,17 +2537,72 @@ static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5526 return (pincap & AC_PINCAP_IN) != 0; 2537 return (pincap & AC_PINCAP_IN) != 0;
5527} 2538}
5528 2539
2540/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
2541static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2542{
2543 struct alc_spec *spec = codec->spec;
2544 hda_nid_t nid;
2545 hda_nid_t *adc_nids = spec->private_adc_nids;
2546 hda_nid_t *cap_nids = spec->private_capsrc_nids;
2547 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2548 bool indep_capsrc = false;
2549 int i, nums = 0;
2550
2551 nid = codec->start_nid;
2552 for (i = 0; i < codec->num_nodes; i++, nid++) {
2553 hda_nid_t src;
2554 const hda_nid_t *list;
2555 unsigned int caps = get_wcaps(codec, nid);
2556 int type = get_wcaps_type(caps);
2557
2558 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
2559 continue;
2560 adc_nids[nums] = nid;
2561 cap_nids[nums] = nid;
2562 src = nid;
2563 for (;;) {
2564 int n;
2565 type = get_wcaps_type(get_wcaps(codec, src));
2566 if (type == AC_WID_PIN)
2567 break;
2568 if (type == AC_WID_AUD_SEL) {
2569 cap_nids[nums] = src;
2570 indep_capsrc = true;
2571 break;
2572 }
2573 n = snd_hda_get_conn_list(codec, src, &list);
2574 if (n > 1) {
2575 cap_nids[nums] = src;
2576 indep_capsrc = true;
2577 break;
2578 } else if (n != 1)
2579 break;
2580 src = *list;
2581 }
2582 if (++nums >= max_nums)
2583 break;
2584 }
2585 spec->adc_nids = spec->private_adc_nids;
2586 spec->capsrc_nids = spec->private_capsrc_nids;
2587 spec->num_adc_nids = nums;
2588 return nums;
2589}
2590
5529/* create playback/capture controls for input pins */ 2591/* create playback/capture controls for input pins */
5530static int alc_auto_create_input_ctls(struct hda_codec *codec, 2592static int alc_auto_create_input_ctls(struct hda_codec *codec)
5531 const struct auto_pin_cfg *cfg,
5532 hda_nid_t mixer,
5533 hda_nid_t cap1, hda_nid_t cap2)
5534{ 2593{
5535 struct alc_spec *spec = codec->spec; 2594 struct alc_spec *spec = codec->spec;
2595 const struct auto_pin_cfg *cfg = &spec->autocfg;
2596 hda_nid_t mixer = spec->mixer_nid;
5536 struct hda_input_mux *imux = &spec->private_imux[0]; 2597 struct hda_input_mux *imux = &spec->private_imux[0];
5537 int i, err, idx, type_idx = 0; 2598 int num_adcs;
2599 int i, c, err, idx, type_idx = 0;
5538 const char *prev_label = NULL; 2600 const char *prev_label = NULL;
5539 2601
2602 num_adcs = alc_auto_fill_adc_caps(codec);
2603 if (num_adcs < 0)
2604 return 0;
2605
5540 for (i = 0; i < cfg->num_inputs; i++) { 2606 for (i = 0; i < cfg->num_inputs; i++) {
5541 hda_nid_t pin; 2607 hda_nid_t pin;
5542 const char *label; 2608 const char *label;
@@ -5563,21 +2629,22 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5563 } 2629 }
5564 } 2630 }
5565 2631
5566 if (!cap1) 2632 for (c = 0; c < num_adcs; c++) {
5567 continue; 2633 hda_nid_t cap = spec->capsrc_nids ?
5568 idx = get_connection_index(codec, cap1, pin); 2634 spec->capsrc_nids[c] : spec->adc_nids[c];
5569 if (idx < 0 && cap2) 2635 idx = get_connection_index(codec, cap, pin);
5570 idx = get_connection_index(codec, cap2, pin); 2636 if (idx >= 0) {
5571 if (idx >= 0) 2637 spec->imux_pins[imux->num_items] = pin;
5572 snd_hda_add_imux_item(imux, label, idx, NULL); 2638 snd_hda_add_imux_item(imux, label, idx, NULL);
2639 break;
2640 }
2641 }
5573 } 2642 }
5574 return 0;
5575}
5576 2643
5577static int alc880_auto_create_input_ctls(struct hda_codec *codec, 2644 spec->num_mux_defs = 1;
5578 const struct auto_pin_cfg *cfg) 2645 spec->input_mux = imux;
5579{ 2646
5580 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 2647 return 0;
5581} 2648}
5582 2649
5583static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2650static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
@@ -5586,25 +2653,11 @@ static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5586 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2653 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5587 pin_type); 2654 pin_type);
5588 /* unmute pin */ 2655 /* unmute pin */
5589 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2656 if (nid_has_mute(codec, nid, HDA_OUTPUT))
2657 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5590 AMP_OUT_UNMUTE); 2658 AMP_OUT_UNMUTE);
5591} 2659}
5592 2660
5593static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5594 hda_nid_t nid, int pin_type,
5595 int dac_idx)
5596{
5597 alc_set_pin_output(codec, nid, pin_type);
5598 /* need the manual connection? */
5599 if (alc880_is_multi_pin(nid)) {
5600 struct alc_spec *spec = codec->spec;
5601 int idx = alc880_multi_pin_idx(nid);
5602 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5603 AC_VERB_SET_CONNECT_SEL,
5604 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5605 }
5606}
5607
5608static int get_pin_type(int line_out_type) 2661static int get_pin_type(int line_out_type)
5609{ 2662{
5610 if (line_out_type == AUTO_PIN_HP_OUT) 2663 if (line_out_type == AUTO_PIN_HP_OUT)
@@ -5613,177 +2666,729 @@ static int get_pin_type(int line_out_type)
5613 return PIN_OUT; 2666 return PIN_OUT;
5614} 2667}
5615 2668
5616static void alc880_auto_init_multi_out(struct hda_codec *codec) 2669static void alc_auto_init_analog_input(struct hda_codec *codec)
5617{ 2670{
5618 struct alc_spec *spec = codec->spec; 2671 struct alc_spec *spec = codec->spec;
2672 struct auto_pin_cfg *cfg = &spec->autocfg;
5619 int i; 2673 int i;
5620 2674
5621 for (i = 0; i < spec->autocfg.line_outs; i++) { 2675 for (i = 0; i < cfg->num_inputs; i++) {
5622 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 2676 hda_nid_t nid = cfg->inputs[i].pin;
5623 int pin_type = get_pin_type(spec->autocfg.line_out_type); 2677 if (alc_is_input_pin(codec, nid)) {
5624 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 2678 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
2679 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
2680 snd_hda_codec_write(codec, nid, 0,
2681 AC_VERB_SET_AMP_GAIN_MUTE,
2682 AMP_OUT_MUTE);
2683 }
2684 }
2685
2686 /* mute all loopback inputs */
2687 if (spec->mixer_nid) {
2688 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
2689 for (i = 0; i < nums; i++)
2690 snd_hda_codec_write(codec, spec->mixer_nid, 0,
2691 AC_VERB_SET_AMP_GAIN_MUTE,
2692 AMP_IN_MUTE(i));
2693 }
2694}
2695
2696/* convert from MIX nid to DAC */
2697static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
2698{
2699 hda_nid_t list[5];
2700 int i, num;
2701
2702 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
2703 return nid;
2704 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
2705 for (i = 0; i < num; i++) {
2706 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2707 return list[i];
5625 } 2708 }
2709 return 0;
2710}
2711
2712/* go down to the selector widget before the mixer */
2713static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2714{
2715 hda_nid_t srcs[5];
2716 int num = snd_hda_get_connections(codec, pin, srcs,
2717 ARRAY_SIZE(srcs));
2718 if (num != 1 ||
2719 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2720 return pin;
2721 return srcs[0];
5626} 2722}
5627 2723
5628static void alc880_auto_init_extra_out(struct hda_codec *codec) 2724/* get MIX nid connected to the given pin targeted to DAC */
2725static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2726 hda_nid_t dac)
2727{
2728 hda_nid_t mix[5];
2729 int i, num;
2730
2731 pin = alc_go_down_to_selector(codec, pin);
2732 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2733 for (i = 0; i < num; i++) {
2734 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2735 return mix[i];
2736 }
2737 return 0;
2738}
2739
2740/* select the connection from pin to DAC if needed */
2741static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2742 hda_nid_t dac)
2743{
2744 hda_nid_t mix[5];
2745 int i, num;
2746
2747 pin = alc_go_down_to_selector(codec, pin);
2748 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2749 if (num < 2)
2750 return 0;
2751 for (i = 0; i < num; i++) {
2752 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2753 snd_hda_codec_update_cache(codec, pin, 0,
2754 AC_VERB_SET_CONNECT_SEL, i);
2755 return 0;
2756 }
2757 }
2758 return 0;
2759}
2760
2761/* look for an empty DAC slot */
2762static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
5629{ 2763{
5630 struct alc_spec *spec = codec->spec; 2764 struct alc_spec *spec = codec->spec;
5631 hda_nid_t pin; 2765 hda_nid_t srcs[5];
2766 int i, num;
5632 2767
5633 pin = spec->autocfg.speaker_pins[0]; 2768 pin = alc_go_down_to_selector(codec, pin);
5634 if (pin) /* connect to front */ 2769 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
5635 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2770 for (i = 0; i < num; i++) {
5636 pin = spec->autocfg.hp_pins[0]; 2771 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
5637 if (pin) /* connect to front */ 2772 if (!nid)
5638 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 2773 continue;
2774 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2775 spec->multiout.num_dacs))
2776 continue;
2777 if (spec->multiout.hp_nid == nid)
2778 continue;
2779 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2780 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2781 continue;
2782 return nid;
2783 }
2784 return 0;
2785}
2786
2787static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2788{
2789 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2790 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
2791 return alc_auto_look_for_dac(codec, pin);
2792 return 0;
5639} 2793}
5640 2794
5641static void alc880_auto_init_analog_input(struct hda_codec *codec) 2795/* fill in the dac_nids table from the parsed pin configuration */
2796static int alc_auto_fill_dac_nids(struct hda_codec *codec)
5642{ 2797{
5643 struct alc_spec *spec = codec->spec; 2798 struct alc_spec *spec = codec->spec;
5644 struct auto_pin_cfg *cfg = &spec->autocfg; 2799 const struct auto_pin_cfg *cfg = &spec->autocfg;
2800 bool redone = false;
5645 int i; 2801 int i;
5646 2802
5647 for (i = 0; i < cfg->num_inputs; i++) { 2803 again:
5648 hda_nid_t nid = cfg->inputs[i].pin; 2804 spec->multiout.num_dacs = 0;
5649 if (alc_is_input_pin(codec, nid)) { 2805 spec->multiout.hp_nid = 0;
5650 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 2806 spec->multiout.extra_out_nid[0] = 0;
5651 if (nid != ALC880_PIN_CD_NID && 2807 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
5652 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 2808 spec->multiout.dac_nids = spec->private_dac_nids;
5653 snd_hda_codec_write(codec, nid, 0, 2809
5654 AC_VERB_SET_AMP_GAIN_MUTE, 2810 /* fill hard-wired DACs first */
5655 AMP_OUT_MUTE); 2811 if (!redone) {
2812 for (i = 0; i < cfg->line_outs; i++)
2813 spec->private_dac_nids[i] =
2814 get_dac_if_single(codec, cfg->line_out_pins[i]);
2815 if (cfg->hp_outs)
2816 spec->multiout.hp_nid =
2817 get_dac_if_single(codec, cfg->hp_pins[0]);
2818 if (cfg->speaker_outs)
2819 spec->multiout.extra_out_nid[0] =
2820 get_dac_if_single(codec, cfg->speaker_pins[0]);
2821 }
2822
2823 for (i = 0; i < cfg->line_outs; i++) {
2824 hda_nid_t pin = cfg->line_out_pins[i];
2825 if (spec->private_dac_nids[i])
2826 continue;
2827 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
2828 if (!spec->private_dac_nids[i] && !redone) {
2829 /* if we can't find primary DACs, re-probe without
2830 * checking the hard-wired DACs
2831 */
2832 redone = true;
2833 goto again;
5656 } 2834 }
5657 } 2835 }
2836
2837 for (i = 0; i < cfg->line_outs; i++) {
2838 if (spec->private_dac_nids[i])
2839 spec->multiout.num_dacs++;
2840 else
2841 memmove(spec->private_dac_nids + i,
2842 spec->private_dac_nids + i + 1,
2843 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2844 }
2845
2846 if (cfg->hp_outs && !spec->multiout.hp_nid)
2847 spec->multiout.hp_nid =
2848 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
2849 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
2850 spec->multiout.extra_out_nid[0] =
2851 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
2852
2853 return 0;
5658} 2854}
5659 2855
5660static void alc880_auto_init_input_src(struct hda_codec *codec) 2856static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2857 const char *pfx, int cidx,
2858 hda_nid_t nid, unsigned int chs)
5661{ 2859{
5662 struct alc_spec *spec = codec->spec; 2860 if (!nid)
5663 int c; 2861 return 0;
5664 2862 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
5665 for (c = 0; c < spec->num_adc_nids; c++) { 2863 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
5666 unsigned int mux_idx;
5667 const struct hda_input_mux *imux;
5668 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5669 imux = &spec->input_mux[mux_idx];
5670 if (!imux->num_items && mux_idx > 0)
5671 imux = &spec->input_mux[0];
5672 if (imux)
5673 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5674 AC_VERB_SET_CONNECT_SEL,
5675 imux->items[0].index);
5676 }
5677} 2864}
5678 2865
5679static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); 2866#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
2867 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
5680 2868
5681/* parse the BIOS configuration and set up the alc_spec */ 2869/* create a mute-switch for the given mixer widget;
5682/* return 1 if successful, 0 if the proper config is not found, 2870 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
5683 * or a negative error code
5684 */ 2871 */
5685static int alc880_parse_auto_config(struct hda_codec *codec) 2872static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2873 const char *pfx, int cidx,
2874 hda_nid_t nid, unsigned int chs)
2875{
2876 int wid_type;
2877 int type;
2878 unsigned long val;
2879 if (!nid)
2880 return 0;
2881 wid_type = get_wcaps_type(get_wcaps(codec, nid));
2882 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
2883 type = ALC_CTL_WIDGET_MUTE;
2884 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
2885 } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2886 type = ALC_CTL_WIDGET_MUTE;
2887 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2888 } else {
2889 type = ALC_CTL_BIND_MUTE;
2890 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2891 }
2892 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2893}
2894
2895#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2896 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2897
2898static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
2899 hda_nid_t pin, hda_nid_t dac)
2900{
2901 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2902 if (nid_has_mute(codec, pin, HDA_OUTPUT))
2903 return pin;
2904 else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
2905 return mix;
2906 else if (nid_has_mute(codec, dac, HDA_OUTPUT))
2907 return dac;
2908 return 0;
2909}
2910
2911static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
2912 hda_nid_t pin, hda_nid_t dac)
2913{
2914 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2915 if (nid_has_volume(codec, dac, HDA_OUTPUT))
2916 return dac;
2917 else if (nid_has_volume(codec, mix, HDA_OUTPUT))
2918 return mix;
2919 else if (nid_has_volume(codec, pin, HDA_OUTPUT))
2920 return pin;
2921 return 0;
2922}
2923
2924/* add playback controls from the parsed DAC table */
2925static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2926 const struct auto_pin_cfg *cfg)
2927{
2928 struct alc_spec *spec = codec->spec;
2929 int i, err, noutputs;
2930
2931 noutputs = cfg->line_outs;
2932 if (spec->multi_ios > 0)
2933 noutputs += spec->multi_ios;
2934
2935 for (i = 0; i < noutputs; i++) {
2936 const char *name;
2937 int index;
2938 hda_nid_t dac, pin;
2939 hda_nid_t sw, vol;
2940
2941 dac = spec->multiout.dac_nids[i];
2942 if (!dac)
2943 continue;
2944 if (i >= cfg->line_outs)
2945 pin = spec->multi_io[i - 1].pin;
2946 else
2947 pin = cfg->line_out_pins[i];
2948
2949 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2950 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2951 name = alc_get_line_out_pfx(spec, i, true, &index);
2952 if (!name) {
2953 /* Center/LFE */
2954 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
2955 if (err < 0)
2956 return err;
2957 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
2958 if (err < 0)
2959 return err;
2960 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
2961 if (err < 0)
2962 return err;
2963 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
2964 if (err < 0)
2965 return err;
2966 } else {
2967 err = alc_auto_add_stereo_vol(codec, name, index, vol);
2968 if (err < 0)
2969 return err;
2970 err = alc_auto_add_stereo_sw(codec, name, index, sw);
2971 if (err < 0)
2972 return err;
2973 }
2974 }
2975 return 0;
2976}
2977
2978/* add playback controls for speaker and HP outputs */
2979static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2980 hda_nid_t dac, const char *pfx)
5686{ 2981{
5687 struct alc_spec *spec = codec->spec; 2982 struct alc_spec *spec = codec->spec;
2983 hda_nid_t sw, vol;
5688 int err; 2984 int err;
5689 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5690 2985
5691 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2986 if (!pin)
5692 alc880_ignore); 2987 return 0;
5693 if (err < 0) 2988 if (!dac) {
5694 return err; 2989 /* the corresponding DAC is already occupied */
5695 if (!spec->autocfg.line_outs) 2990 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
5696 return 0; /* can't find valid BIOS pin config */ 2991 return 0; /* no way */
2992 /* create a switch only */
2993 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
2994 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2995 }
5697 2996
5698 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 2997 sw = alc_look_for_out_mute_nid(codec, pin, dac);
5699 if (err < 0) 2998 vol = alc_look_for_out_vol_nid(codec, pin, dac);
5700 return err; 2999 err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
5701 err = alc_auto_add_multi_channel_mode(codec);
5702 if (err < 0)
5703 return err;
5704 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5705 if (err < 0)
5706 return err;
5707 err = alc880_auto_create_extra_out(spec,
5708 spec->autocfg.speaker_pins[0],
5709 "Speaker");
5710 if (err < 0)
5711 return err;
5712 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5713 "Headphone");
5714 if (err < 0) 3000 if (err < 0)
5715 return err; 3001 return err;
5716 err = alc880_auto_create_input_ctls(codec, &spec->autocfg); 3002 err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
5717 if (err < 0) 3003 if (err < 0)
5718 return err; 3004 return err;
3005 return 0;
3006}
5719 3007
5720 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3008static int alc_auto_create_hp_out(struct hda_codec *codec)
3009{
3010 struct alc_spec *spec = codec->spec;
3011 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3012 spec->multiout.hp_nid,
3013 "Headphone");
3014}
5721 3015
5722 alc_auto_parse_digital(codec); 3016static int alc_auto_create_speaker_out(struct hda_codec *codec)
3017{
3018 struct alc_spec *spec = codec->spec;
3019 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
3020 spec->multiout.extra_out_nid[0],
3021 "Speaker");
3022}
5723 3023
5724 if (spec->kctls.list) 3024static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
5725 add_mixer(spec, spec->kctls.list); 3025 hda_nid_t pin, int pin_type,
3026 hda_nid_t dac)
3027{
3028 int i, num;
3029 hda_nid_t nid, mix = 0;
3030 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
3031
3032 alc_set_pin_output(codec, pin, pin_type);
3033 nid = alc_go_down_to_selector(codec, pin);
3034 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
3035 for (i = 0; i < num; i++) {
3036 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
3037 continue;
3038 mix = srcs[i];
3039 break;
3040 }
3041 if (!mix)
3042 return;
3043
3044 /* need the manual connection? */
3045 if (num > 1)
3046 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
3047 /* unmute mixer widget inputs */
3048 if (nid_has_mute(codec, mix, HDA_INPUT)) {
3049 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3050 AMP_IN_UNMUTE(0));
3051 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3052 AMP_IN_UNMUTE(1));
3053 }
3054 /* initialize volume */
3055 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3056 if (nid)
3057 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3058 AMP_OUT_ZERO);
3059}
5726 3060
5727 add_verb(spec, alc880_volume_init_verbs); 3061static void alc_auto_init_multi_out(struct hda_codec *codec)
3062{
3063 struct alc_spec *spec = codec->spec;
3064 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3065 int i;
5728 3066
5729 spec->num_mux_defs = 1; 3067 for (i = 0; i <= HDA_SIDE; i++) {
5730 spec->input_mux = &spec->private_imux[0]; 3068 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3069 if (nid)
3070 alc_auto_set_output_and_unmute(codec, nid, pin_type,
3071 spec->multiout.dac_nids[i]);
3072 }
3073}
3074
3075static void alc_auto_init_extra_out(struct hda_codec *codec)
3076{
3077 struct alc_spec *spec = codec->spec;
3078 hda_nid_t pin;
3079
3080 pin = spec->autocfg.hp_pins[0];
3081 if (pin)
3082 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
3083 spec->multiout.hp_nid);
3084 pin = spec->autocfg.speaker_pins[0];
3085 if (pin)
3086 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
3087 spec->multiout.extra_out_nid[0]);
3088}
3089
3090/*
3091 * multi-io helper
3092 */
3093static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3094 unsigned int location)
3095{
3096 struct alc_spec *spec = codec->spec;
3097 struct auto_pin_cfg *cfg = &spec->autocfg;
3098 int type, i, num_pins = 0;
3099
3100 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3101 for (i = 0; i < cfg->num_inputs; i++) {
3102 hda_nid_t nid = cfg->inputs[i].pin;
3103 hda_nid_t dac;
3104 unsigned int defcfg, caps;
3105 if (cfg->inputs[i].type != type)
3106 continue;
3107 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3108 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3109 continue;
3110 if (location && get_defcfg_location(defcfg) != location)
3111 continue;
3112 caps = snd_hda_query_pin_caps(codec, nid);
3113 if (!(caps & AC_PINCAP_OUT))
3114 continue;
3115 dac = alc_auto_look_for_dac(codec, nid);
3116 if (!dac)
3117 continue;
3118 spec->multi_io[num_pins].pin = nid;
3119 spec->multi_io[num_pins].dac = dac;
3120 num_pins++;
3121 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3122 }
3123 }
3124 spec->multiout.num_dacs = 1;
3125 if (num_pins < 2)
3126 return 0;
3127 return num_pins;
3128}
3129
3130static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3131 struct snd_ctl_elem_info *uinfo)
3132{
3133 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3134 struct alc_spec *spec = codec->spec;
3135
3136 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3137 uinfo->count = 1;
3138 uinfo->value.enumerated.items = spec->multi_ios + 1;
3139 if (uinfo->value.enumerated.item > spec->multi_ios)
3140 uinfo->value.enumerated.item = spec->multi_ios;
3141 sprintf(uinfo->value.enumerated.name, "%dch",
3142 (uinfo->value.enumerated.item + 1) * 2);
3143 return 0;
3144}
5731 3145
5732 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 3146static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3147 struct snd_ctl_elem_value *ucontrol)
3148{
3149 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3150 struct alc_spec *spec = codec->spec;
3151 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3152 return 0;
3153}
5733 3154
3155static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3156{
3157 struct alc_spec *spec = codec->spec;
3158 hda_nid_t nid = spec->multi_io[idx].pin;
3159
3160 if (!spec->multi_io[idx].ctl_in)
3161 spec->multi_io[idx].ctl_in =
3162 snd_hda_codec_read(codec, nid, 0,
3163 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3164 if (output) {
3165 snd_hda_codec_update_cache(codec, nid, 0,
3166 AC_VERB_SET_PIN_WIDGET_CONTROL,
3167 PIN_OUT);
3168 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3169 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3170 HDA_AMP_MUTE, 0);
3171 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3172 } else {
3173 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3174 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3175 HDA_AMP_MUTE, HDA_AMP_MUTE);
3176 snd_hda_codec_update_cache(codec, nid, 0,
3177 AC_VERB_SET_PIN_WIDGET_CONTROL,
3178 spec->multi_io[idx].ctl_in);
3179 }
3180 return 0;
3181}
3182
3183static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3184 struct snd_ctl_elem_value *ucontrol)
3185{
3186 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3187 struct alc_spec *spec = codec->spec;
3188 int i, ch;
3189
3190 ch = ucontrol->value.enumerated.item[0];
3191 if (ch < 0 || ch > spec->multi_ios)
3192 return -EINVAL;
3193 if (ch == (spec->ext_channel_count - 1) / 2)
3194 return 0;
3195 spec->ext_channel_count = (ch + 1) * 2;
3196 for (i = 0; i < spec->multi_ios; i++)
3197 alc_set_multi_io(codec, i, i < ch);
3198 spec->multiout.max_channels = spec->ext_channel_count;
3199 if (spec->need_dac_fix && !spec->const_channel_count)
3200 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
5734 return 1; 3201 return 1;
5735} 3202}
5736 3203
5737/* additional initialization for auto-configuration model */ 3204static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
5738static void alc880_auto_init(struct hda_codec *codec) 3205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3206 .name = "Channel Mode",
3207 .info = alc_auto_ch_mode_info,
3208 .get = alc_auto_ch_mode_get,
3209 .put = alc_auto_ch_mode_put,
3210};
3211
3212static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3213 int (*fill_dac)(struct hda_codec *))
5739{ 3214{
5740 struct alc_spec *spec = codec->spec; 3215 struct alc_spec *spec = codec->spec;
5741 alc880_auto_init_multi_out(codec); 3216 struct auto_pin_cfg *cfg = &spec->autocfg;
5742 alc880_auto_init_extra_out(codec); 3217 unsigned int location, defcfg;
5743 alc880_auto_init_analog_input(codec); 3218 int num_pins;
5744 alc880_auto_init_input_src(codec); 3219
5745 alc_auto_init_digital(codec); 3220 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
5746 if (spec->unsol_event) 3221 /* use HP as primary out */
5747 alc_inithook(codec); 3222 cfg->speaker_outs = cfg->line_outs;
3223 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3224 sizeof(cfg->speaker_pins));
3225 cfg->line_outs = cfg->hp_outs;
3226 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3227 cfg->hp_outs = 0;
3228 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3229 cfg->line_out_type = AUTO_PIN_HP_OUT;
3230 if (fill_dac)
3231 fill_dac(codec);
3232 }
3233 if (cfg->line_outs != 1 ||
3234 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3235 return 0;
3236
3237 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
3238 location = get_defcfg_location(defcfg);
3239
3240 num_pins = alc_auto_fill_multi_ios(codec, location);
3241 if (num_pins > 0) {
3242 struct snd_kcontrol_new *knew;
3243
3244 knew = alc_kcontrol_new(spec);
3245 if (!knew)
3246 return -ENOMEM;
3247 *knew = alc_auto_channel_mode_enum;
3248 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3249 if (!knew->name)
3250 return -ENOMEM;
3251
3252 spec->multi_ios = num_pins;
3253 spec->ext_channel_count = 2;
3254 spec->multiout.num_dacs = num_pins + 1;
3255 }
3256 return 0;
5748} 3257}
5749 3258
5750/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 3259/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5751 * one of two digital mic pins, e.g. on ALC272 3260 * active input pins
5752 */ 3261 */
5753static void fixup_automic_adc(struct hda_codec *codec) 3262static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5754{ 3263{
5755 struct alc_spec *spec = codec->spec; 3264 struct alc_spec *spec = codec->spec;
5756 int i; 3265 const struct hda_input_mux *imux;
3266 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3267 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3268 int i, n, nums;
5757 3269
5758 for (i = 0; i < spec->num_adc_nids; i++) { 3270 imux = spec->input_mux;
5759 hda_nid_t cap = spec->capsrc_nids ? 3271 if (!imux)
5760 spec->capsrc_nids[i] : spec->adc_nids[i]; 3272 return;
5761 int iidx, eidx; 3273 if (spec->dyn_adc_switch)
3274 return;
5762 3275
5763 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 3276 nums = 0;
5764 if (iidx < 0) 3277 for (n = 0; n < spec->num_adc_nids; n++) {
5765 continue; 3278 hda_nid_t cap = spec->private_capsrc_nids[n];
5766 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 3279 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5767 if (eidx < 0) 3280 for (i = 0; i < imux->num_items; i++) {
5768 continue; 3281 hda_nid_t pin = spec->imux_pins[i];
5769 spec->int_mic.mux_idx = iidx; 3282 if (pin) {
5770 spec->ext_mic.mux_idx = eidx; 3283 if (get_connection_index(codec, cap, pin) < 0)
5771 if (spec->capsrc_nids) 3284 break;
5772 spec->capsrc_nids += i; 3285 } else if (num_conns <= imux->items[i].index)
5773 spec->adc_nids += i; 3286 break;
5774 spec->num_adc_nids = 1; 3287 }
5775 /* optional dock-mic */ 3288 if (i >= imux->num_items) {
5776 eidx = get_connection_index(codec, cap, spec->dock_mic.pin); 3289 adc_nids[nums] = spec->private_adc_nids[n];
5777 if (eidx < 0) 3290 capsrc_nids[nums++] = cap;
5778 spec->dock_mic.pin = 0; 3291 }
5779 else 3292 }
5780 spec->dock_mic.mux_idx = eidx; 3293 if (!nums) {
3294 /* check whether ADC-switch is possible */
3295 if (!alc_check_dyn_adc_switch(codec)) {
3296 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3297 " using fallback 0x%x\n",
3298 codec->chip_name, spec->private_adc_nids[0]);
3299 spec->num_adc_nids = 1;
3300 spec->auto_mic = 0;
3301 return;
3302 }
3303 } else if (nums != spec->num_adc_nids) {
3304 memcpy(spec->private_adc_nids, adc_nids,
3305 nums * sizeof(hda_nid_t));
3306 memcpy(spec->private_capsrc_nids, capsrc_nids,
3307 nums * sizeof(hda_nid_t));
3308 spec->num_adc_nids = nums;
3309 }
3310
3311 if (spec->auto_mic)
3312 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3313 else if (spec->input_mux->num_items == 1)
3314 spec->num_adc_nids = 1; /* reduce to a single ADC */
3315}
3316
3317/*
3318 * initialize ADC paths
3319 */
3320static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3321{
3322 struct alc_spec *spec = codec->spec;
3323 hda_nid_t nid;
3324
3325 nid = spec->adc_nids[adc_idx];
3326 /* mute ADC */
3327 if (nid_has_mute(codec, nid, HDA_INPUT)) {
3328 snd_hda_codec_write(codec, nid, 0,
3329 AC_VERB_SET_AMP_GAIN_MUTE,
3330 AMP_IN_MUTE(0));
5781 return; 3331 return;
5782 } 3332 }
5783 snd_printd(KERN_INFO "hda_codec: %s: " 3333 if (!spec->capsrc_nids)
5784 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 3334 return;
5785 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 3335 nid = spec->capsrc_nids[adc_idx];
5786 spec->auto_mic = 0; /* disable auto-mic to be sure */ 3336 if (nid_has_mute(codec, nid, HDA_OUTPUT))
3337 snd_hda_codec_write(codec, nid, 0,
3338 AC_VERB_SET_AMP_GAIN_MUTE,
3339 AMP_OUT_MUTE);
3340}
3341
3342static void alc_auto_init_input_src(struct hda_codec *codec)
3343{
3344 struct alc_spec *spec = codec->spec;
3345 int c, nums;
3346
3347 for (c = 0; c < spec->num_adc_nids; c++)
3348 alc_auto_init_adc(codec, c);
3349 if (spec->dyn_adc_switch)
3350 nums = 1;
3351 else
3352 nums = spec->num_adc_nids;
3353 for (c = 0; c < nums; c++)
3354 alc_mux_select(codec, 0, spec->cur_mux[c], true);
3355}
3356
3357/* add mic boosts if needed */
3358static int alc_auto_add_mic_boost(struct hda_codec *codec)
3359{
3360 struct alc_spec *spec = codec->spec;
3361 struct auto_pin_cfg *cfg = &spec->autocfg;
3362 int i, err;
3363 int type_idx = 0;
3364 hda_nid_t nid;
3365 const char *prev_label = NULL;
3366
3367 for (i = 0; i < cfg->num_inputs; i++) {
3368 if (cfg->inputs[i].type > AUTO_PIN_MIC)
3369 break;
3370 nid = cfg->inputs[i].pin;
3371 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
3372 const char *label;
3373 char boost_label[32];
3374
3375 label = hda_get_autocfg_input_label(codec, cfg, i);
3376 if (prev_label && !strcmp(label, prev_label))
3377 type_idx++;
3378 else
3379 type_idx = 0;
3380 prev_label = label;
3381
3382 snprintf(boost_label, sizeof(boost_label),
3383 "%s Boost Volume", label);
3384 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3385 boost_label, type_idx,
3386 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
3387 if (err < 0)
3388 return err;
3389 }
3390 }
3391 return 0;
5787} 3392}
5788 3393
5789/* select or unmute the given capsrc route */ 3394/* select or unmute the given capsrc route */
@@ -5793,7 +3398,7 @@ static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5793 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { 3398 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5794 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 3399 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5795 HDA_AMP_MUTE, 0); 3400 HDA_AMP_MUTE, 0);
5796 } else { 3401 } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
5797 snd_hda_codec_write_cache(codec, cap, 0, 3402 snd_hda_codec_write_cache(codec, cap, 0,
5798 AC_VERB_SET_CONNECT_SEL, idx); 3403 AC_VERB_SET_CONNECT_SEL, idx);
5799 } 3404 }
@@ -5821,46 +3426,17 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5821 return -1; /* not found */ 3426 return -1; /* not found */
5822} 3427}
5823 3428
5824/* choose the ADC/MUX containing the input pin and initialize the setup */
5825static void fixup_single_adc(struct hda_codec *codec)
5826{
5827 struct alc_spec *spec = codec->spec;
5828 struct auto_pin_cfg *cfg = &spec->autocfg;
5829 int i;
5830
5831 /* search for the input pin; there must be only one */
5832 if (cfg->num_inputs != 1)
5833 return;
5834 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5835 if (i >= 0) {
5836 /* use only this ADC */
5837 if (spec->capsrc_nids)
5838 spec->capsrc_nids += i;
5839 spec->adc_nids += i;
5840 spec->num_adc_nids = 1;
5841 spec->single_input_src = 1;
5842 }
5843}
5844
5845/* initialize dual adcs */
5846static void fixup_dual_adc_switch(struct hda_codec *codec)
5847{
5848 struct alc_spec *spec = codec->spec;
5849 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5850 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5851 init_capsrc_for_pin(codec, spec->int_mic.pin);
5852}
5853
5854/* initialize some special cases for input sources */ 3429/* initialize some special cases for input sources */
5855static void alc_init_special_input_src(struct hda_codec *codec) 3430static void alc_init_special_input_src(struct hda_codec *codec)
5856{ 3431{
5857 struct alc_spec *spec = codec->spec; 3432 struct alc_spec *spec = codec->spec;
5858 if (spec->dual_adc_switch) 3433 int i;
5859 fixup_dual_adc_switch(codec); 3434
5860 else if (spec->single_input_src) 3435 for (i = 0; i < spec->autocfg.num_inputs; i++)
5861 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); 3436 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
5862} 3437}
5863 3438
3439/* assign appropriate capture mixers */
5864static void set_capture_mixer(struct hda_codec *codec) 3440static void set_capture_mixer(struct hda_codec *codec)
5865{ 3441{
5866 struct alc_spec *spec = codec->spec; 3442 struct alc_spec *spec = codec->spec;
@@ -5872,86 +3448,56 @@ static void set_capture_mixer(struct hda_codec *codec)
5872 alc_capture_mixer2, 3448 alc_capture_mixer2,
5873 alc_capture_mixer3 }, 3449 alc_capture_mixer3 },
5874 }; 3450 };
5875 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 3451
3452 /* check whether either of ADC or MUX has a volume control */
3453 if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
3454 if (!spec->capsrc_nids)
3455 return; /* no volume */
3456 if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
3457 return; /* no volume in capsrc, too */
3458 spec->vol_in_capsrc = 1;
3459 }
3460
3461 if (spec->num_adc_nids > 0) {
5876 int mux = 0; 3462 int mux = 0;
5877 int num_adcs = spec->num_adc_nids; 3463 int num_adcs = 0;
5878 if (spec->dual_adc_switch) 3464
3465 if (spec->input_mux && spec->input_mux->num_items > 1)
3466 mux = 1;
3467 if (spec->auto_mic) {
3468 num_adcs = 1;
3469 mux = 0;
3470 } else if (spec->dyn_adc_switch)
5879 num_adcs = 1; 3471 num_adcs = 1;
5880 else if (spec->auto_mic) 3472 if (!num_adcs) {
5881 fixup_automic_adc(codec); 3473 if (spec->num_adc_nids > 3)
5882 else if (spec->input_mux) { 3474 spec->num_adc_nids = 3;
5883 if (spec->input_mux->num_items > 1) 3475 else if (!spec->num_adc_nids)
5884 mux = 1; 3476 return;
5885 else if (spec->input_mux->num_items == 1) 3477 num_adcs = spec->num_adc_nids;
5886 fixup_single_adc(codec);
5887 } 3478 }
5888 spec->cap_mixer = caps[mux][num_adcs - 1]; 3479 spec->cap_mixer = caps[mux][num_adcs - 1];
5889 } 3480 }
5890} 3481}
5891 3482
5892/* fill adc_nids (and capsrc_nids) containing all active input pins */ 3483/*
5893static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, 3484 * standard auto-parser initializations
5894 int num_nids) 3485 */
3486static void alc_auto_init_std(struct hda_codec *codec)
5895{ 3487{
5896 struct alc_spec *spec = codec->spec; 3488 struct alc_spec *spec = codec->spec;
5897 struct auto_pin_cfg *cfg = &spec->autocfg; 3489 alc_auto_init_multi_out(codec);
5898 int n; 3490 alc_auto_init_extra_out(codec);
5899 hda_nid_t fallback_adc = 0, fallback_cap = 0; 3491 alc_auto_init_analog_input(codec);
5900 3492 alc_auto_init_input_src(codec);
5901 for (n = 0; n < num_nids; n++) { 3493 alc_auto_init_digital(codec);
5902 hda_nid_t adc, cap; 3494 if (spec->unsol_event)
5903 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3495 alc_inithook(codec);
5904 int nconns, i, j;
5905
5906 adc = nids[n];
5907 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5908 continue;
5909 cap = adc;
5910 nconns = snd_hda_get_connections(codec, cap, conn,
5911 ARRAY_SIZE(conn));
5912 if (nconns == 1) {
5913 cap = conn[0];
5914 nconns = snd_hda_get_connections(codec, cap, conn,
5915 ARRAY_SIZE(conn));
5916 }
5917 if (nconns <= 0)
5918 continue;
5919 if (!fallback_adc) {
5920 fallback_adc = adc;
5921 fallback_cap = cap;
5922 }
5923 for (i = 0; i < cfg->num_inputs; i++) {
5924 hda_nid_t nid = cfg->inputs[i].pin;
5925 for (j = 0; j < nconns; j++) {
5926 if (conn[j] == nid)
5927 break;
5928 }
5929 if (j >= nconns)
5930 break;
5931 }
5932 if (i >= cfg->num_inputs) {
5933 int num_adcs = spec->num_adc_nids;
5934 spec->private_adc_nids[num_adcs] = adc;
5935 spec->private_capsrc_nids[num_adcs] = cap;
5936 spec->num_adc_nids++;
5937 spec->adc_nids = spec->private_adc_nids;
5938 if (adc != cap)
5939 spec->capsrc_nids = spec->private_capsrc_nids;
5940 }
5941 }
5942 if (!spec->num_adc_nids) {
5943 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5944 " using fallback 0x%x\n",
5945 codec->chip_name, fallback_adc);
5946 spec->private_adc_nids[0] = fallback_adc;
5947 spec->adc_nids = spec->private_adc_nids;
5948 if (fallback_adc != fallback_cap) {
5949 spec->private_capsrc_nids[0] = fallback_cap;
5950 spec->capsrc_nids = spec->private_adc_nids;
5951 }
5952 }
5953} 3496}
5954 3497
3498/*
3499 * Digital-beep handlers
3500 */
5955#ifdef CONFIG_SND_HDA_INPUT_BEEP 3501#ifdef CONFIG_SND_HDA_INPUT_BEEP
5956#define set_beep_amp(spec, nid, idx, dir) \ 3502#define set_beep_amp(spec, nid, idx, dir) \
5957 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 3503 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -5979,1402 +3525,195 @@ static inline int has_cdefine_beep(struct hda_codec *codec)
5979#define has_cdefine_beep(codec) 0 3525#define has_cdefine_beep(codec) 0
5980#endif 3526#endif
5981 3527
5982/* 3528/* parse the BIOS configuration and set up the alc_spec */
5983 * OK, here we have finally the patch for ALC880 3529/* return 1 if successful, 0 if the proper config is not found,
3530 * or a negative error code
5984 */ 3531 */
5985 3532static int alc_parse_auto_config(struct hda_codec *codec,
5986static int patch_alc880(struct hda_codec *codec) 3533 const hda_nid_t *ignore_nids,
3534 const hda_nid_t *ssid_nids)
5987{ 3535{
5988 struct alc_spec *spec; 3536 struct alc_spec *spec = codec->spec;
5989 int board_config;
5990 int err; 3537 int err;
5991 3538
5992 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3539 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5993 if (spec == NULL) 3540 ignore_nids);
5994 return -ENOMEM; 3541 if (err < 0)
5995
5996 codec->spec = spec;
5997
5998 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5999 alc880_models,
6000 alc880_cfg_tbl);
6001 if (board_config < 0) {
6002 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6003 codec->chip_name);
6004 board_config = ALC880_AUTO;
6005 }
6006
6007 if (board_config == ALC880_AUTO) {
6008 /* automatic parse from the BIOS config */
6009 err = alc880_parse_auto_config(codec);
6010 if (err < 0) {
6011 alc_free(codec);
6012 return err;
6013 } else if (!err) {
6014 printk(KERN_INFO
6015 "hda_codec: Cannot set up configuration "
6016 "from BIOS. Using 3-stack mode...\n");
6017 board_config = ALC880_3ST;
6018 }
6019 }
6020
6021 err = snd_hda_attach_beep_device(codec, 0x1);
6022 if (err < 0) {
6023 alc_free(codec);
6024 return err; 3542 return err;
6025 } 3543 if (!spec->autocfg.line_outs) {
6026 3544 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
6027 if (board_config != ALC880_AUTO) 3545 spec->multiout.max_channels = 2;
6028 setup_preset(codec, &alc880_presets[board_config]); 3546 spec->no_analog = 1;
6029 3547 goto dig_only;
6030 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6031 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6032 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6033
6034 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6035 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6036
6037 if (!spec->adc_nids && spec->input_mux) {
6038 /* check whether NID 0x07 is valid */
6039 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6040 /* get type */
6041 wcap = get_wcaps_type(wcap);
6042 if (wcap != AC_WID_AUD_IN) {
6043 spec->adc_nids = alc880_adc_nids_alt;
6044 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6045 } else {
6046 spec->adc_nids = alc880_adc_nids;
6047 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6048 } 3548 }
3549 return 0; /* can't find valid BIOS pin config */
6049 } 3550 }
6050 set_capture_mixer(codec); 3551 err = alc_auto_fill_dac_nids(codec);
6051 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3552 if (err < 0)
6052 3553 return err;
6053 spec->vmaster_nid = 0x0c; 3554 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
6054 3555 if (err < 0)
6055 codec->patch_ops = alc_patch_ops; 3556 return err;
6056 if (board_config == ALC880_AUTO) 3557 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
6057 spec->init_hook = alc880_auto_init; 3558 if (err < 0)
6058#ifdef CONFIG_SND_HDA_POWER_SAVE 3559 return err;
6059 if (!spec->loopback.amplist) 3560 err = alc_auto_create_hp_out(codec);
6060 spec->loopback.amplist = alc880_loopbacks; 3561 if (err < 0)
6061#endif 3562 return err;
6062 3563 err = alc_auto_create_speaker_out(codec);
6063 return 0; 3564 if (err < 0)
6064} 3565 return err;
6065 3566 err = alc_auto_create_input_ctls(codec);
6066 3567 if (err < 0)
6067/* 3568 return err;
6068 * ALC260 support
6069 */
6070
6071static const hda_nid_t alc260_dac_nids[1] = {
6072 /* front */
6073 0x02,
6074};
6075
6076static const hda_nid_t alc260_adc_nids[1] = {
6077 /* ADC0 */
6078 0x04,
6079};
6080
6081static const hda_nid_t alc260_adc_nids_alt[1] = {
6082 /* ADC1 */
6083 0x05,
6084};
6085
6086/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6087 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6088 */
6089static const hda_nid_t alc260_dual_adc_nids[2] = {
6090 /* ADC0, ADC1 */
6091 0x04, 0x05
6092};
6093
6094#define ALC260_DIGOUT_NID 0x03
6095#define ALC260_DIGIN_NID 0x06
6096
6097static const struct hda_input_mux alc260_capture_source = {
6098 .num_items = 4,
6099 .items = {
6100 { "Mic", 0x0 },
6101 { "Front Mic", 0x1 },
6102 { "Line", 0x2 },
6103 { "CD", 0x4 },
6104 },
6105};
6106
6107/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6108 * headphone jack and the internal CD lines since these are the only pins at
6109 * which audio can appear. For flexibility, also allow the option of
6110 * recording the mixer output on the second ADC (ADC0 doesn't have a
6111 * connection to the mixer output).
6112 */
6113static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6114 {
6115 .num_items = 3,
6116 .items = {
6117 { "Mic/Line", 0x0 },
6118 { "CD", 0x4 },
6119 { "Headphone", 0x2 },
6120 },
6121 },
6122 {
6123 .num_items = 4,
6124 .items = {
6125 { "Mic/Line", 0x0 },
6126 { "CD", 0x4 },
6127 { "Headphone", 0x2 },
6128 { "Mixer", 0x5 },
6129 },
6130 },
6131
6132};
6133
6134/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6135 * the Fujitsu S702x, but jacks are marked differently.
6136 */
6137static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6138 {
6139 .num_items = 4,
6140 .items = {
6141 { "Mic", 0x0 },
6142 { "Line", 0x2 },
6143 { "CD", 0x4 },
6144 { "Headphone", 0x5 },
6145 },
6146 },
6147 {
6148 .num_items = 5,
6149 .items = {
6150 { "Mic", 0x0 },
6151 { "Line", 0x2 },
6152 { "CD", 0x4 },
6153 { "Headphone", 0x6 },
6154 { "Mixer", 0x5 },
6155 },
6156 },
6157};
6158
6159/* Maxdata Favorit 100XS */
6160static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6161 {
6162 .num_items = 2,
6163 .items = {
6164 { "Line/Mic", 0x0 },
6165 { "CD", 0x4 },
6166 },
6167 },
6168 {
6169 .num_items = 3,
6170 .items = {
6171 { "Line/Mic", 0x0 },
6172 { "CD", 0x4 },
6173 { "Mixer", 0x5 },
6174 },
6175 },
6176};
6177
6178/*
6179 * This is just place-holder, so there's something for alc_build_pcms to look
6180 * at when it calculates the maximum number of channels. ALC260 has no mixer
6181 * element which allows changing the channel mode, so the verb list is
6182 * never used.
6183 */
6184static const struct hda_channel_mode alc260_modes[1] = {
6185 { 2, NULL },
6186};
6187
6188 3569
6189/* Mixer combinations 3570 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6190 *
6191 * basic: base_output + input + pc_beep + capture
6192 * HP: base_output + input + capture_alt
6193 * HP_3013: hp_3013 + input + capture
6194 * fujitsu: fujitsu + capture
6195 * acer: acer + capture
6196 */
6197 3571
6198static const struct snd_kcontrol_new alc260_base_output_mixer[] = { 3572 dig_only:
6199 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3573 alc_auto_parse_digital(codec);
6200 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6201 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6202 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6203 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6204 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6205 { } /* end */
6206};
6207 3574
6208static const struct snd_kcontrol_new alc260_input_mixer[] = { 3575 if (!spec->no_analog)
6209 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3576 alc_remove_invalid_adc_nids(codec);
6210 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6211 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6212 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6213 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6214 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6215 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6216 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6217 { } /* end */
6218};
6219 3577
6220/* update HP, line and mono out pins according to the master switch */ 3578 if (ssid_nids)
6221static void alc260_hp_master_update(struct hda_codec *codec) 3579 alc_ssid_check(codec, ssid_nids);
6222{
6223 update_speakers(codec);
6224}
6225 3580
6226static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 3581 if (!spec->no_analog) {
6227 struct snd_ctl_elem_value *ucontrol) 3582 alc_auto_check_switches(codec);
6228{ 3583 err = alc_auto_add_mic_boost(codec);
6229 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3584 if (err < 0)
6230 struct alc_spec *spec = codec->spec; 3585 return err;
6231 *ucontrol->value.integer.value = !spec->master_mute; 3586 }
6232 return 0;
6233}
6234 3587
6235static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 3588 if (spec->kctls.list)
6236 struct snd_ctl_elem_value *ucontrol) 3589 add_mixer(spec, spec->kctls.list);
6237{
6238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6239 struct alc_spec *spec = codec->spec;
6240 int val = !*ucontrol->value.integer.value;
6241 3590
6242 if (val == spec->master_mute)
6243 return 0;
6244 spec->master_mute = val;
6245 alc260_hp_master_update(codec);
6246 return 1; 3591 return 1;
6247} 3592}
6248 3593
6249static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { 3594static int alc880_parse_auto_config(struct hda_codec *codec)
6250 {
6251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6252 .name = "Master Playback Switch",
6253 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6254 .info = snd_ctl_boolean_mono_info,
6255 .get = alc260_hp_master_sw_get,
6256 .put = alc260_hp_master_sw_put,
6257 },
6258 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6259 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6261 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6262 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6263 HDA_OUTPUT),
6264 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6265 { } /* end */
6266};
6267
6268static const struct hda_verb alc260_hp_unsol_verbs[] = {
6269 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6270 {},
6271};
6272
6273static void alc260_hp_setup(struct hda_codec *codec)
6274{
6275 struct alc_spec *spec = codec->spec;
6276
6277 spec->autocfg.hp_pins[0] = 0x0f;
6278 spec->autocfg.speaker_pins[0] = 0x10;
6279 spec->autocfg.speaker_pins[1] = 0x11;
6280 spec->automute = 1;
6281 spec->automute_mode = ALC_AUTOMUTE_PIN;
6282}
6283
6284static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6285 {
6286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6287 .name = "Master Playback Switch",
6288 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6289 .info = snd_ctl_boolean_mono_info,
6290 .get = alc260_hp_master_sw_get,
6291 .put = alc260_hp_master_sw_put,
6292 },
6293 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6294 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6295 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6296 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6297 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6298 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6299 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6300 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6301 { } /* end */
6302};
6303
6304static void alc260_hp_3013_setup(struct hda_codec *codec)
6305{
6306 struct alc_spec *spec = codec->spec;
6307
6308 spec->autocfg.hp_pins[0] = 0x15;
6309 spec->autocfg.speaker_pins[0] = 0x10;
6310 spec->autocfg.speaker_pins[1] = 0x11;
6311 spec->automute = 1;
6312 spec->automute_mode = ALC_AUTOMUTE_PIN;
6313}
6314
6315static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6316 .ops = &snd_hda_bind_vol,
6317 .values = {
6318 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6319 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6320 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6321 0
6322 },
6323};
6324
6325static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6326 .ops = &snd_hda_bind_sw,
6327 .values = {
6328 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6329 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6330 0
6331 },
6332};
6333
6334static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6335 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6336 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6337 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6338 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6339 { } /* end */
6340};
6341
6342static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6343 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6344 {},
6345};
6346
6347static void alc260_hp_3012_setup(struct hda_codec *codec)
6348{ 3595{
6349 struct alc_spec *spec = codec->spec; 3596 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
6350 3597 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6351 spec->autocfg.hp_pins[0] = 0x10; 3598 return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids);
6352 spec->autocfg.speaker_pins[0] = 0x0f;
6353 spec->autocfg.speaker_pins[1] = 0x11;
6354 spec->autocfg.speaker_pins[2] = 0x15;
6355 spec->automute = 1;
6356 spec->automute_mode = ALC_AUTOMUTE_PIN;
6357} 3599}
6358 3600
6359/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3601#ifdef CONFIG_SND_HDA_POWER_SAVE
6360 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3602static const struct hda_amp_list alc880_loopbacks[] = {
6361 */ 3603 { 0x0b, HDA_INPUT, 0 },
6362static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3604 { 0x0b, HDA_INPUT, 1 },
6363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3605 { 0x0b, HDA_INPUT, 2 },
6364 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3606 { 0x0b, HDA_INPUT, 3 },
6365 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3607 { 0x0b, HDA_INPUT, 4 },
6366 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6367 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6368 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6370 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6371 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6372 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6373 { } /* end */
6374};
6375
6376/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6377 * versions of the ALC260 don't act on requests to enable mic bias from NID
6378 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6379 * datasheet doesn't mention this restriction. At this stage it's not clear
6380 * whether this behaviour is intentional or is a hardware bug in chip
6381 * revisions available in early 2006. Therefore for now allow the
6382 * "Headphone Jack Mode" control to span all choices, but if it turns out
6383 * that the lack of mic bias for this NID is intentional we could change the
6384 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6385 *
6386 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6387 * don't appear to make the mic bias available from the "line" jack, even
6388 * though the NID used for this jack (0x14) can supply it. The theory is
6389 * that perhaps Acer have included blocking capacitors between the ALC260
6390 * and the output jack. If this turns out to be the case for all such
6391 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6392 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6393 *
6394 * The C20x Tablet series have a mono internal speaker which is controlled
6395 * via the chip's Mono sum widget and pin complex, so include the necessary
6396 * controls for such models. On models without a "mono speaker" the control
6397 * won't do anything.
6398 */
6399static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6400 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6401 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6402 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6403 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6404 HDA_OUTPUT),
6405 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6406 HDA_INPUT),
6407 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6408 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6409 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6410 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6411 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6412 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6413 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6414 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6415 { } /* end */
6416};
6417
6418/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6419 */
6420static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6421 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6422 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6423 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6424 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6425 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6426 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6427 { } /* end */
6428};
6429
6430/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6431 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6432 */
6433static const struct snd_kcontrol_new alc260_will_mixer[] = {
6434 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6435 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6436 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6437 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6438 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6439 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6440 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6441 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6442 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6443 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6444 { } /* end */
6445};
6446
6447/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6448 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6449 */
6450static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6451 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6452 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6454 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6455 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6456 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6457 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6458 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6459 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6460 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6461 { } /* end */ 3608 { } /* end */
6462}; 3609};
6463
6464/*
6465 * initialization verbs
6466 */
6467static const struct hda_verb alc260_init_verbs[] = {
6468 /* Line In pin widget for input */
6469 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6470 /* CD pin widget for input */
6471 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6472 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6474 /* Mic2 (front panel) pin widget for input and vref at 80% */
6475 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6476 /* LINE-2 is used for line-out in rear */
6477 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6478 /* select line-out */
6479 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6480 /* LINE-OUT pin */
6481 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6482 /* enable HP */
6483 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6484 /* enable Mono */
6485 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6486 /* mute capture amp left and right */
6487 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6488 /* set connection select to line in (default select for this ADC) */
6489 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6490 /* mute capture amp left and right */
6491 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6492 /* set connection select to line in (default select for this ADC) */
6493 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6494 /* set vol=0 Line-Out mixer amp left and right */
6495 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6496 /* unmute pin widget amp left and right (no gain on this amp) */
6497 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6498 /* set vol=0 HP mixer amp left and right */
6499 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6500 /* unmute pin widget amp left and right (no gain on this amp) */
6501 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6502 /* set vol=0 Mono mixer amp left and right */
6503 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6504 /* unmute pin widget amp left and right (no gain on this amp) */
6505 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6506 /* unmute LINE-2 out pin */
6507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6508 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6509 * Line In 2 = 0x03
6510 */
6511 /* mute analog inputs */
6512 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6514 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6515 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6516 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6517 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6518 /* mute Front out path */
6519 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6520 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6521 /* mute Headphone out path */
6522 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6524 /* mute Mono out path */
6525 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6526 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6527 { }
6528};
6529
6530#if 0 /* should be identical with alc260_init_verbs? */
6531static const struct hda_verb alc260_hp_init_verbs[] = {
6532 /* Headphone and output */
6533 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6534 /* mono output */
6535 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6536 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6537 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6538 /* Mic2 (front panel) pin widget for input and vref at 80% */
6539 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6540 /* Line In pin widget for input */
6541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6542 /* Line-2 pin widget for output */
6543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6544 /* CD pin widget for input */
6545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6546 /* unmute amp left and right */
6547 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6548 /* set connection select to line in (default select for this ADC) */
6549 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6550 /* unmute Line-Out mixer amp left and right (volume = 0) */
6551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6552 /* mute pin widget amp left and right (no gain on this amp) */
6553 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6554 /* unmute HP mixer amp left and right (volume = 0) */
6555 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6556 /* mute pin widget amp left and right (no gain on this amp) */
6557 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6558 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6559 * Line In 2 = 0x03
6560 */
6561 /* mute analog inputs */
6562 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6564 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6565 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6567 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6568 /* Unmute Front out path */
6569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6570 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6571 /* Unmute Headphone out path */
6572 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6573 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6574 /* Unmute Mono out path */
6575 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6576 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6577 { }
6578};
6579#endif 3610#endif
6580 3611
6581static const struct hda_verb alc260_hp_3013_init_verbs[] = { 3612/*
6582 /* Line out and output */ 3613 * board setups
6583 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6584 /* mono output */
6585 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6586 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6587 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6588 /* Mic2 (front panel) pin widget for input and vref at 80% */
6589 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6590 /* Line In pin widget for input */
6591 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6592 /* Headphone pin widget for output */
6593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6594 /* CD pin widget for input */
6595 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6596 /* unmute amp left and right */
6597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6598 /* set connection select to line in (default select for this ADC) */
6599 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6600 /* unmute Line-Out mixer amp left and right (volume = 0) */
6601 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6602 /* mute pin widget amp left and right (no gain on this amp) */
6603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6604 /* unmute HP mixer amp left and right (volume = 0) */
6605 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6606 /* mute pin widget amp left and right (no gain on this amp) */
6607 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6608 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6609 * Line In 2 = 0x03
6610 */
6611 /* mute analog inputs */
6612 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6613 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6615 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6617 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6618 /* Unmute Front out path */
6619 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6620 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6621 /* Unmute Headphone out path */
6622 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6623 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6624 /* Unmute Mono out path */
6625 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6626 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6627 { }
6628};
6629
6630/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6631 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6632 * audio = 0x16, internal speaker = 0x10.
6633 */
6634static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6635 /* Disable all GPIOs */
6636 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6637 /* Internal speaker is connected to headphone pin */
6638 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6639 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6641 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6642 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6643 /* Ensure all other unused pins are disabled and muted. */
6644 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6645 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6646 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6647 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6648 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652
6653 /* Disable digital (SPDIF) pins */
6654 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6655 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6656
6657 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6658 * when acting as an output.
6659 */
6660 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6661
6662 /* Start with output sum widgets muted and their output gains at min */
6663 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6664 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6666 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6667 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6669 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6670 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6672
6673 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6674 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6675 /* Unmute Line1 pin widget output buffer since it starts as an output.
6676 * If the pin mode is changed by the user the pin mode control will
6677 * take care of enabling the pin's input/output buffers as needed.
6678 * Therefore there's no need to enable the input buffer at this
6679 * stage.
6680 */
6681 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6682 /* Unmute input buffer of pin widget used for Line-in (no equiv
6683 * mixer ctrl)
6684 */
6685 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6686
6687 /* Mute capture amp left and right */
6688 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6689 /* Set ADC connection select to match default mixer setting - line
6690 * in (on mic1 pin)
6691 */
6692 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6693
6694 /* Do the same for the second ADC: mute capture input amp and
6695 * set ADC connection to line in (on mic1 pin)
6696 */
6697 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6698 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6699
6700 /* Mute all inputs to mixer widget (even unconnected ones) */
6701 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6702 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6703 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6709
6710 { }
6711};
6712
6713/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6714 * similar laptops (adapted from Fujitsu init verbs).
6715 */
6716static const struct hda_verb alc260_acer_init_verbs[] = {
6717 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6718 * the headphone jack. Turn this on and rely on the standard mute
6719 * methods whenever the user wants to turn these outputs off.
6720 */
6721 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6722 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6723 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6724 /* Internal speaker/Headphone jack is connected to Line-out pin */
6725 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6726 /* Internal microphone/Mic jack is connected to Mic1 pin */
6727 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6728 /* Line In jack is connected to Line1 pin */
6729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6730 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6731 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6732 /* Ensure all other unused pins are disabled and muted. */
6733 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6734 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6735 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6736 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6738 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6739 /* Disable digital (SPDIF) pins */
6740 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6741 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6742
6743 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6744 * bus when acting as outputs.
6745 */
6746 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6747 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6748
6749 /* Start with output sum widgets muted and their output gains at min */
6750 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6753 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6756 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6757 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6759
6760 /* Unmute Line-out pin widget amp left and right
6761 * (no equiv mixer ctrl)
6762 */
6763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6764 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6765 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6766 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6767 * inputs. If the pin mode is changed by the user the pin mode control
6768 * will take care of enabling the pin's input/output buffers as needed.
6769 * Therefore there's no need to enable the input buffer at this
6770 * stage.
6771 */
6772 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6774
6775 /* Mute capture amp left and right */
6776 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6777 /* Set ADC connection select to match default mixer setting - mic
6778 * (on mic1 pin)
6779 */
6780 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6781
6782 /* Do similar with the second ADC: mute capture input amp and
6783 * set ADC connection to mic to match ALSA's default state.
6784 */
6785 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6786 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6787
6788 /* Mute all inputs to mixer widget (even unconnected ones) */
6789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6795 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6796 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6797
6798 { }
6799};
6800
6801/* Initialisation sequence for Maxdata Favorit 100XS
6802 * (adapted from Acer init verbs).
6803 */
6804static const struct hda_verb alc260_favorit100_init_verbs[] = {
6805 /* GPIO 0 enables the output jack.
6806 * Turn this on and rely on the standard mute
6807 * methods whenever the user wants to turn these outputs off.
6808 */
6809 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6810 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6811 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6812 /* Line/Mic input jack is connected to Mic1 pin */
6813 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6814 /* Ensure all other unused pins are disabled and muted. */
6815 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6816 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6817 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6818 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6819 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6820 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6821 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6822 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6825 /* Disable digital (SPDIF) pins */
6826 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6827 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6828
6829 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6830 * bus when acting as outputs.
6831 */
6832 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6833 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6834
6835 /* Start with output sum widgets muted and their output gains at min */
6836 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6837 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6838 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6839 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6840 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6841 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6842 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6843 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6844 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6845
6846 /* Unmute Line-out pin widget amp left and right
6847 * (no equiv mixer ctrl)
6848 */
6849 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6850 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6851 * inputs. If the pin mode is changed by the user the pin mode control
6852 * will take care of enabling the pin's input/output buffers as needed.
6853 * Therefore there's no need to enable the input buffer at this
6854 * stage.
6855 */
6856 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6857
6858 /* Mute capture amp left and right */
6859 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6860 /* Set ADC connection select to match default mixer setting - mic
6861 * (on mic1 pin)
6862 */
6863 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6864
6865 /* Do similar with the second ADC: mute capture input amp and
6866 * set ADC connection to mic to match ALSA's default state.
6867 */
6868 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6869 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6870
6871 /* Mute all inputs to mixer widget (even unconnected ones) */
6872 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6873 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6874 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6875 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6876 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6877 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6878 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6879 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6880
6881 { }
6882};
6883
6884static const struct hda_verb alc260_will_verbs[] = {
6885 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6886 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6887 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6888 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6889 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6890 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6891 {}
6892};
6893
6894static const struct hda_verb alc260_replacer_672v_verbs[] = {
6895 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6896 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6897 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6898
6899 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6900 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6901 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6902
6903 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6904 {}
6905};
6906
6907/* toggle speaker-output according to the hp-jack state */
6908static void alc260_replacer_672v_automute(struct hda_codec *codec)
6909{
6910 unsigned int present;
6911
6912 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6913 present = snd_hda_jack_detect(codec, 0x0f);
6914 if (present) {
6915 snd_hda_codec_write_cache(codec, 0x01, 0,
6916 AC_VERB_SET_GPIO_DATA, 1);
6917 snd_hda_codec_write_cache(codec, 0x0f, 0,
6918 AC_VERB_SET_PIN_WIDGET_CONTROL,
6919 PIN_HP);
6920 } else {
6921 snd_hda_codec_write_cache(codec, 0x01, 0,
6922 AC_VERB_SET_GPIO_DATA, 0);
6923 snd_hda_codec_write_cache(codec, 0x0f, 0,
6924 AC_VERB_SET_PIN_WIDGET_CONTROL,
6925 PIN_OUT);
6926 }
6927}
6928
6929static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6930 unsigned int res)
6931{
6932 if ((res >> 26) == ALC880_HP_EVENT)
6933 alc260_replacer_672v_automute(codec);
6934}
6935
6936static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6937 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6938 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6939 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6940 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6941 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6942 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6943 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6944 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6945 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6946 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6947 {}
6948};
6949
6950/* Test configuration for debugging, modelled after the ALC880 test
6951 * configuration.
6952 */
6953#ifdef CONFIG_SND_DEBUG
6954static const hda_nid_t alc260_test_dac_nids[1] = {
6955 0x02,
6956};
6957static const hda_nid_t alc260_test_adc_nids[2] = {
6958 0x04, 0x05,
6959};
6960/* For testing the ALC260, each input MUX needs its own definition since
6961 * the signal assignments are different. This assumes that the first ADC
6962 * is NID 0x04.
6963 */ 3614 */
6964static const struct hda_input_mux alc260_test_capture_sources[2] = { 3615#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6965 { 3616#define alc_board_config \
6966 .num_items = 7, 3617 snd_hda_check_board_config
6967 .items = { 3618#define alc_board_codec_sid_config \
6968 { "MIC1 pin", 0x0 }, 3619 snd_hda_check_board_codec_sid_config
6969 { "MIC2 pin", 0x1 }, 3620#include "alc_quirks.c"
6970 { "LINE1 pin", 0x2 }, 3621#else
6971 { "LINE2 pin", 0x3 }, 3622#define alc_board_config(codec, nums, models, tbl) -1
6972 { "CD pin", 0x4 }, 3623#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
6973 { "LINE-OUT pin", 0x5 }, 3624#define setup_preset(codec, x) /* NOP */
6974 { "HP-OUT pin", 0x6 },
6975 },
6976 },
6977 {
6978 .num_items = 8,
6979 .items = {
6980 { "MIC1 pin", 0x0 },
6981 { "MIC2 pin", 0x1 },
6982 { "LINE1 pin", 0x2 },
6983 { "LINE2 pin", 0x3 },
6984 { "CD pin", 0x4 },
6985 { "Mixer", 0x5 },
6986 { "LINE-OUT pin", 0x6 },
6987 { "HP-OUT pin", 0x7 },
6988 },
6989 },
6990};
6991static const struct snd_kcontrol_new alc260_test_mixer[] = {
6992 /* Output driver widgets */
6993 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6994 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6995 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6996 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6997 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6998 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6999
7000 /* Modes for retasking pin widgets
7001 * Note: the ALC260 doesn't seem to act on requests to enable mic
7002 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7003 * mention this restriction. At this stage it's not clear whether
7004 * this behaviour is intentional or is a hardware bug in chip
7005 * revisions available at least up until early 2006. Therefore for
7006 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7007 * choices, but if it turns out that the lack of mic bias for these
7008 * NIDs is intentional we could change their modes from
7009 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7010 */
7011 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7012 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7013 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7014 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7015 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7016 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7017
7018 /* Loopback mixer controls */
7019 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7020 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7021 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7022 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7023 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7024 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7025 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7026 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7027 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7028 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7029 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7030 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7031 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7032 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7033
7034 /* Controls for GPIO pins, assuming they are configured as outputs */
7035 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7036 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7037 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7038 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7039
7040 /* Switches to allow the digital IO pins to be enabled. The datasheet
7041 * is ambigious as to which NID is which; testing on laptops which
7042 * make this output available should provide clarification.
7043 */
7044 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7045 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7046
7047 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7048 * this output to turn on an external amplifier.
7049 */
7050 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7051 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7052
7053 { } /* end */
7054};
7055static const struct hda_verb alc260_test_init_verbs[] = {
7056 /* Enable all GPIOs as outputs with an initial value of 0 */
7057 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7058 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7059 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7060
7061 /* Enable retasking pins as output, initially without power amp */
7062 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7063 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7065 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7066 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7067 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7068
7069 /* Disable digital (SPDIF) pins initially, but users can enable
7070 * them via a mixer switch. In the case of SPDIF-out, this initverb
7071 * payload also sets the generation to 0, output to be in "consumer"
7072 * PCM format, copyright asserted, no pre-emphasis and no validity
7073 * control.
7074 */
7075 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7076 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7077
7078 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7079 * OUT1 sum bus when acting as an output.
7080 */
7081 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7082 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7083 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7084 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7085
7086 /* Start with output sum widgets muted and their output gains at min */
7087 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7090 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7092 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7093 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7094 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7095 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7096
7097 /* Unmute retasking pin widget output buffers since the default
7098 * state appears to be output. As the pin mode is changed by the
7099 * user the pin mode control will take care of enabling the pin's
7100 * input/output buffers as needed.
7101 */
7102 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7103 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7104 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7106 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7107 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7108 /* Also unmute the mono-out pin widget */
7109 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7110
7111 /* Mute capture amp left and right */
7112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7113 /* Set ADC connection select to match default mixer setting (mic1
7114 * pin)
7115 */
7116 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7117
7118 /* Do the same for the second ADC: mute capture input amp and
7119 * set ADC connection to mic1 pin
7120 */
7121 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7122 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7123
7124 /* Mute all inputs to mixer widget (even unconnected ones) */
7125 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7126 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7127 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7128 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7129 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7130 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7131 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7133
7134 { }
7135};
7136#endif 3625#endif
7137 3626
7138#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7139#define alc260_pcm_analog_capture alc880_pcm_analog_capture
7140
7141#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7142#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7143
7144/* 3627/*
7145 * for BIOS auto-configuration 3628 * OK, here we have finally the patch for ALC880
7146 */ 3629 */
3630#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3631#include "alc880_quirks.c"
3632#endif
7147 3633
7148static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 3634static int patch_alc880(struct hda_codec *codec)
7149 const char *pfx, int *vol_bits)
7150{ 3635{
7151 hda_nid_t nid_vol; 3636 struct alc_spec *spec;
7152 unsigned long vol_val, sw_val; 3637 int board_config;
7153 int err; 3638 int err;
7154 3639
7155 if (nid >= 0x0f && nid < 0x11) { 3640 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7156 nid_vol = nid - 0x7; 3641 if (spec == NULL)
7157 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 3642 return -ENOMEM;
7158 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7159 } else if (nid == 0x11) {
7160 nid_vol = nid - 0x7;
7161 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7162 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7163 } else if (nid >= 0x12 && nid <= 0x15) {
7164 nid_vol = 0x08;
7165 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7166 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7167 } else
7168 return 0; /* N/A */
7169
7170 if (!(*vol_bits & (1 << nid_vol))) {
7171 /* first control for the volume widget */
7172 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7173 if (err < 0)
7174 return err;
7175 *vol_bits |= (1 << nid_vol);
7176 }
7177 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7178 if (err < 0)
7179 return err;
7180 return 1;
7181}
7182 3643
7183/* add playback controls from the parsed DAC table */ 3644 codec->spec = spec;
7184static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7185 const struct auto_pin_cfg *cfg)
7186{
7187 hda_nid_t nid;
7188 int err;
7189 int vols = 0;
7190 3645
7191 spec->multiout.num_dacs = 1; 3646 spec->mixer_nid = 0x0b;
7192 spec->multiout.dac_nids = spec->private_dac_nids; 3647 spec->need_dac_fix = 1;
7193 spec->private_dac_nids[0] = 0x02;
7194
7195 nid = cfg->line_out_pins[0];
7196 if (nid) {
7197 const char *pfx;
7198 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7199 pfx = "Master";
7200 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7201 pfx = "Speaker";
7202 else
7203 pfx = "Front";
7204 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7205 if (err < 0)
7206 return err;
7207 }
7208 3648
7209 nid = cfg->speaker_pins[0]; 3649 board_config = alc_board_config(codec, ALC880_MODEL_LAST,
7210 if (nid) { 3650 alc880_models, alc880_cfg_tbl);
7211 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 3651 if (board_config < 0) {
7212 if (err < 0) 3652 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7213 return err; 3653 codec->chip_name);
3654 board_config = ALC_MODEL_AUTO;
7214 } 3655 }
7215 3656
7216 nid = cfg->hp_pins[0]; 3657 if (board_config == ALC_MODEL_AUTO) {
7217 if (nid) { 3658 /* automatic parse from the BIOS config */
7218 err = alc260_add_playback_controls(spec, nid, "Headphone", 3659 err = alc880_parse_auto_config(codec);
7219 &vols); 3660 if (err < 0) {
7220 if (err < 0) 3661 alc_free(codec);
7221 return err; 3662 return err;
3663 }
3664#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3665 else if (!err) {
3666 printk(KERN_INFO
3667 "hda_codec: Cannot set up configuration "
3668 "from BIOS. Using 3-stack mode...\n");
3669 board_config = ALC880_3ST;
3670 }
3671#endif
7222 } 3672 }
7223 return 0;
7224}
7225 3673
7226/* create playback/capture controls for input pins */ 3674 if (board_config != ALC_MODEL_AUTO)
7227static int alc260_auto_create_input_ctls(struct hda_codec *codec, 3675 setup_preset(codec, &alc880_presets[board_config]);
7228 const struct auto_pin_cfg *cfg)
7229{
7230 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7231}
7232 3676
7233static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 3677 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
7234 hda_nid_t nid, int pin_type, 3678 alc_auto_fill_adc_caps(codec);
7235 int sel_idx) 3679 alc_rebuild_imux_for_auto_mic(codec);
7236{ 3680 alc_remove_invalid_adc_nids(codec);
7237 alc_set_pin_output(codec, nid, pin_type);
7238 /* need the manual connection? */
7239 if (nid >= 0x12) {
7240 int idx = nid - 0x12;
7241 snd_hda_codec_write(codec, idx + 0x0b, 0,
7242 AC_VERB_SET_CONNECT_SEL, sel_idx);
7243 } 3681 }
7244}
7245 3682
7246static void alc260_auto_init_multi_out(struct hda_codec *codec) 3683 if (!spec->no_analog && !spec->cap_mixer)
7247{ 3684 set_capture_mixer(codec);
7248 struct alc_spec *spec = codec->spec;
7249 hda_nid_t nid;
7250 3685
7251 nid = spec->autocfg.line_out_pins[0]; 3686 if (!spec->no_analog) {
7252 if (nid) { 3687 err = snd_hda_attach_beep_device(codec, 0x1);
7253 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3688 if (err < 0) {
7254 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 3689 alc_free(codec);
3690 return err;
3691 }
3692 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7255 } 3693 }
7256 3694
7257 nid = spec->autocfg.speaker_pins[0]; 3695 spec->vmaster_nid = 0x0c;
7258 if (nid)
7259 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7260
7261 nid = spec->autocfg.hp_pins[0];
7262 if (nid)
7263 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7264}
7265 3696
7266#define ALC260_PIN_CD_NID 0x16 3697 codec->patch_ops = alc_patch_ops;
7267static void alc260_auto_init_analog_input(struct hda_codec *codec) 3698 if (board_config == ALC_MODEL_AUTO)
7268{ 3699 spec->init_hook = alc_auto_init_std;
7269 struct alc_spec *spec = codec->spec; 3700#ifdef CONFIG_SND_HDA_POWER_SAVE
7270 struct auto_pin_cfg *cfg = &spec->autocfg; 3701 if (!spec->loopback.amplist)
7271 int i; 3702 spec->loopback.amplist = alc880_loopbacks;
3703#endif
7272 3704
7273 for (i = 0; i < cfg->num_inputs; i++) { 3705 return 0;
7274 hda_nid_t nid = cfg->inputs[i].pin;
7275 if (nid >= 0x12) {
7276 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7277 if (nid != ALC260_PIN_CD_NID &&
7278 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7279 snd_hda_codec_write(codec, nid, 0,
7280 AC_VERB_SET_AMP_GAIN_MUTE,
7281 AMP_OUT_MUTE);
7282 }
7283 }
7284} 3706}
7285 3707
7286#define alc260_auto_init_input_src alc880_auto_init_input_src
7287 3708
7288/* 3709/*
7289 * generic initialization of ADC, input mixers and output mixers 3710 * ALC260 support
7290 */ 3711 */
7291static const struct hda_verb alc260_volume_init_verbs[] = {
7292 /*
7293 * Unmute ADC0-1 and set the default input to mic-in
7294 */
7295 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7296 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7297 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7298 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7299
7300 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7301 * mixer widget
7302 * Note: PASD motherboards uses the Line In 2 as the input for
7303 * front panel mic (mic 2)
7304 */
7305 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7306 /* mute analog inputs */
7307 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7308 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7309 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7310 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7311 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7312
7313 /*
7314 * Set up output mixers (0x08 - 0x0a)
7315 */
7316 /* set vol=0 to output mixers */
7317 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7318 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7319 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7320 /* set up input amps for analog loopback */
7321 /* Amp Indices: DAC = 0, mixer = 1 */
7322 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7323 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7324 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7325 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7326 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7327 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7328
7329 { }
7330};
7331
7332static int alc260_parse_auto_config(struct hda_codec *codec) 3712static int alc260_parse_auto_config(struct hda_codec *codec)
7333{ 3713{
7334 struct alc_spec *spec = codec->spec;
7335 int err;
7336 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 3714 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7337 3715 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
7338 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3716 return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids);
7339 alc260_ignore);
7340 if (err < 0)
7341 return err;
7342 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7343 if (err < 0)
7344 return err;
7345 if (!spec->kctls.list)
7346 return 0; /* can't find valid BIOS pin config */
7347 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7348 if (err < 0)
7349 return err;
7350
7351 spec->multiout.max_channels = 2;
7352
7353 if (spec->autocfg.dig_outs)
7354 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7355 if (spec->kctls.list)
7356 add_mixer(spec, spec->kctls.list);
7357
7358 add_verb(spec, alc260_volume_init_verbs);
7359
7360 spec->num_mux_defs = 1;
7361 spec->input_mux = &spec->private_imux[0];
7362
7363 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7364
7365 return 1;
7366}
7367
7368/* additional initialization for auto-configuration model */
7369static void alc260_auto_init(struct hda_codec *codec)
7370{
7371 struct alc_spec *spec = codec->spec;
7372 alc260_auto_init_multi_out(codec);
7373 alc260_auto_init_analog_input(codec);
7374 alc260_auto_init_input_src(codec);
7375 alc_auto_init_digital(codec);
7376 if (spec->unsol_event)
7377 alc_inithook(codec);
7378} 3717}
7379 3718
7380#ifdef CONFIG_SND_HDA_POWER_SAVE 3719#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -7411,186 +3750,10 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7411}; 3750};
7412 3751
7413/* 3752/*
7414 * ALC260 configurations
7415 */ 3753 */
7416static const char * const alc260_models[ALC260_MODEL_LAST] = { 3754#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
7417 [ALC260_BASIC] = "basic", 3755#include "alc260_quirks.c"
7418 [ALC260_HP] = "hp",
7419 [ALC260_HP_3013] = "hp-3013",
7420 [ALC260_HP_DC7600] = "hp-dc7600",
7421 [ALC260_FUJITSU_S702X] = "fujitsu",
7422 [ALC260_ACER] = "acer",
7423 [ALC260_WILL] = "will",
7424 [ALC260_REPLACER_672V] = "replacer",
7425 [ALC260_FAVORIT100] = "favorit100",
7426#ifdef CONFIG_SND_DEBUG
7427 [ALC260_TEST] = "test",
7428#endif
7429 [ALC260_AUTO] = "auto",
7430};
7431
7432static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7433 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7434 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7435 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7436 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7437 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7438 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7439 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7440 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7441 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7442 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7443 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7444 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7445 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7446 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7447 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7448 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7449 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7450 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7451 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7452 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7453 {}
7454};
7455
7456static const struct alc_config_preset alc260_presets[] = {
7457 [ALC260_BASIC] = {
7458 .mixers = { alc260_base_output_mixer,
7459 alc260_input_mixer },
7460 .init_verbs = { alc260_init_verbs },
7461 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462 .dac_nids = alc260_dac_nids,
7463 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7464 .adc_nids = alc260_dual_adc_nids,
7465 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7466 .channel_mode = alc260_modes,
7467 .input_mux = &alc260_capture_source,
7468 },
7469 [ALC260_HP] = {
7470 .mixers = { alc260_hp_output_mixer,
7471 alc260_input_mixer },
7472 .init_verbs = { alc260_init_verbs,
7473 alc260_hp_unsol_verbs },
7474 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7475 .dac_nids = alc260_dac_nids,
7476 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7477 .adc_nids = alc260_adc_nids_alt,
7478 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7479 .channel_mode = alc260_modes,
7480 .input_mux = &alc260_capture_source,
7481 .unsol_event = alc_sku_unsol_event,
7482 .setup = alc260_hp_setup,
7483 .init_hook = alc_inithook,
7484 },
7485 [ALC260_HP_DC7600] = {
7486 .mixers = { alc260_hp_dc7600_mixer,
7487 alc260_input_mixer },
7488 .init_verbs = { alc260_init_verbs,
7489 alc260_hp_dc7600_verbs },
7490 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7491 .dac_nids = alc260_dac_nids,
7492 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7493 .adc_nids = alc260_adc_nids_alt,
7494 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7495 .channel_mode = alc260_modes,
7496 .input_mux = &alc260_capture_source,
7497 .unsol_event = alc_sku_unsol_event,
7498 .setup = alc260_hp_3012_setup,
7499 .init_hook = alc_inithook,
7500 },
7501 [ALC260_HP_3013] = {
7502 .mixers = { alc260_hp_3013_mixer,
7503 alc260_input_mixer },
7504 .init_verbs = { alc260_hp_3013_init_verbs,
7505 alc260_hp_3013_unsol_verbs },
7506 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7507 .dac_nids = alc260_dac_nids,
7508 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7509 .adc_nids = alc260_adc_nids_alt,
7510 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7511 .channel_mode = alc260_modes,
7512 .input_mux = &alc260_capture_source,
7513 .unsol_event = alc_sku_unsol_event,
7514 .setup = alc260_hp_3013_setup,
7515 .init_hook = alc_inithook,
7516 },
7517 [ALC260_FUJITSU_S702X] = {
7518 .mixers = { alc260_fujitsu_mixer },
7519 .init_verbs = { alc260_fujitsu_init_verbs },
7520 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7521 .dac_nids = alc260_dac_nids,
7522 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7523 .adc_nids = alc260_dual_adc_nids,
7524 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7525 .channel_mode = alc260_modes,
7526 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7527 .input_mux = alc260_fujitsu_capture_sources,
7528 },
7529 [ALC260_ACER] = {
7530 .mixers = { alc260_acer_mixer },
7531 .init_verbs = { alc260_acer_init_verbs },
7532 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7533 .dac_nids = alc260_dac_nids,
7534 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7535 .adc_nids = alc260_dual_adc_nids,
7536 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7537 .channel_mode = alc260_modes,
7538 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7539 .input_mux = alc260_acer_capture_sources,
7540 },
7541 [ALC260_FAVORIT100] = {
7542 .mixers = { alc260_favorit100_mixer },
7543 .init_verbs = { alc260_favorit100_init_verbs },
7544 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7545 .dac_nids = alc260_dac_nids,
7546 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7547 .adc_nids = alc260_dual_adc_nids,
7548 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7549 .channel_mode = alc260_modes,
7550 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7551 .input_mux = alc260_favorit100_capture_sources,
7552 },
7553 [ALC260_WILL] = {
7554 .mixers = { alc260_will_mixer },
7555 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7556 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7557 .dac_nids = alc260_dac_nids,
7558 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7559 .adc_nids = alc260_adc_nids,
7560 .dig_out_nid = ALC260_DIGOUT_NID,
7561 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7562 .channel_mode = alc260_modes,
7563 .input_mux = &alc260_capture_source,
7564 },
7565 [ALC260_REPLACER_672V] = {
7566 .mixers = { alc260_replacer_672v_mixer },
7567 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7568 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7569 .dac_nids = alc260_dac_nids,
7570 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7571 .adc_nids = alc260_adc_nids,
7572 .dig_out_nid = ALC260_DIGOUT_NID,
7573 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7574 .channel_mode = alc260_modes,
7575 .input_mux = &alc260_capture_source,
7576 .unsol_event = alc260_replacer_672v_unsol_event,
7577 .init_hook = alc260_replacer_672v_automute,
7578 },
7579#ifdef CONFIG_SND_DEBUG
7580 [ALC260_TEST] = {
7581 .mixers = { alc260_test_mixer },
7582 .init_verbs = { alc260_test_init_verbs },
7583 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7584 .dac_nids = alc260_test_dac_nids,
7585 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7586 .adc_nids = alc260_test_adc_nids,
7587 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7588 .channel_mode = alc260_modes,
7589 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7590 .input_mux = alc260_test_capture_sources,
7591 },
7592#endif 3756#endif
7593};
7594 3757
7595static int patch_alc260(struct hda_codec *codec) 3758static int patch_alc260(struct hda_codec *codec)
7596{ 3759{
@@ -7603,73 +3766,66 @@ static int patch_alc260(struct hda_codec *codec)
7603 3766
7604 codec->spec = spec; 3767 codec->spec = spec;
7605 3768
7606 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 3769 spec->mixer_nid = 0x07;
7607 alc260_models, 3770
7608 alc260_cfg_tbl); 3771 board_config = alc_board_config(codec, ALC260_MODEL_LAST,
3772 alc260_models, alc260_cfg_tbl);
7609 if (board_config < 0) { 3773 if (board_config < 0) {
7610 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3774 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7611 codec->chip_name); 3775 codec->chip_name);
7612 board_config = ALC260_AUTO; 3776 board_config = ALC_MODEL_AUTO;
7613 } 3777 }
7614 3778
7615 if (board_config == ALC260_AUTO) { 3779 if (board_config == ALC_MODEL_AUTO) {
7616 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 3780 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7617 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3781 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7618 } 3782 }
7619 3783
7620 if (board_config == ALC260_AUTO) { 3784 if (board_config == ALC_MODEL_AUTO) {
7621 /* automatic parse from the BIOS config */ 3785 /* automatic parse from the BIOS config */
7622 err = alc260_parse_auto_config(codec); 3786 err = alc260_parse_auto_config(codec);
7623 if (err < 0) { 3787 if (err < 0) {
7624 alc_free(codec); 3788 alc_free(codec);
7625 return err; 3789 return err;
7626 } else if (!err) { 3790 }
3791#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3792 else if (!err) {
7627 printk(KERN_INFO 3793 printk(KERN_INFO
7628 "hda_codec: Cannot set up configuration " 3794 "hda_codec: Cannot set up configuration "
7629 "from BIOS. Using base mode...\n"); 3795 "from BIOS. Using base mode...\n");
7630 board_config = ALC260_BASIC; 3796 board_config = ALC260_BASIC;
7631 } 3797 }
3798#endif
7632 } 3799 }
7633 3800
7634 err = snd_hda_attach_beep_device(codec, 0x1); 3801 if (board_config != ALC_MODEL_AUTO)
7635 if (err < 0) { 3802 setup_preset(codec, &alc260_presets[board_config]);
7636 alc_free(codec); 3803
7637 return err; 3804 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3805 alc_auto_fill_adc_caps(codec);
3806 alc_rebuild_imux_for_auto_mic(codec);
3807 alc_remove_invalid_adc_nids(codec);
7638 } 3808 }
7639 3809
7640 if (board_config != ALC260_AUTO) 3810 if (!spec->no_analog && !spec->cap_mixer)
7641 setup_preset(codec, &alc260_presets[board_config]); 3811 set_capture_mixer(codec);
7642 3812
7643 spec->stream_analog_playback = &alc260_pcm_analog_playback; 3813 if (!spec->no_analog) {
7644 spec->stream_analog_capture = &alc260_pcm_analog_capture; 3814 err = snd_hda_attach_beep_device(codec, 0x1);
7645 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 3815 if (err < 0) {
7646 3816 alc_free(codec);
7647 spec->stream_digital_playback = &alc260_pcm_digital_playback; 3817 return err;
7648 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7649
7650 if (!spec->adc_nids && spec->input_mux) {
7651 /* check whether NID 0x04 is valid */
7652 unsigned int wcap = get_wcaps(codec, 0x04);
7653 wcap = get_wcaps_type(wcap);
7654 /* get type */
7655 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7656 spec->adc_nids = alc260_adc_nids_alt;
7657 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7658 } else {
7659 spec->adc_nids = alc260_adc_nids;
7660 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7661 } 3818 }
3819 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7662 } 3820 }
7663 set_capture_mixer(codec);
7664 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7665 3821
7666 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 3822 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7667 3823
7668 spec->vmaster_nid = 0x08; 3824 spec->vmaster_nid = 0x08;
7669 3825
7670 codec->patch_ops = alc_patch_ops; 3826 codec->patch_ops = alc_patch_ops;
7671 if (board_config == ALC260_AUTO) 3827 if (board_config == ALC_MODEL_AUTO)
7672 spec->init_hook = alc260_auto_init; 3828 spec->init_hook = alc_auto_init_std;
7673 spec->shutup = alc_eapd_shutup; 3829 spec->shutup = alc_eapd_shutup;
7674#ifdef CONFIG_SND_HDA_POWER_SAVE 3830#ifdef CONFIG_SND_HDA_POWER_SAVE
7675 if (!spec->loopback.amplist) 3831 if (!spec->loopback.amplist)
@@ -7691,3299 +3847,10 @@ static int patch_alc260(struct hda_codec *codec)
7691 * In addition, an independent DAC for the multi-playback (not used in this 3847 * In addition, an independent DAC for the multi-playback (not used in this
7692 * driver yet). 3848 * driver yet).
7693 */ 3849 */
7694#define ALC882_DIGOUT_NID 0x06
7695#define ALC882_DIGIN_NID 0x0a
7696#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7697#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7698#define ALC1200_DIGOUT_NID 0x10
7699
7700
7701static const struct hda_channel_mode alc882_ch_modes[1] = {
7702 { 8, NULL }
7703};
7704
7705/* DACs */
7706static const hda_nid_t alc882_dac_nids[4] = {
7707 /* front, rear, clfe, rear_surr */
7708 0x02, 0x03, 0x04, 0x05
7709};
7710#define alc883_dac_nids alc882_dac_nids
7711
7712/* ADCs */
7713#define alc882_adc_nids alc880_adc_nids
7714#define alc882_adc_nids_alt alc880_adc_nids_alt
7715#define alc883_adc_nids alc882_adc_nids_alt
7716static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7717static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7718#define alc889_adc_nids alc880_adc_nids
7719
7720static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7721static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7722#define alc883_capsrc_nids alc882_capsrc_nids_alt
7723static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7724#define alc889_capsrc_nids alc882_capsrc_nids
7725
7726/* input MUX */
7727/* FIXME: should be a matrix-type input source selection */
7728
7729static const struct hda_input_mux alc882_capture_source = {
7730 .num_items = 4,
7731 .items = {
7732 { "Mic", 0x0 },
7733 { "Front Mic", 0x1 },
7734 { "Line", 0x2 },
7735 { "CD", 0x4 },
7736 },
7737};
7738
7739#define alc883_capture_source alc882_capture_source
7740
7741static const struct hda_input_mux alc889_capture_source = {
7742 .num_items = 3,
7743 .items = {
7744 { "Front Mic", 0x0 },
7745 { "Mic", 0x3 },
7746 { "Line", 0x2 },
7747 },
7748};
7749
7750static const struct hda_input_mux mb5_capture_source = {
7751 .num_items = 3,
7752 .items = {
7753 { "Mic", 0x1 },
7754 { "Line", 0x7 },
7755 { "CD", 0x4 },
7756 },
7757};
7758
7759static const struct hda_input_mux macmini3_capture_source = {
7760 .num_items = 2,
7761 .items = {
7762 { "Line", 0x2 },
7763 { "CD", 0x4 },
7764 },
7765};
7766
7767static const struct hda_input_mux alc883_3stack_6ch_intel = {
7768 .num_items = 4,
7769 .items = {
7770 { "Mic", 0x1 },
7771 { "Front Mic", 0x0 },
7772 { "Line", 0x2 },
7773 { "CD", 0x4 },
7774 },
7775};
7776
7777static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7778 .num_items = 2,
7779 .items = {
7780 { "Mic", 0x1 },
7781 { "Line", 0x2 },
7782 },
7783};
7784
7785static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7786 .num_items = 4,
7787 .items = {
7788 { "Mic", 0x0 },
7789 { "Internal Mic", 0x1 },
7790 { "Line", 0x2 },
7791 { "CD", 0x4 },
7792 },
7793};
7794
7795static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7796 .num_items = 2,
7797 .items = {
7798 { "Mic", 0x0 },
7799 { "Internal Mic", 0x1 },
7800 },
7801};
7802
7803static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7804 .num_items = 3,
7805 .items = {
7806 { "Mic", 0x0 },
7807 { "Front Mic", 0x1 },
7808 { "Line", 0x4 },
7809 },
7810};
7811
7812static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7813 .num_items = 2,
7814 .items = {
7815 { "Mic", 0x0 },
7816 { "Line", 0x2 },
7817 },
7818};
7819
7820static const struct hda_input_mux alc889A_mb31_capture_source = {
7821 .num_items = 2,
7822 .items = {
7823 { "Mic", 0x0 },
7824 /* Front Mic (0x01) unused */
7825 { "Line", 0x2 },
7826 /* Line 2 (0x03) unused */
7827 /* CD (0x04) unused? */
7828 },
7829};
7830
7831static const struct hda_input_mux alc889A_imac91_capture_source = {
7832 .num_items = 2,
7833 .items = {
7834 { "Mic", 0x01 },
7835 { "Line", 0x2 }, /* Not sure! */
7836 },
7837};
7838
7839/*
7840 * 2ch mode
7841 */
7842static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7843 { 2, NULL }
7844};
7845
7846/*
7847 * 2ch mode
7848 */
7849static const struct hda_verb alc882_3ST_ch2_init[] = {
7850 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7851 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7852 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7853 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7854 { } /* end */
7855};
7856
7857/*
7858 * 4ch mode
7859 */
7860static const struct hda_verb alc882_3ST_ch4_init[] = {
7861 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7862 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867};
7868
7869/*
7870 * 6ch mode
7871 */
7872static const struct hda_verb alc882_3ST_ch6_init[] = {
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7875 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7876 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7877 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7878 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7879 { } /* end */
7880};
7881
7882static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7883 { 2, alc882_3ST_ch2_init },
7884 { 4, alc882_3ST_ch4_init },
7885 { 6, alc882_3ST_ch6_init },
7886};
7887
7888#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7889
7890/*
7891 * 2ch mode
7892 */
7893static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7894 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7895 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7896 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7897 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7898 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7899 { } /* end */
7900};
7901
7902/*
7903 * 4ch mode
7904 */
7905static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7909 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7911 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7912 { } /* end */
7913};
7914
7915/*
7916 * 6ch mode
7917 */
7918static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7919 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7921 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7922 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7923 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7924 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7925 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7926 { } /* end */
7927};
7928
7929static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7930 { 2, alc883_3ST_ch2_clevo_init },
7931 { 4, alc883_3ST_ch4_clevo_init },
7932 { 6, alc883_3ST_ch6_clevo_init },
7933};
7934
7935
7936/*
7937 * 6ch mode
7938 */
7939static const struct hda_verb alc882_sixstack_ch6_init[] = {
7940 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7941 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7943 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7944 { } /* end */
7945};
7946
7947/*
7948 * 8ch mode
7949 */
7950static const struct hda_verb alc882_sixstack_ch8_init[] = {
7951 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7952 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7953 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7954 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7955 { } /* end */
7956};
7957
7958static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7959 { 6, alc882_sixstack_ch6_init },
7960 { 8, alc882_sixstack_ch8_init },
7961};
7962
7963
7964/* Macbook Air 2,1 */
7965
7966static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7967 { 2, NULL },
7968};
7969
7970/*
7971 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7972 */
7973
7974/*
7975 * 2ch mode
7976 */
7977static const struct hda_verb alc885_mbp_ch2_init[] = {
7978 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7980 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7981 { } /* end */
7982};
7983
7984/*
7985 * 4ch mode
7986 */
7987static const struct hda_verb alc885_mbp_ch4_init[] = {
7988 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7989 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7990 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7991 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7992 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7993 { } /* end */
7994};
7995
7996static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7997 { 2, alc885_mbp_ch2_init },
7998 { 4, alc885_mbp_ch4_init },
7999};
8000
8001/*
8002 * 2ch
8003 * Speakers/Woofer/HP = Front
8004 * LineIn = Input
8005 */
8006static const struct hda_verb alc885_mb5_ch2_init[] = {
8007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8008 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8009 { } /* end */
8010};
8011
8012/*
8013 * 6ch mode
8014 * Speakers/HP = Front
8015 * Woofer = LFE
8016 * LineIn = Surround
8017 */
8018static const struct hda_verb alc885_mb5_ch6_init[] = {
8019 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8020 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8021 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8022 { } /* end */
8023};
8024
8025static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8026 { 2, alc885_mb5_ch2_init },
8027 { 6, alc885_mb5_ch6_init },
8028};
8029
8030#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8031
8032/*
8033 * 2ch mode
8034 */
8035static const struct hda_verb alc883_4ST_ch2_init[] = {
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8042 { } /* end */
8043};
8044
8045/*
8046 * 4ch mode
8047 */
8048static const struct hda_verb alc883_4ST_ch4_init[] = {
8049 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8050 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8053 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8054 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8055 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8056 { } /* end */
8057};
8058
8059/*
8060 * 6ch mode
8061 */
8062static const struct hda_verb alc883_4ST_ch6_init[] = {
8063 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8064 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8065 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8068 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8071 { } /* end */
8072};
8073
8074/*
8075 * 8ch mode
8076 */
8077static const struct hda_verb alc883_4ST_ch8_init[] = {
8078 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8079 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8080 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8081 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8082 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8083 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8084 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8085 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8086 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8087 { } /* end */
8088};
8089
8090static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8091 { 2, alc883_4ST_ch2_init },
8092 { 4, alc883_4ST_ch4_init },
8093 { 6, alc883_4ST_ch6_init },
8094 { 8, alc883_4ST_ch8_init },
8095};
8096
8097
8098/*
8099 * 2ch mode
8100 */
8101static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8102 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8103 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8104 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8105 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8106 { } /* end */
8107};
8108
8109/*
8110 * 4ch mode
8111 */
8112static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8113 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8114 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118 { } /* end */
8119};
8120
8121/*
8122 * 6ch mode
8123 */
8124static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8125 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8126 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8127 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8128 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8129 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8130 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8131 { } /* end */
8132};
8133
8134static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8135 { 2, alc883_3ST_ch2_intel_init },
8136 { 4, alc883_3ST_ch4_intel_init },
8137 { 6, alc883_3ST_ch6_intel_init },
8138};
8139
8140/*
8141 * 2ch mode
8142 */
8143static const struct hda_verb alc889_ch2_intel_init[] = {
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150 { } /* end */
8151};
8152
8153/*
8154 * 6ch mode
8155 */
8156static const struct hda_verb alc889_ch6_intel_init[] = {
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8163 { } /* end */
8164};
8165
8166/*
8167 * 8ch mode
8168 */
8169static const struct hda_verb alc889_ch8_intel_init[] = {
8170 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8171 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8172 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8173 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8174 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8175 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8176 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8177 { } /* end */
8178};
8179
8180static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8181 { 2, alc889_ch2_intel_init },
8182 { 6, alc889_ch6_intel_init },
8183 { 8, alc889_ch8_intel_init },
8184};
8185
8186/*
8187 * 6ch mode
8188 */
8189static const struct hda_verb alc883_sixstack_ch6_init[] = {
8190 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8191 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8193 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8194 { } /* end */
8195};
8196
8197/*
8198 * 8ch mode
8199 */
8200static const struct hda_verb alc883_sixstack_ch8_init[] = {
8201 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8202 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8203 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8204 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8205 { } /* end */
8206};
8207
8208static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8209 { 6, alc883_sixstack_ch6_init },
8210 { 8, alc883_sixstack_ch8_init },
8211};
8212
8213
8214/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8215 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8216 */
8217static const struct snd_kcontrol_new alc882_base_mixer[] = {
8218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8219 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8221 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8222 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8223 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8224 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8225 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8226 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8227 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8239 { } /* end */
8240};
8241
8242/* Macbook Air 2,1 same control for HP and internal Speaker */
8243
8244static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8245 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8246 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8247 { }
8248};
8249
8250
8251static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8252 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8253 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8254 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8258 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8260 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8261 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8262 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8263 { } /* end */
8264};
8265
8266static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8268 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8270 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8271 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8272 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8273 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8274 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8275 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8276 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8278 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8279 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8281 { } /* end */
8282};
8283
8284static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8285 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8286 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8287 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8289 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8290 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8291 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8292 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8293 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8294 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8295 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8296 { } /* end */
8297};
8298
8299static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8300 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8301 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8302 { } /* end */
8303};
8304
8305
8306static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8310 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8316 { } /* end */
8317};
8318
8319static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8322 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8323 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8324 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8325 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8326 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8330 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8331 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8333 { } /* end */
8334};
8335
8336/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8337 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8338 */
8339static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8340 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8341 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8342 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8343 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8344 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8345 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8346 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8347 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8348 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8349 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8353 { } /* end */
8354};
8355
8356static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8357 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8358 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8359 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8360 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8361 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8362 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8363 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8365 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8366 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8367 { } /* end */
8368};
8369
8370static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8371 {
8372 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8373 .name = "Channel Mode",
8374 .info = alc_ch_mode_info,
8375 .get = alc_ch_mode_get,
8376 .put = alc_ch_mode_put,
8377 },
8378 { } /* end */
8379};
8380
8381static const struct hda_verb alc882_base_init_verbs[] = {
8382 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8384 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8385 /* Rear mixer */
8386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8388 /* CLFE mixer */
8389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8391 /* Side mixer */
8392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8393 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8394
8395 /* Front Pin: output 0 (0x0c) */
8396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8397 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8398 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8399 /* Rear Pin: output 1 (0x0d) */
8400 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8401 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8402 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8403 /* CLFE Pin: output 2 (0x0e) */
8404 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8405 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8407 /* Side Pin: output 3 (0x0f) */
8408 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8409 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8411 /* Mic (rear) pin: input vref at 80% */
8412 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8413 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8414 /* Front Mic pin: input vref at 80% */
8415 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8416 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8417 /* Line In pin: input */
8418 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8419 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8420 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8421 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8422 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8423 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8424 /* CD pin widget for input */
8425 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8426
8427 /* FIXME: use matrix-type input source selection */
8428 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8429 /* Input mixer2 */
8430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8431 /* Input mixer3 */
8432 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 /* ADC2: mute amp left and right */
8434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8435 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8436 /* ADC3: mute amp left and right */
8437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8439
8440 { }
8441};
8442
8443static const struct hda_verb alc882_adc1_init_verbs[] = {
8444 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8445 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8446 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8447 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8449 /* ADC1: mute amp left and right */
8450 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8451 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8452 { }
8453};
8454
8455static const struct hda_verb alc882_eapd_verbs[] = {
8456 /* change to EAPD mode */
8457 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8458 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8459 { }
8460};
8461
8462static const struct hda_verb alc889_eapd_verbs[] = {
8463 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8464 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8465 { }
8466};
8467
8468static const struct hda_verb alc_hp15_unsol_verbs[] = {
8469 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8471 {}
8472};
8473
8474static const struct hda_verb alc885_init_verbs[] = {
8475 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8477 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8478 /* Rear mixer */
8479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8480 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8481 /* CLFE mixer */
8482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8484 /* Side mixer */
8485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8487
8488 /* Front HP Pin: output 0 (0x0c) */
8489 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8492 /* Front Pin: output 0 (0x0c) */
8493 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8494 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8495 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8496 /* Rear Pin: output 1 (0x0d) */
8497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8498 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8500 /* CLFE Pin: output 2 (0x0e) */
8501 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8502 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8503 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8504 /* Side Pin: output 3 (0x0f) */
8505 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8506 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8508 /* Mic (rear) pin: input vref at 80% */
8509 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8510 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8511 /* Front Mic pin: input vref at 80% */
8512 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8513 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8514 /* Line In pin: input */
8515 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8516 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8517
8518 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8519 /* Input mixer1 */
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 /* Input mixer2 */
8522 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8523 /* Input mixer3 */
8524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8525 /* ADC2: mute amp left and right */
8526 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8527 /* ADC3: mute amp left and right */
8528 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8529
8530 { }
8531};
8532
8533static const struct hda_verb alc885_init_input_verbs[] = {
8534 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8535 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8536 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8537 { }
8538};
8539
8540
8541/* Unmute Selector 24h and set the default input to front mic */
8542static const struct hda_verb alc889_init_input_verbs[] = {
8543 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8544 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8545 { }
8546};
8547
8548
8549#define alc883_init_verbs alc882_base_init_verbs
8550
8551/* Mac Pro test */
8552static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8553 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8554 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8555 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8556 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8557 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8558 /* FIXME: this looks suspicious...
8559 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8560 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8561 */
8562 { } /* end */
8563};
8564
8565static const struct hda_verb alc882_macpro_init_verbs[] = {
8566 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8570 /* Front Pin: output 0 (0x0c) */
8571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8573 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8574 /* Front Mic pin: input vref at 80% */
8575 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8576 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8577 /* Speaker: output */
8578 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8579 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8580 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8581 /* Headphone output (output 0 - 0x0c) */
8582 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8583 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8584 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8585
8586 /* FIXME: use matrix-type input source selection */
8587 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8588 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8589 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8593 /* Input mixer2 */
8594 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8595 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8596 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8598 /* Input mixer3 */
8599 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8600 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8601 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8602 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8603 /* ADC1: mute amp left and right */
8604 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8605 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8606 /* ADC2: mute amp left and right */
8607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8608 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8609 /* ADC3: mute amp left and right */
8610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8611 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8612
8613 { }
8614};
8615
8616/* Macbook 5,1 */
8617static const struct hda_verb alc885_mb5_init_verbs[] = {
8618 /* DACs */
8619 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8620 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8621 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8622 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8623 /* Front mixer */
8624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8627 /* Surround mixer */
8628 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8629 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8631 /* LFE mixer */
8632 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8633 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8634 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8635 /* HP mixer */
8636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8637 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8639 /* Front Pin (0x0c) */
8640 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8643 /* LFE Pin (0x0e) */
8644 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8645 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8647 /* HP Pin (0x0f) */
8648 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8649 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8650 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8652 /* Front Mic pin: input vref at 80% */
8653 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8654 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8655 /* Line In pin */
8656 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8657 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8658
8659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8660 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8662 { }
8663};
8664
8665/* Macmini 3,1 */
8666static const struct hda_verb alc885_macmini3_init_verbs[] = {
8667 /* DACs */
8668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8672 /* Front mixer */
8673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8676 /* Surround mixer */
8677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8680 /* LFE mixer */
8681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8684 /* HP mixer */
8685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8688 /* Front Pin (0x0c) */
8689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8692 /* LFE Pin (0x0e) */
8693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8696 /* HP Pin (0x0f) */
8697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8701 /* Line In pin */
8702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8704
8705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8709 { }
8710};
8711
8712
8713static const struct hda_verb alc885_mba21_init_verbs[] = {
8714 /*Internal and HP Speaker Mixer*/
8715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8718 /*Internal Speaker Pin (0x0c)*/
8719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8722 /* HP Pin: output 0 (0x0e) */
8723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8727 /* Line in (is hp when jack connected)*/
8728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8730
8731 { }
8732 };
8733
8734
8735/* Macbook Pro rev3 */
8736static const struct hda_verb alc885_mbp3_init_verbs[] = {
8737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8738 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8739 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8741 /* Rear mixer */
8742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8743 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8744 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8745 /* HP mixer */
8746 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8747 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8749 /* Front Pin: output 0 (0x0c) */
8750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8752 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8753 /* HP Pin: output 0 (0x0e) */
8754 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8757 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8758 /* Mic (rear) pin: input vref at 80% */
8759 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8760 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8761 /* Front Mic pin: input vref at 80% */
8762 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8763 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8764 /* Line In pin: use output 1 when in LineOut mode */
8765 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8766 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8767 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8768
8769 /* FIXME: use matrix-type input source selection */
8770 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8771 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8776 /* Input mixer2 */
8777 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8779 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8780 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8781 /* Input mixer3 */
8782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8783 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8784 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8785 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8786 /* ADC1: mute amp left and right */
8787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8788 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8789 /* ADC2: mute amp left and right */
8790 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8791 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 /* ADC3: mute amp left and right */
8793 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8794 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8795
8796 { }
8797};
8798
8799/* iMac 9,1 */
8800static const struct hda_verb alc885_imac91_init_verbs[] = {
8801 /* Internal Speaker Pin (0x0c) */
8802 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8803 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8804 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8805 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8806 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8807 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8808 /* HP Pin: Rear */
8809 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8810 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8811 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8812 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8813 /* Line in Rear */
8814 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8815 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8816 /* Front Mic pin: input vref at 80% */
8817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8819 /* Rear mixer */
8820 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8821 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8822 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8823 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8824 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8827 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8828 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8829 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8830 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8831 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8832 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8833 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8834 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8835 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8836 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8837 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8838 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8839 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8840 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8841 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8842 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8843 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8844 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8845 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8846 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8847 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8848 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8849 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8850 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8851 { }
8852};
8853
8854/* iMac 24 mixer. */
8855static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8856 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8857 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8858 { } /* end */
8859};
8860
8861/* iMac 24 init verbs. */
8862static const struct hda_verb alc885_imac24_init_verbs[] = {
8863 /* Internal speakers: output 0 (0x0c) */
8864 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8865 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8866 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8867 /* Internal speakers: output 0 (0x0c) */
8868 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8869 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8870 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8871 /* Headphone: output 0 (0x0c) */
8872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8873 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8874 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8875 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8876 /* Front Mic: input vref at 80% */
8877 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8879 { }
8880};
8881
8882/* Toggle speaker-output according to the hp-jack state */
8883static void alc885_imac24_setup(struct hda_codec *codec)
8884{
8885 struct alc_spec *spec = codec->spec;
8886
8887 spec->autocfg.hp_pins[0] = 0x14;
8888 spec->autocfg.speaker_pins[0] = 0x18;
8889 spec->autocfg.speaker_pins[1] = 0x1a;
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
8892}
8893
8894#define alc885_mb5_setup alc885_imac24_setup
8895#define alc885_macmini3_setup alc885_imac24_setup
8896
8897/* Macbook Air 2,1 */
8898static void alc885_mba21_setup(struct hda_codec *codec)
8899{
8900 struct alc_spec *spec = codec->spec;
8901
8902 spec->autocfg.hp_pins[0] = 0x14;
8903 spec->autocfg.speaker_pins[0] = 0x18;
8904 spec->automute = 1;
8905 spec->automute_mode = ALC_AUTOMUTE_AMP;
8906}
8907
8908
8909
8910static void alc885_mbp3_setup(struct hda_codec *codec)
8911{
8912 struct alc_spec *spec = codec->spec;
8913
8914 spec->autocfg.hp_pins[0] = 0x15;
8915 spec->autocfg.speaker_pins[0] = 0x14;
8916 spec->automute = 1;
8917 spec->automute_mode = ALC_AUTOMUTE_AMP;
8918}
8919
8920static void alc885_imac91_setup(struct hda_codec *codec)
8921{
8922 struct alc_spec *spec = codec->spec;
8923
8924 spec->autocfg.hp_pins[0] = 0x14;
8925 spec->autocfg.speaker_pins[0] = 0x18;
8926 spec->autocfg.speaker_pins[1] = 0x1a;
8927 spec->automute = 1;
8928 spec->automute_mode = ALC_AUTOMUTE_AMP;
8929}
8930
8931static const struct hda_verb alc882_targa_verbs[] = {
8932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8933 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8934
8935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8936 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8937
8938 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8939 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8940 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8941
8942 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8943 { } /* end */
8944};
8945
8946/* toggle speaker-output according to the hp-jack state */
8947static void alc882_targa_automute(struct hda_codec *codec)
8948{
8949 struct alc_spec *spec = codec->spec;
8950 alc_hp_automute(codec);
8951 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8952 spec->jack_present ? 1 : 3);
8953}
8954
8955static void alc882_targa_setup(struct hda_codec *codec)
8956{
8957 struct alc_spec *spec = codec->spec;
8958
8959 spec->autocfg.hp_pins[0] = 0x14;
8960 spec->autocfg.speaker_pins[0] = 0x1b;
8961 spec->automute = 1;
8962 spec->automute_mode = ALC_AUTOMUTE_AMP;
8963}
8964
8965static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8966{
8967 if ((res >> 26) == ALC880_HP_EVENT)
8968 alc882_targa_automute(codec);
8969}
8970
8971static const struct hda_verb alc882_asus_a7j_verbs[] = {
8972 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8973 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8974
8975 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8976 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8977 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8978
8979 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8980 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8981 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8982
8983 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8984 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8985 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 { } /* end */
8987};
8988
8989static const struct hda_verb alc882_asus_a7m_verbs[] = {
8990 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8991 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8992
8993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8994 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8996
8997 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8998 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8999 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
9000
9001 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
9002 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
9003 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
9004 { } /* end */
9005};
9006
9007static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
9008{
9009 unsigned int gpiostate, gpiomask, gpiodir;
9010
9011 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
9012 AC_VERB_GET_GPIO_DATA, 0);
9013
9014 if (!muted)
9015 gpiostate |= (1 << pin);
9016 else
9017 gpiostate &= ~(1 << pin);
9018
9019 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9020 AC_VERB_GET_GPIO_MASK, 0);
9021 gpiomask |= (1 << pin);
9022
9023 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9024 AC_VERB_GET_GPIO_DIRECTION, 0);
9025 gpiodir |= (1 << pin);
9026
9027
9028 snd_hda_codec_write(codec, codec->afg, 0,
9029 AC_VERB_SET_GPIO_MASK, gpiomask);
9030 snd_hda_codec_write(codec, codec->afg, 0,
9031 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9032
9033 msleep(1);
9034
9035 snd_hda_codec_write(codec, codec->afg, 0,
9036 AC_VERB_SET_GPIO_DATA, gpiostate);
9037}
9038
9039/* set up GPIO at initialization */
9040static void alc885_macpro_init_hook(struct hda_codec *codec)
9041{
9042 alc882_gpio_mute(codec, 0, 0);
9043 alc882_gpio_mute(codec, 1, 0);
9044}
9045
9046/* set up GPIO and update auto-muting at initialization */
9047static void alc885_imac24_init_hook(struct hda_codec *codec)
9048{
9049 alc885_macpro_init_hook(codec);
9050 alc_hp_automute(codec);
9051}
9052
9053/*
9054 * generic initialization of ADC, input mixers and output mixers
9055 */
9056static const struct hda_verb alc883_auto_init_verbs[] = {
9057 /*
9058 * Unmute ADC0-2 and set the default input to mic-in
9059 */
9060 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9061 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9063 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064
9065 /*
9066 * Set up output mixers (0x0c - 0x0f)
9067 */
9068 /* set vol=0 to output mixers */
9069 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9070 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9071 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9072 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9073 /* set up input amps for analog loopback */
9074 /* Amp Indices: DAC = 0, mixer = 1 */
9075 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9076 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9077 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9078 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9079 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9080 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9081 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9082 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9083 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9084 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9085
9086 /* FIXME: use matrix-type input source selection */
9087 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9088 /* Input mixer2 */
9089 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9090 /* Input mixer3 */
9091 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9092 { }
9093};
9094
9095/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9096static const struct hda_verb alc889A_mb31_ch2_init[] = {
9097 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9098 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9099 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9101 { } /* end */
9102};
9103
9104/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9105static const struct hda_verb alc889A_mb31_ch4_init[] = {
9106 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9107 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9108 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9109 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9110 { } /* end */
9111};
9112
9113/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9114static const struct hda_verb alc889A_mb31_ch5_init[] = {
9115 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9116 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9118 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9119 { } /* end */
9120};
9121
9122/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9123static const struct hda_verb alc889A_mb31_ch6_init[] = {
9124 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9125 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9126 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9127 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9128 { } /* end */
9129};
9130
9131static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9132 { 2, alc889A_mb31_ch2_init },
9133 { 4, alc889A_mb31_ch4_init },
9134 { 5, alc889A_mb31_ch5_init },
9135 { 6, alc889A_mb31_ch6_init },
9136};
9137
9138static const struct hda_verb alc883_medion_eapd_verbs[] = {
9139 /* eanable EAPD on medion laptop */
9140 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9141 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9142 { }
9143};
9144
9145#define alc883_base_mixer alc882_base_mixer
9146
9147static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9148 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9149 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9150 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9151 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9153 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9154 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9158 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9160 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9161 { } /* end */
9162};
9163
9164static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9168 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9172 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9175 { } /* end */
9176};
9177
9178static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9179 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9180 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9181 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9182 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9183 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9185 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9187 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9188 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9189 { } /* end */
9190};
9191
9192static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9193 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9194 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9195 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9196 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9197 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9199 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9203 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9205 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9206 { } /* end */
9207};
9208
9209static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9210 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9211 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9213 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9214 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9215 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9216 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9217 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9219 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9220 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9221 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9222 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9226 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9227 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9228 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9229 { } /* end */
9230};
9231
9232static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9233 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9234 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9236 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9237 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9238 HDA_OUTPUT),
9239 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9240 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9241 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9243 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9244 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9247 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9248 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9249 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9250 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9251 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9253 { } /* end */
9254};
9255
9256static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9258 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9260 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9261 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9262 HDA_OUTPUT),
9263 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9264 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9265 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9266 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9267 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9269 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9270 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9273 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9275 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9276 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9277 { } /* end */
9278};
9279
9280static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9282 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9283 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9284 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9285 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9286 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9287 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9288 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9289 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9290 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9291 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9295 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9297 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9299 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9300 { } /* end */
9301};
9302
9303static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9304 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9305 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9306 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9307 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9308 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9309 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9310 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9311 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9312 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9313 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9314 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9315 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9316 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9317 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9319 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9321 { } /* end */
9322};
9323
9324static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9325 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9326 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9328 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9329 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9330 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9331 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9332 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9333 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9334 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9335 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9336 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9337 { } /* end */
9338};
9339
9340static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9341 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9342 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9343 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9344 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9345 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9346 { } /* end */
9347};
9348
9349static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9350 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9351 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9352 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9353 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9355 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9356 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9358 { } /* end */
9359};
9360
9361static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9362 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9363 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9366 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9369 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9370 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9371 { } /* end */
9372};
9373
9374static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9375 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9376 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9377 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9378 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9379 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9380 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9381 { } /* end */
9382};
9383
9384static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9385 /* Unmute front mixer */
9386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9388
9389 /* Set speaker pin to front mixer */
9390 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9391
9392 /* Init headphone pin */
9393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9395 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9396 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9397
9398 { } /* end */
9399};
9400
9401/* toggle speaker-output according to the hp-jack state */
9402static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9403{
9404 struct alc_spec *spec = codec->spec;
9405
9406 spec->autocfg.hp_pins[0] = 0x1a;
9407 spec->autocfg.speaker_pins[0] = 0x15;
9408 spec->automute = 1;
9409 spec->automute_mode = ALC_AUTOMUTE_AMP;
9410}
9411
9412static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9413 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9414 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9415 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9416 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9417 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9421 { } /* end */
9422};
9423
9424static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9426 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9427 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9428 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9429 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9430 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9432 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9434 { } /* end */
9435};
9436
9437static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9438 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9439 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9441 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9442 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9443 0x0d, 1, 0x0, HDA_OUTPUT),
9444 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9445 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9446 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9447 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9448 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9449 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9450 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9451 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9452 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9454 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9455 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9457 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9459 { } /* end */
9460};
9461
9462static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9463 /* Output mixers */
9464 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9465 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9466 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9467 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9468 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9469 HDA_OUTPUT),
9470 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9471 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9472 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9473 /* Output switches */
9474 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9475 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9476 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9477 /* Boost mixers */
9478 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9479 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9480 /* Input mixers */
9481 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9482 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9485 { } /* end */
9486};
9487
9488static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9489 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9490 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9491 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9492 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9493 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9495 { } /* end */
9496};
9497
9498static const struct hda_bind_ctls alc883_bind_cap_vol = {
9499 .ops = &snd_hda_bind_vol,
9500 .values = {
9501 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9502 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9503 0
9504 },
9505};
9506
9507static const struct hda_bind_ctls alc883_bind_cap_switch = {
9508 .ops = &snd_hda_bind_sw,
9509 .values = {
9510 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9511 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9512 0
9513 },
9514};
9515
9516static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9518 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9523 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9524 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9525 { } /* end */
9526};
9527
9528static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9529 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9530 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9531 {
9532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9533 /* .name = "Capture Source", */
9534 .name = "Input Source",
9535 .count = 1,
9536 .info = alc_mux_enum_info,
9537 .get = alc_mux_enum_get,
9538 .put = alc_mux_enum_put,
9539 },
9540 { } /* end */
9541};
9542
9543static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9544 {
9545 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9546 .name = "Channel Mode",
9547 .info = alc_ch_mode_info,
9548 .get = alc_ch_mode_get,
9549 .put = alc_ch_mode_put,
9550 },
9551 { } /* end */
9552};
9553
9554/* toggle speaker-output according to the hp-jack state */
9555static void alc883_mitac_setup(struct hda_codec *codec)
9556{
9557 struct alc_spec *spec = codec->spec;
9558
9559 spec->autocfg.hp_pins[0] = 0x15;
9560 spec->autocfg.speaker_pins[0] = 0x14;
9561 spec->autocfg.speaker_pins[1] = 0x17;
9562 spec->automute = 1;
9563 spec->automute_mode = ALC_AUTOMUTE_AMP;
9564}
9565
9566static const struct hda_verb alc883_mitac_verbs[] = {
9567 /* HP */
9568 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9570 /* Subwoofer */
9571 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9572 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9573
9574 /* enable unsolicited event */
9575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9576 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9577
9578 { } /* end */
9579};
9580
9581static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9582 /* HP */
9583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9584 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9585 /* Int speaker */
9586 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9587
9588 /* enable unsolicited event */
9589 /*
9590 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9591 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9592 */
9593
9594 { } /* end */
9595};
9596
9597static const struct hda_verb alc883_clevo_m720_verbs[] = {
9598 /* HP */
9599 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9600 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9601 /* Int speaker */
9602 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9603 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9604
9605 /* enable unsolicited event */
9606 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9607 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9608
9609 { } /* end */
9610};
9611
9612static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9613 /* HP */
9614 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9615 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9616 /* Subwoofer */
9617 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9618 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9619
9620 /* enable unsolicited event */
9621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9622
9623 { } /* end */
9624};
9625
9626static const struct hda_verb alc883_targa_verbs[] = {
9627 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9629
9630 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9631 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9632
9633/* Connect Line-Out side jack (SPDIF) to Side */
9634 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9635 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9636 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9637/* Connect Mic jack to CLFE */
9638 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9639 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9640 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9641/* Connect Line-in jack to Surround */
9642 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9643 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9644 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9645/* Connect HP out jack to Front */
9646 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9647 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9648 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9649
9650 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9651
9652 { } /* end */
9653};
9654
9655static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9657 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9658 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9659 { } /* end */
9660};
9661
9662static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9663 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9664 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9666 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9667 { } /* end */
9668};
9669
9670static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9671 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9672 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9673 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9674 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9675 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9676 { } /* end */
9677};
9678
9679static const struct hda_verb alc883_haier_w66_verbs[] = {
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9682
9683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9684
9685 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9689 { } /* end */
9690};
9691
9692static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9694 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9695 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9696 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9698 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9699 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9700 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9701 { } /* end */
9702};
9703
9704static const struct hda_verb alc888_6st_dell_verbs[] = {
9705 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9706 { }
9707};
9708
9709static const struct hda_verb alc883_vaiott_verbs[] = {
9710 /* HP */
9711 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9712 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9713
9714 /* enable unsolicited event */
9715 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9716
9717 { } /* end */
9718};
9719
9720static void alc888_3st_hp_setup(struct hda_codec *codec)
9721{
9722 struct alc_spec *spec = codec->spec;
9723
9724 spec->autocfg.hp_pins[0] = 0x1b;
9725 spec->autocfg.speaker_pins[0] = 0x14;
9726 spec->autocfg.speaker_pins[1] = 0x16;
9727 spec->autocfg.speaker_pins[2] = 0x18;
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
9730}
9731
9732static const struct hda_verb alc888_3st_hp_verbs[] = {
9733 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9734 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9735 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9736 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9737 { } /* end */
9738};
9739
9740/*
9741 * 2ch mode
9742 */
9743static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9744 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9745 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9746 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9747 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9748 { } /* end */
9749};
9750
9751/*
9752 * 4ch mode
9753 */
9754static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9755 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9756 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9757 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9758 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9759 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9760 { } /* end */
9761};
9762
9763/*
9764 * 6ch mode
9765 */
9766static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9767 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9768 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9769 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9770 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9771 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9772 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9773 { } /* end */
9774};
9775
9776static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9777 { 2, alc888_3st_hp_2ch_init },
9778 { 4, alc888_3st_hp_4ch_init },
9779 { 6, alc888_3st_hp_6ch_init },
9780};
9781
9782static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9783{
9784 struct alc_spec *spec = codec->spec;
9785
9786 spec->autocfg.hp_pins[0] = 0x1b;
9787 spec->autocfg.line_out_pins[0] = 0x14;
9788 spec->autocfg.speaker_pins[0] = 0x15;
9789 spec->automute = 1;
9790 spec->automute_mode = ALC_AUTOMUTE_AMP;
9791}
9792
9793/* toggle speaker-output according to the hp-jack state */
9794static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9795{
9796 struct alc_spec *spec = codec->spec;
9797
9798 spec->autocfg.hp_pins[0] = 0x14;
9799 spec->autocfg.speaker_pins[0] = 0x15;
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
9802}
9803
9804/* toggle speaker-output according to the hp-jack state */
9805#define alc883_targa_init_hook alc882_targa_init_hook
9806#define alc883_targa_unsol_event alc882_targa_unsol_event
9807
9808static void alc883_clevo_m720_setup(struct hda_codec *codec)
9809{
9810 struct alc_spec *spec = codec->spec;
9811
9812 spec->autocfg.hp_pins[0] = 0x15;
9813 spec->autocfg.speaker_pins[0] = 0x14;
9814 spec->automute = 1;
9815 spec->automute_mode = ALC_AUTOMUTE_AMP;
9816}
9817
9818static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9819{
9820 alc_hp_automute(codec);
9821 alc88x_simple_mic_automute(codec);
9822}
9823
9824static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9825 unsigned int res)
9826{
9827 switch (res >> 26) {
9828 case ALC880_MIC_EVENT:
9829 alc88x_simple_mic_automute(codec);
9830 break;
9831 default:
9832 alc_sku_unsol_event(codec, res);
9833 break;
9834 }
9835}
9836
9837/* toggle speaker-output according to the hp-jack state */
9838static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9839{
9840 struct alc_spec *spec = codec->spec;
9841
9842 spec->autocfg.hp_pins[0] = 0x14;
9843 spec->autocfg.speaker_pins[0] = 0x15;
9844 spec->automute = 1;
9845 spec->automute_mode = ALC_AUTOMUTE_AMP;
9846}
9847
9848static void alc883_haier_w66_setup(struct hda_codec *codec)
9849{
9850 struct alc_spec *spec = codec->spec;
9851
9852 spec->autocfg.hp_pins[0] = 0x1b;
9853 spec->autocfg.speaker_pins[0] = 0x14;
9854 spec->automute = 1;
9855 spec->automute_mode = ALC_AUTOMUTE_AMP;
9856}
9857
9858static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9859{
9860 struct alc_spec *spec = codec->spec;
9861
9862 spec->autocfg.hp_pins[0] = 0x1b;
9863 spec->autocfg.line_out_pins[0] = 0x14;
9864 spec->autocfg.speaker_pins[0] = 0x15;
9865 spec->automute = 1;
9866 spec->detect_line = 1;
9867 spec->automute_lines = 1;
9868 spec->automute_mode = ALC_AUTOMUTE_AMP;
9869}
9870
9871/* toggle speaker-output according to the hp-jack state */
9872static void alc883_acer_aspire_setup(struct hda_codec *codec)
9873{
9874 struct alc_spec *spec = codec->spec;
9875
9876 spec->autocfg.hp_pins[0] = 0x14;
9877 spec->autocfg.speaker_pins[0] = 0x15;
9878 spec->autocfg.speaker_pins[1] = 0x16;
9879 spec->automute = 1;
9880 spec->automute_mode = ALC_AUTOMUTE_AMP;
9881}
9882
9883static const struct hda_verb alc883_acer_eapd_verbs[] = {
9884 /* HP Pin: output 0 (0x0c) */
9885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9887 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9888 /* Front Pin: output 0 (0x0c) */
9889 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9890 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9891 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9892 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9893 /* eanable EAPD on medion laptop */
9894 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9895 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9896 /* enable unsolicited event */
9897 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9898 { }
9899};
9900
9901static void alc888_6st_dell_setup(struct hda_codec *codec)
9902{
9903 struct alc_spec *spec = codec->spec;
9904
9905 spec->autocfg.hp_pins[0] = 0x1b;
9906 spec->autocfg.speaker_pins[0] = 0x14;
9907 spec->autocfg.speaker_pins[1] = 0x15;
9908 spec->autocfg.speaker_pins[2] = 0x16;
9909 spec->autocfg.speaker_pins[3] = 0x17;
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
9912}
9913
9914static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9915{
9916 struct alc_spec *spec = codec->spec;
9917
9918 spec->autocfg.hp_pins[0] = 0x1b;
9919 spec->autocfg.speaker_pins[0] = 0x14;
9920 spec->autocfg.speaker_pins[1] = 0x15;
9921 spec->autocfg.speaker_pins[2] = 0x16;
9922 spec->autocfg.speaker_pins[3] = 0x17;
9923 spec->autocfg.speaker_pins[4] = 0x1a;
9924 spec->automute = 1;
9925 spec->automute_mode = ALC_AUTOMUTE_AMP;
9926}
9927
9928static void alc883_vaiott_setup(struct hda_codec *codec)
9929{
9930 struct alc_spec *spec = codec->spec;
9931
9932 spec->autocfg.hp_pins[0] = 0x15;
9933 spec->autocfg.speaker_pins[0] = 0x14;
9934 spec->autocfg.speaker_pins[1] = 0x17;
9935 spec->automute = 1;
9936 spec->automute_mode = ALC_AUTOMUTE_AMP;
9937}
9938
9939static const struct hda_verb alc888_asus_m90v_verbs[] = {
9940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9941 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9942 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9943 /* enable unsolicited event */
9944 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9945 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9946 { } /* end */
9947};
9948
9949static void alc883_mode2_setup(struct hda_codec *codec)
9950{
9951 struct alc_spec *spec = codec->spec;
9952
9953 spec->autocfg.hp_pins[0] = 0x1b;
9954 spec->autocfg.speaker_pins[0] = 0x14;
9955 spec->autocfg.speaker_pins[1] = 0x15;
9956 spec->autocfg.speaker_pins[2] = 0x16;
9957 spec->ext_mic.pin = 0x18;
9958 spec->int_mic.pin = 0x19;
9959 spec->ext_mic.mux_idx = 0;
9960 spec->int_mic.mux_idx = 1;
9961 spec->auto_mic = 1;
9962 spec->automute = 1;
9963 spec->automute_mode = ALC_AUTOMUTE_AMP;
9964}
9965
9966static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9967 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9968 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9971 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9972 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9973 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9974 /* enable unsolicited event */
9975 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9976 { } /* end */
9977};
9978
9979static void alc883_eee1601_inithook(struct hda_codec *codec)
9980{
9981 struct alc_spec *spec = codec->spec;
9982
9983 spec->autocfg.hp_pins[0] = 0x14;
9984 spec->autocfg.speaker_pins[0] = 0x1b;
9985 alc_hp_automute(codec);
9986}
9987
9988static const struct hda_verb alc889A_mb31_verbs[] = {
9989 /* Init rear pin (used as headphone output) */
9990 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9991 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9992 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9993 /* Init line pin (used as output in 4ch and 6ch mode) */
9994 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9995 /* Init line 2 pin (used as headphone out by default) */
9996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9997 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9998 { } /* end */
9999};
10000
10001/* Mute speakers according to the headphone jack state */
10002static void alc889A_mb31_automute(struct hda_codec *codec)
10003{
10004 unsigned int present;
10005
10006 /* Mute only in 2ch or 4ch mode */
10007 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
10008 == 0x00) {
10009 present = snd_hda_jack_detect(codec, 0x15);
10010 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
10011 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10012 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10013 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10014 }
10015}
10016
10017static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10018{
10019 if ((res >> 26) == ALC880_HP_EVENT)
10020 alc889A_mb31_automute(codec);
10021}
10022
10023
10024#ifdef CONFIG_SND_HDA_POWER_SAVE 3850#ifdef CONFIG_SND_HDA_POWER_SAVE
10025#define alc882_loopbacks alc880_loopbacks 3851#define alc882_loopbacks alc880_loopbacks
10026#endif 3852#endif
10027 3853
10028/* pcm configuration: identical with ALC880 */
10029#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10030#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10031#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10032#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10033
10034static const hda_nid_t alc883_slave_dig_outs[] = {
10035 ALC1200_DIGOUT_NID, 0,
10036};
10037
10038static const hda_nid_t alc1200_slave_dig_outs[] = {
10039 ALC883_DIGOUT_NID, 0,
10040};
10041
10042/*
10043 * configuration and preset
10044 */
10045static const char * const alc882_models[ALC882_MODEL_LAST] = {
10046 [ALC882_3ST_DIG] = "3stack-dig",
10047 [ALC882_6ST_DIG] = "6stack-dig",
10048 [ALC882_ARIMA] = "arima",
10049 [ALC882_W2JC] = "w2jc",
10050 [ALC882_TARGA] = "targa",
10051 [ALC882_ASUS_A7J] = "asus-a7j",
10052 [ALC882_ASUS_A7M] = "asus-a7m",
10053 [ALC885_MACPRO] = "macpro",
10054 [ALC885_MB5] = "mb5",
10055 [ALC885_MACMINI3] = "macmini3",
10056 [ALC885_MBA21] = "mba21",
10057 [ALC885_MBP3] = "mbp3",
10058 [ALC885_IMAC24] = "imac24",
10059 [ALC885_IMAC91] = "imac91",
10060 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10061 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10062 [ALC883_3ST_6ch] = "3stack-6ch",
10063 [ALC883_6ST_DIG] = "alc883-6stack-dig",
10064 [ALC883_TARGA_DIG] = "targa-dig",
10065 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10066 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10067 [ALC883_ACER] = "acer",
10068 [ALC883_ACER_ASPIRE] = "acer-aspire",
10069 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10070 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10071 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10072 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10073 [ALC883_MEDION] = "medion",
10074 [ALC883_MEDION_WIM2160] = "medion-wim2160",
10075 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
10076 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10077 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10078 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10079 [ALC888_LENOVO_SKY] = "lenovo-sky",
10080 [ALC883_HAIER_W66] = "haier-w66",
10081 [ALC888_3ST_HP] = "3stack-hp",
10082 [ALC888_6ST_DELL] = "6stack-dell",
10083 [ALC883_MITAC] = "mitac",
10084 [ALC883_CLEVO_M540R] = "clevo-m540r",
10085 [ALC883_CLEVO_M720] = "clevo-m720",
10086 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10087 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10088 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10089 [ALC889A_INTEL] = "intel-alc889a",
10090 [ALC889_INTEL] = "intel-x58",
10091 [ALC1200_ASUS_P5Q] = "asus-p5q",
10092 [ALC889A_MB31] = "mb31",
10093 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10094 [ALC882_AUTO] = "auto",
10095};
10096
10097static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10098 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10099
10100 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10101 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10102 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10103 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10104 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10105 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10106 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10107 ALC888_ACER_ASPIRE_4930G),
10108 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10109 ALC888_ACER_ASPIRE_4930G),
10110 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10111 ALC888_ACER_ASPIRE_8930G),
10112 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10113 ALC888_ACER_ASPIRE_8930G),
10114 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10115 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10116 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10117 ALC888_ACER_ASPIRE_6530G),
10118 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10119 ALC888_ACER_ASPIRE_6530G),
10120 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10121 ALC888_ACER_ASPIRE_7730G),
10122 /* default Acer -- disabled as it causes more problems.
10123 * model=auto should work fine now
10124 */
10125 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10126
10127 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10128
10129 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10130 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10131 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10132 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10133 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10134 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10135
10136 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10137 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10138 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10139 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10140 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10141 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10142 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10143 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10144 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10145 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10146 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10147
10148 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10149 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10150 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10151 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10152 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10153 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10154 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10155 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10156 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10157
10158 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10159 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10160 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10162 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10163 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10164 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10165 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10167 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10168 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10169 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10170 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10171 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10172 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10173 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10174 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10175 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10176 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10177 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10178 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10179 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10180 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10181 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10182 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10183 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10184 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10185 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10186 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10187 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10188 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10189
10190 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10191 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10192 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10193 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10194 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10195 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10196 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10197 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10198 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10199 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10200 ALC883_FUJITSU_PI2515),
10201 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10202 ALC888_FUJITSU_XA3530),
10203 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10204 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10205 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10206 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10207 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10208 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10209 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10210 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10211
10212 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10213 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10214 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10215 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10216 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10217 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10218 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10219
10220 {}
10221};
10222
10223/* codec SSID table for Intel Mac */
10224static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10225 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10226 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10227 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10228 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10229 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10230 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10231 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10232 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10233 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10234 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10235 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10236 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10237 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10238 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10239 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10240 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10241 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10242 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10243 * so apparently no perfect solution yet
10244 */
10245 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10246 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10247 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10248 {} /* terminator */
10249};
10250
10251static const struct alc_config_preset alc882_presets[] = {
10252 [ALC882_3ST_DIG] = {
10253 .mixers = { alc882_base_mixer },
10254 .init_verbs = { alc882_base_init_verbs,
10255 alc882_adc1_init_verbs },
10256 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10257 .dac_nids = alc882_dac_nids,
10258 .dig_out_nid = ALC882_DIGOUT_NID,
10259 .dig_in_nid = ALC882_DIGIN_NID,
10260 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10261 .channel_mode = alc882_ch_modes,
10262 .need_dac_fix = 1,
10263 .input_mux = &alc882_capture_source,
10264 },
10265 [ALC882_6ST_DIG] = {
10266 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10267 .init_verbs = { alc882_base_init_verbs,
10268 alc882_adc1_init_verbs },
10269 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10270 .dac_nids = alc882_dac_nids,
10271 .dig_out_nid = ALC882_DIGOUT_NID,
10272 .dig_in_nid = ALC882_DIGIN_NID,
10273 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10274 .channel_mode = alc882_sixstack_modes,
10275 .input_mux = &alc882_capture_source,
10276 },
10277 [ALC882_ARIMA] = {
10278 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10279 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10280 alc882_eapd_verbs },
10281 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10282 .dac_nids = alc882_dac_nids,
10283 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10284 .channel_mode = alc882_sixstack_modes,
10285 .input_mux = &alc882_capture_source,
10286 },
10287 [ALC882_W2JC] = {
10288 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10289 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10290 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292 .dac_nids = alc882_dac_nids,
10293 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10294 .channel_mode = alc880_threestack_modes,
10295 .need_dac_fix = 1,
10296 .input_mux = &alc882_capture_source,
10297 .dig_out_nid = ALC882_DIGOUT_NID,
10298 },
10299 [ALC885_MBA21] = {
10300 .mixers = { alc885_mba21_mixer },
10301 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10302 .num_dacs = 2,
10303 .dac_nids = alc882_dac_nids,
10304 .channel_mode = alc885_mba21_ch_modes,
10305 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10306 .input_mux = &alc882_capture_source,
10307 .unsol_event = alc_sku_unsol_event,
10308 .setup = alc885_mba21_setup,
10309 .init_hook = alc_hp_automute,
10310 },
10311 [ALC885_MBP3] = {
10312 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10313 .init_verbs = { alc885_mbp3_init_verbs,
10314 alc880_gpio1_init_verbs },
10315 .num_dacs = 2,
10316 .dac_nids = alc882_dac_nids,
10317 .hp_nid = 0x04,
10318 .channel_mode = alc885_mbp_4ch_modes,
10319 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10320 .input_mux = &alc882_capture_source,
10321 .dig_out_nid = ALC882_DIGOUT_NID,
10322 .dig_in_nid = ALC882_DIGIN_NID,
10323 .unsol_event = alc_sku_unsol_event,
10324 .setup = alc885_mbp3_setup,
10325 .init_hook = alc_hp_automute,
10326 },
10327 [ALC885_MB5] = {
10328 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10329 .init_verbs = { alc885_mb5_init_verbs,
10330 alc880_gpio1_init_verbs },
10331 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10332 .dac_nids = alc882_dac_nids,
10333 .channel_mode = alc885_mb5_6ch_modes,
10334 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10335 .input_mux = &mb5_capture_source,
10336 .dig_out_nid = ALC882_DIGOUT_NID,
10337 .dig_in_nid = ALC882_DIGIN_NID,
10338 .unsol_event = alc_sku_unsol_event,
10339 .setup = alc885_mb5_setup,
10340 .init_hook = alc_hp_automute,
10341 },
10342 [ALC885_MACMINI3] = {
10343 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10344 .init_verbs = { alc885_macmini3_init_verbs,
10345 alc880_gpio1_init_verbs },
10346 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10347 .dac_nids = alc882_dac_nids,
10348 .channel_mode = alc885_macmini3_6ch_modes,
10349 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10350 .input_mux = &macmini3_capture_source,
10351 .dig_out_nid = ALC882_DIGOUT_NID,
10352 .dig_in_nid = ALC882_DIGIN_NID,
10353 .unsol_event = alc_sku_unsol_event,
10354 .setup = alc885_macmini3_setup,
10355 .init_hook = alc_hp_automute,
10356 },
10357 [ALC885_MACPRO] = {
10358 .mixers = { alc882_macpro_mixer },
10359 .init_verbs = { alc882_macpro_init_verbs },
10360 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10361 .dac_nids = alc882_dac_nids,
10362 .dig_out_nid = ALC882_DIGOUT_NID,
10363 .dig_in_nid = ALC882_DIGIN_NID,
10364 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10365 .channel_mode = alc882_ch_modes,
10366 .input_mux = &alc882_capture_source,
10367 .init_hook = alc885_macpro_init_hook,
10368 },
10369 [ALC885_IMAC24] = {
10370 .mixers = { alc885_imac24_mixer },
10371 .init_verbs = { alc885_imac24_init_verbs },
10372 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10373 .dac_nids = alc882_dac_nids,
10374 .dig_out_nid = ALC882_DIGOUT_NID,
10375 .dig_in_nid = ALC882_DIGIN_NID,
10376 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10377 .channel_mode = alc882_ch_modes,
10378 .input_mux = &alc882_capture_source,
10379 .unsol_event = alc_sku_unsol_event,
10380 .setup = alc885_imac24_setup,
10381 .init_hook = alc885_imac24_init_hook,
10382 },
10383 [ALC885_IMAC91] = {
10384 .mixers = {alc885_imac91_mixer},
10385 .init_verbs = { alc885_imac91_init_verbs,
10386 alc880_gpio1_init_verbs },
10387 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10388 .dac_nids = alc882_dac_nids,
10389 .channel_mode = alc885_mba21_ch_modes,
10390 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10391 .input_mux = &alc889A_imac91_capture_source,
10392 .dig_out_nid = ALC882_DIGOUT_NID,
10393 .dig_in_nid = ALC882_DIGIN_NID,
10394 .unsol_event = alc_sku_unsol_event,
10395 .setup = alc885_imac91_setup,
10396 .init_hook = alc_hp_automute,
10397 },
10398 [ALC882_TARGA] = {
10399 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10400 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10401 alc880_gpio3_init_verbs, alc882_targa_verbs},
10402 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10403 .dac_nids = alc882_dac_nids,
10404 .dig_out_nid = ALC882_DIGOUT_NID,
10405 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10406 .adc_nids = alc882_adc_nids,
10407 .capsrc_nids = alc882_capsrc_nids,
10408 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10409 .channel_mode = alc882_3ST_6ch_modes,
10410 .need_dac_fix = 1,
10411 .input_mux = &alc882_capture_source,
10412 .unsol_event = alc_sku_unsol_event,
10413 .setup = alc882_targa_setup,
10414 .init_hook = alc882_targa_automute,
10415 },
10416 [ALC882_ASUS_A7J] = {
10417 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10418 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10419 alc882_asus_a7j_verbs},
10420 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10421 .dac_nids = alc882_dac_nids,
10422 .dig_out_nid = ALC882_DIGOUT_NID,
10423 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10424 .adc_nids = alc882_adc_nids,
10425 .capsrc_nids = alc882_capsrc_nids,
10426 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10427 .channel_mode = alc882_3ST_6ch_modes,
10428 .need_dac_fix = 1,
10429 .input_mux = &alc882_capture_source,
10430 },
10431 [ALC882_ASUS_A7M] = {
10432 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10433 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10434 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10435 alc882_asus_a7m_verbs },
10436 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10437 .dac_nids = alc882_dac_nids,
10438 .dig_out_nid = ALC882_DIGOUT_NID,
10439 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10440 .channel_mode = alc880_threestack_modes,
10441 .need_dac_fix = 1,
10442 .input_mux = &alc882_capture_source,
10443 },
10444 [ALC883_3ST_2ch_DIG] = {
10445 .mixers = { alc883_3ST_2ch_mixer },
10446 .init_verbs = { alc883_init_verbs },
10447 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10448 .dac_nids = alc883_dac_nids,
10449 .dig_out_nid = ALC883_DIGOUT_NID,
10450 .dig_in_nid = ALC883_DIGIN_NID,
10451 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10452 .channel_mode = alc883_3ST_2ch_modes,
10453 .input_mux = &alc883_capture_source,
10454 },
10455 [ALC883_3ST_6ch_DIG] = {
10456 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10457 .init_verbs = { alc883_init_verbs },
10458 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10459 .dac_nids = alc883_dac_nids,
10460 .dig_out_nid = ALC883_DIGOUT_NID,
10461 .dig_in_nid = ALC883_DIGIN_NID,
10462 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10463 .channel_mode = alc883_3ST_6ch_modes,
10464 .need_dac_fix = 1,
10465 .input_mux = &alc883_capture_source,
10466 },
10467 [ALC883_3ST_6ch] = {
10468 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10469 .init_verbs = { alc883_init_verbs },
10470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10471 .dac_nids = alc883_dac_nids,
10472 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10473 .channel_mode = alc883_3ST_6ch_modes,
10474 .need_dac_fix = 1,
10475 .input_mux = &alc883_capture_source,
10476 },
10477 [ALC883_3ST_6ch_INTEL] = {
10478 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10479 .init_verbs = { alc883_init_verbs },
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
10482 .dig_out_nid = ALC883_DIGOUT_NID,
10483 .dig_in_nid = ALC883_DIGIN_NID,
10484 .slave_dig_outs = alc883_slave_dig_outs,
10485 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10486 .channel_mode = alc883_3ST_6ch_intel_modes,
10487 .need_dac_fix = 1,
10488 .input_mux = &alc883_3stack_6ch_intel,
10489 },
10490 [ALC889A_INTEL] = {
10491 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10492 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10493 alc_hp15_unsol_verbs },
10494 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10495 .dac_nids = alc883_dac_nids,
10496 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10497 .adc_nids = alc889_adc_nids,
10498 .dig_out_nid = ALC883_DIGOUT_NID,
10499 .dig_in_nid = ALC883_DIGIN_NID,
10500 .slave_dig_outs = alc883_slave_dig_outs,
10501 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10502 .channel_mode = alc889_8ch_intel_modes,
10503 .capsrc_nids = alc889_capsrc_nids,
10504 .input_mux = &alc889_capture_source,
10505 .setup = alc889_automute_setup,
10506 .init_hook = alc_hp_automute,
10507 .unsol_event = alc_sku_unsol_event,
10508 .need_dac_fix = 1,
10509 },
10510 [ALC889_INTEL] = {
10511 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10512 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10513 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10514 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10515 .dac_nids = alc883_dac_nids,
10516 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10517 .adc_nids = alc889_adc_nids,
10518 .dig_out_nid = ALC883_DIGOUT_NID,
10519 .dig_in_nid = ALC883_DIGIN_NID,
10520 .slave_dig_outs = alc883_slave_dig_outs,
10521 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10522 .channel_mode = alc889_8ch_intel_modes,
10523 .capsrc_nids = alc889_capsrc_nids,
10524 .input_mux = &alc889_capture_source,
10525 .setup = alc889_automute_setup,
10526 .init_hook = alc889_intel_init_hook,
10527 .unsol_event = alc_sku_unsol_event,
10528 .need_dac_fix = 1,
10529 },
10530 [ALC883_6ST_DIG] = {
10531 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10532 .init_verbs = { alc883_init_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_sixstack_modes),
10538 .channel_mode = alc883_sixstack_modes,
10539 .input_mux = &alc883_capture_source,
10540 },
10541 [ALC883_TARGA_DIG] = {
10542 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10543 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10544 alc883_targa_verbs},
10545 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10546 .dac_nids = alc883_dac_nids,
10547 .dig_out_nid = ALC883_DIGOUT_NID,
10548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10549 .channel_mode = alc883_3ST_6ch_modes,
10550 .need_dac_fix = 1,
10551 .input_mux = &alc883_capture_source,
10552 .unsol_event = alc883_targa_unsol_event,
10553 .setup = alc882_targa_setup,
10554 .init_hook = alc882_targa_automute,
10555 },
10556 [ALC883_TARGA_2ch_DIG] = {
10557 .mixers = { alc883_targa_2ch_mixer},
10558 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10559 alc883_targa_verbs},
10560 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10561 .dac_nids = alc883_dac_nids,
10562 .adc_nids = alc883_adc_nids_alt,
10563 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10564 .capsrc_nids = alc883_capsrc_nids,
10565 .dig_out_nid = ALC883_DIGOUT_NID,
10566 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567 .channel_mode = alc883_3ST_2ch_modes,
10568 .input_mux = &alc883_capture_source,
10569 .unsol_event = alc883_targa_unsol_event,
10570 .setup = alc882_targa_setup,
10571 .init_hook = alc882_targa_automute,
10572 },
10573 [ALC883_TARGA_8ch_DIG] = {
10574 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10575 alc883_chmode_mixer },
10576 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10577 alc883_targa_verbs },
10578 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10579 .dac_nids = alc883_dac_nids,
10580 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10581 .adc_nids = alc883_adc_nids_rev,
10582 .capsrc_nids = alc883_capsrc_nids_rev,
10583 .dig_out_nid = ALC883_DIGOUT_NID,
10584 .dig_in_nid = ALC883_DIGIN_NID,
10585 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10586 .channel_mode = alc883_4ST_8ch_modes,
10587 .need_dac_fix = 1,
10588 .input_mux = &alc883_capture_source,
10589 .unsol_event = alc883_targa_unsol_event,
10590 .setup = alc882_targa_setup,
10591 .init_hook = alc882_targa_automute,
10592 },
10593 [ALC883_ACER] = {
10594 .mixers = { alc883_base_mixer },
10595 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10596 * and the headphone jack. Turn this on and rely on the
10597 * standard mute methods whenever the user wants to turn
10598 * these outputs off.
10599 */
10600 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10601 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10602 .dac_nids = alc883_dac_nids,
10603 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10604 .channel_mode = alc883_3ST_2ch_modes,
10605 .input_mux = &alc883_capture_source,
10606 },
10607 [ALC883_ACER_ASPIRE] = {
10608 .mixers = { alc883_acer_aspire_mixer },
10609 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10610 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10611 .dac_nids = alc883_dac_nids,
10612 .dig_out_nid = ALC883_DIGOUT_NID,
10613 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10614 .channel_mode = alc883_3ST_2ch_modes,
10615 .input_mux = &alc883_capture_source,
10616 .unsol_event = alc_sku_unsol_event,
10617 .setup = alc883_acer_aspire_setup,
10618 .init_hook = alc_hp_automute,
10619 },
10620 [ALC888_ACER_ASPIRE_4930G] = {
10621 .mixers = { alc888_acer_aspire_4930g_mixer,
10622 alc883_chmode_mixer },
10623 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10624 alc888_acer_aspire_4930g_verbs },
10625 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10626 .dac_nids = alc883_dac_nids,
10627 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10628 .adc_nids = alc883_adc_nids_rev,
10629 .capsrc_nids = alc883_capsrc_nids_rev,
10630 .dig_out_nid = ALC883_DIGOUT_NID,
10631 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10632 .channel_mode = alc883_3ST_6ch_modes,
10633 .need_dac_fix = 1,
10634 .const_channel_count = 6,
10635 .num_mux_defs =
10636 ARRAY_SIZE(alc888_2_capture_sources),
10637 .input_mux = alc888_2_capture_sources,
10638 .unsol_event = alc_sku_unsol_event,
10639 .setup = alc888_acer_aspire_4930g_setup,
10640 .init_hook = alc_hp_automute,
10641 },
10642 [ALC888_ACER_ASPIRE_6530G] = {
10643 .mixers = { alc888_acer_aspire_6530_mixer },
10644 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10645 alc888_acer_aspire_6530g_verbs },
10646 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10647 .dac_nids = alc883_dac_nids,
10648 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10649 .adc_nids = alc883_adc_nids_rev,
10650 .capsrc_nids = alc883_capsrc_nids_rev,
10651 .dig_out_nid = ALC883_DIGOUT_NID,
10652 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10653 .channel_mode = alc883_3ST_2ch_modes,
10654 .num_mux_defs =
10655 ARRAY_SIZE(alc888_2_capture_sources),
10656 .input_mux = alc888_acer_aspire_6530_sources,
10657 .unsol_event = alc_sku_unsol_event,
10658 .setup = alc888_acer_aspire_6530g_setup,
10659 .init_hook = alc_hp_automute,
10660 },
10661 [ALC888_ACER_ASPIRE_8930G] = {
10662 .mixers = { alc889_acer_aspire_8930g_mixer,
10663 alc883_chmode_mixer },
10664 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10665 alc889_acer_aspire_8930g_verbs,
10666 alc889_eapd_verbs},
10667 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10668 .dac_nids = alc883_dac_nids,
10669 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10670 .adc_nids = alc889_adc_nids,
10671 .capsrc_nids = alc889_capsrc_nids,
10672 .dig_out_nid = ALC883_DIGOUT_NID,
10673 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10674 .channel_mode = alc883_3ST_6ch_modes,
10675 .need_dac_fix = 1,
10676 .const_channel_count = 6,
10677 .num_mux_defs =
10678 ARRAY_SIZE(alc889_capture_sources),
10679 .input_mux = alc889_capture_sources,
10680 .unsol_event = alc_sku_unsol_event,
10681 .setup = alc889_acer_aspire_8930g_setup,
10682 .init_hook = alc_hp_automute,
10683#ifdef CONFIG_SND_HDA_POWER_SAVE
10684 .power_hook = alc_power_eapd,
10685#endif
10686 },
10687 [ALC888_ACER_ASPIRE_7730G] = {
10688 .mixers = { alc883_3ST_6ch_mixer,
10689 alc883_chmode_mixer },
10690 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10691 alc888_acer_aspire_7730G_verbs },
10692 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10693 .dac_nids = alc883_dac_nids,
10694 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10695 .adc_nids = alc883_adc_nids_rev,
10696 .capsrc_nids = alc883_capsrc_nids_rev,
10697 .dig_out_nid = ALC883_DIGOUT_NID,
10698 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10699 .channel_mode = alc883_3ST_6ch_modes,
10700 .need_dac_fix = 1,
10701 .const_channel_count = 6,
10702 .input_mux = &alc883_capture_source,
10703 .unsol_event = alc_sku_unsol_event,
10704 .setup = alc888_acer_aspire_7730g_setup,
10705 .init_hook = alc_hp_automute,
10706 },
10707 [ALC883_MEDION] = {
10708 .mixers = { alc883_fivestack_mixer,
10709 alc883_chmode_mixer },
10710 .init_verbs = { alc883_init_verbs,
10711 alc883_medion_eapd_verbs },
10712 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10713 .dac_nids = alc883_dac_nids,
10714 .adc_nids = alc883_adc_nids_alt,
10715 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10716 .capsrc_nids = alc883_capsrc_nids,
10717 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10718 .channel_mode = alc883_sixstack_modes,
10719 .input_mux = &alc883_capture_source,
10720 },
10721 [ALC883_MEDION_WIM2160] = {
10722 .mixers = { alc883_medion_wim2160_mixer },
10723 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10724 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10725 .dac_nids = alc883_dac_nids,
10726 .dig_out_nid = ALC883_DIGOUT_NID,
10727 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10728 .adc_nids = alc883_adc_nids,
10729 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10730 .channel_mode = alc883_3ST_2ch_modes,
10731 .input_mux = &alc883_capture_source,
10732 .unsol_event = alc_sku_unsol_event,
10733 .setup = alc883_medion_wim2160_setup,
10734 .init_hook = alc_hp_automute,
10735 },
10736 [ALC883_LAPTOP_EAPD] = {
10737 .mixers = { alc883_base_mixer },
10738 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10739 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10740 .dac_nids = alc883_dac_nids,
10741 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10742 .channel_mode = alc883_3ST_2ch_modes,
10743 .input_mux = &alc883_capture_source,
10744 },
10745 [ALC883_CLEVO_M540R] = {
10746 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10747 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10748 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10749 .dac_nids = alc883_dac_nids,
10750 .dig_out_nid = ALC883_DIGOUT_NID,
10751 .dig_in_nid = ALC883_DIGIN_NID,
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10753 .channel_mode = alc883_3ST_6ch_clevo_modes,
10754 .need_dac_fix = 1,
10755 .input_mux = &alc883_capture_source,
10756 /* This machine has the hardware HP auto-muting, thus
10757 * we need no software mute via unsol event
10758 */
10759 },
10760 [ALC883_CLEVO_M720] = {
10761 .mixers = { alc883_clevo_m720_mixer },
10762 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
10765 .dig_out_nid = ALC883_DIGOUT_NID,
10766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10767 .channel_mode = alc883_3ST_2ch_modes,
10768 .input_mux = &alc883_capture_source,
10769 .unsol_event = alc883_clevo_m720_unsol_event,
10770 .setup = alc883_clevo_m720_setup,
10771 .init_hook = alc883_clevo_m720_init_hook,
10772 },
10773 [ALC883_LENOVO_101E_2ch] = {
10774 .mixers = { alc883_lenovo_101e_2ch_mixer},
10775 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10777 .dac_nids = alc883_dac_nids,
10778 .adc_nids = alc883_adc_nids_alt,
10779 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10780 .capsrc_nids = alc883_capsrc_nids,
10781 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10782 .channel_mode = alc883_3ST_2ch_modes,
10783 .input_mux = &alc883_lenovo_101e_capture_source,
10784 .setup = alc883_lenovo_101e_setup,
10785 .unsol_event = alc_sku_unsol_event,
10786 .init_hook = alc_inithook,
10787 },
10788 [ALC883_LENOVO_NB0763] = {
10789 .mixers = { alc883_lenovo_nb0763_mixer },
10790 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10791 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10792 .dac_nids = alc883_dac_nids,
10793 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10794 .channel_mode = alc883_3ST_2ch_modes,
10795 .need_dac_fix = 1,
10796 .input_mux = &alc883_lenovo_nb0763_capture_source,
10797 .unsol_event = alc_sku_unsol_event,
10798 .setup = alc883_lenovo_nb0763_setup,
10799 .init_hook = alc_hp_automute,
10800 },
10801 [ALC888_LENOVO_MS7195_DIG] = {
10802 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10803 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10804 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10805 .dac_nids = alc883_dac_nids,
10806 .dig_out_nid = ALC883_DIGOUT_NID,
10807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10808 .channel_mode = alc883_3ST_6ch_modes,
10809 .need_dac_fix = 1,
10810 .input_mux = &alc883_capture_source,
10811 .unsol_event = alc_sku_unsol_event,
10812 .setup = alc888_lenovo_ms7195_setup,
10813 .init_hook = alc_inithook,
10814 },
10815 [ALC883_HAIER_W66] = {
10816 .mixers = { alc883_targa_2ch_mixer},
10817 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10818 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10819 .dac_nids = alc883_dac_nids,
10820 .dig_out_nid = ALC883_DIGOUT_NID,
10821 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10822 .channel_mode = alc883_3ST_2ch_modes,
10823 .input_mux = &alc883_capture_source,
10824 .unsol_event = alc_sku_unsol_event,
10825 .setup = alc883_haier_w66_setup,
10826 .init_hook = alc_hp_automute,
10827 },
10828 [ALC888_3ST_HP] = {
10829 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10830 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10832 .dac_nids = alc883_dac_nids,
10833 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10834 .channel_mode = alc888_3st_hp_modes,
10835 .need_dac_fix = 1,
10836 .input_mux = &alc883_capture_source,
10837 .unsol_event = alc_sku_unsol_event,
10838 .setup = alc888_3st_hp_setup,
10839 .init_hook = alc_hp_automute,
10840 },
10841 [ALC888_6ST_DELL] = {
10842 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10843 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
10846 .dig_out_nid = ALC883_DIGOUT_NID,
10847 .dig_in_nid = ALC883_DIGIN_NID,
10848 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10849 .channel_mode = alc883_sixstack_modes,
10850 .input_mux = &alc883_capture_source,
10851 .unsol_event = alc_sku_unsol_event,
10852 .setup = alc888_6st_dell_setup,
10853 .init_hook = alc_hp_automute,
10854 },
10855 [ALC883_MITAC] = {
10856 .mixers = { alc883_mitac_mixer },
10857 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859 .dac_nids = alc883_dac_nids,
10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10861 .channel_mode = alc883_3ST_2ch_modes,
10862 .input_mux = &alc883_capture_source,
10863 .unsol_event = alc_sku_unsol_event,
10864 .setup = alc883_mitac_setup,
10865 .init_hook = alc_hp_automute,
10866 },
10867 [ALC883_FUJITSU_PI2515] = {
10868 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10869 .init_verbs = { alc883_init_verbs,
10870 alc883_2ch_fujitsu_pi2515_verbs},
10871 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10872 .dac_nids = alc883_dac_nids,
10873 .dig_out_nid = ALC883_DIGOUT_NID,
10874 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10875 .channel_mode = alc883_3ST_2ch_modes,
10876 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10877 .unsol_event = alc_sku_unsol_event,
10878 .setup = alc883_2ch_fujitsu_pi2515_setup,
10879 .init_hook = alc_hp_automute,
10880 },
10881 [ALC888_FUJITSU_XA3530] = {
10882 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10883 .init_verbs = { alc883_init_verbs,
10884 alc888_fujitsu_xa3530_verbs },
10885 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10886 .dac_nids = alc883_dac_nids,
10887 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10888 .adc_nids = alc883_adc_nids_rev,
10889 .capsrc_nids = alc883_capsrc_nids_rev,
10890 .dig_out_nid = ALC883_DIGOUT_NID,
10891 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10892 .channel_mode = alc888_4ST_8ch_intel_modes,
10893 .num_mux_defs =
10894 ARRAY_SIZE(alc888_2_capture_sources),
10895 .input_mux = alc888_2_capture_sources,
10896 .unsol_event = alc_sku_unsol_event,
10897 .setup = alc888_fujitsu_xa3530_setup,
10898 .init_hook = alc_hp_automute,
10899 },
10900 [ALC888_LENOVO_SKY] = {
10901 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10902 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10903 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904 .dac_nids = alc883_dac_nids,
10905 .dig_out_nid = ALC883_DIGOUT_NID,
10906 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10907 .channel_mode = alc883_sixstack_modes,
10908 .need_dac_fix = 1,
10909 .input_mux = &alc883_lenovo_sky_capture_source,
10910 .unsol_event = alc_sku_unsol_event,
10911 .setup = alc888_lenovo_sky_setup,
10912 .init_hook = alc_hp_automute,
10913 },
10914 [ALC888_ASUS_M90V] = {
10915 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10916 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10917 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10918 .dac_nids = alc883_dac_nids,
10919 .dig_out_nid = ALC883_DIGOUT_NID,
10920 .dig_in_nid = ALC883_DIGIN_NID,
10921 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10922 .channel_mode = alc883_3ST_6ch_modes,
10923 .need_dac_fix = 1,
10924 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10925 .unsol_event = alc_sku_unsol_event,
10926 .setup = alc883_mode2_setup,
10927 .init_hook = alc_inithook,
10928 },
10929 [ALC888_ASUS_EEE1601] = {
10930 .mixers = { alc883_asus_eee1601_mixer },
10931 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10932 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10933 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10934 .dac_nids = alc883_dac_nids,
10935 .dig_out_nid = ALC883_DIGOUT_NID,
10936 .dig_in_nid = ALC883_DIGIN_NID,
10937 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10938 .channel_mode = alc883_3ST_2ch_modes,
10939 .need_dac_fix = 1,
10940 .input_mux = &alc883_asus_eee1601_capture_source,
10941 .unsol_event = alc_sku_unsol_event,
10942 .init_hook = alc883_eee1601_inithook,
10943 },
10944 [ALC1200_ASUS_P5Q] = {
10945 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10946 .init_verbs = { alc883_init_verbs },
10947 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10948 .dac_nids = alc883_dac_nids,
10949 .dig_out_nid = ALC1200_DIGOUT_NID,
10950 .dig_in_nid = ALC883_DIGIN_NID,
10951 .slave_dig_outs = alc1200_slave_dig_outs,
10952 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10953 .channel_mode = alc883_sixstack_modes,
10954 .input_mux = &alc883_capture_source,
10955 },
10956 [ALC889A_MB31] = {
10957 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10958 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10959 alc880_gpio1_init_verbs },
10960 .adc_nids = alc883_adc_nids,
10961 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10962 .capsrc_nids = alc883_capsrc_nids,
10963 .dac_nids = alc883_dac_nids,
10964 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10965 .channel_mode = alc889A_mb31_6ch_modes,
10966 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10967 .input_mux = &alc889A_mb31_capture_source,
10968 .dig_out_nid = ALC883_DIGOUT_NID,
10969 .unsol_event = alc889A_mb31_unsol_event,
10970 .init_hook = alc889A_mb31_automute,
10971 },
10972 [ALC883_SONY_VAIO_TT] = {
10973 .mixers = { alc883_vaiott_mixer },
10974 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10975 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10976 .dac_nids = alc883_dac_nids,
10977 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10978 .channel_mode = alc883_3ST_2ch_modes,
10979 .input_mux = &alc883_capture_source,
10980 .unsol_event = alc_sku_unsol_event,
10981 .setup = alc883_vaiott_setup,
10982 .init_hook = alc_hp_automute,
10983 },
10984};
10985
10986
10987/* 3854/*
10988 * Pin config fixes 3855 * Pin config fixes
10989 */ 3856 */
@@ -11036,255 +3903,19 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11036/* 3903/*
11037 * BIOS auto configuration 3904 * BIOS auto configuration
11038 */ 3905 */
11039static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11040 const struct auto_pin_cfg *cfg)
11041{
11042 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11043}
11044
11045static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11046 hda_nid_t nid, int pin_type,
11047 hda_nid_t dac)
11048{
11049 int idx;
11050
11051 /* set as output */
11052 alc_set_pin_output(codec, nid, pin_type);
11053
11054 if (dac == 0x25)
11055 idx = 4;
11056 else if (dac >= 0x02 && dac <= 0x05)
11057 idx = dac - 2;
11058 else
11059 return;
11060 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11061}
11062
11063static void alc882_auto_init_multi_out(struct hda_codec *codec)
11064{
11065 struct alc_spec *spec = codec->spec;
11066 int i;
11067
11068 for (i = 0; i <= HDA_SIDE; i++) {
11069 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11070 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11071 if (nid)
11072 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11073 spec->multiout.dac_nids[i]);
11074 }
11075}
11076
11077static void alc882_auto_init_hp_out(struct hda_codec *codec)
11078{
11079 struct alc_spec *spec = codec->spec;
11080 hda_nid_t pin, dac;
11081 int i;
11082
11083 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11084 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11085 pin = spec->autocfg.hp_pins[i];
11086 if (!pin)
11087 break;
11088 dac = spec->multiout.hp_nid;
11089 if (!dac)
11090 dac = spec->multiout.dac_nids[0]; /* to front */
11091 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11092 }
11093 }
11094
11095 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11096 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11097 pin = spec->autocfg.speaker_pins[i];
11098 if (!pin)
11099 break;
11100 dac = spec->multiout.extra_out_nid[0];
11101 if (!dac)
11102 dac = spec->multiout.dac_nids[0]; /* to front */
11103 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11104 }
11105 }
11106}
11107
11108static void alc882_auto_init_analog_input(struct hda_codec *codec)
11109{
11110 struct alc_spec *spec = codec->spec;
11111 struct auto_pin_cfg *cfg = &spec->autocfg;
11112 int i;
11113
11114 for (i = 0; i < cfg->num_inputs; i++) {
11115 hda_nid_t nid = cfg->inputs[i].pin;
11116 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11117 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11118 snd_hda_codec_write(codec, nid, 0,
11119 AC_VERB_SET_AMP_GAIN_MUTE,
11120 AMP_OUT_MUTE);
11121 }
11122}
11123
11124static void alc882_auto_init_input_src(struct hda_codec *codec)
11125{
11126 struct alc_spec *spec = codec->spec;
11127 int c;
11128
11129 for (c = 0; c < spec->num_adc_nids; c++) {
11130 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11131 hda_nid_t nid = spec->capsrc_nids[c];
11132 unsigned int mux_idx;
11133 const struct hda_input_mux *imux;
11134 int conns, mute, idx, item;
11135
11136 /* mute ADC */
11137 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11138 AC_VERB_SET_AMP_GAIN_MUTE,
11139 AMP_IN_MUTE(0));
11140
11141 conns = snd_hda_get_connections(codec, nid, conn_list,
11142 ARRAY_SIZE(conn_list));
11143 if (conns < 0)
11144 continue;
11145 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11146 imux = &spec->input_mux[mux_idx];
11147 if (!imux->num_items && mux_idx > 0)
11148 imux = &spec->input_mux[0];
11149 for (idx = 0; idx < conns; idx++) {
11150 /* if the current connection is the selected one,
11151 * unmute it as default - otherwise mute it
11152 */
11153 mute = AMP_IN_MUTE(idx);
11154 for (item = 0; item < imux->num_items; item++) {
11155 if (imux->items[item].index == idx) {
11156 if (spec->cur_mux[c] == item)
11157 mute = AMP_IN_UNMUTE(idx);
11158 break;
11159 }
11160 }
11161 /* check if we have a selector or mixer
11162 * we could check for the widget type instead, but
11163 * just check for Amp-In presence (in case of mixer
11164 * without amp-in there is something wrong, this
11165 * function shouldn't be used or capsrc nid is wrong)
11166 */
11167 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11168 snd_hda_codec_write(codec, nid, 0,
11169 AC_VERB_SET_AMP_GAIN_MUTE,
11170 mute);
11171 else if (mute != AMP_IN_MUTE(idx))
11172 snd_hda_codec_write(codec, nid, 0,
11173 AC_VERB_SET_CONNECT_SEL,
11174 idx);
11175 }
11176 }
11177}
11178
11179/* add mic boosts if needed */
11180static int alc_auto_add_mic_boost(struct hda_codec *codec)
11181{
11182 struct alc_spec *spec = codec->spec;
11183 struct auto_pin_cfg *cfg = &spec->autocfg;
11184 int i, err;
11185 int type_idx = 0;
11186 hda_nid_t nid;
11187 const char *prev_label = NULL;
11188
11189 for (i = 0; i < cfg->num_inputs; i++) {
11190 if (cfg->inputs[i].type > AUTO_PIN_MIC)
11191 break;
11192 nid = cfg->inputs[i].pin;
11193 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11194 const char *label;
11195 char boost_label[32];
11196
11197 label = hda_get_autocfg_input_label(codec, cfg, i);
11198 if (prev_label && !strcmp(label, prev_label))
11199 type_idx++;
11200 else
11201 type_idx = 0;
11202 prev_label = label;
11203
11204 snprintf(boost_label, sizeof(boost_label),
11205 "%s Boost Volume", label);
11206 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11207 boost_label, type_idx,
11208 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11209 if (err < 0)
11210 return err;
11211 }
11212 }
11213 return 0;
11214}
11215
11216/* almost identical with ALC880 parser... */ 3906/* almost identical with ALC880 parser... */
11217static int alc882_parse_auto_config(struct hda_codec *codec) 3907static int alc882_parse_auto_config(struct hda_codec *codec)
11218{ 3908{
11219 struct alc_spec *spec = codec->spec;
11220 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 3909 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11221 int err; 3910 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
11222 3911 return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids);
11223 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11224 alc882_ignore);
11225 if (err < 0)
11226 return err;
11227 if (!spec->autocfg.line_outs)
11228 return 0; /* can't find valid BIOS pin config */
11229
11230 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11231 if (err < 0)
11232 return err;
11233 err = alc_auto_add_multi_channel_mode(codec);
11234 if (err < 0)
11235 return err;
11236 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11237 if (err < 0)
11238 return err;
11239 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11240 "Headphone");
11241 if (err < 0)
11242 return err;
11243 err = alc880_auto_create_extra_out(spec,
11244 spec->autocfg.speaker_pins[0],
11245 "Speaker");
11246 if (err < 0)
11247 return err;
11248 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11249 if (err < 0)
11250 return err;
11251
11252 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11253
11254 alc_auto_parse_digital(codec);
11255
11256 if (spec->kctls.list)
11257 add_mixer(spec, spec->kctls.list);
11258
11259 add_verb(spec, alc883_auto_init_verbs);
11260 /* if ADC 0x07 is available, initialize it, too */
11261 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11262 add_verb(spec, alc882_adc1_init_verbs);
11263
11264 spec->num_mux_defs = 1;
11265 spec->input_mux = &spec->private_imux[0];
11266
11267 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11268
11269 err = alc_auto_add_mic_boost(codec);
11270 if (err < 0)
11271 return err;
11272
11273 return 1; /* config found */
11274} 3912}
11275 3913
11276/* additional initialization for auto-configuration model */ 3914/*
11277static void alc882_auto_init(struct hda_codec *codec) 3915 */
11278{ 3916#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
11279 struct alc_spec *spec = codec->spec; 3917#include "alc882_quirks.c"
11280 alc882_auto_init_multi_out(codec); 3918#endif
11281 alc882_auto_init_hp_out(codec);
11282 alc882_auto_init_analog_input(codec);
11283 alc882_auto_init_input_src(codec);
11284 alc_auto_init_digital(codec);
11285 if (spec->unsol_event)
11286 alc_inithook(codec);
11287}
11288 3919
11289static int patch_alc882(struct hda_codec *codec) 3920static int patch_alc882(struct hda_codec *codec)
11290{ 3921{
@@ -11297,6 +3928,8 @@ static int patch_alc882(struct hda_codec *codec)
11297 3928
11298 codec->spec = spec; 3929 codec->spec = spec;
11299 3930
3931 spec->mixer_nid = 0x0b;
3932
11300 switch (codec->vendor_id) { 3933 switch (codec->vendor_id) {
11301 case 0x10ec0882: 3934 case 0x10ec0882:
11302 case 0x10ec0885: 3935 case 0x10ec0885:
@@ -11307,106 +3940,71 @@ static int patch_alc882(struct hda_codec *codec)
11307 break; 3940 break;
11308 } 3941 }
11309 3942
11310 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 3943 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
11311 alc882_models, 3944 alc882_models, alc882_cfg_tbl);
11312 alc882_cfg_tbl);
11313 3945
11314 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 3946 if (board_config < 0)
11315 board_config = snd_hda_check_board_codec_sid_config(codec, 3947 board_config = alc_board_codec_sid_config(codec,
11316 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 3948 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11317 3949
11318 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 3950 if (board_config < 0) {
11319 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3951 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11320 codec->chip_name); 3952 codec->chip_name);
11321 board_config = ALC882_AUTO; 3953 board_config = ALC_MODEL_AUTO;
11322 } 3954 }
11323 3955
11324 if (board_config == ALC882_AUTO) { 3956 if (board_config == ALC_MODEL_AUTO) {
11325 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 3957 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11326 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3958 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11327 } 3959 }
11328 3960
11329 alc_auto_parse_customize_define(codec); 3961 alc_auto_parse_customize_define(codec);
11330 3962
11331 if (board_config == ALC882_AUTO) { 3963 if (board_config == ALC_MODEL_AUTO) {
11332 /* automatic parse from the BIOS config */ 3964 /* automatic parse from the BIOS config */
11333 err = alc882_parse_auto_config(codec); 3965 err = alc882_parse_auto_config(codec);
11334 if (err < 0) { 3966 if (err < 0) {
11335 alc_free(codec); 3967 alc_free(codec);
11336 return err; 3968 return err;
11337 } else if (!err) { 3969 }
3970#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3971 else if (!err) {
11338 printk(KERN_INFO 3972 printk(KERN_INFO
11339 "hda_codec: Cannot set up configuration " 3973 "hda_codec: Cannot set up configuration "
11340 "from BIOS. Using base mode...\n"); 3974 "from BIOS. Using base mode...\n");
11341 board_config = ALC882_3ST_DIG; 3975 board_config = ALC882_3ST_DIG;
11342 } 3976 }
3977#endif
11343 } 3978 }
11344 3979
11345 if (has_cdefine_beep(codec)) { 3980 if (board_config != ALC_MODEL_AUTO)
11346 err = snd_hda_attach_beep_device(codec, 0x1);
11347 if (err < 0) {
11348 alc_free(codec);
11349 return err;
11350 }
11351 }
11352
11353 if (board_config != ALC882_AUTO)
11354 setup_preset(codec, &alc882_presets[board_config]); 3981 setup_preset(codec, &alc882_presets[board_config]);
11355 3982
11356 spec->stream_analog_playback = &alc882_pcm_analog_playback; 3983 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
11357 spec->stream_analog_capture = &alc882_pcm_analog_capture; 3984 alc_auto_fill_adc_caps(codec);
11358 /* FIXME: setup DAC5 */ 3985 alc_rebuild_imux_for_auto_mic(codec);
11359 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 3986 alc_remove_invalid_adc_nids(codec);
11360 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11361
11362 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11363 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11364
11365 if (!spec->adc_nids && spec->input_mux) {
11366 int i, j;
11367 spec->num_adc_nids = 0;
11368 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11369 const struct hda_input_mux *imux = spec->input_mux;
11370 hda_nid_t cap;
11371 hda_nid_t items[16];
11372 hda_nid_t nid = alc882_adc_nids[i];
11373 unsigned int wcap = get_wcaps(codec, nid);
11374 /* get type */
11375 wcap = get_wcaps_type(wcap);
11376 if (wcap != AC_WID_AUD_IN)
11377 continue;
11378 spec->private_adc_nids[spec->num_adc_nids] = nid;
11379 err = snd_hda_get_connections(codec, nid, &cap, 1);
11380 if (err < 0)
11381 continue;
11382 err = snd_hda_get_connections(codec, cap, items,
11383 ARRAY_SIZE(items));
11384 if (err < 0)
11385 continue;
11386 for (j = 0; j < imux->num_items; j++)
11387 if (imux->items[j].index >= err)
11388 break;
11389 if (j < imux->num_items)
11390 continue;
11391 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11392 spec->num_adc_nids++;
11393 }
11394 spec->adc_nids = spec->private_adc_nids;
11395 spec->capsrc_nids = spec->private_capsrc_nids;
11396 } 3987 }
11397 3988
11398 set_capture_mixer(codec); 3989 if (!spec->no_analog && !spec->cap_mixer)
3990 set_capture_mixer(codec);
11399 3991
11400 if (has_cdefine_beep(codec)) 3992 if (!spec->no_analog && has_cdefine_beep(codec)) {
3993 err = snd_hda_attach_beep_device(codec, 0x1);
3994 if (err < 0) {
3995 alc_free(codec);
3996 return err;
3997 }
11401 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3998 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
3999 }
11402 4000
11403 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4001 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11404 4002
11405 spec->vmaster_nid = 0x0c; 4003 spec->vmaster_nid = 0x0c;
11406 4004
11407 codec->patch_ops = alc_patch_ops; 4005 codec->patch_ops = alc_patch_ops;
11408 if (board_config == ALC882_AUTO) 4006 if (board_config == ALC_MODEL_AUTO)
11409 spec->init_hook = alc882_auto_init; 4007 spec->init_hook = alc_auto_init_std;
11410 4008
11411 alc_init_jacks(codec); 4009 alc_init_jacks(codec);
11412#ifdef CONFIG_SND_HDA_POWER_SAVE 4010#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -11421,1192 +4019,13 @@ static int patch_alc882(struct hda_codec *codec)
11421/* 4019/*
11422 * ALC262 support 4020 * ALC262 support
11423 */ 4021 */
11424 4022static int alc262_parse_auto_config(struct hda_codec *codec)
11425#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11426#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11427
11428#define alc262_dac_nids alc260_dac_nids
11429#define alc262_adc_nids alc882_adc_nids
11430#define alc262_adc_nids_alt alc882_adc_nids_alt
11431#define alc262_capsrc_nids alc882_capsrc_nids
11432#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11433
11434#define alc262_modes alc260_modes
11435#define alc262_capture_source alc882_capture_source
11436
11437static const hda_nid_t alc262_dmic_adc_nids[1] = {
11438 /* ADC0 */
11439 0x09
11440};
11441
11442static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11443
11444static const struct snd_kcontrol_new alc262_base_mixer[] = {
11445 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11448 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11457 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11459 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11460 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11461 { } /* end */
11462};
11463
11464/* update HP, line and mono-out pins according to the master switch */
11465#define alc262_hp_master_update alc260_hp_master_update
11466
11467static void alc262_hp_bpc_setup(struct hda_codec *codec)
11468{
11469 struct alc_spec *spec = codec->spec;
11470
11471 spec->autocfg.hp_pins[0] = 0x1b;
11472 spec->autocfg.speaker_pins[0] = 0x16;
11473 spec->automute = 1;
11474 spec->automute_mode = ALC_AUTOMUTE_PIN;
11475}
11476
11477static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11478{
11479 struct alc_spec *spec = codec->spec;
11480
11481 spec->autocfg.hp_pins[0] = 0x15;
11482 spec->autocfg.speaker_pins[0] = 0x16;
11483 spec->automute = 1;
11484 spec->automute_mode = ALC_AUTOMUTE_PIN;
11485}
11486
11487#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11488#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11489
11490#define ALC262_HP_MASTER_SWITCH \
11491 { \
11492 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11493 .name = "Master Playback Switch", \
11494 .info = snd_ctl_boolean_mono_info, \
11495 .get = alc262_hp_master_sw_get, \
11496 .put = alc262_hp_master_sw_put, \
11497 }, \
11498 { \
11499 .iface = NID_MAPPING, \
11500 .name = "Master Playback Switch", \
11501 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11502 }
11503
11504
11505static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11506 ALC262_HP_MASTER_SWITCH,
11507 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11509 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11511 HDA_OUTPUT),
11512 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11513 HDA_OUTPUT),
11514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11517 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11518 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11519 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11520 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11522 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11523 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11524 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11525 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11526 { } /* end */
11527};
11528
11529static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11530 ALC262_HP_MASTER_SWITCH,
11531 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11532 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11535 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11536 HDA_OUTPUT),
11537 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11538 HDA_OUTPUT),
11539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11541 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11544 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11545 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11546 { } /* end */
11547};
11548
11549static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11550 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11551 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11552 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11553 { } /* end */
11554};
11555
11556/* mute/unmute internal speaker according to the hp jack and mute state */
11557static void alc262_hp_t5735_setup(struct hda_codec *codec)
11558{
11559 struct alc_spec *spec = codec->spec;
11560
11561 spec->autocfg.hp_pins[0] = 0x15;
11562 spec->autocfg.speaker_pins[0] = 0x14;
11563 spec->automute = 1;
11564 spec->automute_mode = ALC_AUTOMUTE_PIN;
11565}
11566
11567static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11568 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11569 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11570 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11571 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11572 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11574 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11575 { } /* end */
11576};
11577
11578static const struct hda_verb alc262_hp_t5735_verbs[] = {
11579 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11581
11582 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11583 { }
11584};
11585
11586static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11587 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11588 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11589 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11590 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11591 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11592 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11593 { } /* end */
11594};
11595
11596static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11597 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11598 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11599 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11600 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11601 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11602 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11604 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11606 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11607 {}
11608};
11609
11610static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11611 .num_items = 1,
11612 .items = {
11613 { "Line", 0x1 },
11614 },
11615};
11616
11617/* bind hp and internal speaker mute (with plug check) as master switch */
11618#define alc262_hippo_master_update alc262_hp_master_update
11619#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11620#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11621
11622#define ALC262_HIPPO_MASTER_SWITCH \
11623 { \
11624 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11625 .name = "Master Playback Switch", \
11626 .info = snd_ctl_boolean_mono_info, \
11627 .get = alc262_hippo_master_sw_get, \
11628 .put = alc262_hippo_master_sw_put, \
11629 }, \
11630 { \
11631 .iface = NID_MAPPING, \
11632 .name = "Master Playback Switch", \
11633 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11634 (SUBDEV_SPEAKER(0) << 16), \
11635 }
11636
11637static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11638 ALC262_HIPPO_MASTER_SWITCH,
11639 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11640 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11641 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11642 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11643 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11644 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11645 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11646 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11648 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11649 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11650 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11651 { } /* end */
11652};
11653
11654static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11655 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11656 ALC262_HIPPO_MASTER_SWITCH,
11657 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11658 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11660 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11663 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11666 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11667 { } /* end */
11668};
11669
11670/* mute/unmute internal speaker according to the hp jack and mute state */
11671static void alc262_hippo_setup(struct hda_codec *codec)
11672{
11673 struct alc_spec *spec = codec->spec;
11674
11675 spec->autocfg.hp_pins[0] = 0x15;
11676 spec->autocfg.speaker_pins[0] = 0x14;
11677 spec->automute = 1;
11678 spec->automute_mode = ALC_AUTOMUTE_AMP;
11679}
11680
11681static void alc262_hippo1_setup(struct hda_codec *codec)
11682{
11683 struct alc_spec *spec = codec->spec;
11684
11685 spec->autocfg.hp_pins[0] = 0x1b;
11686 spec->autocfg.speaker_pins[0] = 0x14;
11687 spec->automute = 1;
11688 spec->automute_mode = ALC_AUTOMUTE_AMP;
11689}
11690
11691
11692static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11693 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11694 ALC262_HIPPO_MASTER_SWITCH,
11695 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11696 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11697 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11698 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11699 { } /* end */
11700};
11701
11702static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11703 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11704 ALC262_HIPPO_MASTER_SWITCH,
11705 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11708 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11709 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11710 { } /* end */
11711};
11712
11713static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11714 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11715 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11716 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11717 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11718 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11719 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11722 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11723 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11725 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11726 { } /* end */
11727};
11728
11729static const struct hda_verb alc262_tyan_verbs[] = {
11730 /* Headphone automute */
11731 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11732 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11733 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11734
11735 /* P11 AUX_IN, white 4-pin connector */
11736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11737 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11738 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11739 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11740
11741 {}
11742};
11743
11744/* unsolicited event for HP jack sensing */
11745static void alc262_tyan_setup(struct hda_codec *codec)
11746{
11747 struct alc_spec *spec = codec->spec;
11748
11749 spec->autocfg.hp_pins[0] = 0x1b;
11750 spec->autocfg.speaker_pins[0] = 0x15;
11751 spec->automute = 1;
11752 spec->automute_mode = ALC_AUTOMUTE_AMP;
11753}
11754
11755
11756#define alc262_capture_mixer alc882_capture_mixer
11757#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11758
11759/*
11760 * generic initialization of ADC, input mixers and output mixers
11761 */
11762static const struct hda_verb alc262_init_verbs[] = {
11763 /*
11764 * Unmute ADC0-2 and set the default input to mic-in
11765 */
11766 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11767 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11768 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11769 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11770 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11771 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11772
11773 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11774 * mixer widget
11775 * Note: PASD motherboards uses the Line In 2 as the input for
11776 * front panel mic (mic 2)
11777 */
11778 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11779 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11780 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11781 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11782 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11783 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11784
11785 /*
11786 * Set up output mixers (0x0c - 0x0e)
11787 */
11788 /* set vol=0 to output mixers */
11789 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11790 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11792 /* set up input amps for analog loopback */
11793 /* Amp Indices: DAC = 0, mixer = 1 */
11794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11797 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11798 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11799 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11800
11801 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11802 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11803 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11805 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11806 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11807
11808 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11809 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11810 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11811 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11812 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11813
11814 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11816
11817 /* FIXME: use matrix-type input source selection */
11818 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11819 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11820 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11821 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11822 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11823 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11824 /* Input mixer2 */
11825 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11826 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11827 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11828 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11829 /* Input mixer3 */
11830 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11831 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11833 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11834
11835 { }
11836};
11837
11838static const struct hda_verb alc262_eapd_verbs[] = {
11839 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11840 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11841 { }
11842};
11843
11844static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11846 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11847 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11848
11849 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11850 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11851 {}
11852};
11853
11854static const struct hda_verb alc262_sony_unsol_verbs[] = {
11855 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11858
11859 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11860 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11861 {}
11862};
11863
11864static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11865 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11866 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11867 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11868 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11869 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11870 { } /* end */
11871};
11872
11873static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11874 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11875 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11878 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11879 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11880 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11881 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11882 {}
11883};
11884
11885static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11886{
11887 struct alc_spec *spec = codec->spec;
11888
11889 spec->autocfg.hp_pins[0] = 0x15;
11890 spec->autocfg.speaker_pins[0] = 0x14;
11891 spec->ext_mic.pin = 0x18;
11892 spec->ext_mic.mux_idx = 0;
11893 spec->int_mic.pin = 0x12;
11894 spec->int_mic.mux_idx = 9;
11895 spec->auto_mic = 1;
11896 spec->automute = 1;
11897 spec->automute_mode = ALC_AUTOMUTE_PIN;
11898}
11899
11900/*
11901 * nec model
11902 * 0x15 = headphone
11903 * 0x16 = internal speaker
11904 * 0x18 = external mic
11905 */
11906
11907static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11908 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11909 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11910
11911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11913 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11914
11915 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11917 { } /* end */
11918};
11919
11920static const struct hda_verb alc262_nec_verbs[] = {
11921 /* Unmute Speaker */
11922 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11923
11924 /* Headphone */
11925 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11926 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11927
11928 /* External mic to headphone */
11929 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11930 /* External mic to speaker */
11931 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11932 {}
11933};
11934
11935/*
11936 * fujitsu model
11937 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11938 * 0x1b = port replicator headphone out
11939 */
11940
11941#define ALC_HP_EVENT ALC880_HP_EVENT
11942
11943static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11944 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11945 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11946 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11947 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11948 {}
11949};
11950
11951static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11952 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11953 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11954 {}
11955};
11956
11957static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11958 /* Front Mic pin: input vref at 50% */
11959 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11960 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11961 {}
11962};
11963
11964static const struct hda_input_mux alc262_fujitsu_capture_source = {
11965 .num_items = 3,
11966 .items = {
11967 { "Mic", 0x0 },
11968 { "Internal Mic", 0x1 },
11969 { "CD", 0x4 },
11970 },
11971};
11972
11973static const struct hda_input_mux alc262_HP_capture_source = {
11974 .num_items = 5,
11975 .items = {
11976 { "Mic", 0x0 },
11977 { "Front Mic", 0x1 },
11978 { "Line", 0x2 },
11979 { "CD", 0x4 },
11980 { "AUX IN", 0x6 },
11981 },
11982};
11983
11984static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11985 .num_items = 4,
11986 .items = {
11987 { "Mic", 0x0 },
11988 { "Front Mic", 0x2 },
11989 { "Line", 0x1 },
11990 { "CD", 0x4 },
11991 },
11992};
11993
11994static void alc262_fujitsu_setup(struct hda_codec *codec)
11995{
11996 struct alc_spec *spec = codec->spec;
11997
11998 spec->autocfg.hp_pins[0] = 0x14;
11999 spec->autocfg.hp_pins[1] = 0x1b;
12000 spec->autocfg.speaker_pins[0] = 0x15;
12001 spec->automute = 1;
12002 spec->automute_mode = ALC_AUTOMUTE_AMP;
12003}
12004
12005/* bind volumes of both NID 0x0c and 0x0d */
12006static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
12007 .ops = &snd_hda_bind_vol,
12008 .values = {
12009 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
12010 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
12011 0
12012 },
12013};
12014
12015static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12016 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12017 {
12018 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12019 .name = "Master Playback Switch",
12020 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12021 .info = snd_ctl_boolean_mono_info,
12022 .get = alc262_hp_master_sw_get,
12023 .put = alc262_hp_master_sw_put,
12024 },
12025 {
12026 .iface = NID_MAPPING,
12027 .name = "Master Playback Switch",
12028 .private_value = 0x1b,
12029 },
12030 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12031 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12032 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12035 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12036 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12037 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12038 { } /* end */
12039};
12040
12041static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12042{
12043 struct alc_spec *spec = codec->spec;
12044
12045 spec->autocfg.hp_pins[0] = 0x1b;
12046 spec->autocfg.speaker_pins[0] = 0x14;
12047 spec->autocfg.speaker_pins[1] = 0x16;
12048 spec->automute = 1;
12049 spec->automute_mode = ALC_AUTOMUTE_AMP;
12050}
12051
12052static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12053 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12054 {
12055 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12056 .name = "Master Playback Switch",
12057 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12058 .info = snd_ctl_boolean_mono_info,
12059 .get = alc262_hp_master_sw_get,
12060 .put = alc262_hp_master_sw_put,
12061 },
12062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12065 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12067 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12068 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12069 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12070 { } /* end */
12071};
12072
12073static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12074 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12075 ALC262_HIPPO_MASTER_SWITCH,
12076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12077 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12078 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12079 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12080 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12081 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12082 { } /* end */
12083};
12084
12085/* additional init verbs for Benq laptops */
12086static const struct hda_verb alc262_EAPD_verbs[] = {
12087 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12088 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12089 {}
12090};
12091
12092static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12095
12096 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12097 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12098 {}
12099};
12100
12101/* Samsung Q1 Ultra Vista model setup */
12102static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12103 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12104 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12105 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12106 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12107 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12108 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12109 { } /* end */
12110};
12111
12112static const struct hda_verb alc262_ultra_verbs[] = {
12113 /* output mixer */
12114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12116 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12117 /* speaker */
12118 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12119 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12120 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12121 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12122 /* HP */
12123 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12124 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12125 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12126 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12127 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12128 /* internal mic */
12129 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12130 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12131 /* ADC, choose mic */
12132 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12133 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12134 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12135 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12136 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12142 {}
12143};
12144
12145/* mute/unmute internal speaker according to the hp jack and mute state */
12146static void alc262_ultra_automute(struct hda_codec *codec)
12147{
12148 struct alc_spec *spec = codec->spec;
12149 unsigned int mute;
12150
12151 mute = 0;
12152 /* auto-mute only when HP is used as HP */
12153 if (!spec->cur_mux[0]) {
12154 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12155 if (spec->jack_present)
12156 mute = HDA_AMP_MUTE;
12157 }
12158 /* mute/unmute internal speaker */
12159 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12160 HDA_AMP_MUTE, mute);
12161 /* mute/unmute HP */
12162 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12163 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12164}
12165
12166/* unsolicited event for HP jack sensing */
12167static void alc262_ultra_unsol_event(struct hda_codec *codec,
12168 unsigned int res)
12169{
12170 if ((res >> 26) != ALC880_HP_EVENT)
12171 return;
12172 alc262_ultra_automute(codec);
12173}
12174
12175static const struct hda_input_mux alc262_ultra_capture_source = {
12176 .num_items = 2,
12177 .items = {
12178 { "Mic", 0x1 },
12179 { "Headphone", 0x7 },
12180 },
12181};
12182
12183static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12184 struct snd_ctl_elem_value *ucontrol)
12185{
12186 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12187 struct alc_spec *spec = codec->spec;
12188 int ret;
12189
12190 ret = alc_mux_enum_put(kcontrol, ucontrol);
12191 if (!ret)
12192 return 0;
12193 /* reprogram the HP pin as mic or HP according to the input source */
12194 snd_hda_codec_write_cache(codec, 0x15, 0,
12195 AC_VERB_SET_PIN_WIDGET_CONTROL,
12196 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12197 alc262_ultra_automute(codec); /* mute/unmute HP */
12198 return ret;
12199}
12200
12201static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12202 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12203 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12204 {
12205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12206 .name = "Capture Source",
12207 .info = alc_mux_enum_info,
12208 .get = alc_mux_enum_get,
12209 .put = alc262_ultra_mux_enum_put,
12210 },
12211 {
12212 .iface = NID_MAPPING,
12213 .name = "Capture Source",
12214 .private_value = 0x15,
12215 },
12216 { } /* end */
12217};
12218
12219/* We use two mixers depending on the output pin; 0x16 is a mono output
12220 * and thus it's bound with a different mixer.
12221 * This function returns which mixer amp should be used.
12222 */
12223static int alc262_check_volbit(hda_nid_t nid)
12224{
12225 if (!nid)
12226 return 0;
12227 else if (nid == 0x16)
12228 return 2;
12229 else
12230 return 1;
12231}
12232
12233static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12234 const char *pfx, int *vbits, int idx)
12235{
12236 unsigned long val;
12237 int vbit;
12238
12239 vbit = alc262_check_volbit(nid);
12240 if (!vbit)
12241 return 0;
12242 if (*vbits & vbit) /* a volume control for this mixer already there */
12243 return 0;
12244 *vbits |= vbit;
12245 if (vbit == 2)
12246 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12247 else
12248 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12249 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12250}
12251
12252static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12253 const char *pfx, int idx)
12254{
12255 unsigned long val;
12256
12257 if (!nid)
12258 return 0;
12259 if (nid == 0x16)
12260 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12261 else
12262 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12263 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12264}
12265
12266/* add playback controls from the parsed DAC table */
12267static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12268 const struct auto_pin_cfg *cfg)
12269{ 4023{
12270 const char *pfx; 4024 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12271 int vbits; 4025 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
12272 int i, err; 4026 return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids);
12273
12274 spec->multiout.num_dacs = 1; /* only use one dac */
12275 spec->multiout.dac_nids = spec->private_dac_nids;
12276 spec->private_dac_nids[0] = 2;
12277
12278 pfx = alc_get_line_out_pfx(spec, true);
12279 if (!pfx)
12280 pfx = "Front";
12281 for (i = 0; i < 2; i++) {
12282 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12283 if (err < 0)
12284 return err;
12285 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12286 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12287 "Speaker", i);
12288 if (err < 0)
12289 return err;
12290 }
12291 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12292 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12293 "Headphone", i);
12294 if (err < 0)
12295 return err;
12296 }
12297 }
12298
12299 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12300 alc262_check_volbit(cfg->speaker_pins[0]) |
12301 alc262_check_volbit(cfg->hp_pins[0]);
12302 if (vbits == 1 || vbits == 2)
12303 pfx = "Master"; /* only one mixer is used */
12304 vbits = 0;
12305 for (i = 0; i < 2; i++) {
12306 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12307 &vbits, i);
12308 if (err < 0)
12309 return err;
12310 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12311 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12312 "Speaker", &vbits, i);
12313 if (err < 0)
12314 return err;
12315 }
12316 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12317 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12318 "Headphone", &vbits, i);
12319 if (err < 0)
12320 return err;
12321 }
12322 }
12323 return 0;
12324} 4027}
12325 4028
12326#define alc262_auto_create_input_ctls \
12327 alc882_auto_create_input_ctls
12328
12329/*
12330 * generic initialization of ADC, input mixers and output mixers
12331 */
12332static const struct hda_verb alc262_volume_init_verbs[] = {
12333 /*
12334 * Unmute ADC0-2 and set the default input to mic-in
12335 */
12336 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12338 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12339 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12340 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342
12343 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12344 * mixer widget
12345 * Note: PASD motherboards uses the Line In 2 as the input for
12346 * front panel mic (mic 2)
12347 */
12348 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12352 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12353 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12354
12355 /*
12356 * Set up output mixers (0x0c - 0x0f)
12357 */
12358 /* set vol=0 to output mixers */
12359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12361 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12362
12363 /* set up input amps for analog loopback */
12364 /* Amp Indices: DAC = 0, mixer = 1 */
12365 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12366 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12367 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12368 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12370 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12371
12372 /* FIXME: use matrix-type input source selection */
12373 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12374 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12375 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12376 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12377 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12378 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12379 /* Input mixer2 */
12380 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12381 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12382 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12383 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12384 /* Input mixer3 */
12385 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12387 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12388 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12389
12390 { }
12391};
12392
12393static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12394 /*
12395 * Unmute ADC0-2 and set the default input to mic-in
12396 */
12397 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12398 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12399 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12400 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12401 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12402 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12403
12404 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12405 * mixer widget
12406 * Note: PASD motherboards uses the Line In 2 as the input for
12407 * front panel mic (mic 2)
12408 */
12409 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12410 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12411 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12412 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12413 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12414 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12415 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12416 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12417
12418 /*
12419 * Set up output mixers (0x0c - 0x0e)
12420 */
12421 /* set vol=0 to output mixers */
12422 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12423 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12425
12426 /* set up input amps for analog loopback */
12427 /* Amp Indices: DAC = 0, mixer = 1 */
12428 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12431 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12434
12435 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12436 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12437 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12438
12439 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12440 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12441
12442 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12444
12445 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12446 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12447 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12448 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12449 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12450
12451 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12453 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12454 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12455 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12456 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12457
12458
12459 /* FIXME: use matrix-type input source selection */
12460 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12461 /* Input mixer1: only unmute Mic */
12462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12463 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12464 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12465 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12466 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12467 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12468 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12469 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12471 /* Input mixer2 */
12472 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12473 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12474 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12479 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12480 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12481 /* Input mixer3 */
12482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12484 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12485 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12486 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12487 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12488 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12491
12492 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12493
12494 { }
12495};
12496
12497static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12498 /*
12499 * Unmute ADC0-2 and set the default input to mic-in
12500 */
12501 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12503 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12504 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12505 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12506 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12507
12508 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12509 * mixer widget
12510 * Note: PASD motherboards uses the Line In 2 as the input for front
12511 * panel mic (mic 2)
12512 */
12513 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12514 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12515 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12516 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12517 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12518 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12519 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12520 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12521 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12522 /*
12523 * Set up output mixers (0x0c - 0x0e)
12524 */
12525 /* set vol=0 to output mixers */
12526 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12527 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12528 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12529
12530 /* set up input amps for analog loopback */
12531 /* Amp Indices: DAC = 0, mixer = 1 */
12532 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12533 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12534 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12535 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12536 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12537 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12538
12539
12540 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12541 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12542 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12543 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12544 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12545 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12546 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12547
12548 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12549 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12550
12551 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12552 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12553
12554 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12556 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12558 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12559 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12560
12561 /* FIXME: use matrix-type input source selection */
12562 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12563 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12564 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12565 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12566 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12567 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12568 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12569 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12570 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12571 /* Input mixer2 */
12572 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12573 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12574 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12575 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12576 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12577 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12578 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12579 /* Input mixer3 */
12580 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12581 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12585 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12587
12588 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12589
12590 { }
12591};
12592
12593static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12594
12595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12597 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12598
12599 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12600 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12601 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12602 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12603
12604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12605 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12606 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12607 {}
12608};
12609
12610/* 4029/*
12611 * Pin config fixes 4030 * Pin config fixes
12612 */ 4031 */
@@ -12645,396 +4064,11 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12645#define alc262_loopbacks alc880_loopbacks 4064#define alc262_loopbacks alc880_loopbacks
12646#endif 4065#endif
12647 4066
12648/* pcm configuration: identical with ALC880 */
12649#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12650#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12651#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12652#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12653
12654/* 4067/*
12655 * BIOS auto configuration
12656 */ 4068 */
12657static int alc262_parse_auto_config(struct hda_codec *codec) 4069#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
12658{ 4070#include "alc262_quirks.c"
12659 struct alc_spec *spec = codec->spec;
12660 int err;
12661 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12662
12663 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12664 alc262_ignore);
12665 if (err < 0)
12666 return err;
12667 if (!spec->autocfg.line_outs) {
12668 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12669 spec->multiout.max_channels = 2;
12670 spec->no_analog = 1;
12671 goto dig_only;
12672 }
12673 return 0; /* can't find valid BIOS pin config */
12674 }
12675 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12676 if (err < 0)
12677 return err;
12678 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12679 if (err < 0)
12680 return err;
12681
12682 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12683
12684 dig_only:
12685 alc_auto_parse_digital(codec);
12686
12687 if (spec->kctls.list)
12688 add_mixer(spec, spec->kctls.list);
12689
12690 add_verb(spec, alc262_volume_init_verbs);
12691 spec->num_mux_defs = 1;
12692 spec->input_mux = &spec->private_imux[0];
12693
12694 err = alc_auto_add_mic_boost(codec);
12695 if (err < 0)
12696 return err;
12697
12698 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12699
12700 return 1;
12701}
12702
12703#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12704#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12705#define alc262_auto_init_analog_input alc882_auto_init_analog_input
12706#define alc262_auto_init_input_src alc882_auto_init_input_src
12707
12708
12709/* init callback for auto-configuration model -- overriding the default init */
12710static void alc262_auto_init(struct hda_codec *codec)
12711{
12712 struct alc_spec *spec = codec->spec;
12713 alc262_auto_init_multi_out(codec);
12714 alc262_auto_init_hp_out(codec);
12715 alc262_auto_init_analog_input(codec);
12716 alc262_auto_init_input_src(codec);
12717 alc_auto_init_digital(codec);
12718 if (spec->unsol_event)
12719 alc_inithook(codec);
12720}
12721
12722/*
12723 * configuration and preset
12724 */
12725static const char * const alc262_models[ALC262_MODEL_LAST] = {
12726 [ALC262_BASIC] = "basic",
12727 [ALC262_HIPPO] = "hippo",
12728 [ALC262_HIPPO_1] = "hippo_1",
12729 [ALC262_FUJITSU] = "fujitsu",
12730 [ALC262_HP_BPC] = "hp-bpc",
12731 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12732 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12733 [ALC262_HP_RP5700] = "hp-rp5700",
12734 [ALC262_BENQ_ED8] = "benq",
12735 [ALC262_BENQ_T31] = "benq-t31",
12736 [ALC262_SONY_ASSAMD] = "sony-assamd",
12737 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12738 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12739 [ALC262_ULTRA] = "ultra",
12740 [ALC262_LENOVO_3000] = "lenovo-3000",
12741 [ALC262_NEC] = "nec",
12742 [ALC262_TYAN] = "tyan",
12743 [ALC262_AUTO] = "auto",
12744};
12745
12746static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12747 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12748 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12749 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12750 ALC262_HP_BPC),
12751 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12752 ALC262_HP_BPC),
12753 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12754 ALC262_HP_BPC),
12755 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12756 ALC262_AUTO),
12757 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12758 ALC262_HP_BPC),
12759 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12760 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12761 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12762 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12763 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12764 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12765 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12766 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12767 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12768 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12769 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12770 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12771 ALC262_HP_TC_T5735),
12772 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12773 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12774 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12775 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12776 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12777 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12778 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12779 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12780#if 0 /* disable the quirk since model=auto works better in recent versions */
12781 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12782 ALC262_SONY_ASSAMD),
12783#endif 4071#endif
12784 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12785 ALC262_TOSHIBA_RX1),
12786 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12787 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12788 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12789 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12790 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12791 ALC262_ULTRA),
12792 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12793 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12794 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12795 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12796 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12797 {}
12798};
12799
12800static const struct alc_config_preset alc262_presets[] = {
12801 [ALC262_BASIC] = {
12802 .mixers = { alc262_base_mixer },
12803 .init_verbs = { alc262_init_verbs },
12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805 .dac_nids = alc262_dac_nids,
12806 .hp_nid = 0x03,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
12810 },
12811 [ALC262_HIPPO] = {
12812 .mixers = { alc262_hippo_mixer },
12813 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815 .dac_nids = alc262_dac_nids,
12816 .hp_nid = 0x03,
12817 .dig_out_nid = ALC262_DIGOUT_NID,
12818 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12819 .channel_mode = alc262_modes,
12820 .input_mux = &alc262_capture_source,
12821 .unsol_event = alc_sku_unsol_event,
12822 .setup = alc262_hippo_setup,
12823 .init_hook = alc_inithook,
12824 },
12825 [ALC262_HIPPO_1] = {
12826 .mixers = { alc262_hippo1_mixer },
12827 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12828 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12829 .dac_nids = alc262_dac_nids,
12830 .hp_nid = 0x02,
12831 .dig_out_nid = ALC262_DIGOUT_NID,
12832 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12833 .channel_mode = alc262_modes,
12834 .input_mux = &alc262_capture_source,
12835 .unsol_event = alc_sku_unsol_event,
12836 .setup = alc262_hippo1_setup,
12837 .init_hook = alc_inithook,
12838 },
12839 [ALC262_FUJITSU] = {
12840 .mixers = { alc262_fujitsu_mixer },
12841 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12842 alc262_fujitsu_unsol_verbs },
12843 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12844 .dac_nids = alc262_dac_nids,
12845 .hp_nid = 0x03,
12846 .dig_out_nid = ALC262_DIGOUT_NID,
12847 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12848 .channel_mode = alc262_modes,
12849 .input_mux = &alc262_fujitsu_capture_source,
12850 .unsol_event = alc_sku_unsol_event,
12851 .setup = alc262_fujitsu_setup,
12852 .init_hook = alc_inithook,
12853 },
12854 [ALC262_HP_BPC] = {
12855 .mixers = { alc262_HP_BPC_mixer },
12856 .init_verbs = { alc262_HP_BPC_init_verbs },
12857 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12858 .dac_nids = alc262_dac_nids,
12859 .hp_nid = 0x03,
12860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12861 .channel_mode = alc262_modes,
12862 .input_mux = &alc262_HP_capture_source,
12863 .unsol_event = alc_sku_unsol_event,
12864 .setup = alc262_hp_bpc_setup,
12865 .init_hook = alc_inithook,
12866 },
12867 [ALC262_HP_BPC_D7000_WF] = {
12868 .mixers = { alc262_HP_BPC_WildWest_mixer },
12869 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12870 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12871 .dac_nids = alc262_dac_nids,
12872 .hp_nid = 0x03,
12873 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12874 .channel_mode = alc262_modes,
12875 .input_mux = &alc262_HP_D7000_capture_source,
12876 .unsol_event = alc_sku_unsol_event,
12877 .setup = alc262_hp_wildwest_setup,
12878 .init_hook = alc_inithook,
12879 },
12880 [ALC262_HP_BPC_D7000_WL] = {
12881 .mixers = { alc262_HP_BPC_WildWest_mixer,
12882 alc262_HP_BPC_WildWest_option_mixer },
12883 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12884 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12885 .dac_nids = alc262_dac_nids,
12886 .hp_nid = 0x03,
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
12889 .input_mux = &alc262_HP_D7000_capture_source,
12890 .unsol_event = alc_sku_unsol_event,
12891 .setup = alc262_hp_wildwest_setup,
12892 .init_hook = alc_inithook,
12893 },
12894 [ALC262_HP_TC_T5735] = {
12895 .mixers = { alc262_hp_t5735_mixer },
12896 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12897 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12898 .dac_nids = alc262_dac_nids,
12899 .hp_nid = 0x03,
12900 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12901 .channel_mode = alc262_modes,
12902 .input_mux = &alc262_capture_source,
12903 .unsol_event = alc_sku_unsol_event,
12904 .setup = alc262_hp_t5735_setup,
12905 .init_hook = alc_inithook,
12906 },
12907 [ALC262_HP_RP5700] = {
12908 .mixers = { alc262_hp_rp5700_mixer },
12909 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12910 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12911 .dac_nids = alc262_dac_nids,
12912 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12913 .channel_mode = alc262_modes,
12914 .input_mux = &alc262_hp_rp5700_capture_source,
12915 },
12916 [ALC262_BENQ_ED8] = {
12917 .mixers = { alc262_base_mixer },
12918 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12919 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12920 .dac_nids = alc262_dac_nids,
12921 .hp_nid = 0x03,
12922 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12923 .channel_mode = alc262_modes,
12924 .input_mux = &alc262_capture_source,
12925 },
12926 [ALC262_SONY_ASSAMD] = {
12927 .mixers = { alc262_sony_mixer },
12928 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12929 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12930 .dac_nids = alc262_dac_nids,
12931 .hp_nid = 0x02,
12932 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12933 .channel_mode = alc262_modes,
12934 .input_mux = &alc262_capture_source,
12935 .unsol_event = alc_sku_unsol_event,
12936 .setup = alc262_hippo_setup,
12937 .init_hook = alc_inithook,
12938 },
12939 [ALC262_BENQ_T31] = {
12940 .mixers = { alc262_benq_t31_mixer },
12941 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12942 alc_hp15_unsol_verbs },
12943 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12944 .dac_nids = alc262_dac_nids,
12945 .hp_nid = 0x03,
12946 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12947 .channel_mode = alc262_modes,
12948 .input_mux = &alc262_capture_source,
12949 .unsol_event = alc_sku_unsol_event,
12950 .setup = alc262_hippo_setup,
12951 .init_hook = alc_inithook,
12952 },
12953 [ALC262_ULTRA] = {
12954 .mixers = { alc262_ultra_mixer },
12955 .cap_mixer = alc262_ultra_capture_mixer,
12956 .init_verbs = { alc262_ultra_verbs },
12957 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12958 .dac_nids = alc262_dac_nids,
12959 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12960 .channel_mode = alc262_modes,
12961 .input_mux = &alc262_ultra_capture_source,
12962 .adc_nids = alc262_adc_nids, /* ADC0 */
12963 .capsrc_nids = alc262_capsrc_nids,
12964 .num_adc_nids = 1, /* single ADC */
12965 .unsol_event = alc262_ultra_unsol_event,
12966 .init_hook = alc262_ultra_automute,
12967 },
12968 [ALC262_LENOVO_3000] = {
12969 .mixers = { alc262_lenovo_3000_mixer },
12970 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12971 alc262_lenovo_3000_unsol_verbs,
12972 alc262_lenovo_3000_init_verbs },
12973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12974 .dac_nids = alc262_dac_nids,
12975 .hp_nid = 0x03,
12976 .dig_out_nid = ALC262_DIGOUT_NID,
12977 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12978 .channel_mode = alc262_modes,
12979 .input_mux = &alc262_fujitsu_capture_source,
12980 .unsol_event = alc_sku_unsol_event,
12981 .setup = alc262_lenovo_3000_setup,
12982 .init_hook = alc_inithook,
12983 },
12984 [ALC262_NEC] = {
12985 .mixers = { alc262_nec_mixer },
12986 .init_verbs = { alc262_nec_verbs },
12987 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12988 .dac_nids = alc262_dac_nids,
12989 .hp_nid = 0x03,
12990 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12991 .channel_mode = alc262_modes,
12992 .input_mux = &alc262_capture_source,
12993 },
12994 [ALC262_TOSHIBA_S06] = {
12995 .mixers = { alc262_toshiba_s06_mixer },
12996 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12997 alc262_eapd_verbs },
12998 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12999 .capsrc_nids = alc262_dmic_capsrc_nids,
13000 .dac_nids = alc262_dac_nids,
13001 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
13002 .num_adc_nids = 1, /* single ADC */
13003 .dig_out_nid = ALC262_DIGOUT_NID,
13004 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13005 .channel_mode = alc262_modes,
13006 .unsol_event = alc_sku_unsol_event,
13007 .setup = alc262_toshiba_s06_setup,
13008 .init_hook = alc_inithook,
13009 },
13010 [ALC262_TOSHIBA_RX1] = {
13011 .mixers = { alc262_toshiba_rx1_mixer },
13012 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
13013 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13014 .dac_nids = alc262_dac_nids,
13015 .hp_nid = 0x03,
13016 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13017 .channel_mode = alc262_modes,
13018 .input_mux = &alc262_capture_source,
13019 .unsol_event = alc_sku_unsol_event,
13020 .setup = alc262_hippo_setup,
13021 .init_hook = alc_inithook,
13022 },
13023 [ALC262_TYAN] = {
13024 .mixers = { alc262_tyan_mixer },
13025 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13026 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13027 .dac_nids = alc262_dac_nids,
13028 .hp_nid = 0x02,
13029 .dig_out_nid = ALC262_DIGOUT_NID,
13030 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13031 .channel_mode = alc262_modes,
13032 .input_mux = &alc262_capture_source,
13033 .unsol_event = alc_sku_unsol_event,
13034 .setup = alc262_tyan_setup,
13035 .init_hook = alc_hp_automute,
13036 },
13037};
13038 4072
13039static int patch_alc262(struct hda_codec *codec) 4073static int patch_alc262(struct hda_codec *codec)
13040{ 4074{
@@ -13047,6 +4081,9 @@ static int patch_alc262(struct hda_codec *codec)
13047 return -ENOMEM; 4081 return -ENOMEM;
13048 4082
13049 codec->spec = spec; 4083 codec->spec = spec;
4084
4085 spec->mixer_nid = 0x0b;
4086
13050#if 0 4087#if 0
13051 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 4088 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13052 * under-run 4089 * under-run
@@ -13063,96 +4100,65 @@ static int patch_alc262(struct hda_codec *codec)
13063 4100
13064 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 4101 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13065 4102
13066 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 4103 board_config = alc_board_config(codec, ALC262_MODEL_LAST,
13067 alc262_models, 4104 alc262_models, alc262_cfg_tbl);
13068 alc262_cfg_tbl);
13069 4105
13070 if (board_config < 0) { 4106 if (board_config < 0) {
13071 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4107 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13072 codec->chip_name); 4108 codec->chip_name);
13073 board_config = ALC262_AUTO; 4109 board_config = ALC_MODEL_AUTO;
13074 } 4110 }
13075 4111
13076 if (board_config == ALC262_AUTO) { 4112 if (board_config == ALC_MODEL_AUTO) {
13077 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 4113 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13078 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4114 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13079 } 4115 }
13080 4116
13081 if (board_config == ALC262_AUTO) { 4117 if (board_config == ALC_MODEL_AUTO) {
13082 /* automatic parse from the BIOS config */ 4118 /* automatic parse from the BIOS config */
13083 err = alc262_parse_auto_config(codec); 4119 err = alc262_parse_auto_config(codec);
13084 if (err < 0) { 4120 if (err < 0) {
13085 alc_free(codec); 4121 alc_free(codec);
13086 return err; 4122 return err;
13087 } else if (!err) { 4123 }
4124#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4125 else if (!err) {
13088 printk(KERN_INFO 4126 printk(KERN_INFO
13089 "hda_codec: Cannot set up configuration " 4127 "hda_codec: Cannot set up configuration "
13090 "from BIOS. Using base mode...\n"); 4128 "from BIOS. Using base mode...\n");
13091 board_config = ALC262_BASIC; 4129 board_config = ALC262_BASIC;
13092 } 4130 }
4131#endif
4132 }
4133
4134 if (board_config != ALC_MODEL_AUTO)
4135 setup_preset(codec, &alc262_presets[board_config]);
4136
4137 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
4138 alc_auto_fill_adc_caps(codec);
4139 alc_rebuild_imux_for_auto_mic(codec);
4140 alc_remove_invalid_adc_nids(codec);
13093 } 4141 }
13094 4142
4143 if (!spec->no_analog && !spec->cap_mixer)
4144 set_capture_mixer(codec);
4145
13095 if (!spec->no_analog && has_cdefine_beep(codec)) { 4146 if (!spec->no_analog && has_cdefine_beep(codec)) {
13096 err = snd_hda_attach_beep_device(codec, 0x1); 4147 err = snd_hda_attach_beep_device(codec, 0x1);
13097 if (err < 0) { 4148 if (err < 0) {
13098 alc_free(codec); 4149 alc_free(codec);
13099 return err; 4150 return err;
13100 } 4151 }
13101 }
13102
13103 if (board_config != ALC262_AUTO)
13104 setup_preset(codec, &alc262_presets[board_config]);
13105
13106 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13107 spec->stream_analog_capture = &alc262_pcm_analog_capture;
13108
13109 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13110 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13111
13112 if (!spec->adc_nids && spec->input_mux) {
13113 int i;
13114 /* check whether the digital-mic has to be supported */
13115 for (i = 0; i < spec->input_mux->num_items; i++) {
13116 if (spec->input_mux->items[i].index >= 9)
13117 break;
13118 }
13119 if (i < spec->input_mux->num_items) {
13120 /* use only ADC0 */
13121 spec->adc_nids = alc262_dmic_adc_nids;
13122 spec->num_adc_nids = 1;
13123 spec->capsrc_nids = alc262_dmic_capsrc_nids;
13124 } else {
13125 /* all analog inputs */
13126 /* check whether NID 0x07 is valid */
13127 unsigned int wcap = get_wcaps(codec, 0x07);
13128
13129 /* get type */
13130 wcap = get_wcaps_type(wcap);
13131 if (wcap != AC_WID_AUD_IN) {
13132 spec->adc_nids = alc262_adc_nids_alt;
13133 spec->num_adc_nids =
13134 ARRAY_SIZE(alc262_adc_nids_alt);
13135 spec->capsrc_nids = alc262_capsrc_nids_alt;
13136 } else {
13137 spec->adc_nids = alc262_adc_nids;
13138 spec->num_adc_nids =
13139 ARRAY_SIZE(alc262_adc_nids);
13140 spec->capsrc_nids = alc262_capsrc_nids;
13141 }
13142 }
13143 }
13144 if (!spec->cap_mixer && !spec->no_analog)
13145 set_capture_mixer(codec);
13146 if (!spec->no_analog && has_cdefine_beep(codec))
13147 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4152 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4153 }
13148 4154
13149 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4155 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13150 4156
13151 spec->vmaster_nid = 0x0c; 4157 spec->vmaster_nid = 0x0c;
13152 4158
13153 codec->patch_ops = alc_patch_ops; 4159 codec->patch_ops = alc_patch_ops;
13154 if (board_config == ALC262_AUTO) 4160 if (board_config == ALC_MODEL_AUTO)
13155 spec->init_hook = alc262_auto_init; 4161 spec->init_hook = alc_auto_init_std;
13156 spec->shutup = alc_eapd_shutup; 4162 spec->shutup = alc_eapd_shutup;
13157 4163
13158 alc_init_jacks(codec); 4164 alc_init_jacks(codec);
@@ -13165,51 +4171,8 @@ static int patch_alc262(struct hda_codec *codec)
13165} 4171}
13166 4172
13167/* 4173/*
13168 * ALC268 channel source setting (2 channel) 4174 * ALC268
13169 */ 4175 */
13170#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13171#define alc268_modes alc260_modes
13172
13173static const hda_nid_t alc268_dac_nids[2] = {
13174 /* front, hp */
13175 0x02, 0x03
13176};
13177
13178static const hda_nid_t alc268_adc_nids[2] = {
13179 /* ADC0-1 */
13180 0x08, 0x07
13181};
13182
13183static const hda_nid_t alc268_adc_nids_alt[1] = {
13184 /* ADC0 */
13185 0x08
13186};
13187
13188static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13189
13190static const struct snd_kcontrol_new alc268_base_mixer[] = {
13191 /* output mixer control */
13192 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13193 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13195 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13196 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13197 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13198 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13199 { }
13200};
13201
13202static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13203 /* output mixer control */
13204 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13205 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13206 ALC262_HIPPO_MASTER_SWITCH,
13207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13208 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13209 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13210 { }
13211};
13212
13213/* bind Beep switches of both NID 0x0f and 0x10 */ 4176/* bind Beep switches of both NID 0x0f and 0x10 */
13214static const struct hda_bind_ctls alc268_bind_beep_sw = { 4177static const struct hda_bind_ctls alc268_bind_beep_sw = {
13215 .ops = &snd_hda_bind_sw, 4178 .ops = &snd_hda_bind_sw,
@@ -13226,846 +4189,36 @@ static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13226 { } 4189 { }
13227}; 4190};
13228 4191
13229static const struct hda_verb alc268_eapd_verbs[] = { 4192/* set PCBEEP vol = 0, mute connections */
13230 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 4193static const struct hda_verb alc268_beep_init_verbs[] = {
13231 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13232 { }
13233};
13234
13235/* Toshiba specific */
13236static const struct hda_verb alc268_toshiba_verbs[] = {
13237 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13238 { } /* end */
13239};
13240
13241/* Acer specific */
13242/* bind volumes of both NID 0x02 and 0x03 */
13243static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13244 .ops = &snd_hda_bind_vol,
13245 .values = {
13246 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13247 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13248 0
13249 },
13250};
13251
13252static void alc268_acer_setup(struct hda_codec *codec)
13253{
13254 struct alc_spec *spec = codec->spec;
13255
13256 spec->autocfg.hp_pins[0] = 0x14;
13257 spec->autocfg.speaker_pins[0] = 0x15;
13258 spec->automute = 1;
13259 spec->automute_mode = ALC_AUTOMUTE_AMP;
13260}
13261
13262#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13263#define alc268_acer_master_sw_put alc262_hp_master_sw_put
13264
13265static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13266 /* output mixer control */
13267 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13268 {
13269 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13270 .name = "Master Playback Switch",
13271 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13272 .info = snd_ctl_boolean_mono_info,
13273 .get = alc268_acer_master_sw_get,
13274 .put = alc268_acer_master_sw_put,
13275 },
13276 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13277 { }
13278};
13279
13280static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13281 /* output mixer control */
13282 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13283 {
13284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13285 .name = "Master Playback Switch",
13286 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13287 .info = snd_ctl_boolean_mono_info,
13288 .get = alc268_acer_master_sw_get,
13289 .put = alc268_acer_master_sw_put,
13290 },
13291 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13292 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13293 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13294 { }
13295};
13296
13297static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13298 /* output mixer control */
13299 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13300 {
13301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13302 .name = "Master Playback Switch",
13303 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13304 .info = snd_ctl_boolean_mono_info,
13305 .get = alc268_acer_master_sw_get,
13306 .put = alc268_acer_master_sw_put,
13307 },
13308 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13309 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13310 { }
13311};
13312
13313static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13314 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13315 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13316 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13317 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13318 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13320 { }
13321};
13322
13323static const struct hda_verb alc268_acer_verbs[] = {
13324 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13325 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13328 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13329 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13330 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13331 { }
13332};
13333
13334/* unsolicited event for HP jack sensing */
13335#define alc268_toshiba_setup alc262_hippo_setup
13336
13337static void alc268_acer_lc_setup(struct hda_codec *codec)
13338{
13339 struct alc_spec *spec = codec->spec;
13340 spec->autocfg.hp_pins[0] = 0x15;
13341 spec->autocfg.speaker_pins[0] = 0x14;
13342 spec->automute = 1;
13343 spec->automute_mode = ALC_AUTOMUTE_AMP;
13344 spec->ext_mic.pin = 0x18;
13345 spec->ext_mic.mux_idx = 0;
13346 spec->int_mic.pin = 0x12;
13347 spec->int_mic.mux_idx = 6;
13348 spec->auto_mic = 1;
13349}
13350
13351static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13352 /* output mixer control */
13353 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13354 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13355 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13357 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13358 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13359 { }
13360};
13361
13362static const struct hda_verb alc268_dell_verbs[] = {
13363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13366 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13367 { }
13368};
13369
13370/* mute/unmute internal speaker according to the hp jack and mute state */
13371static void alc268_dell_setup(struct hda_codec *codec)
13372{
13373 struct alc_spec *spec = codec->spec;
13374
13375 spec->autocfg.hp_pins[0] = 0x15;
13376 spec->autocfg.speaker_pins[0] = 0x14;
13377 spec->ext_mic.pin = 0x18;
13378 spec->ext_mic.mux_idx = 0;
13379 spec->int_mic.pin = 0x19;
13380 spec->int_mic.mux_idx = 1;
13381 spec->auto_mic = 1;
13382 spec->automute = 1;
13383 spec->automute_mode = ALC_AUTOMUTE_PIN;
13384}
13385
13386static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13387 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13388 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13389 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13391 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13392 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13393 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13394 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13395 { }
13396};
13397
13398static const struct hda_verb alc267_quanta_il1_verbs[] = {
13399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13401 { }
13402};
13403
13404static void alc267_quanta_il1_setup(struct hda_codec *codec)
13405{
13406 struct alc_spec *spec = codec->spec;
13407 spec->autocfg.hp_pins[0] = 0x15;
13408 spec->autocfg.speaker_pins[0] = 0x14;
13409 spec->ext_mic.pin = 0x18;
13410 spec->ext_mic.mux_idx = 0;
13411 spec->int_mic.pin = 0x19;
13412 spec->int_mic.mux_idx = 1;
13413 spec->auto_mic = 1;
13414 spec->automute = 1;
13415 spec->automute_mode = ALC_AUTOMUTE_PIN;
13416}
13417
13418/*
13419 * generic initialization of ADC, input mixers and output mixers
13420 */
13421static const struct hda_verb alc268_base_init_verbs[] = {
13422 /* Unmute DAC0-1 and set vol = 0 */
13423 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13424 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13425
13426 /*
13427 * Set up output mixers (0x0c - 0x0e)
13428 */
13429 /* set vol=0 to output mixers */
13430 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13431 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13432
13433 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13434 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13435
13436 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13437 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13438 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13439 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13440 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13441 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13442 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13443 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13444
13445 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13447 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13448 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13449 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13450
13451 /* set PCBEEP vol = 0, mute connections */
13452 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 4194 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4195 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13454 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4196 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13455
13456 /* Unmute Selector 23h,24h and set the default input to mic-in */
13457
13458 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13460 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13462
13463 { } 4197 { }
13464}; 4198};
13465 4199
13466/* 4200/*
13467 * generic initialization of ADC, input mixers and output mixers
13468 */
13469static const struct hda_verb alc268_volume_init_verbs[] = {
13470 /* set output DAC */
13471 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13472 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13473
13474 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13475 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13476 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13477 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13478 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13479
13480 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13482 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13483
13484 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13485 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13486
13487 /* set PCBEEP vol = 0, mute connections */
13488 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13489 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13490 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13491
13492 { }
13493};
13494
13495static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13496 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13497 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13498 { } /* end */
13499};
13500
13501static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13502 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13503 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13504 _DEFINE_CAPSRC(1),
13505 { } /* end */
13506};
13507
13508static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13509 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13510 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13511 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13512 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13513 _DEFINE_CAPSRC(2),
13514 { } /* end */
13515};
13516
13517static const struct hda_input_mux alc268_capture_source = {
13518 .num_items = 4,
13519 .items = {
13520 { "Mic", 0x0 },
13521 { "Front Mic", 0x1 },
13522 { "Line", 0x2 },
13523 { "CD", 0x3 },
13524 },
13525};
13526
13527static const struct hda_input_mux alc268_acer_capture_source = {
13528 .num_items = 3,
13529 .items = {
13530 { "Mic", 0x0 },
13531 { "Internal Mic", 0x1 },
13532 { "Line", 0x2 },
13533 },
13534};
13535
13536static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13537 .num_items = 3,
13538 .items = {
13539 { "Mic", 0x0 },
13540 { "Internal Mic", 0x6 },
13541 { "Line", 0x2 },
13542 },
13543};
13544
13545#ifdef CONFIG_SND_DEBUG
13546static const struct snd_kcontrol_new alc268_test_mixer[] = {
13547 /* Volume widgets */
13548 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13549 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13550 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13551 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13552 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13553 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13554 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13555 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13556 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13557 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13558 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13559 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13560 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13561 /* The below appears problematic on some hardwares */
13562 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13563 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13564 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13565 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13566 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13567
13568 /* Modes for retasking pin widgets */
13569 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13570 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13571 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13572 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13573
13574 /* Controls for GPIO pins, assuming they are configured as outputs */
13575 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13576 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13577 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13578 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13579
13580 /* Switches to allow the digital SPDIF output pin to be enabled.
13581 * The ALC268 does not have an SPDIF input.
13582 */
13583 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13584
13585 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13586 * this output to turn on an external amplifier.
13587 */
13588 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13589 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13590
13591 { } /* end */
13592};
13593#endif
13594
13595/* create input playback/capture controls for the given pin */
13596static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13597 const char *ctlname, int idx)
13598{
13599 hda_nid_t dac;
13600 int err;
13601
13602 switch (nid) {
13603 case 0x14:
13604 case 0x16:
13605 dac = 0x02;
13606 break;
13607 case 0x15:
13608 case 0x1a: /* ALC259/269 only */
13609 case 0x1b: /* ALC259/269 only */
13610 case 0x21: /* ALC269vb has this pin, too */
13611 dac = 0x03;
13612 break;
13613 default:
13614 snd_printd(KERN_WARNING "hda_codec: "
13615 "ignoring pin 0x%x as unknown\n", nid);
13616 return 0;
13617 }
13618 if (spec->multiout.dac_nids[0] != dac &&
13619 spec->multiout.dac_nids[1] != dac) {
13620 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13621 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13622 HDA_OUTPUT));
13623 if (err < 0)
13624 return err;
13625 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13626 }
13627
13628 if (nid != 0x16)
13629 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13630 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13631 else /* mono */
13632 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13633 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13634 if (err < 0)
13635 return err;
13636 return 0;
13637}
13638
13639/* add playback controls from the parsed DAC table */
13640static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13641 const struct auto_pin_cfg *cfg)
13642{
13643 hda_nid_t nid;
13644 int err;
13645
13646 spec->multiout.dac_nids = spec->private_dac_nids;
13647
13648 nid = cfg->line_out_pins[0];
13649 if (nid) {
13650 const char *name;
13651 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13652 name = "Speaker";
13653 else
13654 name = "Front";
13655 err = alc268_new_analog_output(spec, nid, name, 0);
13656 if (err < 0)
13657 return err;
13658 }
13659
13660 nid = cfg->speaker_pins[0];
13661 if (nid == 0x1d) {
13662 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13663 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13664 if (err < 0)
13665 return err;
13666 } else if (nid) {
13667 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13668 if (err < 0)
13669 return err;
13670 }
13671 nid = cfg->hp_pins[0];
13672 if (nid) {
13673 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13674 if (err < 0)
13675 return err;
13676 }
13677
13678 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13679 if (nid == 0x16) {
13680 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13681 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13682 if (err < 0)
13683 return err;
13684 }
13685 return 0;
13686}
13687
13688/* create playback/capture controls for input pins */
13689static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13690 const struct auto_pin_cfg *cfg)
13691{
13692 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13693}
13694
13695static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13696 hda_nid_t nid, int pin_type)
13697{
13698 int idx;
13699
13700 alc_set_pin_output(codec, nid, pin_type);
13701 if (nid == 0x14 || nid == 0x16)
13702 idx = 0;
13703 else
13704 idx = 1;
13705 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13706}
13707
13708static void alc268_auto_init_multi_out(struct hda_codec *codec)
13709{
13710 struct alc_spec *spec = codec->spec;
13711 int i;
13712
13713 for (i = 0; i < spec->autocfg.line_outs; i++) {
13714 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13715 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13716 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13717 }
13718}
13719
13720static void alc268_auto_init_hp_out(struct hda_codec *codec)
13721{
13722 struct alc_spec *spec = codec->spec;
13723 hda_nid_t pin;
13724 int i;
13725
13726 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13727 pin = spec->autocfg.hp_pins[i];
13728 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13729 }
13730 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13731 pin = spec->autocfg.speaker_pins[i];
13732 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13733 }
13734 if (spec->autocfg.mono_out_pin)
13735 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13736 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13737}
13738
13739static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13740{
13741 struct alc_spec *spec = codec->spec;
13742 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13743 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13744 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13745 unsigned int dac_vol1, dac_vol2;
13746
13747 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13748 snd_hda_codec_write(codec, speaker_nid, 0,
13749 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13750 /* mute mixer inputs from 0x1d */
13751 snd_hda_codec_write(codec, 0x0f, 0,
13752 AC_VERB_SET_AMP_GAIN_MUTE,
13753 AMP_IN_UNMUTE(1));
13754 snd_hda_codec_write(codec, 0x10, 0,
13755 AC_VERB_SET_AMP_GAIN_MUTE,
13756 AMP_IN_UNMUTE(1));
13757 } else {
13758 /* unmute mixer inputs from 0x1d */
13759 snd_hda_codec_write(codec, 0x0f, 0,
13760 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13761 snd_hda_codec_write(codec, 0x10, 0,
13762 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13763 }
13764
13765 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13766 if (line_nid == 0x14)
13767 dac_vol2 = AMP_OUT_ZERO;
13768 else if (line_nid == 0x15)
13769 dac_vol1 = AMP_OUT_ZERO;
13770 if (hp_nid == 0x14)
13771 dac_vol2 = AMP_OUT_ZERO;
13772 else if (hp_nid == 0x15)
13773 dac_vol1 = AMP_OUT_ZERO;
13774 if (line_nid != 0x16 || hp_nid != 0x16 ||
13775 spec->autocfg.line_out_pins[1] != 0x16 ||
13776 spec->autocfg.line_out_pins[2] != 0x16)
13777 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13778
13779 snd_hda_codec_write(codec, 0x02, 0,
13780 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13781 snd_hda_codec_write(codec, 0x03, 0,
13782 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13783}
13784
13785/* pcm configuration: identical with ALC880 */
13786#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13787#define alc268_pcm_analog_capture alc880_pcm_analog_capture
13788#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13789#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13790
13791/*
13792 * BIOS auto configuration 4201 * BIOS auto configuration
13793 */ 4202 */
13794static int alc268_parse_auto_config(struct hda_codec *codec) 4203static int alc268_parse_auto_config(struct hda_codec *codec)
13795{ 4204{
4205 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
13796 struct alc_spec *spec = codec->spec; 4206 struct alc_spec *spec = codec->spec;
13797 int err; 4207 int err = alc_parse_auto_config(codec, NULL, alc268_ssids);
13798 static const hda_nid_t alc268_ignore[] = { 0 }; 4208 if (err > 0) {
13799 4209 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
13800 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4210 add_mixer(spec, alc268_beep_mixer);
13801 alc268_ignore); 4211 add_verb(spec, alc268_beep_init_verbs);
13802 if (err < 0)
13803 return err;
13804 if (!spec->autocfg.line_outs) {
13805 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13806 spec->multiout.max_channels = 2;
13807 spec->no_analog = 1;
13808 goto dig_only;
13809 } 4212 }
13810 return 0; /* can't find valid BIOS pin config */
13811 } 4213 }
13812 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 4214 return err;
13813 if (err < 0)
13814 return err;
13815 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13816 if (err < 0)
13817 return err;
13818
13819 spec->multiout.max_channels = 2;
13820
13821 dig_only:
13822 /* digital only support output */
13823 alc_auto_parse_digital(codec);
13824 if (spec->kctls.list)
13825 add_mixer(spec, spec->kctls.list);
13826
13827 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13828 add_mixer(spec, alc268_beep_mixer);
13829
13830 add_verb(spec, alc268_volume_init_verbs);
13831 spec->num_mux_defs = 2;
13832 spec->input_mux = &spec->private_imux[0];
13833
13834 err = alc_auto_add_mic_boost(codec);
13835 if (err < 0)
13836 return err;
13837
13838 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13839
13840 return 1;
13841}
13842
13843#define alc268_auto_init_analog_input alc882_auto_init_analog_input
13844#define alc268_auto_init_input_src alc882_auto_init_input_src
13845
13846/* init callback for auto-configuration model -- overriding the default init */
13847static void alc268_auto_init(struct hda_codec *codec)
13848{
13849 struct alc_spec *spec = codec->spec;
13850 alc268_auto_init_multi_out(codec);
13851 alc268_auto_init_hp_out(codec);
13852 alc268_auto_init_mono_speaker_out(codec);
13853 alc268_auto_init_analog_input(codec);
13854 alc268_auto_init_input_src(codec);
13855 alc_auto_init_digital(codec);
13856 if (spec->unsol_event)
13857 alc_inithook(codec);
13858} 4215}
13859 4216
13860/* 4217/*
13861 * configuration and preset
13862 */ 4218 */
13863static const char * const alc268_models[ALC268_MODEL_LAST] = { 4219#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
13864 [ALC267_QUANTA_IL1] = "quanta-il1", 4220#include "alc268_quirks.c"
13865 [ALC268_3ST] = "3stack",
13866 [ALC268_TOSHIBA] = "toshiba",
13867 [ALC268_ACER] = "acer",
13868 [ALC268_ACER_DMIC] = "acer-dmic",
13869 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13870 [ALC268_DELL] = "dell",
13871 [ALC268_ZEPTO] = "zepto",
13872#ifdef CONFIG_SND_DEBUG
13873 [ALC268_TEST] = "test",
13874#endif 4221#endif
13875 [ALC268_AUTO] = "auto",
13876};
13877
13878static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13879 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13880 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13881 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13882 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13883 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13884 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13885 ALC268_ACER_ASPIRE_ONE),
13886 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13887 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13888 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13889 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13890 /* almost compatible with toshiba but with optional digital outs;
13891 * auto-probing seems working fine
13892 */
13893 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13894 ALC268_AUTO),
13895 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13896 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13897 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13898 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13899 {}
13900};
13901
13902/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13903static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13904 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13905 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13906 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13907 ALC268_TOSHIBA),
13908 {}
13909};
13910
13911static const struct alc_config_preset alc268_presets[] = {
13912 [ALC267_QUANTA_IL1] = {
13913 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13914 alc268_capture_nosrc_mixer },
13915 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13916 alc267_quanta_il1_verbs },
13917 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13918 .dac_nids = alc268_dac_nids,
13919 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13920 .adc_nids = alc268_adc_nids_alt,
13921 .hp_nid = 0x03,
13922 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13923 .channel_mode = alc268_modes,
13924 .unsol_event = alc_sku_unsol_event,
13925 .setup = alc267_quanta_il1_setup,
13926 .init_hook = alc_inithook,
13927 },
13928 [ALC268_3ST] = {
13929 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13930 alc268_beep_mixer },
13931 .init_verbs = { alc268_base_init_verbs },
13932 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13933 .dac_nids = alc268_dac_nids,
13934 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13935 .adc_nids = alc268_adc_nids_alt,
13936 .capsrc_nids = alc268_capsrc_nids,
13937 .hp_nid = 0x03,
13938 .dig_out_nid = ALC268_DIGOUT_NID,
13939 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13940 .channel_mode = alc268_modes,
13941 .input_mux = &alc268_capture_source,
13942 },
13943 [ALC268_TOSHIBA] = {
13944 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13945 alc268_beep_mixer },
13946 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13947 alc268_toshiba_verbs },
13948 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13949 .dac_nids = alc268_dac_nids,
13950 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13951 .adc_nids = alc268_adc_nids_alt,
13952 .capsrc_nids = alc268_capsrc_nids,
13953 .hp_nid = 0x03,
13954 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13955 .channel_mode = alc268_modes,
13956 .input_mux = &alc268_capture_source,
13957 .unsol_event = alc_sku_unsol_event,
13958 .setup = alc268_toshiba_setup,
13959 .init_hook = alc_inithook,
13960 },
13961 [ALC268_ACER] = {
13962 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13963 alc268_beep_mixer },
13964 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13965 alc268_acer_verbs },
13966 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13967 .dac_nids = alc268_dac_nids,
13968 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13969 .adc_nids = alc268_adc_nids_alt,
13970 .capsrc_nids = alc268_capsrc_nids,
13971 .hp_nid = 0x02,
13972 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13973 .channel_mode = alc268_modes,
13974 .input_mux = &alc268_acer_capture_source,
13975 .unsol_event = alc_sku_unsol_event,
13976 .setup = alc268_acer_setup,
13977 .init_hook = alc_inithook,
13978 },
13979 [ALC268_ACER_DMIC] = {
13980 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13981 alc268_beep_mixer },
13982 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13983 alc268_acer_verbs },
13984 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13985 .dac_nids = alc268_dac_nids,
13986 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13987 .adc_nids = alc268_adc_nids_alt,
13988 .capsrc_nids = alc268_capsrc_nids,
13989 .hp_nid = 0x02,
13990 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13991 .channel_mode = alc268_modes,
13992 .input_mux = &alc268_acer_dmic_capture_source,
13993 .unsol_event = alc_sku_unsol_event,
13994 .setup = alc268_acer_setup,
13995 .init_hook = alc_inithook,
13996 },
13997 [ALC268_ACER_ASPIRE_ONE] = {
13998 .mixers = { alc268_acer_aspire_one_mixer,
13999 alc268_beep_mixer,
14000 alc268_capture_nosrc_mixer },
14001 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14002 alc268_acer_aspire_one_verbs },
14003 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14004 .dac_nids = alc268_dac_nids,
14005 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14006 .adc_nids = alc268_adc_nids_alt,
14007 .capsrc_nids = alc268_capsrc_nids,
14008 .hp_nid = 0x03,
14009 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14010 .channel_mode = alc268_modes,
14011 .unsol_event = alc_sku_unsol_event,
14012 .setup = alc268_acer_lc_setup,
14013 .init_hook = alc_inithook,
14014 },
14015 [ALC268_DELL] = {
14016 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
14017 alc268_capture_nosrc_mixer },
14018 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14019 alc268_dell_verbs },
14020 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14021 .dac_nids = alc268_dac_nids,
14022 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14023 .adc_nids = alc268_adc_nids_alt,
14024 .capsrc_nids = alc268_capsrc_nids,
14025 .hp_nid = 0x02,
14026 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14027 .channel_mode = alc268_modes,
14028 .unsol_event = alc_sku_unsol_event,
14029 .setup = alc268_dell_setup,
14030 .init_hook = alc_inithook,
14031 },
14032 [ALC268_ZEPTO] = {
14033 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14034 alc268_beep_mixer },
14035 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14036 alc268_toshiba_verbs },
14037 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14038 .dac_nids = alc268_dac_nids,
14039 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14040 .adc_nids = alc268_adc_nids_alt,
14041 .capsrc_nids = alc268_capsrc_nids,
14042 .hp_nid = 0x03,
14043 .dig_out_nid = ALC268_DIGOUT_NID,
14044 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14045 .channel_mode = alc268_modes,
14046 .input_mux = &alc268_capture_source,
14047 .unsol_event = alc_sku_unsol_event,
14048 .setup = alc268_toshiba_setup,
14049 .init_hook = alc_inithook,
14050 },
14051#ifdef CONFIG_SND_DEBUG
14052 [ALC268_TEST] = {
14053 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14054 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14055 alc268_volume_init_verbs },
14056 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14057 .dac_nids = alc268_dac_nids,
14058 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14059 .adc_nids = alc268_adc_nids_alt,
14060 .capsrc_nids = alc268_capsrc_nids,
14061 .hp_nid = 0x03,
14062 .dig_out_nid = ALC268_DIGOUT_NID,
14063 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14064 .channel_mode = alc268_modes,
14065 .input_mux = &alc268_capture_source,
14066 },
14067#endif
14068};
14069 4222
14070static int patch_alc268(struct hda_codec *codec) 4223static int patch_alc268(struct hda_codec *codec)
14071{ 4224{
@@ -14079,43 +4232,41 @@ static int patch_alc268(struct hda_codec *codec)
14079 4232
14080 codec->spec = spec; 4233 codec->spec = spec;
14081 4234
14082 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 4235 /* ALC268 has no aa-loopback mixer */
14083 alc268_models, 4236
14084 alc268_cfg_tbl); 4237 board_config = alc_board_config(codec, ALC268_MODEL_LAST,
4238 alc268_models, alc268_cfg_tbl);
14085 4239
14086 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 4240 if (board_config < 0)
14087 board_config = snd_hda_check_board_codec_sid_config(codec, 4241 board_config = alc_board_codec_sid_config(codec,
14088 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 4242 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14089 4243
14090 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 4244 if (board_config < 0) {
14091 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4245 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14092 codec->chip_name); 4246 codec->chip_name);
14093 board_config = ALC268_AUTO; 4247 board_config = ALC_MODEL_AUTO;
14094 } 4248 }
14095 4249
14096 if (board_config == ALC268_AUTO) { 4250 if (board_config == ALC_MODEL_AUTO) {
14097 /* automatic parse from the BIOS config */ 4251 /* automatic parse from the BIOS config */
14098 err = alc268_parse_auto_config(codec); 4252 err = alc268_parse_auto_config(codec);
14099 if (err < 0) { 4253 if (err < 0) {
14100 alc_free(codec); 4254 alc_free(codec);
14101 return err; 4255 return err;
14102 } else if (!err) { 4256 }
4257#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4258 else if (!err) {
14103 printk(KERN_INFO 4259 printk(KERN_INFO
14104 "hda_codec: Cannot set up configuration " 4260 "hda_codec: Cannot set up configuration "
14105 "from BIOS. Using base mode...\n"); 4261 "from BIOS. Using base mode...\n");
14106 board_config = ALC268_3ST; 4262 board_config = ALC268_3ST;
14107 } 4263 }
4264#endif
14108 } 4265 }
14109 4266
14110 if (board_config != ALC268_AUTO) 4267 if (board_config != ALC_MODEL_AUTO)
14111 setup_preset(codec, &alc268_presets[board_config]); 4268 setup_preset(codec, &alc268_presets[board_config]);
14112 4269
14113 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14114 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14115 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14116
14117 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14118
14119 has_beep = 0; 4270 has_beep = 0;
14120 for (i = 0; i < spec->num_mixers; i++) { 4271 for (i = 0; i < spec->num_mixers; i++) {
14121 if (spec->mixers[i] == alc268_beep_mixer) { 4272 if (spec->mixers[i] == alc268_beep_mixer) {
@@ -14140,34 +4291,19 @@ static int patch_alc268(struct hda_codec *codec)
14140 } 4291 }
14141 4292
14142 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 4293 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14143 /* check whether NID 0x07 is valid */ 4294 alc_auto_fill_adc_caps(codec);
14144 unsigned int wcap = get_wcaps(codec, 0x07); 4295 alc_rebuild_imux_for_auto_mic(codec);
14145 4296 alc_remove_invalid_adc_nids(codec);
14146 spec->capsrc_nids = alc268_capsrc_nids;
14147 /* get type */
14148 wcap = get_wcaps_type(wcap);
14149 if (spec->auto_mic ||
14150 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14151 spec->adc_nids = alc268_adc_nids_alt;
14152 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14153 if (spec->auto_mic)
14154 fixup_automic_adc(codec);
14155 if (spec->auto_mic || spec->input_mux->num_items == 1)
14156 add_mixer(spec, alc268_capture_nosrc_mixer);
14157 else
14158 add_mixer(spec, alc268_capture_alt_mixer);
14159 } else {
14160 spec->adc_nids = alc268_adc_nids;
14161 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14162 add_mixer(spec, alc268_capture_mixer);
14163 }
14164 } 4297 }
14165 4298
4299 if (!spec->no_analog && !spec->cap_mixer)
4300 set_capture_mixer(codec);
4301
14166 spec->vmaster_nid = 0x02; 4302 spec->vmaster_nid = 0x02;
14167 4303
14168 codec->patch_ops = alc_patch_ops; 4304 codec->patch_ops = alc_patch_ops;
14169 if (board_config == ALC268_AUTO) 4305 if (board_config == ALC_MODEL_AUTO)
14170 spec->init_hook = alc268_auto_init; 4306 spec->init_hook = alc_auto_init_std;
14171 spec->shutup = alc_eapd_shutup; 4307 spec->shutup = alc_eapd_shutup;
14172 4308
14173 alc_init_jacks(codec); 4309 alc_init_jacks(codec);
@@ -14176,498 +4312,12 @@ static int patch_alc268(struct hda_codec *codec)
14176} 4312}
14177 4313
14178/* 4314/*
14179 * ALC269 channel source setting (2 channel) 4315 * ALC269
14180 */ 4316 */
14181#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14182
14183#define alc269_dac_nids alc260_dac_nids
14184
14185static const hda_nid_t alc269_adc_nids[1] = {
14186 /* ADC1 */
14187 0x08,
14188};
14189
14190static const hda_nid_t alc269_capsrc_nids[1] = {
14191 0x23,
14192};
14193
14194static const hda_nid_t alc269vb_adc_nids[1] = {
14195 /* ADC1 */
14196 0x09,
14197};
14198
14199static const hda_nid_t alc269vb_capsrc_nids[1] = {
14200 0x22,
14201};
14202
14203static const hda_nid_t alc269_adc_candidates[] = {
14204 0x08, 0x09, 0x07, 0x11,
14205};
14206
14207#define alc269_modes alc260_modes
14208#define alc269_capture_source alc880_lg_lw_capture_source
14209
14210static const struct snd_kcontrol_new alc269_base_mixer[] = {
14211 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14213 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14214 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14218 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14219 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14221 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14222 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14223 { } /* end */
14224};
14225
14226static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14227 /* output mixer control */
14228 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14229 {
14230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14231 .name = "Master Playback Switch",
14232 .subdevice = HDA_SUBDEV_AMP_FLAG,
14233 .info = snd_hda_mixer_amp_switch_info,
14234 .get = snd_hda_mixer_amp_switch_get,
14235 .put = alc268_acer_master_sw_put,
14236 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14237 },
14238 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14239 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14241 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14242 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14243 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14244 { }
14245};
14246
14247static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14248 /* output mixer control */
14249 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14250 {
14251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14252 .name = "Master Playback Switch",
14253 .subdevice = HDA_SUBDEV_AMP_FLAG,
14254 .info = snd_hda_mixer_amp_switch_info,
14255 .get = snd_hda_mixer_amp_switch_get,
14256 .put = alc268_acer_master_sw_put,
14257 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14258 },
14259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14261 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14262 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14263 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14264 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14265 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14266 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14267 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14268 { }
14269};
14270
14271static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14272 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14273 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14274 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14275 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14276 { } /* end */
14277};
14278
14279static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14280 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14281 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14282 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14284 { } /* end */
14285};
14286
14287static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14288 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14289 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14290 { } /* end */
14291};
14292
14293/* capture mixer elements */
14294static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14295 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14296 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14298 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14299 { } /* end */
14300};
14301
14302static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14303 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14304 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14306 { } /* end */
14307};
14308
14309static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14310 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14311 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14312 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14313 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14314 { } /* end */
14315};
14316
14317static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14318 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14319 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14320 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14321 { } /* end */
14322};
14323
14324/* FSC amilo */
14325#define alc269_fujitsu_mixer alc269_laptop_mixer
14326
14327static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14328 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14333 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14334 { }
14335};
14336
14337static const struct hda_verb alc269_lifebook_verbs[] = {
14338 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14339 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14340 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14342 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14344 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14345 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14346 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14347 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14348 { }
14349};
14350
14351/* toggle speaker-output according to the hp-jack state */
14352static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14353{
14354 alc_hp_automute(codec);
14355
14356 snd_hda_codec_write(codec, 0x20, 0,
14357 AC_VERB_SET_COEF_INDEX, 0x0c);
14358 snd_hda_codec_write(codec, 0x20, 0,
14359 AC_VERB_SET_PROC_COEF, 0x680);
14360
14361 snd_hda_codec_write(codec, 0x20, 0,
14362 AC_VERB_SET_COEF_INDEX, 0x0c);
14363 snd_hda_codec_write(codec, 0x20, 0,
14364 AC_VERB_SET_PROC_COEF, 0x480);
14365}
14366
14367#define alc269_lifebook_speaker_automute \
14368 alc269_quanta_fl1_speaker_automute
14369
14370static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14371{
14372 unsigned int present_laptop;
14373 unsigned int present_dock;
14374
14375 present_laptop = snd_hda_jack_detect(codec, 0x18);
14376 present_dock = snd_hda_jack_detect(codec, 0x1b);
14377
14378 /* Laptop mic port overrides dock mic port, design decision */
14379 if (present_dock)
14380 snd_hda_codec_write(codec, 0x23, 0,
14381 AC_VERB_SET_CONNECT_SEL, 0x3);
14382 if (present_laptop)
14383 snd_hda_codec_write(codec, 0x23, 0,
14384 AC_VERB_SET_CONNECT_SEL, 0x0);
14385 if (!present_dock && !present_laptop)
14386 snd_hda_codec_write(codec, 0x23, 0,
14387 AC_VERB_SET_CONNECT_SEL, 0x1);
14388}
14389
14390static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14391 unsigned int res)
14392{
14393 switch (res >> 26) {
14394 case ALC880_HP_EVENT:
14395 alc269_quanta_fl1_speaker_automute(codec);
14396 break;
14397 case ALC880_MIC_EVENT:
14398 alc_mic_automute(codec);
14399 break;
14400 }
14401}
14402
14403static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14404 unsigned int res)
14405{
14406 if ((res >> 26) == ALC880_HP_EVENT)
14407 alc269_lifebook_speaker_automute(codec);
14408 if ((res >> 26) == ALC880_MIC_EVENT)
14409 alc269_lifebook_mic_autoswitch(codec);
14410}
14411
14412static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14413{
14414 struct alc_spec *spec = codec->spec;
14415 spec->autocfg.hp_pins[0] = 0x15;
14416 spec->autocfg.speaker_pins[0] = 0x14;
14417 spec->automute_mixer_nid[0] = 0x0c;
14418 spec->automute = 1;
14419 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14420 spec->ext_mic.pin = 0x18;
14421 spec->ext_mic.mux_idx = 0;
14422 spec->int_mic.pin = 0x19;
14423 spec->int_mic.mux_idx = 1;
14424 spec->auto_mic = 1;
14425}
14426
14427static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14428{
14429 alc269_quanta_fl1_speaker_automute(codec);
14430 alc_mic_automute(codec);
14431}
14432
14433static void alc269_lifebook_setup(struct hda_codec *codec)
14434{
14435 struct alc_spec *spec = codec->spec;
14436 spec->autocfg.hp_pins[0] = 0x15;
14437 spec->autocfg.hp_pins[1] = 0x1a;
14438 spec->autocfg.speaker_pins[0] = 0x14;
14439 spec->automute_mixer_nid[0] = 0x0c;
14440 spec->automute = 1;
14441 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14442}
14443
14444static void alc269_lifebook_init_hook(struct hda_codec *codec)
14445{
14446 alc269_lifebook_speaker_automute(codec);
14447 alc269_lifebook_mic_autoswitch(codec);
14448}
14449
14450static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14451 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14452 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14453 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14454 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14455 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14456 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14457 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14458 {}
14459};
14460
14461static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14462 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14463 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14464 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14467 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14468 {}
14469};
14470
14471static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14472 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14473 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14474 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14475 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14476 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14477 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14478 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14479 {}
14480};
14481
14482static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14483 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14484 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14485 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14487 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14488 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14489 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14490 {}
14491};
14492
14493static const struct hda_verb alc271_acer_dmic_verbs[] = {
14494 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14495 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14496 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14498 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14499 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14500 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14501 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14502 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14503 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14504 { }
14505};
14506
14507static void alc269_laptop_amic_setup(struct hda_codec *codec)
14508{
14509 struct alc_spec *spec = codec->spec;
14510 spec->autocfg.hp_pins[0] = 0x15;
14511 spec->autocfg.speaker_pins[0] = 0x14;
14512 spec->automute_mixer_nid[0] = 0x0c;
14513 spec->automute = 1;
14514 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14515 spec->ext_mic.pin = 0x18;
14516 spec->ext_mic.mux_idx = 0;
14517 spec->int_mic.pin = 0x19;
14518 spec->int_mic.mux_idx = 1;
14519 spec->auto_mic = 1;
14520}
14521
14522static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14523{
14524 struct alc_spec *spec = codec->spec;
14525 spec->autocfg.hp_pins[0] = 0x15;
14526 spec->autocfg.speaker_pins[0] = 0x14;
14527 spec->automute_mixer_nid[0] = 0x0c;
14528 spec->automute = 1;
14529 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14530 spec->ext_mic.pin = 0x18;
14531 spec->ext_mic.mux_idx = 0;
14532 spec->int_mic.pin = 0x12;
14533 spec->int_mic.mux_idx = 5;
14534 spec->auto_mic = 1;
14535}
14536
14537static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14538{
14539 struct alc_spec *spec = codec->spec;
14540 spec->autocfg.hp_pins[0] = 0x21;
14541 spec->autocfg.speaker_pins[0] = 0x14;
14542 spec->automute_mixer_nid[0] = 0x0c;
14543 spec->automute = 1;
14544 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14545 spec->ext_mic.pin = 0x18;
14546 spec->ext_mic.mux_idx = 0;
14547 spec->int_mic.pin = 0x19;
14548 spec->int_mic.mux_idx = 1;
14549 spec->auto_mic = 1;
14550}
14551
14552static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14553{
14554 struct alc_spec *spec = codec->spec;
14555 spec->autocfg.hp_pins[0] = 0x21;
14556 spec->autocfg.speaker_pins[0] = 0x14;
14557 spec->automute_mixer_nid[0] = 0x0c;
14558 spec->automute = 1;
14559 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14560 spec->ext_mic.pin = 0x18;
14561 spec->ext_mic.mux_idx = 0;
14562 spec->int_mic.pin = 0x12;
14563 spec->int_mic.mux_idx = 6;
14564 spec->auto_mic = 1;
14565}
14566
14567/*
14568 * generic initialization of ADC, input mixers and output mixers
14569 */
14570static const struct hda_verb alc269_init_verbs[] = {
14571 /*
14572 * Unmute ADC0 and set the default input to mic-in
14573 */
14574 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14575
14576 /*
14577 * Set up output mixers (0x02 - 0x03)
14578 */
14579 /* set vol=0 to output mixers */
14580 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14581 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14582
14583 /* set up input amps for analog loopback */
14584 /* Amp Indices: DAC = 0, mixer = 1 */
14585 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14586 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14587 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14588 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14589 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14590 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14591
14592 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14595 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14596 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14597 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14598 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14599
14600 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14601 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14602
14603 /* FIXME: use Mux-type input source selection */
14604 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14605 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14606 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14607
14608 /* set EAPD */
14609 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14610 { }
14611};
14612
14613static const struct hda_verb alc269vb_init_verbs[] = {
14614 /*
14615 * Unmute ADC0 and set the default input to mic-in
14616 */
14617 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14618
14619 /*
14620 * Set up output mixers (0x02 - 0x03)
14621 */
14622 /* set vol=0 to output mixers */
14623 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14624 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14625
14626 /* set up input amps for analog loopback */
14627 /* Amp Indices: DAC = 0, mixer = 1 */
14628 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14629 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14630 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14631 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14632 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14633 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14634
14635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14636 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14637 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14638 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14640 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14641 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14642
14643 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14644 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14645
14646 /* FIXME: use Mux-type input source selection */
14647 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14648 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14649 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14650
14651 /* set EAPD */
14652 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14653 { }
14654};
14655
14656#define alc269_auto_create_multi_out_ctls \
14657 alc268_auto_create_multi_out_ctls
14658#define alc269_auto_create_input_ctls \
14659 alc268_auto_create_input_ctls
14660
14661#ifdef CONFIG_SND_HDA_POWER_SAVE 4317#ifdef CONFIG_SND_HDA_POWER_SAVE
14662#define alc269_loopbacks alc880_loopbacks 4318#define alc269_loopbacks alc880_loopbacks
14663#endif 4319#endif
14664 4320
14665/* pcm configuration: identical with ALC880 */
14666#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14667#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14668#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14669#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14670
14671static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { 4321static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14672 .substreams = 1, 4322 .substreams = 1,
14673 .channels_min = 2, 4323 .channels_min = 2,
@@ -14675,9 +4325,9 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14675 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 4325 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14676 /* NID is set in alc_build_pcms */ 4326 /* NID is set in alc_build_pcms */
14677 .ops = { 4327 .ops = {
14678 .open = alc880_playback_pcm_open, 4328 .open = alc_playback_pcm_open,
14679 .prepare = alc880_playback_pcm_prepare, 4329 .prepare = alc_playback_pcm_prepare,
14680 .cleanup = alc880_playback_pcm_cleanup 4330 .cleanup = alc_playback_pcm_cleanup
14681 }, 4331 },
14682}; 4332};
14683 4333
@@ -14718,44 +4368,11 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14718} 4368}
14719#endif /* CONFIG_SND_HDA_POWER_SAVE */ 4369#endif /* CONFIG_SND_HDA_POWER_SAVE */
14720 4370
14721static int alc275_setup_dual_adc(struct hda_codec *codec)
14722{
14723 struct alc_spec *spec = codec->spec;
14724
14725 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14726 return 0;
14727 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14728 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14729 if (spec->ext_mic.pin <= 0x12) {
14730 spec->private_adc_nids[0] = 0x08;
14731 spec->private_adc_nids[1] = 0x11;
14732 spec->private_capsrc_nids[0] = 0x23;
14733 spec->private_capsrc_nids[1] = 0x22;
14734 } else {
14735 spec->private_adc_nids[0] = 0x11;
14736 spec->private_adc_nids[1] = 0x08;
14737 spec->private_capsrc_nids[0] = 0x22;
14738 spec->private_capsrc_nids[1] = 0x23;
14739 }
14740 spec->adc_nids = spec->private_adc_nids;
14741 spec->capsrc_nids = spec->private_capsrc_nids;
14742 spec->num_adc_nids = 2;
14743 spec->dual_adc_switch = 1;
14744 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14745 spec->adc_nids[0], spec->adc_nids[1]);
14746 return 1;
14747 }
14748 return 0;
14749}
14750
14751/* different alc269-variants */ 4371/* different alc269-variants */
14752enum { 4372enum {
14753 ALC269_TYPE_NORMAL, 4373 ALC269_TYPE_ALC269VA,
14754 ALC269_TYPE_ALC258,
14755 ALC269_TYPE_ALC259,
14756 ALC269_TYPE_ALC269VB, 4374 ALC269_TYPE_ALC269VB,
14757 ALC269_TYPE_ALC270, 4375 ALC269_TYPE_ALC269VC,
14758 ALC269_TYPE_ALC271X,
14759}; 4376};
14760 4377
14761/* 4378/*
@@ -14763,76 +4380,14 @@ enum {
14763 */ 4380 */
14764static int alc269_parse_auto_config(struct hda_codec *codec) 4381static int alc269_parse_auto_config(struct hda_codec *codec)
14765{ 4382{
14766 struct alc_spec *spec = codec->spec;
14767 int err;
14768 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 4383 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14769 4384 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
14770 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4385 static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 };
14771 alc269_ignore);
14772 if (err < 0)
14773 return err;
14774
14775 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14776 if (err < 0)
14777 return err;
14778 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14779 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14780 else
14781 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14782 0x22, 0);
14783 if (err < 0)
14784 return err;
14785
14786 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14787
14788 alc_auto_parse_digital(codec);
14789
14790 if (spec->kctls.list)
14791 add_mixer(spec, spec->kctls.list);
14792
14793 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14794 add_verb(spec, alc269vb_init_verbs);
14795 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14796 } else {
14797 add_verb(spec, alc269_init_verbs);
14798 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14799 }
14800
14801 spec->num_mux_defs = 1;
14802 spec->input_mux = &spec->private_imux[0];
14803
14804 if (!alc275_setup_dual_adc(codec))
14805 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14806 sizeof(alc269_adc_candidates));
14807
14808 err = alc_auto_add_mic_boost(codec);
14809 if (err < 0)
14810 return err;
14811
14812 if (!spec->cap_mixer && !spec->no_analog)
14813 set_capture_mixer(codec);
14814
14815 return 1;
14816}
14817
14818#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14819#define alc269_auto_init_hp_out alc268_auto_init_hp_out
14820#define alc269_auto_init_analog_input alc882_auto_init_analog_input
14821#define alc269_auto_init_input_src alc882_auto_init_input_src
14822
14823
14824/* init callback for auto-configuration model -- overriding the default init */
14825static void alc269_auto_init(struct hda_codec *codec)
14826{
14827 struct alc_spec *spec = codec->spec; 4386 struct alc_spec *spec = codec->spec;
14828 alc269_auto_init_multi_out(codec); 4387 const hda_nid_t *ssids = spec->codec_variant == ALC269_TYPE_ALC269VA ?
14829 alc269_auto_init_hp_out(codec); 4388 alc269va_ssids : alc269_ssids;
14830 alc269_auto_init_analog_input(codec); 4389
14831 if (!spec->dual_adc_switch) 4390 return alc_parse_auto_config(codec, alc269_ignore, ssids);
14832 alc269_auto_init_input_src(codec);
14833 alc_auto_init_digital(codec);
14834 if (spec->unsol_event)
14835 alc_inithook(codec);
14836} 4391}
14837 4392
14838static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 4393static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
@@ -14908,6 +4463,21 @@ static void alc271_fixup_dmic(struct hda_codec *codec,
14908 snd_hda_sequence_write(codec, verbs); 4463 snd_hda_sequence_write(codec, verbs);
14909} 4464}
14910 4465
4466static void alc269_fixup_pcm_44k(struct hda_codec *codec,
4467 const struct alc_fixup *fix, int action)
4468{
4469 struct alc_spec *spec = codec->spec;
4470
4471 if (action != ALC_FIXUP_ACT_PROBE)
4472 return;
4473
4474 /* Due to a hardware problem on Lenovo Ideadpad, we need to
4475 * fix the sample rate of analog I/O to 44.1kHz
4476 */
4477 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
4478 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
4479}
4480
14911enum { 4481enum {
14912 ALC269_FIXUP_SONY_VAIO, 4482 ALC269_FIXUP_SONY_VAIO,
14913 ALC275_FIXUP_SONY_VAIO_GPIO2, 4483 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -14917,6 +4487,7 @@ enum {
14917 ALC269_FIXUP_LENOVO_EAPD, 4487 ALC269_FIXUP_LENOVO_EAPD,
14918 ALC275_FIXUP_SONY_HWEQ, 4488 ALC275_FIXUP_SONY_HWEQ,
14919 ALC271_FIXUP_DMIC, 4489 ALC271_FIXUP_DMIC,
4490 ALC269_FIXUP_PCM_44K,
14920}; 4491};
14921 4492
14922static const struct alc_fixup alc269_fixups[] = { 4493static const struct alc_fixup alc269_fixups[] = {
@@ -14975,9 +4546,14 @@ static const struct alc_fixup alc269_fixups[] = {
14975 .type = ALC_FIXUP_FUNC, 4546 .type = ALC_FIXUP_FUNC,
14976 .v.func = alc271_fixup_dmic, 4547 .v.func = alc271_fixup_dmic,
14977 }, 4548 },
4549 [ALC269_FIXUP_PCM_44K] = {
4550 .type = ALC_FIXUP_FUNC,
4551 .v.func = alc269_fixup_pcm_44k,
4552 },
14978}; 4553};
14979 4554
14980static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4555static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4556 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14981 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 4557 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14982 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4558 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14983 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4559 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -14989,209 +4565,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14989 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 4565 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14990 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 4566 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14991 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 4567 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14992 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 4568 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
14993 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 4569 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14994 {} 4570 {}
14995}; 4571};
14996 4572
14997 4573
14998/*
14999 * configuration and preset
15000 */
15001static const char * const alc269_models[ALC269_MODEL_LAST] = {
15002 [ALC269_BASIC] = "basic",
15003 [ALC269_QUANTA_FL1] = "quanta",
15004 [ALC269_AMIC] = "laptop-amic",
15005 [ALC269_DMIC] = "laptop-dmic",
15006 [ALC269_FUJITSU] = "fujitsu",
15007 [ALC269_LIFEBOOK] = "lifebook",
15008 [ALC269_AUTO] = "auto",
15009};
15010
15011static const struct snd_pci_quirk alc269_cfg_tbl[] = {
15012 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
15013 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
15014 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
15015 ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15029 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15030 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15031 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15032 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15033 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15034 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15035 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15036 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15037 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15038 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15041 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15042 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15043 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15044 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15045 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15046 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15047 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15048 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15049 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15050 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15051 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15052 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15053 ALC269_DMIC),
15054 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15055 ALC269_DMIC),
15056 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15057 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15058 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15059 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15060 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15061 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15062 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15063 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15064 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15065 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15066 {}
15067};
15068
15069static const struct alc_config_preset alc269_presets[] = {
15070 [ALC269_BASIC] = {
15071 .mixers = { alc269_base_mixer },
15072 .init_verbs = { alc269_init_verbs },
15073 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074 .dac_nids = alc269_dac_nids,
15075 .hp_nid = 0x03,
15076 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15077 .channel_mode = alc269_modes,
15078 .input_mux = &alc269_capture_source,
15079 },
15080 [ALC269_QUANTA_FL1] = {
15081 .mixers = { alc269_quanta_fl1_mixer },
15082 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15083 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15084 .dac_nids = alc269_dac_nids,
15085 .hp_nid = 0x03,
15086 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15087 .channel_mode = alc269_modes,
15088 .input_mux = &alc269_capture_source,
15089 .unsol_event = alc269_quanta_fl1_unsol_event,
15090 .setup = alc269_quanta_fl1_setup,
15091 .init_hook = alc269_quanta_fl1_init_hook,
15092 },
15093 [ALC269_AMIC] = {
15094 .mixers = { alc269_laptop_mixer },
15095 .cap_mixer = alc269_laptop_analog_capture_mixer,
15096 .init_verbs = { alc269_init_verbs,
15097 alc269_laptop_amic_init_verbs },
15098 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15099 .dac_nids = alc269_dac_nids,
15100 .hp_nid = 0x03,
15101 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15102 .channel_mode = alc269_modes,
15103 .unsol_event = alc_sku_unsol_event,
15104 .setup = alc269_laptop_amic_setup,
15105 .init_hook = alc_inithook,
15106 },
15107 [ALC269_DMIC] = {
15108 .mixers = { alc269_laptop_mixer },
15109 .cap_mixer = alc269_laptop_digital_capture_mixer,
15110 .init_verbs = { alc269_init_verbs,
15111 alc269_laptop_dmic_init_verbs },
15112 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15113 .dac_nids = alc269_dac_nids,
15114 .hp_nid = 0x03,
15115 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15116 .channel_mode = alc269_modes,
15117 .unsol_event = alc_sku_unsol_event,
15118 .setup = alc269_laptop_dmic_setup,
15119 .init_hook = alc_inithook,
15120 },
15121 [ALC269VB_AMIC] = {
15122 .mixers = { alc269vb_laptop_mixer },
15123 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15124 .init_verbs = { alc269vb_init_verbs,
15125 alc269vb_laptop_amic_init_verbs },
15126 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15127 .dac_nids = alc269_dac_nids,
15128 .hp_nid = 0x03,
15129 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15130 .channel_mode = alc269_modes,
15131 .unsol_event = alc_sku_unsol_event,
15132 .setup = alc269vb_laptop_amic_setup,
15133 .init_hook = alc_inithook,
15134 },
15135 [ALC269VB_DMIC] = {
15136 .mixers = { alc269vb_laptop_mixer },
15137 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15138 .init_verbs = { alc269vb_init_verbs,
15139 alc269vb_laptop_dmic_init_verbs },
15140 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15141 .dac_nids = alc269_dac_nids,
15142 .hp_nid = 0x03,
15143 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15144 .channel_mode = alc269_modes,
15145 .unsol_event = alc_sku_unsol_event,
15146 .setup = alc269vb_laptop_dmic_setup,
15147 .init_hook = alc_inithook,
15148 },
15149 [ALC269_FUJITSU] = {
15150 .mixers = { alc269_fujitsu_mixer },
15151 .cap_mixer = alc269_laptop_digital_capture_mixer,
15152 .init_verbs = { alc269_init_verbs,
15153 alc269_laptop_dmic_init_verbs },
15154 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15155 .dac_nids = alc269_dac_nids,
15156 .hp_nid = 0x03,
15157 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15158 .channel_mode = alc269_modes,
15159 .unsol_event = alc_sku_unsol_event,
15160 .setup = alc269_laptop_dmic_setup,
15161 .init_hook = alc_inithook,
15162 },
15163 [ALC269_LIFEBOOK] = {
15164 .mixers = { alc269_lifebook_mixer },
15165 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15166 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15167 .dac_nids = alc269_dac_nids,
15168 .hp_nid = 0x03,
15169 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15170 .channel_mode = alc269_modes,
15171 .input_mux = &alc269_capture_source,
15172 .unsol_event = alc269_lifebook_unsol_event,
15173 .setup = alc269_lifebook_setup,
15174 .init_hook = alc269_lifebook_init_hook,
15175 },
15176 [ALC271_ACER] = {
15177 .mixers = { alc269_asus_mixer },
15178 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15179 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15180 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15181 .dac_nids = alc269_dac_nids,
15182 .adc_nids = alc262_dmic_adc_nids,
15183 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15184 .capsrc_nids = alc262_dmic_capsrc_nids,
15185 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15186 .channel_mode = alc269_modes,
15187 .input_mux = &alc269_capture_source,
15188 .dig_out_nid = ALC880_DIGOUT_NID,
15189 .unsol_event = alc_sku_unsol_event,
15190 .setup = alc269vb_laptop_dmic_setup,
15191 .init_hook = alc_inithook,
15192 },
15193};
15194
15195static int alc269_fill_coef(struct hda_codec *codec) 4574static int alc269_fill_coef(struct hda_codec *codec)
15196{ 4575{
15197 int val; 4576 int val;
@@ -15234,6 +4613,12 @@ static int alc269_fill_coef(struct hda_codec *codec)
15234 return 0; 4613 return 0;
15235} 4614}
15236 4615
4616/*
4617 */
4618#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4619#include "alc269_quirks.c"
4620#endif
4621
15237static int patch_alc269(struct hda_codec *codec) 4622static int patch_alc269(struct hda_codec *codec)
15238{ 4623{
15239 struct alc_spec *spec; 4624 struct alc_spec *spec;
@@ -15246,105 +4631,94 @@ static int patch_alc269(struct hda_codec *codec)
15246 4631
15247 codec->spec = spec; 4632 codec->spec = spec;
15248 4633
4634 spec->mixer_nid = 0x0b;
4635
15249 alc_auto_parse_customize_define(codec); 4636 alc_auto_parse_customize_define(codec);
15250 4637
15251 if (codec->vendor_id == 0x10ec0269) { 4638 if (codec->vendor_id == 0x10ec0269) {
4639 spec->codec_variant = ALC269_TYPE_ALC269VA;
15252 coef = alc_read_coef_idx(codec, 0); 4640 coef = alc_read_coef_idx(codec, 0);
15253 if ((coef & 0x00f0) == 0x0010) { 4641 if ((coef & 0x00f0) == 0x0010) {
15254 if (codec->bus->pci->subsystem_vendor == 0x1025 && 4642 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15255 spec->cdefine.platform_type == 1) { 4643 spec->cdefine.platform_type == 1) {
15256 alc_codec_rename(codec, "ALC271X"); 4644 alc_codec_rename(codec, "ALC271X");
15257 spec->codec_variant = ALC269_TYPE_ALC271X;
15258 } else if ((coef & 0xf000) == 0x1000) {
15259 spec->codec_variant = ALC269_TYPE_ALC270;
15260 } else if ((coef & 0xf000) == 0x2000) { 4645 } else if ((coef & 0xf000) == 0x2000) {
15261 alc_codec_rename(codec, "ALC259"); 4646 alc_codec_rename(codec, "ALC259");
15262 spec->codec_variant = ALC269_TYPE_ALC259;
15263 } else if ((coef & 0xf000) == 0x3000) { 4647 } else if ((coef & 0xf000) == 0x3000) {
15264 alc_codec_rename(codec, "ALC258"); 4648 alc_codec_rename(codec, "ALC258");
15265 spec->codec_variant = ALC269_TYPE_ALC258; 4649 } else if ((coef & 0xfff0) == 0x3010) {
4650 alc_codec_rename(codec, "ALC277");
15266 } else { 4651 } else {
15267 alc_codec_rename(codec, "ALC269VB"); 4652 alc_codec_rename(codec, "ALC269VB");
15268 spec->codec_variant = ALC269_TYPE_ALC269VB;
15269 } 4653 }
4654 spec->codec_variant = ALC269_TYPE_ALC269VB;
4655 } else if ((coef & 0x00f0) == 0x0020) {
4656 if (coef == 0xa023)
4657 alc_codec_rename(codec, "ALC259");
4658 else if (coef == 0x6023)
4659 alc_codec_rename(codec, "ALC281X");
4660 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4661 codec->bus->pci->subsystem_device == 0x21f3)
4662 alc_codec_rename(codec, "ALC3202");
4663 else
4664 alc_codec_rename(codec, "ALC269VC");
4665 spec->codec_variant = ALC269_TYPE_ALC269VC;
15270 } else 4666 } else
15271 alc_fix_pll_init(codec, 0x20, 0x04, 15); 4667 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15272 alc269_fill_coef(codec); 4668 alc269_fill_coef(codec);
15273 } 4669 }
15274 4670
15275 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 4671 board_config = alc_board_config(codec, ALC269_MODEL_LAST,
15276 alc269_models, 4672 alc269_models, alc269_cfg_tbl);
15277 alc269_cfg_tbl);
15278 4673
15279 if (board_config < 0) { 4674 if (board_config < 0) {
15280 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4675 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15281 codec->chip_name); 4676 codec->chip_name);
15282 board_config = ALC269_AUTO; 4677 board_config = ALC_MODEL_AUTO;
15283 } 4678 }
15284 4679
15285 if (board_config == ALC269_AUTO) { 4680 if (board_config == ALC_MODEL_AUTO) {
15286 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 4681 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15287 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4682 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15288 } 4683 }
15289 4684
15290 if (board_config == ALC269_AUTO) { 4685 if (board_config == ALC_MODEL_AUTO) {
15291 /* automatic parse from the BIOS config */ 4686 /* automatic parse from the BIOS config */
15292 err = alc269_parse_auto_config(codec); 4687 err = alc269_parse_auto_config(codec);
15293 if (err < 0) { 4688 if (err < 0) {
15294 alc_free(codec); 4689 alc_free(codec);
15295 return err; 4690 return err;
15296 } else if (!err) { 4691 }
4692#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4693 else if (!err) {
15297 printk(KERN_INFO 4694 printk(KERN_INFO
15298 "hda_codec: Cannot set up configuration " 4695 "hda_codec: Cannot set up configuration "
15299 "from BIOS. Using base mode...\n"); 4696 "from BIOS. Using base mode...\n");
15300 board_config = ALC269_BASIC; 4697 board_config = ALC269_BASIC;
15301 } 4698 }
4699#endif
15302 } 4700 }
15303 4701
15304 if (has_cdefine_beep(codec)) { 4702 if (board_config != ALC_MODEL_AUTO)
15305 err = snd_hda_attach_beep_device(codec, 0x1);
15306 if (err < 0) {
15307 alc_free(codec);
15308 return err;
15309 }
15310 }
15311
15312 if (board_config != ALC269_AUTO)
15313 setup_preset(codec, &alc269_presets[board_config]); 4703 setup_preset(codec, &alc269_presets[board_config]);
15314 4704
15315 if (board_config == ALC269_QUANTA_FL1) { 4705 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
15316 /* Due to a hardware problem on Lenovo Ideadpad, we need to 4706 alc_auto_fill_adc_caps(codec);
15317 * fix the sample rate of analog I/O to 44.1kHz 4707 alc_rebuild_imux_for_auto_mic(codec);
15318 */ 4708 alc_remove_invalid_adc_nids(codec);
15319 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15320 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15321 } else if (spec->dual_adc_switch) {
15322 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15323 /* switch ADC dynamically */
15324 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15325 } else {
15326 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15327 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15328 }
15329 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15330 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15331
15332 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15333 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15334 spec->adc_nids = alc269_adc_nids;
15335 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15336 spec->capsrc_nids = alc269_capsrc_nids;
15337 } else {
15338 spec->adc_nids = alc269vb_adc_nids;
15339 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15340 spec->capsrc_nids = alc269vb_capsrc_nids;
15341 }
15342 } 4709 }
15343 4710
15344 if (!spec->cap_mixer) 4711 if (!spec->no_analog && !spec->cap_mixer)
15345 set_capture_mixer(codec); 4712 set_capture_mixer(codec);
15346 if (has_cdefine_beep(codec)) 4713
4714 if (!spec->no_analog && has_cdefine_beep(codec)) {
4715 err = snd_hda_attach_beep_device(codec, 0x1);
4716 if (err < 0) {
4717 alc_free(codec);
4718 return err;
4719 }
15347 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 4720 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
4721 }
15348 4722
15349 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4723 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15350 4724
@@ -15354,8 +4728,8 @@ static int patch_alc269(struct hda_codec *codec)
15354#ifdef SND_HDA_NEEDS_RESUME 4728#ifdef SND_HDA_NEEDS_RESUME
15355 codec->patch_ops.resume = alc269_resume; 4729 codec->patch_ops.resume = alc269_resume;
15356#endif 4730#endif
15357 if (board_config == ALC269_AUTO) 4731 if (board_config == ALC_MODEL_AUTO)
15358 spec->init_hook = alc269_auto_init; 4732 spec->init_hook = alc_auto_init_std;
15359 spec->shutup = alc269_shutup; 4733 spec->shutup = alc269_shutup;
15360 4734
15361 alc_init_jacks(codec); 4735 alc_init_jacks(codec);
@@ -15370,883 +4744,14 @@ static int patch_alc269(struct hda_codec *codec)
15370} 4744}
15371 4745
15372/* 4746/*
15373 * ALC861 channel source setting (2/6 channel selection for 3-stack) 4747 * ALC861
15374 */
15375
15376/*
15377 * set the path ways for 2 channel output
15378 * need to set the codec line out and mic 1 pin widgets to inputs
15379 */
15380static const struct hda_verb alc861_threestack_ch2_init[] = {
15381 /* set pin widget 1Ah (line in) for input */
15382 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15383 /* set pin widget 18h (mic1/2) for input, for mic also enable
15384 * the vref
15385 */
15386 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15387
15388 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15389#if 0
15390 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15391 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15392#endif
15393 { } /* end */
15394};
15395/*
15396 * 6ch mode
15397 * need to set the codec line out and mic 1 pin widgets to outputs
15398 */ 4748 */
15399static const struct hda_verb alc861_threestack_ch6_init[] = {
15400 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15401 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15402 /* set pin widget 18h (mic1) for output (CLFE)*/
15403 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15404
15405 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15406 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15407
15408 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15409#if 0
15410 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15411 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15412#endif
15413 { } /* end */
15414};
15415
15416static const struct hda_channel_mode alc861_threestack_modes[2] = {
15417 { 2, alc861_threestack_ch2_init },
15418 { 6, alc861_threestack_ch6_init },
15419};
15420/* Set mic1 as input and unmute the mixer */
15421static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15422 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15424 { } /* end */
15425};
15426/* Set mic1 as output and mute mixer */
15427static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15428 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15429 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15430 { } /* end */
15431};
15432
15433static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15434 { 2, alc861_uniwill_m31_ch2_init },
15435 { 4, alc861_uniwill_m31_ch4_init },
15436};
15437
15438/* Set mic1 and line-in as input and unmute the mixer */
15439static const struct hda_verb alc861_asus_ch2_init[] = {
15440 /* set pin widget 1Ah (line in) for input */
15441 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15442 /* set pin widget 18h (mic1/2) for input, for mic also enable
15443 * the vref
15444 */
15445 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15446
15447 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15448#if 0
15449 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15450 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15451#endif
15452 { } /* end */
15453};
15454/* Set mic1 nad line-in as output and mute mixer */
15455static const struct hda_verb alc861_asus_ch6_init[] = {
15456 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15457 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15458 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15459 /* set pin widget 18h (mic1) for output (CLFE)*/
15460 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15461 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15462 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15463 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15464
15465 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15466#if 0
15467 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15468 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15469#endif
15470 { } /* end */
15471};
15472
15473static const struct hda_channel_mode alc861_asus_modes[2] = {
15474 { 2, alc861_asus_ch2_init },
15475 { 6, alc861_asus_ch6_init },
15476};
15477 4749
15478/* patch-ALC861 */
15479
15480static const struct snd_kcontrol_new alc861_base_mixer[] = {
15481 /* output mixer control */
15482 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15485 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15486 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15487
15488 /*Input mixer control */
15489 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15490 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15491 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15493 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15497 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15498 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15499
15500 { } /* end */
15501};
15502
15503static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15504 /* output mixer control */
15505 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15506 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15508 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15509 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15510
15511 /* Input mixer control */
15512 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15514 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15515 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15516 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15517 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15519 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15520 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15522
15523 {
15524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15525 .name = "Channel Mode",
15526 .info = alc_ch_mode_info,
15527 .get = alc_ch_mode_get,
15528 .put = alc_ch_mode_put,
15529 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15530 },
15531 { } /* end */
15532};
15533
15534static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15535 /* output mixer control */
15536 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15537 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15538 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15539
15540 { } /* end */
15541};
15542
15543static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15544 /* output mixer control */
15545 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15546 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15547 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15548 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15549 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15550
15551 /* Input mixer control */
15552 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15554 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15555 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15556 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15557 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15558 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15559 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15561 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15562
15563 {
15564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15565 .name = "Channel Mode",
15566 .info = alc_ch_mode_info,
15567 .get = alc_ch_mode_get,
15568 .put = alc_ch_mode_put,
15569 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15570 },
15571 { } /* end */
15572};
15573
15574static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15575 /* output mixer control */
15576 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15577 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15578 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15579 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15580 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15581
15582 /* Input mixer control */
15583 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15584 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15585 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15586 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15587 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15588 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15589 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15590 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15592 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15593
15594 {
15595 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15596 .name = "Channel Mode",
15597 .info = alc_ch_mode_info,
15598 .get = alc_ch_mode_get,
15599 .put = alc_ch_mode_put,
15600 .private_value = ARRAY_SIZE(alc861_asus_modes),
15601 },
15602 { }
15603};
15604
15605/* additional mixer */
15606static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15607 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15608 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15609 { }
15610};
15611
15612/*
15613 * generic initialization of ADC, input mixers and output mixers
15614 */
15615static const struct hda_verb alc861_base_init_verbs[] = {
15616 /*
15617 * Unmute ADC0 and set the default input to mic-in
15618 */
15619 /* port-A for surround (rear panel) */
15620 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15621 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15622 /* port-B for mic-in (rear panel) with vref */
15623 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15624 /* port-C for line-in (rear panel) */
15625 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15626 /* port-D for Front */
15627 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15628 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15629 /* port-E for HP out (front panel) */
15630 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15631 /* route front PCM to HP */
15632 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15633 /* port-F for mic-in (front panel) with vref */
15634 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15635 /* port-G for CLFE (rear panel) */
15636 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15637 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15638 /* port-H for side (rear panel) */
15639 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15640 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15641 /* CD-in */
15642 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15643 /* route front mic to ADC1*/
15644 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15645 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646
15647 /* Unmute DAC0~3 & spdif out*/
15648 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15649 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15651 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15653
15654 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15655 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15656 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15657 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15658 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15659
15660 /* Unmute Stereo Mixer 15 */
15661 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15662 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15664 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15665
15666 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15668 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15669 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15670 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15671 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15672 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15673 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15674 /* hp used DAC 3 (Front) */
15675 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15676 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15677
15678 { }
15679};
15680
15681static const struct hda_verb alc861_threestack_init_verbs[] = {
15682 /*
15683 * Unmute ADC0 and set the default input to mic-in
15684 */
15685 /* port-A for surround (rear panel) */
15686 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15687 /* port-B for mic-in (rear panel) with vref */
15688 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15689 /* port-C for line-in (rear panel) */
15690 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15691 /* port-D for Front */
15692 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15693 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15694 /* port-E for HP out (front panel) */
15695 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15696 /* route front PCM to HP */
15697 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15698 /* port-F for mic-in (front panel) with vref */
15699 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15700 /* port-G for CLFE (rear panel) */
15701 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15702 /* port-H for side (rear panel) */
15703 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15704 /* CD-in */
15705 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15706 /* route front mic to ADC1*/
15707 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15708 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 /* Unmute DAC0~3 & spdif out*/
15710 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15711 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15712 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15713 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15714 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15715
15716 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15717 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15718 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15719 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15720 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15721
15722 /* Unmute Stereo Mixer 15 */
15723 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15726 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15727
15728 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15729 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15730 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15731 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15732 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15733 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15734 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15735 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15736 /* hp used DAC 3 (Front) */
15737 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15738 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15739 { }
15740};
15741
15742static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15743 /*
15744 * Unmute ADC0 and set the default input to mic-in
15745 */
15746 /* port-A for surround (rear panel) */
15747 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15748 /* port-B for mic-in (rear panel) with vref */
15749 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15750 /* port-C for line-in (rear panel) */
15751 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15752 /* port-D for Front */
15753 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15754 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15755 /* port-E for HP out (front panel) */
15756 /* this has to be set to VREF80 */
15757 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15758 /* route front PCM to HP */
15759 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15760 /* port-F for mic-in (front panel) with vref */
15761 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15762 /* port-G for CLFE (rear panel) */
15763 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15764 /* port-H for side (rear panel) */
15765 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15766 /* CD-in */
15767 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15768 /* route front mic to ADC1*/
15769 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15770 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 /* Unmute DAC0~3 & spdif out*/
15772 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15773 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15774 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15775 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15777
15778 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15779 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783
15784 /* Unmute Stereo Mixer 15 */
15785 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15787 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15788 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15789
15790 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15791 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15792 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15793 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15794 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15796 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15797 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15798 /* hp used DAC 3 (Front) */
15799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15800 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15801 { }
15802};
15803
15804static const struct hda_verb alc861_asus_init_verbs[] = {
15805 /*
15806 * Unmute ADC0 and set the default input to mic-in
15807 */
15808 /* port-A for surround (rear panel)
15809 * according to codec#0 this is the HP jack
15810 */
15811 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15812 /* route front PCM to HP */
15813 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15814 /* port-B for mic-in (rear panel) with vref */
15815 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15816 /* port-C for line-in (rear panel) */
15817 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15818 /* port-D for Front */
15819 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15820 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15821 /* port-E for HP out (front panel) */
15822 /* this has to be set to VREF80 */
15823 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15824 /* route front PCM to HP */
15825 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15826 /* port-F for mic-in (front panel) with vref */
15827 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15828 /* port-G for CLFE (rear panel) */
15829 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15830 /* port-H for side (rear panel) */
15831 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15832 /* CD-in */
15833 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15834 /* route front mic to ADC1*/
15835 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15836 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15837 /* Unmute DAC0~3 & spdif out*/
15838 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15839 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15840 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15841 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15842 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15843 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15844 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15845 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15846 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15847 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15848
15849 /* Unmute Stereo Mixer 15 */
15850 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15851 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15852 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15854
15855 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15856 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15857 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15858 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15860 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15861 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15862 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15863 /* hp used DAC 3 (Front) */
15864 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15865 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15866 { }
15867};
15868
15869/* additional init verbs for ASUS laptops */
15870static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15871 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15872 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15873 { }
15874};
15875
15876/*
15877 * generic initialization of ADC, input mixers and output mixers
15878 */
15879static const struct hda_verb alc861_auto_init_verbs[] = {
15880 /*
15881 * Unmute ADC0 and set the default input to mic-in
15882 */
15883 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15884 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15885
15886 /* Unmute DAC0~3 & spdif out*/
15887 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15888 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15889 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15890 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15891 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15892
15893 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15894 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15895 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15896 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15897 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15898
15899 /* Unmute Stereo Mixer 15 */
15900 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15901 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15902 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15903 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15904
15905 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15906 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15907 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15908 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15909 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15910 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15911 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15912 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15913
15914 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15915 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15916 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15917 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15918 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15919 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15920 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15921 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15922
15923 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15924
15925 { }
15926};
15927
15928static const struct hda_verb alc861_toshiba_init_verbs[] = {
15929 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15930
15931 { }
15932};
15933
15934/* toggle speaker-output according to the hp-jack state */
15935static void alc861_toshiba_automute(struct hda_codec *codec)
15936{
15937 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15938
15939 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15940 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15941 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15942 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15943}
15944
15945static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15946 unsigned int res)
15947{
15948 if ((res >> 26) == ALC880_HP_EVENT)
15949 alc861_toshiba_automute(codec);
15950}
15951
15952/* pcm configuration: identical with ALC880 */
15953#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15954#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15955#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15956#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15957
15958
15959#define ALC861_DIGOUT_NID 0x07
15960
15961static const struct hda_channel_mode alc861_8ch_modes[1] = {
15962 { 8, NULL }
15963};
15964
15965static const hda_nid_t alc861_dac_nids[4] = {
15966 /* front, surround, clfe, side */
15967 0x03, 0x06, 0x05, 0x04
15968};
15969
15970static const hda_nid_t alc660_dac_nids[3] = {
15971 /* front, clfe, surround */
15972 0x03, 0x05, 0x06
15973};
15974
15975static const hda_nid_t alc861_adc_nids[1] = {
15976 /* ADC0-2 */
15977 0x08,
15978};
15979
15980static const struct hda_input_mux alc861_capture_source = {
15981 .num_items = 5,
15982 .items = {
15983 { "Mic", 0x0 },
15984 { "Front Mic", 0x3 },
15985 { "Line", 0x1 },
15986 { "CD", 0x4 },
15987 { "Mixer", 0x5 },
15988 },
15989};
15990
15991static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15992{
15993 struct alc_spec *spec = codec->spec;
15994 hda_nid_t mix, srcs[5];
15995 int i, j, num;
15996
15997 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15998 return 0;
15999 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16000 if (num < 0)
16001 return 0;
16002 for (i = 0; i < num; i++) {
16003 unsigned int type;
16004 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
16005 if (type != AC_WID_AUD_OUT)
16006 continue;
16007 for (j = 0; j < spec->multiout.num_dacs; j++)
16008 if (spec->multiout.dac_nids[j] == srcs[i])
16009 break;
16010 if (j >= spec->multiout.num_dacs)
16011 return srcs[i];
16012 }
16013 return 0;
16014}
16015
16016/* fill in the dac_nids table from the parsed pin configuration */
16017static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
16018 const struct auto_pin_cfg *cfg)
16019{
16020 struct alc_spec *spec = codec->spec;
16021 int i;
16022 hda_nid_t nid, dac;
16023
16024 spec->multiout.dac_nids = spec->private_dac_nids;
16025 for (i = 0; i < cfg->line_outs; i++) {
16026 nid = cfg->line_out_pins[i];
16027 dac = alc861_look_for_dac(codec, nid);
16028 if (!dac)
16029 continue;
16030 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16031 }
16032 return 0;
16033}
16034
16035static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16036 hda_nid_t nid, int idx, unsigned int chs)
16037{
16038 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16039 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16040}
16041
16042#define alc861_create_out_sw(codec, pfx, nid, chs) \
16043 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16044
16045/* add playback controls from the parsed DAC table */
16046static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16047 const struct auto_pin_cfg *cfg)
16048{
16049 struct alc_spec *spec = codec->spec;
16050 static const char * const chname[4] = {
16051 "Front", "Surround", NULL /*CLFE*/, "Side"
16052 };
16053 const char *pfx = alc_get_line_out_pfx(spec, true);
16054 hda_nid_t nid;
16055 int i, err, noutputs;
16056
16057 noutputs = cfg->line_outs;
16058 if (spec->multi_ios > 0)
16059 noutputs += spec->multi_ios;
16060
16061 for (i = 0; i < noutputs; i++) {
16062 nid = spec->multiout.dac_nids[i];
16063 if (!nid)
16064 continue;
16065 if (!pfx && i == 2) {
16066 /* Center/LFE */
16067 err = alc861_create_out_sw(codec, "Center", nid, 1);
16068 if (err < 0)
16069 return err;
16070 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16071 if (err < 0)
16072 return err;
16073 } else {
16074 const char *name = pfx;
16075 int index = i;
16076 if (!name) {
16077 name = chname[i];
16078 index = 0;
16079 }
16080 err = __alc861_create_out_sw(codec, name, nid, index, 3);
16081 if (err < 0)
16082 return err;
16083 }
16084 }
16085 return 0;
16086}
16087
16088static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16089{
16090 struct alc_spec *spec = codec->spec;
16091 int err;
16092 hda_nid_t nid;
16093
16094 if (!pin)
16095 return 0;
16096
16097 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16098 nid = alc861_look_for_dac(codec, pin);
16099 if (nid) {
16100 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16101 if (err < 0)
16102 return err;
16103 spec->multiout.hp_nid = nid;
16104 }
16105 }
16106 return 0;
16107}
16108
16109/* create playback/capture controls for input pins */
16110static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16111 const struct auto_pin_cfg *cfg)
16112{
16113 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16114}
16115
16116static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16117 hda_nid_t nid,
16118 int pin_type, hda_nid_t dac)
16119{
16120 hda_nid_t mix, srcs[5];
16121 int i, num;
16122
16123 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16124 pin_type);
16125 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16126 AMP_OUT_UNMUTE);
16127 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16128 return;
16129 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16130 if (num < 0)
16131 return;
16132 for (i = 0; i < num; i++) {
16133 unsigned int mute;
16134 if (srcs[i] == dac || srcs[i] == 0x15)
16135 mute = AMP_IN_UNMUTE(i);
16136 else
16137 mute = AMP_IN_MUTE(i);
16138 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16139 mute);
16140 }
16141}
16142
16143static void alc861_auto_init_multi_out(struct hda_codec *codec)
16144{
16145 struct alc_spec *spec = codec->spec;
16146 int i;
16147
16148 for (i = 0; i < spec->autocfg.line_outs; i++) {
16149 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16150 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16151 if (nid)
16152 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16153 spec->multiout.dac_nids[i]);
16154 }
16155}
16156
16157static void alc861_auto_init_hp_out(struct hda_codec *codec)
16158{
16159 struct alc_spec *spec = codec->spec;
16160
16161 if (spec->autocfg.hp_outs)
16162 alc861_auto_set_output_and_unmute(codec,
16163 spec->autocfg.hp_pins[0],
16164 PIN_HP,
16165 spec->multiout.hp_nid);
16166 if (spec->autocfg.speaker_outs)
16167 alc861_auto_set_output_and_unmute(codec,
16168 spec->autocfg.speaker_pins[0],
16169 PIN_OUT,
16170 spec->multiout.dac_nids[0]);
16171}
16172
16173static void alc861_auto_init_analog_input(struct hda_codec *codec)
16174{
16175 struct alc_spec *spec = codec->spec;
16176 struct auto_pin_cfg *cfg = &spec->autocfg;
16177 int i;
16178
16179 for (i = 0; i < cfg->num_inputs; i++) {
16180 hda_nid_t nid = cfg->inputs[i].pin;
16181 if (nid >= 0x0c && nid <= 0x11)
16182 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16183 }
16184}
16185
16186/* parse the BIOS configuration and set up the alc_spec */
16187/* return 1 if successful, 0 if the proper config is not found,
16188 * or a negative error code
16189 */
16190static int alc861_parse_auto_config(struct hda_codec *codec) 4750static int alc861_parse_auto_config(struct hda_codec *codec)
16191{ 4751{
16192 struct alc_spec *spec = codec->spec;
16193 int err;
16194 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 4752 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16195 4753 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
16196 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4754 return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids);
16197 alc861_ignore);
16198 if (err < 0)
16199 return err;
16200 if (!spec->autocfg.line_outs)
16201 return 0; /* can't find valid BIOS pin config */
16202
16203 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16204 if (err < 0)
16205 return err;
16206 err = alc_auto_add_multi_channel_mode(codec);
16207 if (err < 0)
16208 return err;
16209 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16210 if (err < 0)
16211 return err;
16212 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16213 if (err < 0)
16214 return err;
16215 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16216 if (err < 0)
16217 return err;
16218
16219 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16220
16221 alc_auto_parse_digital(codec);
16222
16223 if (spec->kctls.list)
16224 add_mixer(spec, spec->kctls.list);
16225
16226 add_verb(spec, alc861_auto_init_verbs);
16227
16228 spec->num_mux_defs = 1;
16229 spec->input_mux = &spec->private_imux[0];
16230
16231 spec->adc_nids = alc861_adc_nids;
16232 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16233 set_capture_mixer(codec);
16234
16235 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16236
16237 return 1;
16238}
16239
16240/* additional initialization for auto-configuration model */
16241static void alc861_auto_init(struct hda_codec *codec)
16242{
16243 struct alc_spec *spec = codec->spec;
16244 alc861_auto_init_multi_out(codec);
16245 alc861_auto_init_hp_out(codec);
16246 alc861_auto_init_analog_input(codec);
16247 alc_auto_init_digital(codec);
16248 if (spec->unsol_event)
16249 alc_inithook(codec);
16250} 4755}
16251 4756
16252#ifdef CONFIG_SND_HDA_POWER_SAVE 4757#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16260,152 +4765,6 @@ static const struct hda_amp_list alc861_loopbacks[] = {
16260#endif 4765#endif
16261 4766
16262 4767
16263/*
16264 * configuration and preset
16265 */
16266static const char * const alc861_models[ALC861_MODEL_LAST] = {
16267 [ALC861_3ST] = "3stack",
16268 [ALC660_3ST] = "3stack-660",
16269 [ALC861_3ST_DIG] = "3stack-dig",
16270 [ALC861_6ST_DIG] = "6stack-dig",
16271 [ALC861_UNIWILL_M31] = "uniwill-m31",
16272 [ALC861_TOSHIBA] = "toshiba",
16273 [ALC861_ASUS] = "asus",
16274 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16275 [ALC861_AUTO] = "auto",
16276};
16277
16278static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16279 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16280 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16281 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16282 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16283 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16284 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16285 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16286 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16287 * Any other models that need this preset?
16288 */
16289 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16290 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16291 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16292 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16293 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16294 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16295 /* FIXME: the below seems conflict */
16296 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16297 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16298 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16299 {}
16300};
16301
16302static const struct alc_config_preset alc861_presets[] = {
16303 [ALC861_3ST] = {
16304 .mixers = { alc861_3ST_mixer },
16305 .init_verbs = { alc861_threestack_init_verbs },
16306 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16307 .dac_nids = alc861_dac_nids,
16308 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16309 .channel_mode = alc861_threestack_modes,
16310 .need_dac_fix = 1,
16311 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16312 .adc_nids = alc861_adc_nids,
16313 .input_mux = &alc861_capture_source,
16314 },
16315 [ALC861_3ST_DIG] = {
16316 .mixers = { alc861_base_mixer },
16317 .init_verbs = { alc861_threestack_init_verbs },
16318 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16319 .dac_nids = alc861_dac_nids,
16320 .dig_out_nid = ALC861_DIGOUT_NID,
16321 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16322 .channel_mode = alc861_threestack_modes,
16323 .need_dac_fix = 1,
16324 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325 .adc_nids = alc861_adc_nids,
16326 .input_mux = &alc861_capture_source,
16327 },
16328 [ALC861_6ST_DIG] = {
16329 .mixers = { alc861_base_mixer },
16330 .init_verbs = { alc861_base_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16332 .dac_nids = alc861_dac_nids,
16333 .dig_out_nid = ALC861_DIGOUT_NID,
16334 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16335 .channel_mode = alc861_8ch_modes,
16336 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16337 .adc_nids = alc861_adc_nids,
16338 .input_mux = &alc861_capture_source,
16339 },
16340 [ALC660_3ST] = {
16341 .mixers = { alc861_3ST_mixer },
16342 .init_verbs = { alc861_threestack_init_verbs },
16343 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16344 .dac_nids = alc660_dac_nids,
16345 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16346 .channel_mode = alc861_threestack_modes,
16347 .need_dac_fix = 1,
16348 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16349 .adc_nids = alc861_adc_nids,
16350 .input_mux = &alc861_capture_source,
16351 },
16352 [ALC861_UNIWILL_M31] = {
16353 .mixers = { alc861_uniwill_m31_mixer },
16354 .init_verbs = { alc861_uniwill_m31_init_verbs },
16355 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16356 .dac_nids = alc861_dac_nids,
16357 .dig_out_nid = ALC861_DIGOUT_NID,
16358 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16359 .channel_mode = alc861_uniwill_m31_modes,
16360 .need_dac_fix = 1,
16361 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16362 .adc_nids = alc861_adc_nids,
16363 .input_mux = &alc861_capture_source,
16364 },
16365 [ALC861_TOSHIBA] = {
16366 .mixers = { alc861_toshiba_mixer },
16367 .init_verbs = { alc861_base_init_verbs,
16368 alc861_toshiba_init_verbs },
16369 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16370 .dac_nids = alc861_dac_nids,
16371 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16372 .channel_mode = alc883_3ST_2ch_modes,
16373 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16374 .adc_nids = alc861_adc_nids,
16375 .input_mux = &alc861_capture_source,
16376 .unsol_event = alc861_toshiba_unsol_event,
16377 .init_hook = alc861_toshiba_automute,
16378 },
16379 [ALC861_ASUS] = {
16380 .mixers = { alc861_asus_mixer },
16381 .init_verbs = { alc861_asus_init_verbs },
16382 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16383 .dac_nids = alc861_dac_nids,
16384 .dig_out_nid = ALC861_DIGOUT_NID,
16385 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16386 .channel_mode = alc861_asus_modes,
16387 .need_dac_fix = 1,
16388 .hp_nid = 0x06,
16389 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16390 .adc_nids = alc861_adc_nids,
16391 .input_mux = &alc861_capture_source,
16392 },
16393 [ALC861_ASUS_LAPTOP] = {
16394 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16395 .init_verbs = { alc861_asus_init_verbs,
16396 alc861_asus_laptop_init_verbs },
16397 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16398 .dac_nids = alc861_dac_nids,
16399 .dig_out_nid = ALC861_DIGOUT_NID,
16400 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16401 .channel_mode = alc883_3ST_2ch_modes,
16402 .need_dac_fix = 1,
16403 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16404 .adc_nids = alc861_adc_nids,
16405 .input_mux = &alc861_capture_source,
16406 },
16407};
16408
16409/* Pin config fixes */ 4768/* Pin config fixes */
16410enum { 4769enum {
16411 PINFIX_FSC_AMILO_PI1505, 4770 PINFIX_FSC_AMILO_PI1505,
@@ -16427,6 +4786,12 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16427 {} 4786 {}
16428}; 4787};
16429 4788
4789/*
4790 */
4791#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4792#include "alc861_quirks.c"
4793#endif
4794
16430static int patch_alc861(struct hda_codec *codec) 4795static int patch_alc861(struct hda_codec *codec)
16431{ 4796{
16432 struct alc_spec *spec; 4797 struct alc_spec *spec;
@@ -16439,61 +4804,67 @@ static int patch_alc861(struct hda_codec *codec)
16439 4804
16440 codec->spec = spec; 4805 codec->spec = spec;
16441 4806
16442 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 4807 spec->mixer_nid = 0x15;
16443 alc861_models, 4808
16444 alc861_cfg_tbl); 4809 board_config = alc_board_config(codec, ALC861_MODEL_LAST,
4810 alc861_models, alc861_cfg_tbl);
16445 4811
16446 if (board_config < 0) { 4812 if (board_config < 0) {
16447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4813 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16448 codec->chip_name); 4814 codec->chip_name);
16449 board_config = ALC861_AUTO; 4815 board_config = ALC_MODEL_AUTO;
16450 } 4816 }
16451 4817
16452 if (board_config == ALC861_AUTO) { 4818 if (board_config == ALC_MODEL_AUTO) {
16453 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 4819 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16454 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4820 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16455 } 4821 }
16456 4822
16457 if (board_config == ALC861_AUTO) { 4823 if (board_config == ALC_MODEL_AUTO) {
16458 /* automatic parse from the BIOS config */ 4824 /* automatic parse from the BIOS config */
16459 err = alc861_parse_auto_config(codec); 4825 err = alc861_parse_auto_config(codec);
16460 if (err < 0) { 4826 if (err < 0) {
16461 alc_free(codec); 4827 alc_free(codec);
16462 return err; 4828 return err;
16463 } else if (!err) { 4829 }
4830#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4831 else if (!err) {
16464 printk(KERN_INFO 4832 printk(KERN_INFO
16465 "hda_codec: Cannot set up configuration " 4833 "hda_codec: Cannot set up configuration "
16466 "from BIOS. Using base mode...\n"); 4834 "from BIOS. Using base mode...\n");
16467 board_config = ALC861_3ST_DIG; 4835 board_config = ALC861_3ST_DIG;
16468 } 4836 }
4837#endif
16469 } 4838 }
16470 4839
16471 err = snd_hda_attach_beep_device(codec, 0x23); 4840 if (board_config != ALC_MODEL_AUTO)
16472 if (err < 0) {
16473 alc_free(codec);
16474 return err;
16475 }
16476
16477 if (board_config != ALC861_AUTO)
16478 setup_preset(codec, &alc861_presets[board_config]); 4841 setup_preset(codec, &alc861_presets[board_config]);
16479 4842
16480 spec->stream_analog_playback = &alc861_pcm_analog_playback; 4843 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
16481 spec->stream_analog_capture = &alc861_pcm_analog_capture; 4844 alc_auto_fill_adc_caps(codec);
16482 4845 alc_rebuild_imux_for_auto_mic(codec);
16483 spec->stream_digital_playback = &alc861_pcm_digital_playback; 4846 alc_remove_invalid_adc_nids(codec);
16484 spec->stream_digital_capture = &alc861_pcm_digital_capture; 4847 }
16485 4848
16486 if (!spec->cap_mixer) 4849 if (!spec->no_analog && !spec->cap_mixer)
16487 set_capture_mixer(codec); 4850 set_capture_mixer(codec);
16488 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 4851
4852 if (!spec->no_analog) {
4853 err = snd_hda_attach_beep_device(codec, 0x23);
4854 if (err < 0) {
4855 alc_free(codec);
4856 return err;
4857 }
4858 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
4859 }
16489 4860
16490 spec->vmaster_nid = 0x03; 4861 spec->vmaster_nid = 0x03;
16491 4862
16492 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4863 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16493 4864
16494 codec->patch_ops = alc_patch_ops; 4865 codec->patch_ops = alc_patch_ops;
16495 if (board_config == ALC861_AUTO) { 4866 if (board_config == ALC_MODEL_AUTO) {
16496 spec->init_hook = alc861_auto_init; 4867 spec->init_hook = alc_auto_init_std;
16497#ifdef CONFIG_SND_HDA_POWER_SAVE 4868#ifdef CONFIG_SND_HDA_POWER_SAVE
16498 spec->power_hook = alc_power_eapd; 4869 spec->power_hook = alc_power_eapd;
16499#endif 4870#endif
@@ -16513,871 +4884,15 @@ static int patch_alc861(struct hda_codec *codec)
16513 * 4884 *
16514 * In addition, an independent DAC 4885 * In addition, an independent DAC
16515 */ 4886 */
16516#define ALC861VD_DIGOUT_NID 0x06
16517
16518static const hda_nid_t alc861vd_dac_nids[4] = {
16519 /* front, surr, clfe, side surr */
16520 0x02, 0x03, 0x04, 0x05
16521};
16522
16523/* dac_nids for ALC660vd are in a different order - according to
16524 * Realtek's driver.
16525 * This should probably result in a different mixer for 6stack models
16526 * of ALC660vd codecs, but for now there is only 3stack mixer
16527 * - and it is the same as in 861vd.
16528 * adc_nids in ALC660vd are (is) the same as in 861vd
16529 */
16530static const hda_nid_t alc660vd_dac_nids[3] = {
16531 /* front, rear, clfe, rear_surr */
16532 0x02, 0x04, 0x03
16533};
16534
16535static const hda_nid_t alc861vd_adc_nids[1] = {
16536 /* ADC0 */
16537 0x09,
16538};
16539
16540static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16541
16542/* input MUX */
16543/* FIXME: should be a matrix-type input source selection */
16544static const struct hda_input_mux alc861vd_capture_source = {
16545 .num_items = 4,
16546 .items = {
16547 { "Mic", 0x0 },
16548 { "Front Mic", 0x1 },
16549 { "Line", 0x2 },
16550 { "CD", 0x4 },
16551 },
16552};
16553
16554static const struct hda_input_mux alc861vd_dallas_capture_source = {
16555 .num_items = 2,
16556 .items = {
16557 { "Mic", 0x0 },
16558 { "Internal Mic", 0x1 },
16559 },
16560};
16561
16562static const struct hda_input_mux alc861vd_hp_capture_source = {
16563 .num_items = 2,
16564 .items = {
16565 { "Front Mic", 0x0 },
16566 { "ATAPI Mic", 0x1 },
16567 },
16568};
16569
16570/*
16571 * 2ch mode
16572 */
16573static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16574 { 2, NULL }
16575};
16576
16577/*
16578 * 6ch mode
16579 */
16580static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16581 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16582 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16583 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16584 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16585 { } /* end */
16586};
16587
16588/*
16589 * 8ch mode
16590 */
16591static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16592 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16593 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16594 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16595 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16596 { } /* end */
16597};
16598
16599static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16600 { 6, alc861vd_6stack_ch6_init },
16601 { 8, alc861vd_6stack_ch8_init },
16602};
16603
16604static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16605 {
16606 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16607 .name = "Channel Mode",
16608 .info = alc_ch_mode_info,
16609 .get = alc_ch_mode_get,
16610 .put = alc_ch_mode_put,
16611 },
16612 { } /* end */
16613};
16614
16615/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16616 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16617 */
16618static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16619 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16620 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16621
16622 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16623 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16624
16625 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16626 HDA_OUTPUT),
16627 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16628 HDA_OUTPUT),
16629 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16630 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16631
16632 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16633 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16634
16635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16636
16637 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16640
16641 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16644
16645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16647
16648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16650
16651 { } /* end */
16652};
16653
16654static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16655 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16657
16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16659
16660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16663
16664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16667
16668 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16669 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16670
16671 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16672 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16673
16674 { } /* end */
16675};
16676
16677static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16678 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16680 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16681
16682 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16683
16684 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16687
16688 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16689 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16690 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16691
16692 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16693 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16694
16695 { } /* end */
16696};
16697
16698/* Pin assignment: Speaker=0x14, HP = 0x15,
16699 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16700 */
16701static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16702 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16703 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16704 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16705 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16706 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16709 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16710 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16711 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16712 { } /* end */
16713};
16714
16715/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16716 * Front Mic=0x18, ATAPI Mic = 0x19,
16717 */
16718static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16720 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16721 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16722 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16723 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16724 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16725 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16726 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16727
16728 { } /* end */
16729};
16730
16731/*
16732 * generic initialization of ADC, input mixers and output mixers
16733 */
16734static const struct hda_verb alc861vd_volume_init_verbs[] = {
16735 /*
16736 * Unmute ADC0 and set the default input to mic-in
16737 */
16738 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16740
16741 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16742 * the analog-loopback mixer widget
16743 */
16744 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16745 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16746 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16747 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16748 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16749 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16750
16751 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16752 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16753 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16754 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16755 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16756
16757 /*
16758 * Set up output mixers (0x02 - 0x05)
16759 */
16760 /* set vol=0 to output mixers */
16761 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16762 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16763 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16764 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16765
16766 /* set up input amps for analog loopback */
16767 /* Amp Indices: DAC = 0, mixer = 1 */
16768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16769 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16770 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16771 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16772 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16773 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16774 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16775 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16776
16777 { }
16778};
16779
16780/*
16781 * 3-stack pin configuration:
16782 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16783 */
16784static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16785 /*
16786 * Set pin mode and muting
16787 */
16788 /* set front pin widgets 0x14 for output */
16789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16791 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16792
16793 /* Mic (rear) pin: input vref at 80% */
16794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16796 /* Front Mic pin: input vref at 80% */
16797 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16798 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16799 /* Line In pin: input */
16800 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16801 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16802 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16803 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16804 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16805 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16806 /* CD pin widget for input */
16807 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16808
16809 { }
16810};
16811
16812/*
16813 * 6-stack pin configuration:
16814 */
16815static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16816 /*
16817 * Set pin mode and muting
16818 */
16819 /* set front pin widgets 0x14 for output */
16820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16821 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16822 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16823
16824 /* Rear Pin: output 1 (0x0d) */
16825 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16827 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16828 /* CLFE Pin: output 2 (0x0e) */
16829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16831 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16832 /* Side Pin: output 3 (0x0f) */
16833 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16835 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16836
16837 /* Mic (rear) pin: input vref at 80% */
16838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16839 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16840 /* Front Mic pin: input vref at 80% */
16841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16842 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16843 /* Line In pin: input */
16844 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16845 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16846 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16847 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16848 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16849 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16850 /* CD pin widget for input */
16851 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16852
16853 { }
16854};
16855
16856static const struct hda_verb alc861vd_eapd_verbs[] = {
16857 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16858 { }
16859};
16860
16861static const struct hda_verb alc660vd_eapd_verbs[] = {
16862 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16863 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16864 { }
16865};
16866
16867static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16868 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16869 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16870 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16871 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16872 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16873 {}
16874};
16875
16876static void alc861vd_lenovo_setup(struct hda_codec *codec)
16877{
16878 struct alc_spec *spec = codec->spec;
16879 spec->autocfg.hp_pins[0] = 0x1b;
16880 spec->autocfg.speaker_pins[0] = 0x14;
16881 spec->automute = 1;
16882 spec->automute_mode = ALC_AUTOMUTE_AMP;
16883}
16884
16885static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16886{
16887 alc_hp_automute(codec);
16888 alc88x_simple_mic_automute(codec);
16889}
16890
16891static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16892 unsigned int res)
16893{
16894 switch (res >> 26) {
16895 case ALC880_MIC_EVENT:
16896 alc88x_simple_mic_automute(codec);
16897 break;
16898 default:
16899 alc_sku_unsol_event(codec, res);
16900 break;
16901 }
16902}
16903
16904static const struct hda_verb alc861vd_dallas_verbs[] = {
16905 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16906 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16907 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16908 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16909
16910 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16912 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16913 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16914 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16915 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16916 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16917 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16918
16919 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16920 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16922 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16923 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16924 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16925 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16926 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16927
16928 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16929 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16930 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16931 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16932 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16934 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16935 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16936
16937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16938 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16939 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16940 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16941
16942 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16943 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16944 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16945
16946 { } /* end */
16947};
16948
16949/* toggle speaker-output according to the hp-jack state */
16950static void alc861vd_dallas_setup(struct hda_codec *codec)
16951{
16952 struct alc_spec *spec = codec->spec;
16953
16954 spec->autocfg.hp_pins[0] = 0x15;
16955 spec->autocfg.speaker_pins[0] = 0x14;
16956 spec->automute = 1;
16957 spec->automute_mode = ALC_AUTOMUTE_AMP;
16958}
16959
16960#ifdef CONFIG_SND_HDA_POWER_SAVE 4887#ifdef CONFIG_SND_HDA_POWER_SAVE
16961#define alc861vd_loopbacks alc880_loopbacks 4888#define alc861vd_loopbacks alc880_loopbacks
16962#endif 4889#endif
16963 4890
16964/* pcm configuration: identical with ALC880 */
16965#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16966#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16967#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16968#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16969
16970/*
16971 * configuration and preset
16972 */
16973static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16974 [ALC660VD_3ST] = "3stack-660",
16975 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16976 [ALC660VD_ASUS_V1S] = "asus-v1s",
16977 [ALC861VD_3ST] = "3stack",
16978 [ALC861VD_3ST_DIG] = "3stack-digout",
16979 [ALC861VD_6ST_DIG] = "6stack-digout",
16980 [ALC861VD_LENOVO] = "lenovo",
16981 [ALC861VD_DALLAS] = "dallas",
16982 [ALC861VD_HP] = "hp",
16983 [ALC861VD_AUTO] = "auto",
16984};
16985
16986static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16987 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16988 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16989 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16990 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16991 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16992 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16993 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16994 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16995 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16996 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16997 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16998 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16999 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
17000 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
17001 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
17002 {}
17003};
17004
17005static const struct alc_config_preset alc861vd_presets[] = {
17006 [ALC660VD_3ST] = {
17007 .mixers = { alc861vd_3st_mixer },
17008 .init_verbs = { alc861vd_volume_init_verbs,
17009 alc861vd_3stack_init_verbs },
17010 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17011 .dac_nids = alc660vd_dac_nids,
17012 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17013 .channel_mode = alc861vd_3stack_2ch_modes,
17014 .input_mux = &alc861vd_capture_source,
17015 },
17016 [ALC660VD_3ST_DIG] = {
17017 .mixers = { alc861vd_3st_mixer },
17018 .init_verbs = { alc861vd_volume_init_verbs,
17019 alc861vd_3stack_init_verbs },
17020 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17021 .dac_nids = alc660vd_dac_nids,
17022 .dig_out_nid = ALC861VD_DIGOUT_NID,
17023 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17024 .channel_mode = alc861vd_3stack_2ch_modes,
17025 .input_mux = &alc861vd_capture_source,
17026 },
17027 [ALC861VD_3ST] = {
17028 .mixers = { alc861vd_3st_mixer },
17029 .init_verbs = { alc861vd_volume_init_verbs,
17030 alc861vd_3stack_init_verbs },
17031 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17032 .dac_nids = alc861vd_dac_nids,
17033 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17034 .channel_mode = alc861vd_3stack_2ch_modes,
17035 .input_mux = &alc861vd_capture_source,
17036 },
17037 [ALC861VD_3ST_DIG] = {
17038 .mixers = { alc861vd_3st_mixer },
17039 .init_verbs = { alc861vd_volume_init_verbs,
17040 alc861vd_3stack_init_verbs },
17041 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17042 .dac_nids = alc861vd_dac_nids,
17043 .dig_out_nid = ALC861VD_DIGOUT_NID,
17044 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17045 .channel_mode = alc861vd_3stack_2ch_modes,
17046 .input_mux = &alc861vd_capture_source,
17047 },
17048 [ALC861VD_6ST_DIG] = {
17049 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17050 .init_verbs = { alc861vd_volume_init_verbs,
17051 alc861vd_6stack_init_verbs },
17052 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17053 .dac_nids = alc861vd_dac_nids,
17054 .dig_out_nid = ALC861VD_DIGOUT_NID,
17055 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17056 .channel_mode = alc861vd_6stack_modes,
17057 .input_mux = &alc861vd_capture_source,
17058 },
17059 [ALC861VD_LENOVO] = {
17060 .mixers = { alc861vd_lenovo_mixer },
17061 .init_verbs = { alc861vd_volume_init_verbs,
17062 alc861vd_3stack_init_verbs,
17063 alc861vd_eapd_verbs,
17064 alc861vd_lenovo_unsol_verbs },
17065 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17066 .dac_nids = alc660vd_dac_nids,
17067 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17068 .channel_mode = alc861vd_3stack_2ch_modes,
17069 .input_mux = &alc861vd_capture_source,
17070 .unsol_event = alc861vd_lenovo_unsol_event,
17071 .setup = alc861vd_lenovo_setup,
17072 .init_hook = alc861vd_lenovo_init_hook,
17073 },
17074 [ALC861VD_DALLAS] = {
17075 .mixers = { alc861vd_dallas_mixer },
17076 .init_verbs = { alc861vd_dallas_verbs },
17077 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17078 .dac_nids = alc861vd_dac_nids,
17079 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17080 .channel_mode = alc861vd_3stack_2ch_modes,
17081 .input_mux = &alc861vd_dallas_capture_source,
17082 .unsol_event = alc_sku_unsol_event,
17083 .setup = alc861vd_dallas_setup,
17084 .init_hook = alc_hp_automute,
17085 },
17086 [ALC861VD_HP] = {
17087 .mixers = { alc861vd_hp_mixer },
17088 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17089 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17090 .dac_nids = alc861vd_dac_nids,
17091 .dig_out_nid = ALC861VD_DIGOUT_NID,
17092 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17093 .channel_mode = alc861vd_3stack_2ch_modes,
17094 .input_mux = &alc861vd_hp_capture_source,
17095 .unsol_event = alc_sku_unsol_event,
17096 .setup = alc861vd_dallas_setup,
17097 .init_hook = alc_hp_automute,
17098 },
17099 [ALC660VD_ASUS_V1S] = {
17100 .mixers = { alc861vd_lenovo_mixer },
17101 .init_verbs = { alc861vd_volume_init_verbs,
17102 alc861vd_3stack_init_verbs,
17103 alc861vd_eapd_verbs,
17104 alc861vd_lenovo_unsol_verbs },
17105 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17106 .dac_nids = alc660vd_dac_nids,
17107 .dig_out_nid = ALC861VD_DIGOUT_NID,
17108 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17109 .channel_mode = alc861vd_3stack_2ch_modes,
17110 .input_mux = &alc861vd_capture_source,
17111 .unsol_event = alc861vd_lenovo_unsol_event,
17112 .setup = alc861vd_lenovo_setup,
17113 .init_hook = alc861vd_lenovo_init_hook,
17114 },
17115};
17116
17117/*
17118 * BIOS auto configuration
17119 */
17120static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17121 const struct auto_pin_cfg *cfg)
17122{
17123 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17124}
17125
17126
17127static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17128 hda_nid_t nid, int pin_type, int dac_idx)
17129{
17130 alc_set_pin_output(codec, nid, pin_type);
17131}
17132
17133static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17134{
17135 struct alc_spec *spec = codec->spec;
17136 int i;
17137
17138 for (i = 0; i <= HDA_SIDE; i++) {
17139 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17140 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17141 if (nid)
17142 alc861vd_auto_set_output_and_unmute(codec, nid,
17143 pin_type, i);
17144 }
17145}
17146
17147
17148static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17149{
17150 struct alc_spec *spec = codec->spec;
17151 hda_nid_t pin;
17152
17153 pin = spec->autocfg.hp_pins[0];
17154 if (pin) /* connect to front and use dac 0 */
17155 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17156 pin = spec->autocfg.speaker_pins[0];
17157 if (pin)
17158 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17159}
17160
17161#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17162
17163static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17164{
17165 struct alc_spec *spec = codec->spec;
17166 struct auto_pin_cfg *cfg = &spec->autocfg;
17167 int i;
17168
17169 for (i = 0; i < cfg->num_inputs; i++) {
17170 hda_nid_t nid = cfg->inputs[i].pin;
17171 if (alc_is_input_pin(codec, nid)) {
17172 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17173 if (nid != ALC861VD_PIN_CD_NID &&
17174 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17175 snd_hda_codec_write(codec, nid, 0,
17176 AC_VERB_SET_AMP_GAIN_MUTE,
17177 AMP_OUT_MUTE);
17178 }
17179 }
17180}
17181
17182#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17183
17184#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17185#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17186
17187/* add playback controls from the parsed DAC table */
17188/* Based on ALC880 version. But ALC861VD has separate,
17189 * different NIDs for mute/unmute switch and volume control */
17190static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17191 const struct auto_pin_cfg *cfg)
17192{
17193 static const char * const chname[4] = {
17194 "Front", "Surround", "CLFE", "Side"
17195 };
17196 const char *pfx = alc_get_line_out_pfx(spec, true);
17197 hda_nid_t nid_v, nid_s;
17198 int i, err, noutputs;
17199
17200 noutputs = cfg->line_outs;
17201 if (spec->multi_ios > 0)
17202 noutputs += spec->multi_ios;
17203
17204 for (i = 0; i < noutputs; i++) {
17205 if (!spec->multiout.dac_nids[i])
17206 continue;
17207 nid_v = alc861vd_idx_to_mixer_vol(
17208 alc880_dac_to_idx(
17209 spec->multiout.dac_nids[i]));
17210 nid_s = alc861vd_idx_to_mixer_switch(
17211 alc880_dac_to_idx(
17212 spec->multiout.dac_nids[i]));
17213
17214 if (!pfx && i == 2) {
17215 /* Center/LFE */
17216 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17217 "Center",
17218 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17219 HDA_OUTPUT));
17220 if (err < 0)
17221 return err;
17222 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17223 "LFE",
17224 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17225 HDA_OUTPUT));
17226 if (err < 0)
17227 return err;
17228 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17229 "Center",
17230 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17231 HDA_INPUT));
17232 if (err < 0)
17233 return err;
17234 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17235 "LFE",
17236 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17237 HDA_INPUT));
17238 if (err < 0)
17239 return err;
17240 } else {
17241 const char *name = pfx;
17242 int index = i;
17243 if (!name) {
17244 name = chname[i];
17245 index = 0;
17246 }
17247 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17248 name, index,
17249 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17250 HDA_OUTPUT));
17251 if (err < 0)
17252 return err;
17253 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17254 name, index,
17255 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17256 HDA_INPUT));
17257 if (err < 0)
17258 return err;
17259 }
17260 }
17261 return 0;
17262}
17263
17264/* add playback controls for speaker and HP outputs */
17265/* Based on ALC880 version. But ALC861VD has separate,
17266 * different NIDs for mute/unmute switch and volume control */
17267static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17268 hda_nid_t pin, const char *pfx)
17269{
17270 hda_nid_t nid_v, nid_s;
17271 int err;
17272
17273 if (!pin)
17274 return 0;
17275
17276 if (alc880_is_fixed_pin(pin)) {
17277 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17278 /* specify the DAC as the extra output */
17279 if (!spec->multiout.hp_nid)
17280 spec->multiout.hp_nid = nid_v;
17281 else
17282 spec->multiout.extra_out_nid[0] = nid_v;
17283 /* control HP volume/switch on the output mixer amp */
17284 nid_v = alc861vd_idx_to_mixer_vol(
17285 alc880_fixed_pin_idx(pin));
17286 nid_s = alc861vd_idx_to_mixer_switch(
17287 alc880_fixed_pin_idx(pin));
17288
17289 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17290 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17291 if (err < 0)
17292 return err;
17293 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17294 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17295 if (err < 0)
17296 return err;
17297 } else if (alc880_is_multi_pin(pin)) {
17298 /* set manual connection */
17299 /* we have only a switch on HP-out PIN */
17300 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17301 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17302 if (err < 0)
17303 return err;
17304 }
17305 return 0;
17306}
17307
17308/* parse the BIOS configuration and set up the alc_spec
17309 * return 1 if successful, 0 if the proper config is not found,
17310 * or a negative error code
17311 * Based on ALC880 version - had to change it to override
17312 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17313static int alc861vd_parse_auto_config(struct hda_codec *codec) 4891static int alc861vd_parse_auto_config(struct hda_codec *codec)
17314{ 4892{
17315 struct alc_spec *spec = codec->spec;
17316 int err;
17317 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 4893 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17318 4894 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
17319 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4895 return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids);
17320 alc861vd_ignore);
17321 if (err < 0)
17322 return err;
17323 if (!spec->autocfg.line_outs)
17324 return 0; /* can't find valid BIOS pin config */
17325
17326 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17327 if (err < 0)
17328 return err;
17329 err = alc_auto_add_multi_channel_mode(codec);
17330 if (err < 0)
17331 return err;
17332 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17333 if (err < 0)
17334 return err;
17335 err = alc861vd_auto_create_extra_out(spec,
17336 spec->autocfg.speaker_pins[0],
17337 "Speaker");
17338 if (err < 0)
17339 return err;
17340 err = alc861vd_auto_create_extra_out(spec,
17341 spec->autocfg.hp_pins[0],
17342 "Headphone");
17343 if (err < 0)
17344 return err;
17345 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17346 if (err < 0)
17347 return err;
17348
17349 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17350
17351 alc_auto_parse_digital(codec);
17352
17353 if (spec->kctls.list)
17354 add_mixer(spec, spec->kctls.list);
17355
17356 add_verb(spec, alc861vd_volume_init_verbs);
17357
17358 spec->num_mux_defs = 1;
17359 spec->input_mux = &spec->private_imux[0];
17360
17361 err = alc_auto_add_mic_boost(codec);
17362 if (err < 0)
17363 return err;
17364
17365 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17366
17367 return 1;
17368}
17369
17370/* additional initialization for auto-configuration model */
17371static void alc861vd_auto_init(struct hda_codec *codec)
17372{
17373 struct alc_spec *spec = codec->spec;
17374 alc861vd_auto_init_multi_out(codec);
17375 alc861vd_auto_init_hp_out(codec);
17376 alc861vd_auto_init_analog_input(codec);
17377 alc861vd_auto_init_input_src(codec);
17378 alc_auto_init_digital(codec);
17379 if (spec->unsol_event)
17380 alc_inithook(codec);
17381} 4896}
17382 4897
17383enum { 4898enum {
@@ -17402,6 +4917,18 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17402 {} 4917 {}
17403}; 4918};
17404 4919
4920static const struct hda_verb alc660vd_eapd_verbs[] = {
4921 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
4922 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
4923 { }
4924};
4925
4926/*
4927 */
4928#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4929#include "alc861vd_quirks.c"
4930#endif
4931
17405static int patch_alc861vd(struct hda_codec *codec) 4932static int patch_alc861vd(struct hda_codec *codec)
17406{ 4933{
17407 struct alc_spec *spec; 4934 struct alc_spec *spec;
@@ -17413,42 +4940,40 @@ static int patch_alc861vd(struct hda_codec *codec)
17413 4940
17414 codec->spec = spec; 4941 codec->spec = spec;
17415 4942
17416 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 4943 spec->mixer_nid = 0x0b;
17417 alc861vd_models,
17418 alc861vd_cfg_tbl);
17419 4944
17420 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 4945 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
4946 alc861vd_models, alc861vd_cfg_tbl);
4947
4948 if (board_config < 0) {
17421 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4949 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17422 codec->chip_name); 4950 codec->chip_name);
17423 board_config = ALC861VD_AUTO; 4951 board_config = ALC_MODEL_AUTO;
17424 } 4952 }
17425 4953
17426 if (board_config == ALC861VD_AUTO) { 4954 if (board_config == ALC_MODEL_AUTO) {
17427 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 4955 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17428 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4956 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17429 } 4957 }
17430 4958
17431 if (board_config == ALC861VD_AUTO) { 4959 if (board_config == ALC_MODEL_AUTO) {
17432 /* automatic parse from the BIOS config */ 4960 /* automatic parse from the BIOS config */
17433 err = alc861vd_parse_auto_config(codec); 4961 err = alc861vd_parse_auto_config(codec);
17434 if (err < 0) { 4962 if (err < 0) {
17435 alc_free(codec); 4963 alc_free(codec);
17436 return err; 4964 return err;
17437 } else if (!err) { 4965 }
4966#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4967 else if (!err) {
17438 printk(KERN_INFO 4968 printk(KERN_INFO
17439 "hda_codec: Cannot set up configuration " 4969 "hda_codec: Cannot set up configuration "
17440 "from BIOS. Using base mode...\n"); 4970 "from BIOS. Using base mode...\n");
17441 board_config = ALC861VD_3ST; 4971 board_config = ALC861VD_3ST;
17442 } 4972 }
4973#endif
17443 } 4974 }
17444 4975
17445 err = snd_hda_attach_beep_device(codec, 0x23); 4976 if (board_config != ALC_MODEL_AUTO)
17446 if (err < 0) {
17447 alc_free(codec);
17448 return err;
17449 }
17450
17451 if (board_config != ALC861VD_AUTO)
17452 setup_preset(codec, &alc861vd_presets[board_config]); 4977 setup_preset(codec, &alc861vd_presets[board_config]);
17453 4978
17454 if (codec->vendor_id == 0x10ec0660) { 4979 if (codec->vendor_id == 0x10ec0660) {
@@ -17456,21 +4981,23 @@ static int patch_alc861vd(struct hda_codec *codec)
17456 add_verb(spec, alc660vd_eapd_verbs); 4981 add_verb(spec, alc660vd_eapd_verbs);
17457 } 4982 }
17458 4983
17459 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 4984 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
17460 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 4985 alc_auto_fill_adc_caps(codec);
4986 alc_rebuild_imux_for_auto_mic(codec);
4987 alc_remove_invalid_adc_nids(codec);
4988 }
17461 4989
17462 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 4990 if (!spec->no_analog && !spec->cap_mixer)
17463 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 4991 set_capture_mixer(codec);
17464 4992
17465 if (!spec->adc_nids) { 4993 if (!spec->no_analog) {
17466 spec->adc_nids = alc861vd_adc_nids; 4994 err = snd_hda_attach_beep_device(codec, 0x23);
17467 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 4995 if (err < 0) {
4996 alc_free(codec);
4997 return err;
4998 }
4999 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17468 } 5000 }
17469 if (!spec->capsrc_nids)
17470 spec->capsrc_nids = alc861vd_capsrc_nids;
17471
17472 set_capture_mixer(codec);
17473 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17474 5001
17475 spec->vmaster_nid = 0x02; 5002 spec->vmaster_nid = 0x02;
17476 5003
@@ -17478,8 +5005,8 @@ static int patch_alc861vd(struct hda_codec *codec)
17478 5005
17479 codec->patch_ops = alc_patch_ops; 5006 codec->patch_ops = alc_patch_ops;
17480 5007
17481 if (board_config == ALC861VD_AUTO) 5008 if (board_config == ALC_MODEL_AUTO)
17482 spec->init_hook = alc861vd_auto_init; 5009 spec->init_hook = alc_auto_init_std;
17483 spec->shutup = alc_eapd_shutup; 5010 spec->shutup = alc_eapd_shutup;
17484#ifdef CONFIG_SND_HDA_POWER_SAVE 5011#ifdef CONFIG_SND_HDA_POWER_SAVE
17485 if (!spec->loopback.amplist) 5012 if (!spec->loopback.amplist)
@@ -17500,1943 +5027,27 @@ static int patch_alc861vd(struct hda_codec *codec)
17500 * In addition, an independent DAC for the multi-playback (not used in this 5027 * In addition, an independent DAC for the multi-playback (not used in this
17501 * driver yet). 5028 * driver yet).
17502 */ 5029 */
17503#define ALC662_DIGOUT_NID 0x06
17504#define ALC662_DIGIN_NID 0x0a
17505
17506static const hda_nid_t alc662_dac_nids[3] = {
17507 /* front, rear, clfe */
17508 0x02, 0x03, 0x04
17509};
17510
17511static const hda_nid_t alc272_dac_nids[2] = {
17512 0x02, 0x03
17513};
17514
17515static const hda_nid_t alc662_adc_nids[2] = {
17516 /* ADC1-2 */
17517 0x09, 0x08
17518};
17519
17520static const hda_nid_t alc272_adc_nids[1] = {
17521 /* ADC1-2 */
17522 0x08,
17523};
17524
17525static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17526static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17527
17528
17529/* input MUX */
17530/* FIXME: should be a matrix-type input source selection */
17531static const struct hda_input_mux alc662_capture_source = {
17532 .num_items = 4,
17533 .items = {
17534 { "Mic", 0x0 },
17535 { "Front Mic", 0x1 },
17536 { "Line", 0x2 },
17537 { "CD", 0x4 },
17538 },
17539};
17540
17541static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17542 .num_items = 2,
17543 .items = {
17544 { "Mic", 0x1 },
17545 { "Line", 0x2 },
17546 },
17547};
17548
17549static const struct hda_input_mux alc663_capture_source = {
17550 .num_items = 3,
17551 .items = {
17552 { "Mic", 0x0 },
17553 { "Front Mic", 0x1 },
17554 { "Line", 0x2 },
17555 },
17556};
17557
17558#if 0 /* set to 1 for testing other input sources below */
17559static const struct hda_input_mux alc272_nc10_capture_source = {
17560 .num_items = 16,
17561 .items = {
17562 { "Autoselect Mic", 0x0 },
17563 { "Internal Mic", 0x1 },
17564 { "In-0x02", 0x2 },
17565 { "In-0x03", 0x3 },
17566 { "In-0x04", 0x4 },
17567 { "In-0x05", 0x5 },
17568 { "In-0x06", 0x6 },
17569 { "In-0x07", 0x7 },
17570 { "In-0x08", 0x8 },
17571 { "In-0x09", 0x9 },
17572 { "In-0x0a", 0x0a },
17573 { "In-0x0b", 0x0b },
17574 { "In-0x0c", 0x0c },
17575 { "In-0x0d", 0x0d },
17576 { "In-0x0e", 0x0e },
17577 { "In-0x0f", 0x0f },
17578 },
17579};
17580#endif
17581
17582/*
17583 * 2ch mode
17584 */
17585static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17586 { 2, NULL }
17587};
17588
17589/*
17590 * 2ch mode
17591 */
17592static const struct hda_verb alc662_3ST_ch2_init[] = {
17593 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17594 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17595 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17596 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17597 { } /* end */
17598};
17599
17600/*
17601 * 6ch mode
17602 */
17603static const struct hda_verb alc662_3ST_ch6_init[] = {
17604 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17605 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17606 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17607 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17608 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17609 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17610 { } /* end */
17611};
17612
17613static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17614 { 2, alc662_3ST_ch2_init },
17615 { 6, alc662_3ST_ch6_init },
17616};
17617
17618/*
17619 * 2ch mode
17620 */
17621static const struct hda_verb alc662_sixstack_ch6_init[] = {
17622 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17623 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17624 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17625 { } /* end */
17626};
17627
17628/*
17629 * 6ch mode
17630 */
17631static const struct hda_verb alc662_sixstack_ch8_init[] = {
17632 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17633 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17634 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17635 { } /* end */
17636};
17637
17638static const struct hda_channel_mode alc662_5stack_modes[2] = {
17639 { 2, alc662_sixstack_ch6_init },
17640 { 6, alc662_sixstack_ch8_init },
17641};
17642
17643/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17644 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17645 */
17646
17647static const struct snd_kcontrol_new alc662_base_mixer[] = {
17648 /* output mixer control */
17649 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17650 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17651 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17652 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17653 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17654 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17655 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17657 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17658
17659 /*Input mixer control */
17660 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17661 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17662 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17663 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17664 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17665 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17666 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17667 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17668 { } /* end */
17669};
17670
17671static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17672 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17673 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17674 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17675 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17676 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17677 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17678 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17679 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17680 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17681 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17682 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17683 { } /* end */
17684};
17685
17686static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17687 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17688 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17689 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17690 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17691 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17692 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17693 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17694 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17695 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17696 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17697 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17698 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17699 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17703 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17704 { } /* end */
17705};
17706
17707static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17708 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17709 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17710 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17711 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17712 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17713 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17714 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17715 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17717 { } /* end */
17718};
17719
17720static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17721 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17722 ALC262_HIPPO_MASTER_SWITCH,
17723
17724 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17725 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17726 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17727
17728 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17729 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17730 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17731 { } /* end */
17732};
17733
17734static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17735 ALC262_HIPPO_MASTER_SWITCH,
17736 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17737 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17738 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17739 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17740 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17741 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17742 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17745 { } /* end */
17746};
17747
17748static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17749 .ops = &snd_hda_bind_vol,
17750 .values = {
17751 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17752 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17753 0
17754 },
17755};
17756
17757static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17758 .ops = &snd_hda_bind_sw,
17759 .values = {
17760 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17761 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17762 0
17763 },
17764};
17765
17766static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17767 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17768 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17771 { } /* end */
17772};
17773
17774static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17775 .ops = &snd_hda_bind_sw,
17776 .values = {
17777 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17778 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17779 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17780 0
17781 },
17782};
17783
17784static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17785 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17786 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17787 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17788 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17789 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17790 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17791
17792 { } /* end */
17793};
17794
17795static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17796 .ops = &snd_hda_bind_sw,
17797 .values = {
17798 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17799 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17800 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17801 0
17802 },
17803};
17804
17805static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17806 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17807 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17810 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17811 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17812 { } /* end */
17813};
17814
17815static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17816 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17817 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17818 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17819 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17820 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17821 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17822 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17823 { } /* end */
17824};
17825
17826static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17827 .ops = &snd_hda_bind_vol,
17828 .values = {
17829 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17830 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17831 0
17832 },
17833};
17834
17835static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17836 .ops = &snd_hda_bind_sw,
17837 .values = {
17838 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17839 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17840 0
17841 },
17842};
17843
17844static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17845 HDA_BIND_VOL("Master Playback Volume",
17846 &alc663_asus_two_bind_master_vol),
17847 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17848 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17849 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17851 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17852 { } /* end */
17853};
17854
17855static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17856 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17857 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17858 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17862 { } /* end */
17863};
17864
17865static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17866 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17867 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17868 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17869 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17870 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17871
17872 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17873 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17874 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17875 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17876 { } /* end */
17877};
17878
17879static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17880 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17881 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17882 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17883
17884 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17885 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17886 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17887 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17888 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17889 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17890 { } /* end */
17891};
17892
17893static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17894 .ops = &snd_hda_bind_sw,
17895 .values = {
17896 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17897 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17898 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17899 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17900 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17901 0
17902 },
17903};
17904
17905static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17906 .ops = &snd_hda_bind_sw,
17907 .values = {
17908 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17909 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17910 0
17911 },
17912};
17913
17914static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17915 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17916 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17917 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17918 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17919 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17920 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17921 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17922 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17923 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17924 { } /* end */
17925};
17926
17927static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17928 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17929 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17930 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17931 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17932 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17935 { } /* end */
17936};
17937
17938
17939static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17940 {
17941 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17942 .name = "Channel Mode",
17943 .info = alc_ch_mode_info,
17944 .get = alc_ch_mode_get,
17945 .put = alc_ch_mode_put,
17946 },
17947 { } /* end */
17948};
17949
17950static const struct hda_verb alc662_init_verbs[] = {
17951 /* ADC: mute amp left and right */
17952 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17953 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17954
17955 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17956 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17957 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17958 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17959 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17960 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17961
17962 /* Front Pin: output 0 (0x0c) */
17963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17964 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965
17966 /* Rear Pin: output 1 (0x0d) */
17967 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17968 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17969
17970 /* CLFE Pin: output 2 (0x0e) */
17971 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17972 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17973
17974 /* Mic (rear) pin: input vref at 80% */
17975 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17976 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17977 /* Front Mic pin: input vref at 80% */
17978 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17979 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17980 /* Line In pin: input */
17981 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17982 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17983 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17984 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17987 /* CD pin widget for input */
17988 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17989
17990 /* FIXME: use matrix-type input source selection */
17991 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17992 /* Input mixer */
17993 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17995
17996 { }
17997};
17998
17999static const struct hda_verb alc662_eapd_init_verbs[] = {
18000 /* always trun on EAPD */
18001 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
18002 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
18003 { }
18004};
18005
18006static const struct hda_verb alc662_sue_init_verbs[] = {
18007 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18008 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18009 {}
18010};
18011
18012static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
18013 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18014 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18015 {}
18016};
18017
18018/* Set Unsolicited Event*/
18019static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
18020 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18021 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {}
18023};
18024
18025static const struct hda_verb alc663_m51va_init_verbs[] = {
18026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18028 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18034 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18035 {}
18036};
18037
18038static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18039 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18040 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18041 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18044 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18045 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18046 {}
18047};
18048
18049static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18050 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18051 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18053 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18054 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18056 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18057 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18058 {}
18059};
18060
18061static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18064 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18065 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18066 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18067 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18068 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18069 {}
18070};
18071
18072static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18073 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18074 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18075 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18076 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18077 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18078 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18079 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18080 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18081 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18082 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18083 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18084 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18085 {}
18086};
18087
18088static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18090 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18091 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18092 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18093 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18094 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18095 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18096 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18097 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18098 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18099 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18100 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18101 {}
18102};
18103
18104static const struct hda_verb alc663_g71v_init_verbs[] = {
18105 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18106 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18107 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18108
18109 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18110 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18111 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18112
18113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18114 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18115 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18116 {}
18117};
18118
18119static const struct hda_verb alc663_g50v_init_verbs[] = {
18120 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18121 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18122 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18123
18124 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18125 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18126 {}
18127};
18128
18129static const struct hda_verb alc662_ecs_init_verbs[] = {
18130 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18131 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18132 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18133 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18134 {}
18135};
18136
18137static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18138 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18139 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18140 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18141 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18142 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18143 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18144 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18145 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18146 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18147 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18148 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18149 {}
18150};
18151
18152static const struct hda_verb alc272_dell_init_verbs[] = {
18153 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18154 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18155 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18156 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18157 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18158 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18159 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18162 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18163 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18164 {}
18165};
18166
18167static const struct hda_verb alc663_mode7_init_verbs[] = {
18168 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18169 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18170 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18171 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18172 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18173 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18174 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18175 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18176 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18177 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18180 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18181 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18182 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18183 {}
18184};
18185
18186static const struct hda_verb alc663_mode8_init_verbs[] = {
18187 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18188 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18189 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18190 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18191 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18192 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18193 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18194 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18195 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18196 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18197 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18198 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18199 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18200 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18201 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18202 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18203 {}
18204};
18205
18206static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18207 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18208 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18209 { } /* end */
18210};
18211
18212static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18213 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18214 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18215 { } /* end */
18216};
18217
18218static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18219{
18220 struct alc_spec *spec = codec->spec;
18221
18222 spec->autocfg.hp_pins[0] = 0x1b;
18223 spec->autocfg.line_out_pins[0] = 0x14;
18224 spec->autocfg.speaker_pins[0] = 0x15;
18225 spec->automute = 1;
18226 spec->detect_line = 1;
18227 spec->automute_lines = 1;
18228 spec->automute_mode = ALC_AUTOMUTE_AMP;
18229}
18230
18231static void alc662_eeepc_setup(struct hda_codec *codec)
18232{
18233 struct alc_spec *spec = codec->spec;
18234
18235 alc262_hippo1_setup(codec);
18236 spec->ext_mic.pin = 0x18;
18237 spec->ext_mic.mux_idx = 0;
18238 spec->int_mic.pin = 0x19;
18239 spec->int_mic.mux_idx = 1;
18240 spec->auto_mic = 1;
18241}
18242
18243static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18244{
18245 struct alc_spec *spec = codec->spec;
18246
18247 spec->autocfg.hp_pins[0] = 0x14;
18248 spec->autocfg.speaker_pins[0] = 0x1b;
18249 spec->automute = 1;
18250 spec->automute_mode = ALC_AUTOMUTE_AMP;
18251}
18252
18253static void alc663_m51va_setup(struct hda_codec *codec)
18254{
18255 struct alc_spec *spec = codec->spec;
18256 spec->autocfg.hp_pins[0] = 0x21;
18257 spec->autocfg.speaker_pins[0] = 0x14;
18258 spec->automute_mixer_nid[0] = 0x0c;
18259 spec->automute = 1;
18260 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18261 spec->ext_mic.pin = 0x18;
18262 spec->ext_mic.mux_idx = 0;
18263 spec->int_mic.pin = 0x12;
18264 spec->int_mic.mux_idx = 9;
18265 spec->auto_mic = 1;
18266}
18267
18268/* ***************** Mode1 ******************************/
18269static void alc663_mode1_setup(struct hda_codec *codec)
18270{
18271 struct alc_spec *spec = codec->spec;
18272 spec->autocfg.hp_pins[0] = 0x21;
18273 spec->autocfg.speaker_pins[0] = 0x14;
18274 spec->automute_mixer_nid[0] = 0x0c;
18275 spec->automute = 1;
18276 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18277 spec->ext_mic.pin = 0x18;
18278 spec->ext_mic.mux_idx = 0;
18279 spec->int_mic.pin = 0x19;
18280 spec->int_mic.mux_idx = 1;
18281 spec->auto_mic = 1;
18282}
18283
18284/* ***************** Mode2 ******************************/
18285static void alc662_mode2_setup(struct hda_codec *codec)
18286{
18287 struct alc_spec *spec = codec->spec;
18288 spec->autocfg.hp_pins[0] = 0x1b;
18289 spec->autocfg.speaker_pins[0] = 0x14;
18290 spec->automute = 1;
18291 spec->automute_mode = ALC_AUTOMUTE_PIN;
18292 spec->ext_mic.pin = 0x18;
18293 spec->ext_mic.mux_idx = 0;
18294 spec->int_mic.pin = 0x19;
18295 spec->int_mic.mux_idx = 1;
18296 spec->auto_mic = 1;
18297}
18298
18299/* ***************** Mode3 ******************************/
18300static void alc663_mode3_setup(struct hda_codec *codec)
18301{
18302 struct alc_spec *spec = codec->spec;
18303 spec->autocfg.hp_pins[0] = 0x21;
18304 spec->autocfg.hp_pins[0] = 0x15;
18305 spec->autocfg.speaker_pins[0] = 0x14;
18306 spec->automute = 1;
18307 spec->automute_mode = ALC_AUTOMUTE_PIN;
18308 spec->ext_mic.pin = 0x18;
18309 spec->ext_mic.mux_idx = 0;
18310 spec->int_mic.pin = 0x19;
18311 spec->int_mic.mux_idx = 1;
18312 spec->auto_mic = 1;
18313}
18314
18315/* ***************** Mode4 ******************************/
18316static void alc663_mode4_setup(struct hda_codec *codec)
18317{
18318 struct alc_spec *spec = codec->spec;
18319 spec->autocfg.hp_pins[0] = 0x21;
18320 spec->autocfg.speaker_pins[0] = 0x14;
18321 spec->autocfg.speaker_pins[1] = 0x16;
18322 spec->automute_mixer_nid[0] = 0x0c;
18323 spec->automute_mixer_nid[1] = 0x0e;
18324 spec->automute = 1;
18325 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18326 spec->ext_mic.pin = 0x18;
18327 spec->ext_mic.mux_idx = 0;
18328 spec->int_mic.pin = 0x19;
18329 spec->int_mic.mux_idx = 1;
18330 spec->auto_mic = 1;
18331}
18332
18333/* ***************** Mode5 ******************************/
18334static void alc663_mode5_setup(struct hda_codec *codec)
18335{
18336 struct alc_spec *spec = codec->spec;
18337 spec->autocfg.hp_pins[0] = 0x15;
18338 spec->autocfg.speaker_pins[0] = 0x14;
18339 spec->autocfg.speaker_pins[1] = 0x16;
18340 spec->automute_mixer_nid[0] = 0x0c;
18341 spec->automute_mixer_nid[1] = 0x0e;
18342 spec->automute = 1;
18343 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18344 spec->ext_mic.pin = 0x18;
18345 spec->ext_mic.mux_idx = 0;
18346 spec->int_mic.pin = 0x19;
18347 spec->int_mic.mux_idx = 1;
18348 spec->auto_mic = 1;
18349}
18350
18351/* ***************** Mode6 ******************************/
18352static void alc663_mode6_setup(struct hda_codec *codec)
18353{
18354 struct alc_spec *spec = codec->spec;
18355 spec->autocfg.hp_pins[0] = 0x1b;
18356 spec->autocfg.hp_pins[0] = 0x15;
18357 spec->autocfg.speaker_pins[0] = 0x14;
18358 spec->automute_mixer_nid[0] = 0x0c;
18359 spec->automute = 1;
18360 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18361 spec->ext_mic.pin = 0x18;
18362 spec->ext_mic.mux_idx = 0;
18363 spec->int_mic.pin = 0x19;
18364 spec->int_mic.mux_idx = 1;
18365 spec->auto_mic = 1;
18366}
18367
18368/* ***************** Mode7 ******************************/
18369static void alc663_mode7_setup(struct hda_codec *codec)
18370{
18371 struct alc_spec *spec = codec->spec;
18372 spec->autocfg.hp_pins[0] = 0x1b;
18373 spec->autocfg.hp_pins[0] = 0x21;
18374 spec->autocfg.speaker_pins[0] = 0x14;
18375 spec->autocfg.speaker_pins[0] = 0x17;
18376 spec->automute = 1;
18377 spec->automute_mode = ALC_AUTOMUTE_PIN;
18378 spec->ext_mic.pin = 0x18;
18379 spec->ext_mic.mux_idx = 0;
18380 spec->int_mic.pin = 0x19;
18381 spec->int_mic.mux_idx = 1;
18382 spec->auto_mic = 1;
18383}
18384
18385/* ***************** Mode8 ******************************/
18386static void alc663_mode8_setup(struct hda_codec *codec)
18387{
18388 struct alc_spec *spec = codec->spec;
18389 spec->autocfg.hp_pins[0] = 0x21;
18390 spec->autocfg.hp_pins[1] = 0x15;
18391 spec->autocfg.speaker_pins[0] = 0x14;
18392 spec->autocfg.speaker_pins[0] = 0x17;
18393 spec->automute = 1;
18394 spec->automute_mode = ALC_AUTOMUTE_PIN;
18395 spec->ext_mic.pin = 0x18;
18396 spec->ext_mic.mux_idx = 0;
18397 spec->int_mic.pin = 0x12;
18398 spec->int_mic.mux_idx = 9;
18399 spec->auto_mic = 1;
18400}
18401
18402static void alc663_g71v_setup(struct hda_codec *codec)
18403{
18404 struct alc_spec *spec = codec->spec;
18405 spec->autocfg.hp_pins[0] = 0x21;
18406 spec->autocfg.line_out_pins[0] = 0x15;
18407 spec->autocfg.speaker_pins[0] = 0x14;
18408 spec->automute = 1;
18409 spec->automute_mode = ALC_AUTOMUTE_AMP;
18410 spec->detect_line = 1;
18411 spec->automute_lines = 1;
18412 spec->ext_mic.pin = 0x18;
18413 spec->ext_mic.mux_idx = 0;
18414 spec->int_mic.pin = 0x12;
18415 spec->int_mic.mux_idx = 9;
18416 spec->auto_mic = 1;
18417}
18418
18419#define alc663_g50v_setup alc663_m51va_setup
18420
18421static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18422 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18423 ALC262_HIPPO_MASTER_SWITCH,
18424
18425 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18426 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18427 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18428
18429 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18430 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18431 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18432 { } /* end */
18433};
18434
18435static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18436 /* Master Playback automatically created from Speaker and Headphone */
18437 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18438 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18439 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18440 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18441
18442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18443 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18444 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18445
18446 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18447 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18448 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18449 { } /* end */
18450};
18451
18452#ifdef CONFIG_SND_HDA_POWER_SAVE 5030#ifdef CONFIG_SND_HDA_POWER_SAVE
18453#define alc662_loopbacks alc880_loopbacks 5031#define alc662_loopbacks alc880_loopbacks
18454#endif 5032#endif
18455 5033
18456
18457/* pcm configuration: identical with ALC880 */
18458#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18459#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18460#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18461#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18462
18463/*
18464 * configuration and preset
18465 */
18466static const char * const alc662_models[ALC662_MODEL_LAST] = {
18467 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18468 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18469 [ALC662_3ST_6ch] = "3stack-6ch",
18470 [ALC662_5ST_DIG] = "5stack-dig",
18471 [ALC662_LENOVO_101E] = "lenovo-101e",
18472 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18473 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18474 [ALC662_ECS] = "ecs",
18475 [ALC663_ASUS_M51VA] = "m51va",
18476 [ALC663_ASUS_G71V] = "g71v",
18477 [ALC663_ASUS_H13] = "h13",
18478 [ALC663_ASUS_G50V] = "g50v",
18479 [ALC663_ASUS_MODE1] = "asus-mode1",
18480 [ALC662_ASUS_MODE2] = "asus-mode2",
18481 [ALC663_ASUS_MODE3] = "asus-mode3",
18482 [ALC663_ASUS_MODE4] = "asus-mode4",
18483 [ALC663_ASUS_MODE5] = "asus-mode5",
18484 [ALC663_ASUS_MODE6] = "asus-mode6",
18485 [ALC663_ASUS_MODE7] = "asus-mode7",
18486 [ALC663_ASUS_MODE8] = "asus-mode8",
18487 [ALC272_DELL] = "dell",
18488 [ALC272_DELL_ZM1] = "dell-zm1",
18489 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18490 [ALC662_AUTO] = "auto",
18491};
18492
18493static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18494 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18495 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18496 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18497 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18498 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18499 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18500 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18501 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18502 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18503 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18504 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18505 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18506 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18507 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18508 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18509 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18510 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18511 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18512 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18513 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18514 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18515 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18516 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18517 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18518 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18519 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18520 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18521 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18522 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18523 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18524 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18525 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18526 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18527 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18528 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18529 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18530 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18531 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18532 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18533 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18534 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18535 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18536 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18537 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18538 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18539 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18540 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18541 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18542 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18543 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18544 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18545 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18546 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18547 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18548 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18549 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18550 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18551 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18552 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18553 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18554 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18555 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18556 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18557 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18558 ALC662_3ST_6ch_DIG),
18559 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18560 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18561 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18562 ALC662_3ST_6ch_DIG),
18563 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18564 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18565 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18566 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18567 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18568 ALC662_3ST_6ch_DIG),
18569 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18570 ALC663_ASUS_H13),
18571 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18572 {}
18573};
18574
18575static const struct alc_config_preset alc662_presets[] = {
18576 [ALC662_3ST_2ch_DIG] = {
18577 .mixers = { alc662_3ST_2ch_mixer },
18578 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18579 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18580 .dac_nids = alc662_dac_nids,
18581 .dig_out_nid = ALC662_DIGOUT_NID,
18582 .dig_in_nid = ALC662_DIGIN_NID,
18583 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18584 .channel_mode = alc662_3ST_2ch_modes,
18585 .input_mux = &alc662_capture_source,
18586 },
18587 [ALC662_3ST_6ch_DIG] = {
18588 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18589 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18590 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18591 .dac_nids = alc662_dac_nids,
18592 .dig_out_nid = ALC662_DIGOUT_NID,
18593 .dig_in_nid = ALC662_DIGIN_NID,
18594 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18595 .channel_mode = alc662_3ST_6ch_modes,
18596 .need_dac_fix = 1,
18597 .input_mux = &alc662_capture_source,
18598 },
18599 [ALC662_3ST_6ch] = {
18600 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18601 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18602 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18603 .dac_nids = alc662_dac_nids,
18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18605 .channel_mode = alc662_3ST_6ch_modes,
18606 .need_dac_fix = 1,
18607 .input_mux = &alc662_capture_source,
18608 },
18609 [ALC662_5ST_DIG] = {
18610 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18611 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18612 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18613 .dac_nids = alc662_dac_nids,
18614 .dig_out_nid = ALC662_DIGOUT_NID,
18615 .dig_in_nid = ALC662_DIGIN_NID,
18616 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18617 .channel_mode = alc662_5stack_modes,
18618 .input_mux = &alc662_capture_source,
18619 },
18620 [ALC662_LENOVO_101E] = {
18621 .mixers = { alc662_lenovo_101e_mixer },
18622 .init_verbs = { alc662_init_verbs,
18623 alc662_eapd_init_verbs,
18624 alc662_sue_init_verbs },
18625 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18626 .dac_nids = alc662_dac_nids,
18627 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18628 .channel_mode = alc662_3ST_2ch_modes,
18629 .input_mux = &alc662_lenovo_101e_capture_source,
18630 .unsol_event = alc_sku_unsol_event,
18631 .setup = alc662_lenovo_101e_setup,
18632 .init_hook = alc_inithook,
18633 },
18634 [ALC662_ASUS_EEEPC_P701] = {
18635 .mixers = { alc662_eeepc_p701_mixer },
18636 .init_verbs = { alc662_init_verbs,
18637 alc662_eapd_init_verbs,
18638 alc662_eeepc_sue_init_verbs },
18639 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18640 .dac_nids = alc662_dac_nids,
18641 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18642 .channel_mode = alc662_3ST_2ch_modes,
18643 .unsol_event = alc_sku_unsol_event,
18644 .setup = alc662_eeepc_setup,
18645 .init_hook = alc_inithook,
18646 },
18647 [ALC662_ASUS_EEEPC_EP20] = {
18648 .mixers = { alc662_eeepc_ep20_mixer,
18649 alc662_chmode_mixer },
18650 .init_verbs = { alc662_init_verbs,
18651 alc662_eapd_init_verbs,
18652 alc662_eeepc_ep20_sue_init_verbs },
18653 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18654 .dac_nids = alc662_dac_nids,
18655 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18656 .channel_mode = alc662_3ST_6ch_modes,
18657 .input_mux = &alc662_lenovo_101e_capture_source,
18658 .unsol_event = alc_sku_unsol_event,
18659 .setup = alc662_eeepc_ep20_setup,
18660 .init_hook = alc_inithook,
18661 },
18662 [ALC662_ECS] = {
18663 .mixers = { alc662_ecs_mixer },
18664 .init_verbs = { alc662_init_verbs,
18665 alc662_eapd_init_verbs,
18666 alc662_ecs_init_verbs },
18667 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18668 .dac_nids = alc662_dac_nids,
18669 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18670 .channel_mode = alc662_3ST_2ch_modes,
18671 .unsol_event = alc_sku_unsol_event,
18672 .setup = alc662_eeepc_setup,
18673 .init_hook = alc_inithook,
18674 },
18675 [ALC663_ASUS_M51VA] = {
18676 .mixers = { alc663_m51va_mixer },
18677 .init_verbs = { alc662_init_verbs,
18678 alc662_eapd_init_verbs,
18679 alc663_m51va_init_verbs },
18680 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18681 .dac_nids = alc662_dac_nids,
18682 .dig_out_nid = ALC662_DIGOUT_NID,
18683 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18684 .channel_mode = alc662_3ST_2ch_modes,
18685 .unsol_event = alc_sku_unsol_event,
18686 .setup = alc663_m51va_setup,
18687 .init_hook = alc_inithook,
18688 },
18689 [ALC663_ASUS_G71V] = {
18690 .mixers = { alc663_g71v_mixer },
18691 .init_verbs = { alc662_init_verbs,
18692 alc662_eapd_init_verbs,
18693 alc663_g71v_init_verbs },
18694 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18695 .dac_nids = alc662_dac_nids,
18696 .dig_out_nid = ALC662_DIGOUT_NID,
18697 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18698 .channel_mode = alc662_3ST_2ch_modes,
18699 .unsol_event = alc_sku_unsol_event,
18700 .setup = alc663_g71v_setup,
18701 .init_hook = alc_inithook,
18702 },
18703 [ALC663_ASUS_H13] = {
18704 .mixers = { alc663_m51va_mixer },
18705 .init_verbs = { alc662_init_verbs,
18706 alc662_eapd_init_verbs,
18707 alc663_m51va_init_verbs },
18708 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18709 .dac_nids = alc662_dac_nids,
18710 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18711 .channel_mode = alc662_3ST_2ch_modes,
18712 .setup = alc663_m51va_setup,
18713 .unsol_event = alc_sku_unsol_event,
18714 .init_hook = alc_inithook,
18715 },
18716 [ALC663_ASUS_G50V] = {
18717 .mixers = { alc663_g50v_mixer },
18718 .init_verbs = { alc662_init_verbs,
18719 alc662_eapd_init_verbs,
18720 alc663_g50v_init_verbs },
18721 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18722 .dac_nids = alc662_dac_nids,
18723 .dig_out_nid = ALC662_DIGOUT_NID,
18724 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18725 .channel_mode = alc662_3ST_6ch_modes,
18726 .input_mux = &alc663_capture_source,
18727 .unsol_event = alc_sku_unsol_event,
18728 .setup = alc663_g50v_setup,
18729 .init_hook = alc_inithook,
18730 },
18731 [ALC663_ASUS_MODE1] = {
18732 .mixers = { alc663_m51va_mixer },
18733 .cap_mixer = alc662_auto_capture_mixer,
18734 .init_verbs = { alc662_init_verbs,
18735 alc662_eapd_init_verbs,
18736 alc663_21jd_amic_init_verbs },
18737 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18738 .hp_nid = 0x03,
18739 .dac_nids = alc662_dac_nids,
18740 .dig_out_nid = ALC662_DIGOUT_NID,
18741 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18742 .channel_mode = alc662_3ST_2ch_modes,
18743 .unsol_event = alc_sku_unsol_event,
18744 .setup = alc663_mode1_setup,
18745 .init_hook = alc_inithook,
18746 },
18747 [ALC662_ASUS_MODE2] = {
18748 .mixers = { alc662_1bjd_mixer },
18749 .cap_mixer = alc662_auto_capture_mixer,
18750 .init_verbs = { alc662_init_verbs,
18751 alc662_eapd_init_verbs,
18752 alc662_1bjd_amic_init_verbs },
18753 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18754 .dac_nids = alc662_dac_nids,
18755 .dig_out_nid = ALC662_DIGOUT_NID,
18756 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18757 .channel_mode = alc662_3ST_2ch_modes,
18758 .unsol_event = alc_sku_unsol_event,
18759 .setup = alc662_mode2_setup,
18760 .init_hook = alc_inithook,
18761 },
18762 [ALC663_ASUS_MODE3] = {
18763 .mixers = { alc663_two_hp_m1_mixer },
18764 .cap_mixer = alc662_auto_capture_mixer,
18765 .init_verbs = { alc662_init_verbs,
18766 alc662_eapd_init_verbs,
18767 alc663_two_hp_amic_m1_init_verbs },
18768 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18769 .hp_nid = 0x03,
18770 .dac_nids = alc662_dac_nids,
18771 .dig_out_nid = ALC662_DIGOUT_NID,
18772 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18773 .channel_mode = alc662_3ST_2ch_modes,
18774 .unsol_event = alc_sku_unsol_event,
18775 .setup = alc663_mode3_setup,
18776 .init_hook = alc_inithook,
18777 },
18778 [ALC663_ASUS_MODE4] = {
18779 .mixers = { alc663_asus_21jd_clfe_mixer },
18780 .cap_mixer = alc662_auto_capture_mixer,
18781 .init_verbs = { alc662_init_verbs,
18782 alc662_eapd_init_verbs,
18783 alc663_21jd_amic_init_verbs},
18784 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18785 .hp_nid = 0x03,
18786 .dac_nids = alc662_dac_nids,
18787 .dig_out_nid = ALC662_DIGOUT_NID,
18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18789 .channel_mode = alc662_3ST_2ch_modes,
18790 .unsol_event = alc_sku_unsol_event,
18791 .setup = alc663_mode4_setup,
18792 .init_hook = alc_inithook,
18793 },
18794 [ALC663_ASUS_MODE5] = {
18795 .mixers = { alc663_asus_15jd_clfe_mixer },
18796 .cap_mixer = alc662_auto_capture_mixer,
18797 .init_verbs = { alc662_init_verbs,
18798 alc662_eapd_init_verbs,
18799 alc663_15jd_amic_init_verbs },
18800 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18801 .hp_nid = 0x03,
18802 .dac_nids = alc662_dac_nids,
18803 .dig_out_nid = ALC662_DIGOUT_NID,
18804 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18805 .channel_mode = alc662_3ST_2ch_modes,
18806 .unsol_event = alc_sku_unsol_event,
18807 .setup = alc663_mode5_setup,
18808 .init_hook = alc_inithook,
18809 },
18810 [ALC663_ASUS_MODE6] = {
18811 .mixers = { alc663_two_hp_m2_mixer },
18812 .cap_mixer = alc662_auto_capture_mixer,
18813 .init_verbs = { alc662_init_verbs,
18814 alc662_eapd_init_verbs,
18815 alc663_two_hp_amic_m2_init_verbs },
18816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18817 .hp_nid = 0x03,
18818 .dac_nids = alc662_dac_nids,
18819 .dig_out_nid = ALC662_DIGOUT_NID,
18820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18821 .channel_mode = alc662_3ST_2ch_modes,
18822 .unsol_event = alc_sku_unsol_event,
18823 .setup = alc663_mode6_setup,
18824 .init_hook = alc_inithook,
18825 },
18826 [ALC663_ASUS_MODE7] = {
18827 .mixers = { alc663_mode7_mixer },
18828 .cap_mixer = alc662_auto_capture_mixer,
18829 .init_verbs = { alc662_init_verbs,
18830 alc662_eapd_init_verbs,
18831 alc663_mode7_init_verbs },
18832 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18833 .hp_nid = 0x03,
18834 .dac_nids = alc662_dac_nids,
18835 .dig_out_nid = ALC662_DIGOUT_NID,
18836 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18837 .channel_mode = alc662_3ST_2ch_modes,
18838 .unsol_event = alc_sku_unsol_event,
18839 .setup = alc663_mode7_setup,
18840 .init_hook = alc_inithook,
18841 },
18842 [ALC663_ASUS_MODE8] = {
18843 .mixers = { alc663_mode8_mixer },
18844 .cap_mixer = alc662_auto_capture_mixer,
18845 .init_verbs = { alc662_init_verbs,
18846 alc662_eapd_init_verbs,
18847 alc663_mode8_init_verbs },
18848 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18849 .hp_nid = 0x03,
18850 .dac_nids = alc662_dac_nids,
18851 .dig_out_nid = ALC662_DIGOUT_NID,
18852 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18853 .channel_mode = alc662_3ST_2ch_modes,
18854 .unsol_event = alc_sku_unsol_event,
18855 .setup = alc663_mode8_setup,
18856 .init_hook = alc_inithook,
18857 },
18858 [ALC272_DELL] = {
18859 .mixers = { alc663_m51va_mixer },
18860 .cap_mixer = alc272_auto_capture_mixer,
18861 .init_verbs = { alc662_init_verbs,
18862 alc662_eapd_init_verbs,
18863 alc272_dell_init_verbs },
18864 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18865 .dac_nids = alc272_dac_nids,
18866 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18867 .adc_nids = alc272_adc_nids,
18868 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18869 .capsrc_nids = alc272_capsrc_nids,
18870 .channel_mode = alc662_3ST_2ch_modes,
18871 .unsol_event = alc_sku_unsol_event,
18872 .setup = alc663_m51va_setup,
18873 .init_hook = alc_inithook,
18874 },
18875 [ALC272_DELL_ZM1] = {
18876 .mixers = { alc663_m51va_mixer },
18877 .cap_mixer = alc662_auto_capture_mixer,
18878 .init_verbs = { alc662_init_verbs,
18879 alc662_eapd_init_verbs,
18880 alc272_dell_zm1_init_verbs },
18881 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18882 .dac_nids = alc272_dac_nids,
18883 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18884 .adc_nids = alc662_adc_nids,
18885 .num_adc_nids = 1,
18886 .capsrc_nids = alc662_capsrc_nids,
18887 .channel_mode = alc662_3ST_2ch_modes,
18888 .unsol_event = alc_sku_unsol_event,
18889 .setup = alc663_m51va_setup,
18890 .init_hook = alc_inithook,
18891 },
18892 [ALC272_SAMSUNG_NC10] = {
18893 .mixers = { alc272_nc10_mixer },
18894 .init_verbs = { alc662_init_verbs,
18895 alc662_eapd_init_verbs,
18896 alc663_21jd_amic_init_verbs },
18897 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18898 .dac_nids = alc272_dac_nids,
18899 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18900 .channel_mode = alc662_3ST_2ch_modes,
18901 /*.input_mux = &alc272_nc10_capture_source,*/
18902 .unsol_event = alc_sku_unsol_event,
18903 .setup = alc663_mode4_setup,
18904 .init_hook = alc_inithook,
18905 },
18906};
18907
18908
18909/* 5034/*
18910 * BIOS auto configuration 5035 * BIOS auto configuration
18911 */ 5036 */
18912 5037
18913/* convert from MIX nid to DAC */
18914static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18915{
18916 hda_nid_t list[5];
18917 int i, num;
18918
18919 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18920 for (i = 0; i < num; i++) {
18921 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18922 return list[i];
18923 }
18924 return 0;
18925}
18926
18927/* go down to the selector widget before the mixer */
18928static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18929{
18930 hda_nid_t srcs[5];
18931 int num = snd_hda_get_connections(codec, pin, srcs,
18932 ARRAY_SIZE(srcs));
18933 if (num != 1 ||
18934 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18935 return pin;
18936 return srcs[0];
18937}
18938
18939/* get MIX nid connected to the given pin targeted to DAC */
18940static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18941 hda_nid_t dac)
18942{
18943 hda_nid_t mix[5];
18944 int i, num;
18945
18946 pin = alc_go_down_to_selector(codec, pin);
18947 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18948 for (i = 0; i < num; i++) {
18949 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18950 return mix[i];
18951 }
18952 return 0;
18953}
18954
18955/* select the connection from pin to DAC if needed */
18956static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18957 hda_nid_t dac)
18958{
18959 hda_nid_t mix[5];
18960 int i, num;
18961
18962 pin = alc_go_down_to_selector(codec, pin);
18963 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18964 if (num < 2)
18965 return 0;
18966 for (i = 0; i < num; i++) {
18967 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18968 snd_hda_codec_update_cache(codec, pin, 0,
18969 AC_VERB_SET_CONNECT_SEL, i);
18970 return 0;
18971 }
18972 }
18973 return 0;
18974}
18975
18976/* look for an empty DAC slot */
18977static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18978{
18979 struct alc_spec *spec = codec->spec;
18980 hda_nid_t srcs[5];
18981 int i, j, num;
18982
18983 pin = alc_go_down_to_selector(codec, pin);
18984 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18985 for (i = 0; i < num; i++) {
18986 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18987 if (!nid)
18988 continue;
18989 for (j = 0; j < spec->multiout.num_dacs; j++)
18990 if (spec->multiout.dac_nids[j] == nid)
18991 break;
18992 if (j >= spec->multiout.num_dacs)
18993 return nid;
18994 }
18995 return 0;
18996}
18997
18998/* fill in the dac_nids table from the parsed pin configuration */
18999static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19000 const struct auto_pin_cfg *cfg)
19001{
19002 struct alc_spec *spec = codec->spec;
19003 int i;
19004 hda_nid_t dac;
19005
19006 spec->multiout.dac_nids = spec->private_dac_nids;
19007 for (i = 0; i < cfg->line_outs; i++) {
19008 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
19009 if (!dac)
19010 continue;
19011 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19012 }
19013 return 0;
19014}
19015
19016static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19017 hda_nid_t nid, int idx, unsigned int chs)
19018{
19019 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19020 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19021}
19022
19023static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19024 hda_nid_t nid, int idx, unsigned int chs)
19025{
19026 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19027 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19028}
19029
19030#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19031 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19032#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19033 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19034#define alc662_add_stereo_vol(spec, pfx, nid) \
19035 alc662_add_vol_ctl(spec, pfx, nid, 3)
19036#define alc662_add_stereo_sw(spec, pfx, nid) \
19037 alc662_add_sw_ctl(spec, pfx, nid, 3)
19038
19039/* add playback controls from the parsed DAC table */
19040static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19041 const struct auto_pin_cfg *cfg)
19042{
19043 struct alc_spec *spec = codec->spec;
19044 static const char * const chname[4] = {
19045 "Front", "Surround", NULL /*CLFE*/, "Side"
19046 };
19047 const char *pfx = alc_get_line_out_pfx(spec, true);
19048 hda_nid_t nid, mix, pin;
19049 int i, err, noutputs;
19050
19051 noutputs = cfg->line_outs;
19052 if (spec->multi_ios > 0)
19053 noutputs += spec->multi_ios;
19054
19055 for (i = 0; i < noutputs; i++) {
19056 nid = spec->multiout.dac_nids[i];
19057 if (!nid)
19058 continue;
19059 if (i >= cfg->line_outs)
19060 pin = spec->multi_io[i - 1].pin;
19061 else
19062 pin = cfg->line_out_pins[i];
19063 mix = alc_auto_dac_to_mix(codec, pin, nid);
19064 if (!mix)
19065 continue;
19066 if (!pfx && i == 2) {
19067 /* Center/LFE */
19068 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19069 if (err < 0)
19070 return err;
19071 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19072 if (err < 0)
19073 return err;
19074 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19075 if (err < 0)
19076 return err;
19077 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19078 if (err < 0)
19079 return err;
19080 } else {
19081 const char *name = pfx;
19082 int index = i;
19083 if (!name) {
19084 name = chname[i];
19085 index = 0;
19086 }
19087 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19088 if (err < 0)
19089 return err;
19090 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19091 if (err < 0)
19092 return err;
19093 }
19094 }
19095 return 0;
19096}
19097
19098/* add playback controls for speaker and HP outputs */
19099/* return DAC nid if any new DAC is assigned */
19100static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19101 const char *pfx)
19102{
19103 struct alc_spec *spec = codec->spec;
19104 hda_nid_t nid, mix;
19105 int err;
19106
19107 if (!pin)
19108 return 0;
19109 nid = alc_auto_look_for_dac(codec, pin);
19110 if (!nid) {
19111 /* the corresponding DAC is already occupied */
19112 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19113 return 0; /* no way */
19114 /* create a switch only */
19115 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19116 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19117 }
19118
19119 mix = alc_auto_dac_to_mix(codec, pin, nid);
19120 if (!mix)
19121 return 0;
19122 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19123 if (err < 0)
19124 return err;
19125 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19126 if (err < 0)
19127 return err;
19128 return nid;
19129}
19130
19131/* create playback/capture controls for input pins */
19132#define alc662_auto_create_input_ctls \
19133 alc882_auto_create_input_ctls
19134
19135static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19136 hda_nid_t nid, int pin_type,
19137 hda_nid_t dac)
19138{
19139 int i, num;
19140 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19141
19142 alc_set_pin_output(codec, nid, pin_type);
19143 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19144 for (i = 0; i < num; i++) {
19145 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19146 continue;
19147 /* need the manual connection? */
19148 if (num > 1)
19149 snd_hda_codec_write(codec, nid, 0,
19150 AC_VERB_SET_CONNECT_SEL, i);
19151 /* unmute mixer widget inputs */
19152 snd_hda_codec_write(codec, srcs[i], 0,
19153 AC_VERB_SET_AMP_GAIN_MUTE,
19154 AMP_IN_UNMUTE(0));
19155 snd_hda_codec_write(codec, srcs[i], 0,
19156 AC_VERB_SET_AMP_GAIN_MUTE,
19157 AMP_IN_UNMUTE(1));
19158 return;
19159 }
19160}
19161
19162static void alc662_auto_init_multi_out(struct hda_codec *codec)
19163{
19164 struct alc_spec *spec = codec->spec;
19165 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19166 int i;
19167
19168 for (i = 0; i <= HDA_SIDE; i++) {
19169 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19170 if (nid)
19171 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19172 spec->multiout.dac_nids[i]);
19173 }
19174}
19175
19176static void alc662_auto_init_hp_out(struct hda_codec *codec)
19177{
19178 struct alc_spec *spec = codec->spec;
19179 hda_nid_t pin;
19180
19181 pin = spec->autocfg.hp_pins[0];
19182 if (pin)
19183 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19184 spec->multiout.hp_nid);
19185 pin = spec->autocfg.speaker_pins[0];
19186 if (pin)
19187 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19188 spec->multiout.extra_out_nid[0]);
19189}
19190
19191#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19192
19193static void alc662_auto_init_analog_input(struct hda_codec *codec)
19194{
19195 struct alc_spec *spec = codec->spec;
19196 struct auto_pin_cfg *cfg = &spec->autocfg;
19197 int i;
19198
19199 for (i = 0; i < cfg->num_inputs; i++) {
19200 hda_nid_t nid = cfg->inputs[i].pin;
19201 if (alc_is_input_pin(codec, nid)) {
19202 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19203 if (nid != ALC662_PIN_CD_NID &&
19204 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19205 snd_hda_codec_write(codec, nid, 0,
19206 AC_VERB_SET_AMP_GAIN_MUTE,
19207 AMP_OUT_MUTE);
19208 }
19209 }
19210}
19211
19212#define alc662_auto_init_input_src alc882_auto_init_input_src
19213
19214/*
19215 * multi-io helper
19216 */
19217static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19218 unsigned int location)
19219{
19220 struct alc_spec *spec = codec->spec;
19221 struct auto_pin_cfg *cfg = &spec->autocfg;
19222 int type, i, num_pins = 0;
19223
19224 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19225 for (i = 0; i < cfg->num_inputs; i++) {
19226 hda_nid_t nid = cfg->inputs[i].pin;
19227 hda_nid_t dac;
19228 unsigned int defcfg, caps;
19229 if (cfg->inputs[i].type != type)
19230 continue;
19231 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19232 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19233 continue;
19234 if (location && get_defcfg_location(defcfg) != location)
19235 continue;
19236 caps = snd_hda_query_pin_caps(codec, nid);
19237 if (!(caps & AC_PINCAP_OUT))
19238 continue;
19239 dac = alc_auto_look_for_dac(codec, nid);
19240 if (!dac)
19241 continue;
19242 spec->multi_io[num_pins].pin = nid;
19243 spec->multi_io[num_pins].dac = dac;
19244 num_pins++;
19245 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19246 }
19247 }
19248 spec->multiout.num_dacs = 1;
19249 if (num_pins < 2)
19250 return 0;
19251 return num_pins;
19252}
19253
19254static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19255 struct snd_ctl_elem_info *uinfo)
19256{
19257 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19258 struct alc_spec *spec = codec->spec;
19259
19260 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19261 uinfo->count = 1;
19262 uinfo->value.enumerated.items = spec->multi_ios + 1;
19263 if (uinfo->value.enumerated.item > spec->multi_ios)
19264 uinfo->value.enumerated.item = spec->multi_ios;
19265 sprintf(uinfo->value.enumerated.name, "%dch",
19266 (uinfo->value.enumerated.item + 1) * 2);
19267 return 0;
19268}
19269
19270static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19271 struct snd_ctl_elem_value *ucontrol)
19272{
19273 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19274 struct alc_spec *spec = codec->spec;
19275 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19276 return 0;
19277}
19278
19279static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19280{
19281 struct alc_spec *spec = codec->spec;
19282 hda_nid_t nid = spec->multi_io[idx].pin;
19283
19284 if (!spec->multi_io[idx].ctl_in)
19285 spec->multi_io[idx].ctl_in =
19286 snd_hda_codec_read(codec, nid, 0,
19287 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19288 if (output) {
19289 snd_hda_codec_update_cache(codec, nid, 0,
19290 AC_VERB_SET_PIN_WIDGET_CONTROL,
19291 PIN_OUT);
19292 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19293 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19294 HDA_AMP_MUTE, 0);
19295 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19296 } else {
19297 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19298 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19299 HDA_AMP_MUTE, HDA_AMP_MUTE);
19300 snd_hda_codec_update_cache(codec, nid, 0,
19301 AC_VERB_SET_PIN_WIDGET_CONTROL,
19302 spec->multi_io[idx].ctl_in);
19303 }
19304 return 0;
19305}
19306
19307static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19308 struct snd_ctl_elem_value *ucontrol)
19309{
19310 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19311 struct alc_spec *spec = codec->spec;
19312 int i, ch;
19313
19314 ch = ucontrol->value.enumerated.item[0];
19315 if (ch < 0 || ch > spec->multi_ios)
19316 return -EINVAL;
19317 if (ch == (spec->ext_channel_count - 1) / 2)
19318 return 0;
19319 spec->ext_channel_count = (ch + 1) * 2;
19320 for (i = 0; i < spec->multi_ios; i++)
19321 alc_set_multi_io(codec, i, i < ch);
19322 spec->multiout.max_channels = spec->ext_channel_count;
19323 return 1;
19324}
19325
19326static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19327 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19328 .name = "Channel Mode",
19329 .info = alc_auto_ch_mode_info,
19330 .get = alc_auto_ch_mode_get,
19331 .put = alc_auto_ch_mode_put,
19332};
19333
19334static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19335{
19336 struct alc_spec *spec = codec->spec;
19337 struct auto_pin_cfg *cfg = &spec->autocfg;
19338 unsigned int location, defcfg;
19339 int num_pins;
19340
19341 if (cfg->line_outs != 1 ||
19342 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19343 return 0;
19344
19345 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19346 location = get_defcfg_location(defcfg);
19347
19348 num_pins = alc_auto_fill_multi_ios(codec, location);
19349 if (num_pins > 0) {
19350 struct snd_kcontrol_new *knew;
19351
19352 knew = alc_kcontrol_new(spec);
19353 if (!knew)
19354 return -ENOMEM;
19355 *knew = alc_auto_channel_mode_enum;
19356 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19357 if (!knew->name)
19358 return -ENOMEM;
19359
19360 spec->multi_ios = num_pins;
19361 spec->ext_channel_count = 2;
19362 spec->multiout.num_dacs = num_pins + 1;
19363 }
19364 return 0;
19365}
19366
19367static int alc662_parse_auto_config(struct hda_codec *codec) 5038static int alc662_parse_auto_config(struct hda_codec *codec)
19368{ 5039{
19369 struct alc_spec *spec = codec->spec;
19370 int err;
19371 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 5040 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19372 5041 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
19373 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5042 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
19374 alc662_ignore); 5043 const hda_nid_t *ssids;
19375 if (err < 0)
19376 return err;
19377 if (!spec->autocfg.line_outs)
19378 return 0; /* can't find valid BIOS pin config */
19379
19380 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19381 if (err < 0)
19382 return err;
19383 err = alc_auto_add_multi_channel_mode(codec);
19384 if (err < 0)
19385 return err;
19386 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19387 if (err < 0)
19388 return err;
19389 err = alc662_auto_create_extra_out(codec,
19390 spec->autocfg.speaker_pins[0],
19391 "Speaker");
19392 if (err < 0)
19393 return err;
19394 if (err)
19395 spec->multiout.extra_out_nid[0] = err;
19396 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19397 "Headphone");
19398 if (err < 0)
19399 return err;
19400 if (err)
19401 spec->multiout.hp_nid = err;
19402 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19403 if (err < 0)
19404 return err;
19405
19406 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19407
19408 alc_auto_parse_digital(codec);
19409
19410 if (spec->kctls.list)
19411 add_mixer(spec, spec->kctls.list);
19412
19413 spec->num_mux_defs = 1;
19414 spec->input_mux = &spec->private_imux[0];
19415
19416 err = alc_auto_add_mic_boost(codec);
19417 if (err < 0)
19418 return err;
19419 5044
19420 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 5045 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19421 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 5046 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19422 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 5047 ssids = alc663_ssids;
19423 else 5048 else
19424 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5049 ssids = alc662_ssids;
19425 5050 return alc_parse_auto_config(codec, alc662_ignore, ssids);
19426 return 1;
19427}
19428
19429/* additional initialization for auto-configuration model */
19430static void alc662_auto_init(struct hda_codec *codec)
19431{
19432 struct alc_spec *spec = codec->spec;
19433 alc662_auto_init_multi_out(codec);
19434 alc662_auto_init_hp_out(codec);
19435 alc662_auto_init_analog_input(codec);
19436 alc662_auto_init_input_src(codec);
19437 alc_auto_init_digital(codec);
19438 if (spec->unsol_event)
19439 alc_inithook(codec);
19440} 5051}
19441 5052
19442static void alc272_fixup_mario(struct hda_codec *codec, 5053static void alc272_fixup_mario(struct hda_codec *codec,
@@ -19459,6 +5070,7 @@ enum {
19459 ALC272_FIXUP_MARIO, 5070 ALC272_FIXUP_MARIO,
19460 ALC662_FIXUP_CZC_P10T, 5071 ALC662_FIXUP_CZC_P10T,
19461 ALC662_FIXUP_SKU_IGNORE, 5072 ALC662_FIXUP_SKU_IGNORE,
5073 ALC662_FIXUP_HP_RP5800,
19462}; 5074};
19463 5075
19464static const struct alc_fixup alc662_fixups[] = { 5076static const struct alc_fixup alc662_fixups[] = {
@@ -19491,12 +5103,22 @@ static const struct alc_fixup alc662_fixups[] = {
19491 .type = ALC_FIXUP_SKU, 5103 .type = ALC_FIXUP_SKU,
19492 .v.sku = ALC_FIXUP_SKU_IGNORE, 5104 .v.sku = ALC_FIXUP_SKU_IGNORE,
19493 }, 5105 },
5106 [ALC662_FIXUP_HP_RP5800] = {
5107 .type = ALC_FIXUP_PINS,
5108 .v.pins = (const struct alc_pincfg[]) {
5109 { 0x14, 0x0221201f }, /* HP out */
5110 { }
5111 },
5112 .chained = true,
5113 .chain_id = ALC662_FIXUP_SKU_IGNORE
5114 },
19494}; 5115};
19495 5116
19496static const struct snd_pci_quirk alc662_fixup_tbl[] = { 5117static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19497 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 5118 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19498 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 5119 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19499 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 5120 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5121 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
19500 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 5122 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19501 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 5123 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19502 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 5124 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
@@ -19510,6 +5132,12 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
19510}; 5132};
19511 5133
19512 5134
5135/*
5136 */
5137#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5138#include "alc662_quirks.c"
5139#endif
5140
19513static int patch_alc662(struct hda_codec *codec) 5141static int patch_alc662(struct hda_codec *codec)
19514{ 5142{
19515 struct alc_spec *spec; 5143 struct alc_spec *spec;
@@ -19522,6 +5150,8 @@ static int patch_alc662(struct hda_codec *codec)
19522 5150
19523 codec->spec = spec; 5151 codec->spec = spec;
19524 5152
5153 spec->mixer_nid = 0x0b;
5154
19525 alc_auto_parse_customize_define(codec); 5155 alc_auto_parse_customize_define(codec);
19526 5156
19527 alc_fix_pll_init(codec, 0x20, 0x04, 15); 5157 alc_fix_pll_init(codec, 0x20, 0x04, 15);
@@ -19536,16 +5166,15 @@ static int patch_alc662(struct hda_codec *codec)
19536 else if (coef == 0x4011) 5166 else if (coef == 0x4011)
19537 alc_codec_rename(codec, "ALC656"); 5167 alc_codec_rename(codec, "ALC656");
19538 5168
19539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 5169 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
19540 alc662_models, 5170 alc662_models, alc662_cfg_tbl);
19541 alc662_cfg_tbl);
19542 if (board_config < 0) { 5171 if (board_config < 0) {
19543 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5172 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19544 codec->chip_name); 5173 codec->chip_name);
19545 board_config = ALC662_AUTO; 5174 board_config = ALC_MODEL_AUTO;
19546 } 5175 }
19547 5176
19548 if (board_config == ALC662_AUTO) { 5177 if (board_config == ALC_MODEL_AUTO) {
19549 alc_pick_fixup(codec, alc662_fixup_models, 5178 alc_pick_fixup(codec, alc662_fixup_models,
19550 alc662_fixup_tbl, alc662_fixups); 5179 alc662_fixup_tbl, alc662_fixups);
19551 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5180 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
@@ -19554,42 +5183,35 @@ static int patch_alc662(struct hda_codec *codec)
19554 if (err < 0) { 5183 if (err < 0) {
19555 alc_free(codec); 5184 alc_free(codec);
19556 return err; 5185 return err;
19557 } else if (!err) { 5186 }
5187#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5188 else if (!err) {
19558 printk(KERN_INFO 5189 printk(KERN_INFO
19559 "hda_codec: Cannot set up configuration " 5190 "hda_codec: Cannot set up configuration "
19560 "from BIOS. Using base mode...\n"); 5191 "from BIOS. Using base mode...\n");
19561 board_config = ALC662_3ST_2ch_DIG; 5192 board_config = ALC662_3ST_2ch_DIG;
19562 } 5193 }
5194#endif
19563 } 5195 }
19564 5196
19565 if (has_cdefine_beep(codec)) { 5197 if (board_config != ALC_MODEL_AUTO)
19566 err = snd_hda_attach_beep_device(codec, 0x1);
19567 if (err < 0) {
19568 alc_free(codec);
19569 return err;
19570 }
19571 }
19572
19573 if (board_config != ALC662_AUTO)
19574 setup_preset(codec, &alc662_presets[board_config]); 5198 setup_preset(codec, &alc662_presets[board_config]);
19575 5199
19576 spec->stream_analog_playback = &alc662_pcm_analog_playback; 5200 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
19577 spec->stream_analog_capture = &alc662_pcm_analog_capture; 5201 alc_auto_fill_adc_caps(codec);
19578 5202 alc_rebuild_imux_for_auto_mic(codec);
19579 spec->stream_digital_playback = &alc662_pcm_digital_playback; 5203 alc_remove_invalid_adc_nids(codec);
19580 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19581
19582 if (!spec->adc_nids) {
19583 spec->adc_nids = alc662_adc_nids;
19584 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19585 } 5204 }
19586 if (!spec->capsrc_nids)
19587 spec->capsrc_nids = alc662_capsrc_nids;
19588 5205
19589 if (!spec->cap_mixer) 5206 if (!spec->no_analog && !spec->cap_mixer)
19590 set_capture_mixer(codec); 5207 set_capture_mixer(codec);
19591 5208
19592 if (has_cdefine_beep(codec)) { 5209 if (!spec->no_analog && has_cdefine_beep(codec)) {
5210 err = snd_hda_attach_beep_device(codec, 0x1);
5211 if (err < 0) {
5212 alc_free(codec);
5213 return err;
5214 }
19593 switch (codec->vendor_id) { 5215 switch (codec->vendor_id) {
19594 case 0x10ec0662: 5216 case 0x10ec0662:
19595 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5217 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
@@ -19609,8 +5231,8 @@ static int patch_alc662(struct hda_codec *codec)
19609 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5231 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19610 5232
19611 codec->patch_ops = alc_patch_ops; 5233 codec->patch_ops = alc_patch_ops;
19612 if (board_config == ALC662_AUTO) 5234 if (board_config == ALC_MODEL_AUTO)
19613 spec->init_hook = alc662_auto_init; 5235 spec->init_hook = alc_auto_init_std;
19614 spec->shutup = alc_eapd_shutup; 5236 spec->shutup = alc_eapd_shutup;
19615 5237
19616 alc_init_jacks(codec); 5238 alc_init_jacks(codec);
@@ -19652,389 +5274,17 @@ static int patch_alc899(struct hda_codec *codec)
19652/* 5274/*
19653 * ALC680 support 5275 * ALC680 support
19654 */ 5276 */
19655#define ALC680_DIGIN_NID ALC880_DIGIN_NID
19656#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19657#define alc680_modes alc260_modes
19658
19659static const hda_nid_t alc680_dac_nids[3] = {
19660 /* Lout1, Lout2, hp */
19661 0x02, 0x03, 0x04
19662};
19663
19664static const hda_nid_t alc680_adc_nids[3] = {
19665 /* ADC0-2 */
19666 /* DMIC, MIC, Line-in*/
19667 0x07, 0x08, 0x09
19668};
19669
19670/*
19671 * Analog capture ADC cgange
19672 */
19673static void alc680_rec_autoswitch(struct hda_codec *codec)
19674{
19675 struct alc_spec *spec = codec->spec;
19676 struct auto_pin_cfg *cfg = &spec->autocfg;
19677 int pin_found = 0;
19678 int type_found = AUTO_PIN_LAST;
19679 hda_nid_t nid;
19680 int i;
19681
19682 for (i = 0; i < cfg->num_inputs; i++) {
19683 nid = cfg->inputs[i].pin;
19684 if (!is_jack_detectable(codec, nid))
19685 continue;
19686 if (snd_hda_jack_detect(codec, nid)) {
19687 if (cfg->inputs[i].type < type_found) {
19688 type_found = cfg->inputs[i].type;
19689 pin_found = nid;
19690 }
19691 }
19692 }
19693
19694 nid = 0x07;
19695 if (pin_found)
19696 snd_hda_get_connections(codec, pin_found, &nid, 1);
19697
19698 if (nid != spec->cur_adc)
19699 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19700 spec->cur_adc = nid;
19701 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19702 spec->cur_adc_format);
19703}
19704
19705static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19706 struct hda_codec *codec,
19707 unsigned int stream_tag,
19708 unsigned int format,
19709 struct snd_pcm_substream *substream)
19710{
19711 struct alc_spec *spec = codec->spec;
19712 5277
19713 spec->cur_adc = 0x07;
19714 spec->cur_adc_stream_tag = stream_tag;
19715 spec->cur_adc_format = format;
19716
19717 alc680_rec_autoswitch(codec);
19718 return 0;
19719}
19720
19721static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19722 struct hda_codec *codec,
19723 struct snd_pcm_substream *substream)
19724{
19725 snd_hda_codec_cleanup_stream(codec, 0x07);
19726 snd_hda_codec_cleanup_stream(codec, 0x08);
19727 snd_hda_codec_cleanup_stream(codec, 0x09);
19728 return 0;
19729}
19730
19731static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19732 .substreams = 1, /* can be overridden */
19733 .channels_min = 2,
19734 .channels_max = 2,
19735 /* NID is set in alc_build_pcms */
19736 .ops = {
19737 .prepare = alc680_capture_pcm_prepare,
19738 .cleanup = alc680_capture_pcm_cleanup
19739 },
19740};
19741
19742static const struct snd_kcontrol_new alc680_base_mixer[] = {
19743 /* output mixer control */
19744 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19745 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19746 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19747 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19748 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19749 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19750 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19751 { }
19752};
19753
19754static const struct hda_bind_ctls alc680_bind_cap_vol = {
19755 .ops = &snd_hda_bind_vol,
19756 .values = {
19757 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19758 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19759 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19760 0
19761 },
19762};
19763
19764static const struct hda_bind_ctls alc680_bind_cap_switch = {
19765 .ops = &snd_hda_bind_sw,
19766 .values = {
19767 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19768 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19769 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19770 0
19771 },
19772};
19773
19774static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19775 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19776 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19777 { } /* end */
19778};
19779
19780/*
19781 * generic initialization of ADC, input mixers and output mixers
19782 */
19783static const struct hda_verb alc680_init_verbs[] = {
19784 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19785 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19786 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19787
19788 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19789 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19790 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19791 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19792 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19793 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19794
19795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19797 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19799 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19800
19801 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19802 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19803 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19804
19805 { }
19806};
19807
19808/* toggle speaker-output according to the hp-jack state */
19809static void alc680_base_setup(struct hda_codec *codec)
19810{
19811 struct alc_spec *spec = codec->spec;
19812
19813 spec->autocfg.hp_pins[0] = 0x16;
19814 spec->autocfg.speaker_pins[0] = 0x14;
19815 spec->autocfg.speaker_pins[1] = 0x15;
19816 spec->autocfg.num_inputs = 2;
19817 spec->autocfg.inputs[0].pin = 0x18;
19818 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19819 spec->autocfg.inputs[1].pin = 0x19;
19820 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19821 spec->automute = 1;
19822 spec->automute_mode = ALC_AUTOMUTE_AMP;
19823}
19824
19825static void alc680_unsol_event(struct hda_codec *codec,
19826 unsigned int res)
19827{
19828 if ((res >> 26) == ALC880_HP_EVENT)
19829 alc_hp_automute(codec);
19830 if ((res >> 26) == ALC880_MIC_EVENT)
19831 alc680_rec_autoswitch(codec);
19832}
19833
19834static void alc680_inithook(struct hda_codec *codec)
19835{
19836 alc_hp_automute(codec);
19837 alc680_rec_autoswitch(codec);
19838}
19839
19840/* create input playback/capture controls for the given pin */
19841static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19842 const char *ctlname, int idx)
19843{
19844 hda_nid_t dac;
19845 int err;
19846
19847 switch (nid) {
19848 case 0x14:
19849 dac = 0x02;
19850 break;
19851 case 0x15:
19852 dac = 0x03;
19853 break;
19854 case 0x16:
19855 dac = 0x04;
19856 break;
19857 default:
19858 return 0;
19859 }
19860 if (spec->multiout.dac_nids[0] != dac &&
19861 spec->multiout.dac_nids[1] != dac) {
19862 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19863 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19864 HDA_OUTPUT));
19865 if (err < 0)
19866 return err;
19867
19868 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19869 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19870
19871 if (err < 0)
19872 return err;
19873 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19874 }
19875
19876 return 0;
19877}
19878
19879/* add playback controls from the parsed DAC table */
19880static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19881 const struct auto_pin_cfg *cfg)
19882{
19883 hda_nid_t nid;
19884 int err;
19885
19886 spec->multiout.dac_nids = spec->private_dac_nids;
19887
19888 nid = cfg->line_out_pins[0];
19889 if (nid) {
19890 const char *name;
19891 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19892 name = "Speaker";
19893 else
19894 name = "Front";
19895 err = alc680_new_analog_output(spec, nid, name, 0);
19896 if (err < 0)
19897 return err;
19898 }
19899
19900 nid = cfg->speaker_pins[0];
19901 if (nid) {
19902 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19903 if (err < 0)
19904 return err;
19905 }
19906 nid = cfg->hp_pins[0];
19907 if (nid) {
19908 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19909 if (err < 0)
19910 return err;
19911 }
19912
19913 return 0;
19914}
19915
19916static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19917 hda_nid_t nid, int pin_type)
19918{
19919 alc_set_pin_output(codec, nid, pin_type);
19920}
19921
19922static void alc680_auto_init_multi_out(struct hda_codec *codec)
19923{
19924 struct alc_spec *spec = codec->spec;
19925 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19926 if (nid) {
19927 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19928 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19929 }
19930}
19931
19932static void alc680_auto_init_hp_out(struct hda_codec *codec)
19933{
19934 struct alc_spec *spec = codec->spec;
19935 hda_nid_t pin;
19936
19937 pin = spec->autocfg.hp_pins[0];
19938 if (pin)
19939 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19940 pin = spec->autocfg.speaker_pins[0];
19941 if (pin)
19942 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19943}
19944
19945/* pcm configuration: identical with ALC880 */
19946#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19947#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19948#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19949#define alc680_pcm_digital_playback alc880_pcm_digital_playback
19950#define alc680_pcm_digital_capture alc880_pcm_digital_capture
19951
19952/*
19953 * BIOS auto configuration
19954 */
19955static int alc680_parse_auto_config(struct hda_codec *codec) 5278static int alc680_parse_auto_config(struct hda_codec *codec)
19956{ 5279{
19957 struct alc_spec *spec = codec->spec; 5280 return alc_parse_auto_config(codec, NULL, NULL);
19958 int err;
19959 static const hda_nid_t alc680_ignore[] = { 0 };
19960
19961 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19962 alc680_ignore);
19963 if (err < 0)
19964 return err;
19965
19966 if (!spec->autocfg.line_outs) {
19967 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19968 spec->multiout.max_channels = 2;
19969 spec->no_analog = 1;
19970 goto dig_only;
19971 }
19972 return 0; /* can't find valid BIOS pin config */
19973 }
19974 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19975 if (err < 0)
19976 return err;
19977
19978 spec->multiout.max_channels = 2;
19979
19980 dig_only:
19981 /* digital only support output */
19982 alc_auto_parse_digital(codec);
19983 if (spec->kctls.list)
19984 add_mixer(spec, spec->kctls.list);
19985
19986 add_verb(spec, alc680_init_verbs);
19987
19988 err = alc_auto_add_mic_boost(codec);
19989 if (err < 0)
19990 return err;
19991
19992 return 1;
19993}
19994
19995#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19996
19997/* init callback for auto-configuration model -- overriding the default init */
19998static void alc680_auto_init(struct hda_codec *codec)
19999{
20000 struct alc_spec *spec = codec->spec;
20001 alc680_auto_init_multi_out(codec);
20002 alc680_auto_init_hp_out(codec);
20003 alc680_auto_init_analog_input(codec);
20004 alc_auto_init_digital(codec);
20005 if (spec->unsol_event)
20006 alc_inithook(codec);
20007} 5281}
20008 5282
20009/* 5283/*
20010 * configuration and preset
20011 */ 5284 */
20012static const char * const alc680_models[ALC680_MODEL_LAST] = { 5285#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
20013 [ALC680_BASE] = "base", 5286#include "alc680_quirks.c"
20014 [ALC680_AUTO] = "auto", 5287#endif
20015};
20016
20017static const struct snd_pci_quirk alc680_cfg_tbl[] = {
20018 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
20019 {}
20020};
20021
20022static const struct alc_config_preset alc680_presets[] = {
20023 [ALC680_BASE] = {
20024 .mixers = { alc680_base_mixer },
20025 .cap_mixer = alc680_master_capture_mixer,
20026 .init_verbs = { alc680_init_verbs },
20027 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20028 .dac_nids = alc680_dac_nids,
20029 .dig_out_nid = ALC680_DIGOUT_NID,
20030 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20031 .channel_mode = alc680_modes,
20032 .unsol_event = alc680_unsol_event,
20033 .setup = alc680_base_setup,
20034 .init_hook = alc680_inithook,
20035
20036 },
20037};
20038 5288
20039static int patch_alc680(struct hda_codec *codec) 5289static int patch_alc680(struct hda_codec *codec)
20040{ 5290{
@@ -20048,51 +5298,55 @@ static int patch_alc680(struct hda_codec *codec)
20048 5298
20049 codec->spec = spec; 5299 codec->spec = spec;
20050 5300
20051 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 5301 /* ALC680 has no aa-loopback mixer */
20052 alc680_models,
20053 alc680_cfg_tbl);
20054 5302
20055 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 5303 board_config = alc_board_config(codec, ALC680_MODEL_LAST,
5304 alc680_models, alc680_cfg_tbl);
5305
5306 if (board_config < 0) {
20056 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5307 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20057 codec->chip_name); 5308 codec->chip_name);
20058 board_config = ALC680_AUTO; 5309 board_config = ALC_MODEL_AUTO;
20059 } 5310 }
20060 5311
20061 if (board_config == ALC680_AUTO) { 5312 if (board_config == ALC_MODEL_AUTO) {
20062 /* automatic parse from the BIOS config */ 5313 /* automatic parse from the BIOS config */
20063 err = alc680_parse_auto_config(codec); 5314 err = alc680_parse_auto_config(codec);
20064 if (err < 0) { 5315 if (err < 0) {
20065 alc_free(codec); 5316 alc_free(codec);
20066 return err; 5317 return err;
20067 } else if (!err) { 5318 }
5319#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5320 else if (!err) {
20068 printk(KERN_INFO 5321 printk(KERN_INFO
20069 "hda_codec: Cannot set up configuration " 5322 "hda_codec: Cannot set up configuration "
20070 "from BIOS. Using base mode...\n"); 5323 "from BIOS. Using base mode...\n");
20071 board_config = ALC680_BASE; 5324 board_config = ALC680_BASE;
20072 } 5325 }
5326#endif
20073 } 5327 }
20074 5328
20075 if (board_config != ALC680_AUTO) 5329 if (board_config != ALC_MODEL_AUTO) {
20076 setup_preset(codec, &alc680_presets[board_config]); 5330 setup_preset(codec, &alc680_presets[board_config]);
5331#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5332 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
5333#endif
5334 }
20077 5335
20078 spec->stream_analog_playback = &alc680_pcm_analog_playback; 5336 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
20079 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 5337 alc_auto_fill_adc_caps(codec);
20080 spec->stream_digital_playback = &alc680_pcm_digital_playback; 5338 alc_rebuild_imux_for_auto_mic(codec);
20081 spec->stream_digital_capture = &alc680_pcm_digital_capture; 5339 alc_remove_invalid_adc_nids(codec);
20082
20083 if (!spec->adc_nids) {
20084 spec->adc_nids = alc680_adc_nids;
20085 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20086 } 5340 }
20087 5341
20088 if (!spec->cap_mixer) 5342 if (!spec->no_analog && !spec->cap_mixer)
20089 set_capture_mixer(codec); 5343 set_capture_mixer(codec);
20090 5344
20091 spec->vmaster_nid = 0x02; 5345 spec->vmaster_nid = 0x02;
20092 5346
20093 codec->patch_ops = alc_patch_ops; 5347 codec->patch_ops = alc_patch_ops;
20094 if (board_config == ALC680_AUTO) 5348 if (board_config == ALC_MODEL_AUTO)
20095 spec->init_hook = alc680_auto_init; 5349 spec->init_hook = alc_auto_init_std;
20096 5350
20097 return 0; 5351 return 0;
20098} 5352}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f81cc2274f3..56425a53cf1b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1112,7 +1112,9 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1112 } 1112 }
1113 1113
1114 if (spec->multiout.dig_out_nid) { 1114 if (spec->multiout.dig_out_nid) {
1115 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1115 err = snd_hda_create_spdif_out_ctls(codec,
1116 spec->multiout.dig_out_nid,
1117 spec->multiout.dig_out_nid);
1116 if (err < 0) 1118 if (err < 0)
1117 return err; 1119 return err;
1118 err = snd_hda_create_spdif_share_sw(codec, 1120 err = snd_hda_create_spdif_share_sw(codec,
@@ -3406,30 +3408,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3406 return 0; 3408 return 0;
3407} 3409}
3408 3410
3409static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3411/* look for NID recursively */
3410 hda_nid_t nid) 3412#define get_connection_index(codec, mux, nid) \
3411{ 3413 snd_hda_get_conn_index(codec, mux, nid, 1)
3412 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3413 int i, nums;
3414
3415 if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
3416 return -1;
3417
3418 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3419 for (i = 0; i < nums; i++)
3420 if (conn[i] == nid)
3421 return i;
3422
3423 for (i = 0; i < nums; i++) {
3424 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3425 unsigned int wid_type = get_wcaps_type(wid_caps);
3426
3427 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3428 if (get_connection_index(codec, conn[i], nid) >= 0)
3429 return i;
3430 }
3431 return -1;
3432}
3433 3414
3434/* create a volume assigned to the given pin (only if supported) */ 3415/* create a volume assigned to the given pin (only if supported) */
3435/* return 1 if the volume control is created */ 3416/* return 1 if the volume control is created */
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index f43bb0eaed8b..f38160b00e16 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -54,36 +54,10 @@
54#include "hda_codec.h" 54#include "hda_codec.h"
55#include "hda_local.h" 55#include "hda_local.h"
56 56
57#define NID_MAPPING (-1)
58
59/* amp values */
60#define AMP_VAL_IDX_SHIFT 19
61#define AMP_VAL_IDX_MASK (0x0f<<19)
62
63/* Pin Widget NID */ 57/* Pin Widget NID */
64#define VT1708_HP_NID 0x13
65#define VT1708_DIGOUT_NID 0x14
66#define VT1708_DIGIN_NID 0x16
67#define VT1708_DIGIN_PIN 0x26
68#define VT1708_HP_PIN_NID 0x20 58#define VT1708_HP_PIN_NID 0x20
69#define VT1708_CD_PIN_NID 0x24 59#define VT1708_CD_PIN_NID 0x24
70 60
71#define VT1709_HP_DAC_NID 0x28
72#define VT1709_DIGOUT_NID 0x13
73#define VT1709_DIGIN_NID 0x17
74#define VT1709_DIGIN_PIN 0x25
75
76#define VT1708B_HP_NID 0x25
77#define VT1708B_DIGOUT_NID 0x12
78#define VT1708B_DIGIN_NID 0x15
79#define VT1708B_DIGIN_PIN 0x21
80
81#define VT1708S_HP_NID 0x25
82#define VT1708S_DIGOUT_NID 0x12
83
84#define VT1702_HP_NID 0x17
85#define VT1702_DIGOUT_NID 0x11
86
87enum VIA_HDA_CODEC { 61enum VIA_HDA_CODEC {
88 UNKNOWN = -1, 62 UNKNOWN = -1,
89 VT1708, 63 VT1708,
@@ -107,6 +81,39 @@ enum VIA_HDA_CODEC {
107 (spec)->codec_type == VT1812 ||\ 81 (spec)->codec_type == VT1812 ||\
108 (spec)->codec_type == VT1802) 82 (spec)->codec_type == VT1802)
109 83
84#define MAX_NID_PATH_DEPTH 5
85
86/* output-path: DAC -> ... -> pin
87 * idx[] contains the source index number of the next widget;
88 * e.g. idx[0] is the index of the DAC selected by path[1] widget
89 * multi[] indicates whether it's a selector widget with multi-connectors
90 * (i.e. the connection selection is mandatory)
91 * vol_ctl and mute_ctl contains the NIDs for the assigned mixers
92 */
93struct nid_path {
94 int depth;
95 hda_nid_t path[MAX_NID_PATH_DEPTH];
96 unsigned char idx[MAX_NID_PATH_DEPTH];
97 unsigned char multi[MAX_NID_PATH_DEPTH];
98 unsigned int vol_ctl;
99 unsigned int mute_ctl;
100};
101
102/* input-path */
103struct via_input {
104 hda_nid_t pin; /* input-pin or aa-mix */
105 int adc_idx; /* ADC index to be used */
106 int mux_idx; /* MUX index (if any) */
107 const char *label; /* input-source label */
108};
109
110#define VIA_MAX_ADCS 3
111
112enum {
113 STREAM_MULTI_OUT = (1 << 0),
114 STREAM_INDEP_HP = (1 << 1),
115};
116
110struct via_spec { 117struct via_spec {
111 /* codec parameterization */ 118 /* codec parameterization */
112 const struct snd_kcontrol_new *mixers[6]; 119 const struct snd_kcontrol_new *mixers[6];
@@ -115,28 +122,66 @@ struct via_spec {
115 const struct hda_verb *init_verbs[5]; 122 const struct hda_verb *init_verbs[5];
116 unsigned int num_iverbs; 123 unsigned int num_iverbs;
117 124
118 char *stream_name_analog; 125 char stream_name_analog[32];
126 char stream_name_hp[32];
119 const struct hda_pcm_stream *stream_analog_playback; 127 const struct hda_pcm_stream *stream_analog_playback;
120 const struct hda_pcm_stream *stream_analog_capture; 128 const struct hda_pcm_stream *stream_analog_capture;
121 129
122 char *stream_name_digital; 130 char stream_name_digital[32];
123 const struct hda_pcm_stream *stream_digital_playback; 131 const struct hda_pcm_stream *stream_digital_playback;
124 const struct hda_pcm_stream *stream_digital_capture; 132 const struct hda_pcm_stream *stream_digital_capture;
125 133
126 /* playback */ 134 /* playback */
127 struct hda_multi_out multiout; 135 struct hda_multi_out multiout;
128 hda_nid_t slave_dig_outs[2]; 136 hda_nid_t slave_dig_outs[2];
137 hda_nid_t hp_dac_nid;
138 hda_nid_t speaker_dac_nid;
139 int hp_indep_shared; /* indep HP-DAC is shared with side ch */
140 int opened_streams; /* STREAM_* bits */
141 int active_streams; /* STREAM_* bits */
142 int aamix_mode; /* loopback is enabled for output-path? */
143
144 /* Output-paths:
145 * There are different output-paths depending on the setup.
146 * out_path, hp_path and speaker_path are primary paths. If both
147 * direct DAC and aa-loopback routes are available, these contain
148 * the former paths. Meanwhile *_mix_path contain the paths with
149 * loopback mixer. (Since the loopback is only for front channel,
150 * no out_mix_path for surround channels.)
151 * The HP output has another path, hp_indep_path, which is used in
152 * the independent-HP mode.
153 */
154 struct nid_path out_path[HDA_SIDE + 1];
155 struct nid_path out_mix_path;
156 struct nid_path hp_path;
157 struct nid_path hp_mix_path;
158 struct nid_path hp_indep_path;
159 struct nid_path speaker_path;
160 struct nid_path speaker_mix_path;
129 161
130 /* capture */ 162 /* capture */
131 unsigned int num_adc_nids; 163 unsigned int num_adc_nids;
132 const hda_nid_t *adc_nids; 164 hda_nid_t adc_nids[VIA_MAX_ADCS];
133 hda_nid_t mux_nids[3]; 165 hda_nid_t mux_nids[VIA_MAX_ADCS];
166 hda_nid_t aa_mix_nid;
134 hda_nid_t dig_in_nid; 167 hda_nid_t dig_in_nid;
135 hda_nid_t dig_in_pin;
136 168
137 /* capture source */ 169 /* capture source */
138 const struct hda_input_mux *input_mux; 170 bool dyn_adc_switch;
139 unsigned int cur_mux[3]; 171 int num_inputs;
172 struct via_input inputs[AUTO_CFG_MAX_INS + 1];
173 unsigned int cur_mux[VIA_MAX_ADCS];
174
175 /* dynamic DAC switching */
176 unsigned int cur_dac_stream_tag;
177 unsigned int cur_dac_format;
178 unsigned int cur_hp_stream_tag;
179 unsigned int cur_hp_format;
180
181 /* dynamic ADC switching */
182 hda_nid_t cur_adc;
183 unsigned int cur_adc_stream_tag;
184 unsigned int cur_adc_format;
140 185
141 /* PCM information */ 186 /* PCM information */
142 struct hda_pcm pcm_rec[3]; 187 struct hda_pcm pcm_rec[3];
@@ -144,28 +189,38 @@ struct via_spec {
144 /* dynamic controls, init_verbs and input_mux */ 189 /* dynamic controls, init_verbs and input_mux */
145 struct auto_pin_cfg autocfg; 190 struct auto_pin_cfg autocfg;
146 struct snd_array kctls; 191 struct snd_array kctls;
147 struct hda_input_mux private_imux[2];
148 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 192 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
149 193
150 /* HP mode source */ 194 /* HP mode source */
151 const struct hda_input_mux *hp_mux;
152 unsigned int hp_independent_mode; 195 unsigned int hp_independent_mode;
153 unsigned int hp_independent_mode_index;
154 unsigned int smart51_enabled;
155 unsigned int dmic_enabled; 196 unsigned int dmic_enabled;
197 unsigned int no_pin_power_ctl;
156 enum VIA_HDA_CODEC codec_type; 198 enum VIA_HDA_CODEC codec_type;
157 199
200 /* smart51 setup */
201 unsigned int smart51_nums;
202 hda_nid_t smart51_pins[2];
203 int smart51_idxs[2];
204 const char *smart51_labels[2];
205 unsigned int smart51_enabled;
206
158 /* work to check hp jack state */ 207 /* work to check hp jack state */
159 struct hda_codec *codec; 208 struct hda_codec *codec;
160 struct delayed_work vt1708_hp_work; 209 struct delayed_work vt1708_hp_work;
161 int vt1708_jack_detectect; 210 int vt1708_jack_detect;
162 int vt1708_hp_present; 211 int vt1708_hp_present;
163 212
164 void (*set_widgets_power_state)(struct hda_codec *codec); 213 void (*set_widgets_power_state)(struct hda_codec *codec);
165 214
166#ifdef CONFIG_SND_HDA_POWER_SAVE
167 struct hda_loopback_check loopback; 215 struct hda_loopback_check loopback;
168#endif 216 int num_loopbacks;
217 struct hda_amp_list loopback_list[8];
218
219 /* bind capture-volume */
220 struct hda_bind_ctls *bind_cap_vol;
221 struct hda_bind_ctls *bind_cap_sw;
222
223 struct mutex config_mutex;
169}; 224};
170 225
171static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); 226static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
@@ -177,6 +232,7 @@ static struct via_spec * via_new_spec(struct hda_codec *codec)
177 if (spec == NULL) 232 if (spec == NULL)
178 return NULL; 233 return NULL;
179 234
235 mutex_init(&spec->config_mutex);
180 codec->spec = spec; 236 codec->spec = spec;
181 spec->codec = codec; 237 spec->codec = codec;
182 spec->codec_type = get_codec_type(codec); 238 spec->codec_type = get_codec_type(codec);
@@ -237,33 +293,23 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
237#define VIA_JACK_EVENT 0x20 293#define VIA_JACK_EVENT 0x20
238#define VIA_HP_EVENT 0x01 294#define VIA_HP_EVENT 0x01
239#define VIA_GPIO_EVENT 0x02 295#define VIA_GPIO_EVENT 0x02
240#define VIA_MONO_EVENT 0x03 296#define VIA_LINE_EVENT 0x03
241#define VIA_SPEAKER_EVENT 0x04
242#define VIA_BIND_HP_EVENT 0x05
243 297
244enum { 298enum {
245 VIA_CTL_WIDGET_VOL, 299 VIA_CTL_WIDGET_VOL,
246 VIA_CTL_WIDGET_MUTE, 300 VIA_CTL_WIDGET_MUTE,
247 VIA_CTL_WIDGET_ANALOG_MUTE, 301 VIA_CTL_WIDGET_ANALOG_MUTE,
248 VIA_CTL_WIDGET_BIND_PIN_MUTE,
249}; 302};
250 303
251enum { 304static void analog_low_current_mode(struct hda_codec *codec);
252 AUTO_SEQ_FRONT = 0, 305static bool is_aa_path_mute(struct hda_codec *codec);
253 AUTO_SEQ_SURROUND,
254 AUTO_SEQ_CENLFE,
255 AUTO_SEQ_SIDE
256};
257
258static void analog_low_current_mode(struct hda_codec *codec, int stream_idle);
259static int is_aa_path_mute(struct hda_codec *codec);
260 306
261static void vt1708_start_hp_work(struct via_spec *spec) 307static void vt1708_start_hp_work(struct via_spec *spec)
262{ 308{
263 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 309 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
264 return; 310 return;
265 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 311 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
266 !spec->vt1708_jack_detectect); 312 !spec->vt1708_jack_detect);
267 if (!delayed_work_pending(&spec->vt1708_hp_work)) 313 if (!delayed_work_pending(&spec->vt1708_hp_work))
268 schedule_delayed_work(&spec->vt1708_hp_work, 314 schedule_delayed_work(&spec->vt1708_hp_work,
269 msecs_to_jiffies(100)); 315 msecs_to_jiffies(100));
@@ -277,7 +323,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
277 && !is_aa_path_mute(spec->codec)) 323 && !is_aa_path_mute(spec->codec))
278 return; 324 return;
279 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 325 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
280 !spec->vt1708_jack_detectect); 326 !spec->vt1708_jack_detect);
281 cancel_delayed_work_sync(&spec->vt1708_hp_work); 327 cancel_delayed_work_sync(&spec->vt1708_hp_work);
282} 328}
283 329
@@ -295,7 +341,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 341 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
296 342
297 set_widgets_power_state(codec); 343 set_widgets_power_state(codec);
298 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 344 analog_low_current_mode(snd_kcontrol_chip(kcontrol));
299 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 345 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) {
300 if (is_aa_path_mute(codec)) 346 if (is_aa_path_mute(codec))
301 vt1708_start_hp_work(codec->spec); 347 vt1708_start_hp_work(codec->spec);
@@ -315,168 +361,44 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
315 .put = analog_input_switch_put, \ 361 .put = analog_input_switch_put, \
316 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 362 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
317 363
318static void via_hp_bind_automute(struct hda_codec *codec);
319
320static int bind_pin_switch_put(struct snd_kcontrol *kcontrol,
321 struct snd_ctl_elem_value *ucontrol)
322{
323 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
324 struct via_spec *spec = codec->spec;
325 int i;
326 int change = 0;
327
328 long *valp = ucontrol->value.integer.value;
329 int lmute, rmute;
330 if (strstr(kcontrol->id.name, "Switch") == NULL) {
331 snd_printd("Invalid control!\n");
332 return change;
333 }
334 change = snd_hda_mixer_amp_switch_put(kcontrol,
335 ucontrol);
336 /* Get mute value */
337 lmute = *valp ? 0 : HDA_AMP_MUTE;
338 valp++;
339 rmute = *valp ? 0 : HDA_AMP_MUTE;
340
341 /* Set hp pins */
342 if (!spec->hp_independent_mode) {
343 for (i = 0; i < spec->autocfg.hp_outs; i++) {
344 snd_hda_codec_amp_update(
345 codec, spec->autocfg.hp_pins[i],
346 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
347 lmute);
348 snd_hda_codec_amp_update(
349 codec, spec->autocfg.hp_pins[i],
350 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
351 rmute);
352 }
353 }
354
355 if (!lmute && !rmute) {
356 /* Line Outs */
357 for (i = 0; i < spec->autocfg.line_outs; i++)
358 snd_hda_codec_amp_stereo(
359 codec, spec->autocfg.line_out_pins[i],
360 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
361 /* Speakers */
362 for (i = 0; i < spec->autocfg.speaker_outs; i++)
363 snd_hda_codec_amp_stereo(
364 codec, spec->autocfg.speaker_pins[i],
365 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0);
366 /* unmute */
367 via_hp_bind_automute(codec);
368
369 } else {
370 if (lmute) {
371 /* Mute all left channels */
372 for (i = 1; i < spec->autocfg.line_outs; i++)
373 snd_hda_codec_amp_update(
374 codec,
375 spec->autocfg.line_out_pins[i],
376 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
377 lmute);
378 for (i = 0; i < spec->autocfg.speaker_outs; i++)
379 snd_hda_codec_amp_update(
380 codec,
381 spec->autocfg.speaker_pins[i],
382 0, HDA_OUTPUT, 0, HDA_AMP_MUTE,
383 lmute);
384 }
385 if (rmute) {
386 /* mute all right channels */
387 for (i = 1; i < spec->autocfg.line_outs; i++)
388 snd_hda_codec_amp_update(
389 codec,
390 spec->autocfg.line_out_pins[i],
391 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
392 rmute);
393 for (i = 0; i < spec->autocfg.speaker_outs; i++)
394 snd_hda_codec_amp_update(
395 codec,
396 spec->autocfg.speaker_pins[i],
397 1, HDA_OUTPUT, 0, HDA_AMP_MUTE,
398 rmute);
399 }
400 }
401 return change;
402}
403
404#define BIND_PIN_MUTE \
405 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
406 .name = NULL, \
407 .index = 0, \
408 .info = snd_hda_mixer_amp_switch_info, \
409 .get = snd_hda_mixer_amp_switch_get, \
410 .put = bind_pin_switch_put, \
411 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
412
413static const struct snd_kcontrol_new via_control_templates[] = { 364static const struct snd_kcontrol_new via_control_templates[] = {
414 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 365 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
415 HDA_CODEC_MUTE(NULL, 0, 0, 0), 366 HDA_CODEC_MUTE(NULL, 0, 0, 0),
416 ANALOG_INPUT_MUTE, 367 ANALOG_INPUT_MUTE,
417 BIND_PIN_MUTE,
418}; 368};
419 369
420static const hda_nid_t vt1708_adc_nids[2] = {
421 /* ADC1-2 */
422 0x15, 0x27
423};
424
425static const hda_nid_t vt1709_adc_nids[3] = {
426 /* ADC1-2 */
427 0x14, 0x15, 0x16
428};
429 370
430static const hda_nid_t vt1708B_adc_nids[2] = { 371/* add dynamic controls */
431 /* ADC1-2 */ 372static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
432 0x13, 0x14 373 const struct snd_kcontrol_new *tmpl,
433}; 374 const char *name)
434 375{
435static const hda_nid_t vt1708S_adc_nids[2] = { 376 struct snd_kcontrol_new *knew;
436 /* ADC1-2 */
437 0x13, 0x14
438};
439
440static const hda_nid_t vt1702_adc_nids[3] = {
441 /* ADC1-2 */
442 0x12, 0x20, 0x1F
443};
444
445static const hda_nid_t vt1718S_adc_nids[2] = {
446 /* ADC1-2 */
447 0x10, 0x11
448};
449
450static const hda_nid_t vt1716S_adc_nids[2] = {
451 /* ADC1-2 */
452 0x13, 0x14
453};
454
455static const hda_nid_t vt2002P_adc_nids[2] = {
456 /* ADC1-2 */
457 0x10, 0x11
458};
459
460static const hda_nid_t vt1812_adc_nids[2] = {
461 /* ADC1-2 */
462 0x10, 0x11
463};
464 377
378 snd_array_init(&spec->kctls, sizeof(*knew), 32);
379 knew = snd_array_new(&spec->kctls);
380 if (!knew)
381 return NULL;
382 *knew = *tmpl;
383 if (!name)
384 name = tmpl->name;
385 if (name) {
386 knew->name = kstrdup(name, GFP_KERNEL);
387 if (!knew->name)
388 return NULL;
389 }
390 return knew;
391}
465 392
466/* add dynamic controls */
467static int __via_add_control(struct via_spec *spec, int type, const char *name, 393static int __via_add_control(struct via_spec *spec, int type, const char *name,
468 int idx, unsigned long val) 394 int idx, unsigned long val)
469{ 395{
470 struct snd_kcontrol_new *knew; 396 struct snd_kcontrol_new *knew;
471 397
472 snd_array_init(&spec->kctls, sizeof(*knew), 32); 398 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
473 knew = snd_array_new(&spec->kctls);
474 if (!knew) 399 if (!knew)
475 return -ENOMEM; 400 return -ENOMEM;
476 *knew = via_control_templates[type]; 401 knew->index = idx;
477 knew->name = kstrdup(name, GFP_KERNEL);
478 if (!knew->name)
479 return -ENOMEM;
480 if (get_amp_nid_(val)) 402 if (get_amp_nid_(val))
481 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 403 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
482 knew->private_value = val; 404 knew->private_value = val;
@@ -486,21 +408,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name,
486#define via_add_control(spec, type, name, val) \ 408#define via_add_control(spec, type, name, val) \
487 __via_add_control(spec, type, name, 0, val) 409 __via_add_control(spec, type, name, 0, val)
488 410
489static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 411#define via_clone_control(spec, tmpl) __via_clone_ctl(spec, tmpl, NULL)
490 const struct snd_kcontrol_new *tmpl)
491{
492 struct snd_kcontrol_new *knew;
493
494 snd_array_init(&spec->kctls, sizeof(*knew), 32);
495 knew = snd_array_new(&spec->kctls);
496 if (!knew)
497 return NULL;
498 *knew = *tmpl;
499 knew->name = kstrdup(tmpl->name, GFP_KERNEL);
500 if (!knew->name)
501 return NULL;
502 return knew;
503}
504 412
505static void via_free_kctls(struct hda_codec *codec) 413static void via_free_kctls(struct hda_codec *codec)
506{ 414{
@@ -535,58 +443,208 @@ static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
535 return 0; 443 return 0;
536} 444}
537 445
538static void via_auto_set_output_and_unmute(struct hda_codec *codec, 446#define get_connection_index(codec, mux, nid) \
539 hda_nid_t nid, int pin_type, 447 snd_hda_get_conn_index(codec, mux, nid, 0)
540 int dac_idx) 448
449static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
450 unsigned int mask)
451{
452 unsigned int caps;
453 if (!nid)
454 return false;
455 caps = get_wcaps(codec, nid);
456 if (dir == HDA_INPUT)
457 caps &= AC_WCAP_IN_AMP;
458 else
459 caps &= AC_WCAP_OUT_AMP;
460 if (!caps)
461 return false;
462 if (query_amp_caps(codec, nid, dir) & mask)
463 return true;
464 return false;
465}
466
467#define have_mute(codec, nid, dir) \
468 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
469
470/* enable/disable the output-route mixers */
471static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
472 hda_nid_t mix_nid, int idx, bool enable)
473{
474 int i, num, val;
475
476 if (!path)
477 return;
478 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
479 for (i = 0; i < num; i++) {
480 if (i == idx)
481 val = AMP_IN_UNMUTE(i);
482 else
483 val = AMP_IN_MUTE(i);
484 snd_hda_codec_write(codec, mix_nid, 0,
485 AC_VERB_SET_AMP_GAIN_MUTE, val);
486 }
487}
488
489/* enable/disable the output-route */
490static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
491 bool enable, bool force)
492{
493 struct via_spec *spec = codec->spec;
494 int i;
495 for (i = 0; i < path->depth; i++) {
496 hda_nid_t src, dst;
497 int idx = path->idx[i];
498 src = path->path[i];
499 if (i < path->depth - 1)
500 dst = path->path[i + 1];
501 else
502 dst = 0;
503 if (enable && path->multi[i])
504 snd_hda_codec_write(codec, dst, 0,
505 AC_VERB_SET_CONNECT_SEL, idx);
506 if (!force && (dst == spec->aa_mix_nid))
507 continue;
508 if (have_mute(codec, dst, HDA_INPUT))
509 activate_output_mix(codec, path, dst, idx, enable);
510 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
511 continue;
512 if (have_mute(codec, src, HDA_OUTPUT)) {
513 int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
514 snd_hda_codec_write(codec, src, 0,
515 AC_VERB_SET_AMP_GAIN_MUTE, val);
516 }
517 }
518}
519
520/* set the given pin as output */
521static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
522 int pin_type)
541{ 523{
542 /* set as output */ 524 if (!pin)
543 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 525 return;
526 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
544 pin_type); 527 pin_type);
545 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 528 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
546 AMP_OUT_UNMUTE); 529 snd_hda_codec_write(codec, pin, 0,
547 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
548 snd_hda_codec_write(codec, nid, 0,
549 AC_VERB_SET_EAPD_BTLENABLE, 0x02); 530 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
550} 531}
551 532
533static void via_auto_init_output(struct hda_codec *codec,
534 struct nid_path *path, int pin_type)
535{
536 unsigned int caps;
537 hda_nid_t pin;
538
539 if (!path->depth)
540 return;
541 pin = path->path[path->depth - 1];
542
543 init_output_pin(codec, pin, pin_type);
544 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
545 if (caps & AC_AMPCAP_MUTE) {
546 unsigned int val;
547 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
548 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
549 AMP_OUT_MUTE | val);
550 }
551 activate_output_path(codec, path, true, true); /* force on */
552}
552 553
553static void via_auto_init_multi_out(struct hda_codec *codec) 554static void via_auto_init_multi_out(struct hda_codec *codec)
554{ 555{
555 struct via_spec *spec = codec->spec; 556 struct via_spec *spec = codec->spec;
557 struct nid_path *path;
556 int i; 558 int i;
557 559
558 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 560 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
559 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 561 path = &spec->out_path[i];
560 if (nid) 562 if (!i && spec->aamix_mode && spec->out_mix_path.depth)
561 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 563 path = &spec->out_mix_path;
564 via_auto_init_output(codec, path, PIN_OUT);
565 }
566}
567
568/* deactivate the inactive headphone-paths */
569static void deactivate_hp_paths(struct hda_codec *codec)
570{
571 struct via_spec *spec = codec->spec;
572 int shared = spec->hp_indep_shared;
573
574 if (spec->hp_independent_mode) {
575 activate_output_path(codec, &spec->hp_path, false, false);
576 activate_output_path(codec, &spec->hp_mix_path, false, false);
577 if (shared)
578 activate_output_path(codec, &spec->out_path[shared],
579 false, false);
580 } else if (spec->aamix_mode || !spec->hp_path.depth) {
581 activate_output_path(codec, &spec->hp_indep_path, false, false);
582 activate_output_path(codec, &spec->hp_path, false, false);
583 } else {
584 activate_output_path(codec, &spec->hp_indep_path, false, false);
585 activate_output_path(codec, &spec->hp_mix_path, false, false);
562 } 586 }
563} 587}
564 588
565static void via_auto_init_hp_out(struct hda_codec *codec) 589static void via_auto_init_hp_out(struct hda_codec *codec)
566{ 590{
567 struct via_spec *spec = codec->spec; 591 struct via_spec *spec = codec->spec;
568 hda_nid_t pin;
569 int i;
570 592
571 for (i = 0; i < spec->autocfg.hp_outs; i++) { 593 if (!spec->hp_path.depth) {
572 pin = spec->autocfg.hp_pins[i]; 594 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
573 if (pin) /* connect to front */ 595 return;
574 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 596 }
597 deactivate_hp_paths(codec);
598 if (spec->hp_independent_mode)
599 via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP);
600 else if (spec->aamix_mode)
601 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
602 else
603 via_auto_init_output(codec, &spec->hp_path, PIN_HP);
604}
605
606static void via_auto_init_speaker_out(struct hda_codec *codec)
607{
608 struct via_spec *spec = codec->spec;
609
610 if (!spec->autocfg.speaker_outs)
611 return;
612 if (!spec->speaker_path.depth) {
613 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
614 return;
615 }
616 if (!spec->aamix_mode) {
617 activate_output_path(codec, &spec->speaker_mix_path,
618 false, false);
619 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT);
620 } else {
621 activate_output_path(codec, &spec->speaker_path, false, false);
622 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
575 } 623 }
576} 624}
577 625
578static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); 626static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
627static void via_hp_automute(struct hda_codec *codec);
579 628
580static void via_auto_init_analog_input(struct hda_codec *codec) 629static void via_auto_init_analog_input(struct hda_codec *codec)
581{ 630{
582 struct via_spec *spec = codec->spec; 631 struct via_spec *spec = codec->spec;
583 const struct auto_pin_cfg *cfg = &spec->autocfg; 632 const struct auto_pin_cfg *cfg = &spec->autocfg;
633 hda_nid_t conn[HDA_MAX_CONNECTIONS];
584 unsigned int ctl; 634 unsigned int ctl;
585 int i; 635 int i, num_conns;
636
637 /* init ADCs */
638 for (i = 0; i < spec->num_adc_nids; i++) {
639 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
640 AC_VERB_SET_AMP_GAIN_MUTE,
641 AMP_IN_UNMUTE(0));
642 }
586 643
644 /* init pins */
587 for (i = 0; i < cfg->num_inputs; i++) { 645 for (i = 0; i < cfg->num_inputs; i++) {
588 hda_nid_t nid = cfg->inputs[i].pin; 646 hda_nid_t nid = cfg->inputs[i].pin;
589 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 647 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
590 ctl = PIN_OUT; 648 ctl = PIN_OUT;
591 else if (cfg->inputs[i].type == AUTO_PIN_MIC) 649 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
592 ctl = PIN_VREF50; 650 ctl = PIN_VREF50;
@@ -595,6 +653,32 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
595 snd_hda_codec_write(codec, nid, 0, 653 snd_hda_codec_write(codec, nid, 0,
596 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); 654 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
597 } 655 }
656
657 /* init input-src */
658 for (i = 0; i < spec->num_adc_nids; i++) {
659 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
660 if (spec->mux_nids[adc_idx]) {
661 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
662 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
663 AC_VERB_SET_CONNECT_SEL,
664 mux_idx);
665 }
666 if (spec->dyn_adc_switch)
667 break; /* only one input-src */
668 }
669
670 /* init aa-mixer */
671 if (!spec->aa_mix_nid)
672 return;
673 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
674 ARRAY_SIZE(conn));
675 for (i = 0; i < num_conns; i++) {
676 unsigned int caps = get_wcaps(codec, conn[i]);
677 if (get_wcaps_type(caps) == AC_WID_PIN)
678 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
679 AC_VERB_SET_AMP_GAIN_MUTE,
680 AMP_IN_MUTE(i));
681 }
598} 682}
599 683
600static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 684static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
@@ -605,9 +689,13 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
605 unsigned no_presence = (def_conf & AC_DEFCFG_MISC) 689 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
606 >> AC_DEFCFG_MISC_SHIFT 690 >> AC_DEFCFG_MISC_SHIFT
607 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */ 691 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */
608 unsigned present = snd_hda_jack_detect(codec, nid);
609 struct via_spec *spec = codec->spec; 692 struct via_spec *spec = codec->spec;
610 if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) 693 unsigned present = 0;
694
695 no_presence |= spec->no_pin_power_ctl;
696 if (!no_presence)
697 present = snd_hda_jack_detect(codec, nid);
698 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
611 || ((no_presence || present) 699 || ((no_presence || present)
612 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { 700 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
613 *affected_parm = AC_PWRST_D0; /* if it's connected */ 701 *affected_parm = AC_PWRST_D0; /* if it's connected */
@@ -618,124 +706,139 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
618 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); 706 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
619} 707}
620 708
621/* 709static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
622 * input MUX handling 710 struct snd_ctl_elem_info *uinfo)
623 */
624static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *uinfo)
626{ 711{
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 712 static const char * const texts[] = {
628 struct via_spec *spec = codec->spec; 713 "Disabled", "Enabled"
629 return snd_hda_input_mux_info(spec->input_mux, uinfo); 714 };
715
716 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
717 uinfo->count = 1;
718 uinfo->value.enumerated.items = 2;
719 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
720 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
721 strcpy(uinfo->value.enumerated.name,
722 texts[uinfo->value.enumerated.item]);
723 return 0;
630} 724}
631 725
632static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 726static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol) 727 struct snd_ctl_elem_value *ucontrol)
634{ 728{
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct via_spec *spec = codec->spec; 730 struct via_spec *spec = codec->spec;
637 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 731 ucontrol->value.enumerated.item[0] = !spec->no_pin_power_ctl;
638
639 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
640 return 0; 732 return 0;
641} 733}
642 734
643static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 735static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol) 736 struct snd_ctl_elem_value *ucontrol)
645{ 737{
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 738 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 struct via_spec *spec = codec->spec; 739 struct via_spec *spec = codec->spec;
648 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 740 unsigned int val = !ucontrol->value.enumerated.item[0];
649 int ret;
650
651 if (!spec->mux_nids[adc_idx])
652 return -EINVAL;
653 /* switch to D0 beofre change index */
654 if (snd_hda_codec_read(codec, spec->mux_nids[adc_idx], 0,
655 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
656 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
657 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
658 741
659 ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 742 if (val == spec->no_pin_power_ctl)
660 spec->mux_nids[adc_idx], 743 return 0;
661 &spec->cur_mux[adc_idx]); 744 spec->no_pin_power_ctl = val;
662 /* update jack power state */
663 set_widgets_power_state(codec); 745 set_widgets_power_state(codec);
664 746 return 1;
665 return ret;
666} 747}
667 748
749static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751 .name = "Dynamic Power-Control",
752 .info = via_pin_power_ctl_info,
753 .get = via_pin_power_ctl_get,
754 .put = via_pin_power_ctl_put,
755};
756
757
668static int via_independent_hp_info(struct snd_kcontrol *kcontrol, 758static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_info *uinfo) 759 struct snd_ctl_elem_info *uinfo)
670{ 760{
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 761 static const char * const texts[] = { "OFF", "ON" };
672 struct via_spec *spec = codec->spec; 762
673 return snd_hda_input_mux_info(spec->hp_mux, uinfo); 763 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
764 uinfo->count = 1;
765 uinfo->value.enumerated.items = 2;
766 if (uinfo->value.enumerated.item >= 2)
767 uinfo->value.enumerated.item = 1;
768 strcpy(uinfo->value.enumerated.name,
769 texts[uinfo->value.enumerated.item]);
770 return 0;
674} 771}
675 772
676static int via_independent_hp_get(struct snd_kcontrol *kcontrol, 773static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *ucontrol) 774 struct snd_ctl_elem_value *ucontrol)
678{ 775{
679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 776 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
680 hda_nid_t nid = kcontrol->private_value; 777 struct via_spec *spec = codec->spec;
681 unsigned int pinsel;
682
683 /* use !! to translate conn sel 2 for VT1718S */
684 pinsel = !!snd_hda_codec_read(codec, nid, 0,
685 AC_VERB_GET_CONNECT_SEL,
686 0x00);
687 ucontrol->value.enumerated.item[0] = pinsel;
688 778
779 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
689 return 0; 780 return 0;
690} 781}
691 782
692static void activate_ctl(struct hda_codec *codec, const char *name, int active) 783/* adjust spec->multiout setup according to the current flags */
693{ 784static void setup_playback_multi_pcm(struct via_spec *spec)
694 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name);
695 if (ctl) {
696 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
697 ctl->vd[0].access |= active
698 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE;
699 snd_ctl_notify(codec->bus->card,
700 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id);
701 }
702}
703
704static hda_nid_t side_mute_channel(struct via_spec *spec)
705{ 785{
706 switch (spec->codec_type) { 786 const struct auto_pin_cfg *cfg = &spec->autocfg;
707 case VT1708: return 0x1b; 787 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
708 case VT1709_10CH: return 0x29; 788 spec->multiout.hp_nid = 0;
709 case VT1708B_8CH: /* fall thru */ 789 if (!spec->hp_independent_mode) {
710 case VT1708S: return 0x27; 790 if (!spec->hp_indep_shared)
711 case VT2002P: return 0x19; 791 spec->multiout.hp_nid = spec->hp_dac_nid;
712 case VT1802: return 0x15; 792 } else {
713 case VT1812: return 0x15; 793 if (spec->hp_indep_shared)
714 default: return 0; 794 spec->multiout.num_dacs = cfg->line_outs - 1;
715 } 795 }
716} 796}
717 797
718static int update_side_mute_status(struct hda_codec *codec) 798/* update DAC setups according to indep-HP switch;
799 * this function is called only when indep-HP is modified
800 */
801static void switch_indep_hp_dacs(struct hda_codec *codec)
719{ 802{
720 /* mute side channel */
721 struct via_spec *spec = codec->spec; 803 struct via_spec *spec = codec->spec;
722 unsigned int parm; 804 int shared = spec->hp_indep_shared;
723 hda_nid_t sw3 = side_mute_channel(spec); 805 hda_nid_t shared_dac, hp_dac;
724 806
725 if (sw3) { 807 if (!spec->opened_streams)
726 if (VT2002P_COMPATIBLE(spec)) 808 return;
727 parm = spec->hp_independent_mode ? 809
728 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); 810 shared_dac = shared ? spec->multiout.dac_nids[shared] : 0;
729 else 811 hp_dac = spec->hp_dac_nid;
730 parm = spec->hp_independent_mode ? 812 if (spec->hp_independent_mode) {
731 AMP_OUT_MUTE : AMP_OUT_UNMUTE; 813 /* switch to indep-HP mode */
732 snd_hda_codec_write(codec, sw3, 0, 814 if (spec->active_streams & STREAM_MULTI_OUT) {
733 AC_VERB_SET_AMP_GAIN_MUTE, parm); 815 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
734 if (spec->codec_type == VT1812) 816 __snd_hda_codec_cleanup_stream(codec, shared_dac, 1);
735 snd_hda_codec_write(codec, 0x1d, 0, 817 }
736 AC_VERB_SET_AMP_GAIN_MUTE, parm); 818 if (spec->active_streams & STREAM_INDEP_HP)
819 snd_hda_codec_setup_stream(codec, hp_dac,
820 spec->cur_hp_stream_tag, 0,
821 spec->cur_hp_format);
822 } else {
823 /* back to HP or shared-DAC */
824 if (spec->active_streams & STREAM_INDEP_HP)
825 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
826 if (spec->active_streams & STREAM_MULTI_OUT) {
827 hda_nid_t dac;
828 int ch;
829 if (shared_dac) { /* reset mutli-ch DAC */
830 dac = shared_dac;
831 ch = shared * 2;
832 } else { /* reset HP DAC */
833 dac = hp_dac;
834 ch = 0;
835 }
836 snd_hda_codec_setup_stream(codec, dac,
837 spec->cur_dac_stream_tag, ch,
838 spec->cur_dac_format);
839 }
737 } 840 }
738 return 0; 841 setup_playback_multi_pcm(spec);
739} 842}
740 843
741static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 844static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
@@ -743,66 +846,46 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
743{ 846{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 847 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct via_spec *spec = codec->spec; 848 struct via_spec *spec = codec->spec;
746 hda_nid_t nid = kcontrol->private_value; 849 int cur, shared;
747 unsigned int pinsel = ucontrol->value.enumerated.item[0];
748 unsigned int parm0, parm1;
749 /* Get Independent Mode index of headphone pin widget */
750 spec->hp_independent_mode = spec->hp_independent_mode_index == pinsel
751 ? 1 : 0;
752 if (spec->codec_type == VT1718S) {
753 snd_hda_codec_write(codec, nid, 0,
754 AC_VERB_SET_CONNECT_SEL, pinsel ? 2 : 0);
755 /* Set correct mute switch for MW3 */
756 parm0 = spec->hp_independent_mode ?
757 AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0);
758 parm1 = spec->hp_independent_mode ?
759 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1);
760 snd_hda_codec_write(codec, 0x1b, 0,
761 AC_VERB_SET_AMP_GAIN_MUTE, parm0);
762 snd_hda_codec_write(codec, 0x1b, 0,
763 AC_VERB_SET_AMP_GAIN_MUTE, parm1);
764 }
765 else
766 snd_hda_codec_write(codec, nid, 0,
767 AC_VERB_SET_CONNECT_SEL, pinsel);
768 850
769 if (spec->codec_type == VT1812) 851 mutex_lock(&spec->config_mutex);
770 snd_hda_codec_write(codec, 0x35, 0, 852 cur = !!ucontrol->value.enumerated.item[0];
771 AC_VERB_SET_CONNECT_SEL, pinsel); 853 if (spec->hp_independent_mode == cur) {
772 if (spec->multiout.hp_nid && spec->multiout.hp_nid 854 mutex_unlock(&spec->config_mutex);
773 != spec->multiout.dac_nids[HDA_FRONT]) 855 return 0;
774 snd_hda_codec_setup_stream(codec, spec->multiout.hp_nid,
775 0, 0, 0);
776
777 update_side_mute_status(codec);
778 /* update HP volume/swtich active state */
779 if (spec->codec_type == VT1708S
780 || spec->codec_type == VT1702
781 || spec->codec_type == VT1718S
782 || spec->codec_type == VT1716S
783 || VT2002P_COMPATIBLE(spec)) {
784 activate_ctl(codec, "Headphone Playback Volume",
785 spec->hp_independent_mode);
786 activate_ctl(codec, "Headphone Playback Switch",
787 spec->hp_independent_mode);
788 } 856 }
857 spec->hp_independent_mode = cur;
858 shared = spec->hp_indep_shared;
859 deactivate_hp_paths(codec);
860 if (cur)
861 activate_output_path(codec, &spec->hp_indep_path, true, false);
862 else {
863 if (shared)
864 activate_output_path(codec, &spec->out_path[shared],
865 true, false);
866 if (spec->aamix_mode || !spec->hp_path.depth)
867 activate_output_path(codec, &spec->hp_mix_path,
868 true, false);
869 else
870 activate_output_path(codec, &spec->hp_path,
871 true, false);
872 }
873
874 switch_indep_hp_dacs(codec);
875 mutex_unlock(&spec->config_mutex);
876
789 /* update jack power state */ 877 /* update jack power state */
790 set_widgets_power_state(codec); 878 set_widgets_power_state(codec);
791 return 0; 879 via_hp_automute(codec);
880 return 1;
792} 881}
793 882
794static const struct snd_kcontrol_new via_hp_mixer[2] = { 883static const struct snd_kcontrol_new via_hp_mixer = {
795 { 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 885 .name = "Independent HP",
797 .name = "Independent HP", 886 .info = via_independent_hp_info,
798 .info = via_independent_hp_info, 887 .get = via_independent_hp_get,
799 .get = via_independent_hp_get, 888 .put = via_independent_hp_put,
800 .put = via_independent_hp_put,
801 },
802 {
803 .iface = NID_MAPPING,
804 .name = "Independent HP",
805 },
806}; 889};
807 890
808static int via_hp_build(struct hda_codec *codec) 891static int via_hp_build(struct hda_codec *codec)
@@ -810,61 +893,28 @@ static int via_hp_build(struct hda_codec *codec)
810 struct via_spec *spec = codec->spec; 893 struct via_spec *spec = codec->spec;
811 struct snd_kcontrol_new *knew; 894 struct snd_kcontrol_new *knew;
812 hda_nid_t nid; 895 hda_nid_t nid;
813 int nums;
814 hda_nid_t conn[HDA_MAX_CONNECTIONS];
815 896
816 switch (spec->codec_type) { 897 nid = spec->autocfg.hp_pins[0];
817 case VT1718S: 898 knew = via_clone_control(spec, &via_hp_mixer);
818 nid = 0x34;
819 break;
820 case VT2002P:
821 case VT1802:
822 nid = 0x35;
823 break;
824 case VT1812:
825 nid = 0x3d;
826 break;
827 default:
828 nid = spec->autocfg.hp_pins[0];
829 break;
830 }
831
832 if (spec->codec_type != VT1708) {
833 nums = snd_hda_get_connections(codec, nid,
834 conn, HDA_MAX_CONNECTIONS);
835 if (nums <= 1)
836 return 0;
837 }
838
839 knew = via_clone_control(spec, &via_hp_mixer[0]);
840 if (knew == NULL) 899 if (knew == NULL)
841 return -ENOMEM; 900 return -ENOMEM;
842 901
843 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 902 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid;
844 knew->private_value = nid;
845
846 nid = side_mute_channel(spec);
847 if (nid) {
848 knew = via_clone_control(spec, &via_hp_mixer[1]);
849 if (knew == NULL)
850 return -ENOMEM;
851 knew->subdevice = nid;
852 }
853 903
854 return 0; 904 return 0;
855} 905}
856 906
857static void notify_aa_path_ctls(struct hda_codec *codec) 907static void notify_aa_path_ctls(struct hda_codec *codec)
858{ 908{
909 struct via_spec *spec = codec->spec;
859 int i; 910 int i;
860 struct snd_ctl_elem_id id; 911
861 const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; 912 for (i = 0; i < spec->smart51_nums; i++) {
862 struct snd_kcontrol *ctl; 913 struct snd_kcontrol *ctl;
863 914 struct snd_ctl_elem_id id;
864 memset(&id, 0, sizeof(id)); 915 memset(&id, 0, sizeof(id));
865 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 916 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
866 for (i = 0; i < ARRAY_SIZE(labels); i++) { 917 sprintf(id.name, "%s Playback Volume", spec->smart51_labels[i]);
867 sprintf(id.name, "%s Playback Volume", labels[i]);
868 ctl = snd_hda_find_mixer_ctl(codec, id.name); 918 ctl = snd_hda_find_mixer_ctl(codec, id.name);
869 if (ctl) 919 if (ctl)
870 snd_ctl_notify(codec->bus->card, 920 snd_ctl_notify(codec->bus->card,
@@ -876,66 +926,28 @@ static void notify_aa_path_ctls(struct hda_codec *codec)
876static void mute_aa_path(struct hda_codec *codec, int mute) 926static void mute_aa_path(struct hda_codec *codec, int mute)
877{ 927{
878 struct via_spec *spec = codec->spec; 928 struct via_spec *spec = codec->spec;
879 hda_nid_t nid_mixer; 929 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
880 int start_idx;
881 int end_idx;
882 int i; 930 int i;
883 /* get nid of MW0 and start & end index */ 931
884 switch (spec->codec_type) {
885 case VT1708:
886 nid_mixer = 0x17;
887 start_idx = 2;
888 end_idx = 4;
889 break;
890 case VT1709_10CH:
891 case VT1709_6CH:
892 nid_mixer = 0x18;
893 start_idx = 2;
894 end_idx = 4;
895 break;
896 case VT1708B_8CH:
897 case VT1708B_4CH:
898 case VT1708S:
899 case VT1716S:
900 nid_mixer = 0x16;
901 start_idx = 2;
902 end_idx = 4;
903 break;
904 case VT1718S:
905 nid_mixer = 0x21;
906 start_idx = 1;
907 end_idx = 3;
908 break;
909 default:
910 return;
911 }
912 /* check AA path's mute status */ 932 /* check AA path's mute status */
913 for (i = start_idx; i <= end_idx; i++) { 933 for (i = 0; i < spec->smart51_nums; i++) {
914 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE; 934 if (spec->smart51_idxs[i] < 0)
915 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i, 935 continue;
936 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
937 HDA_INPUT, spec->smart51_idxs[i],
916 HDA_AMP_MUTE, val); 938 HDA_AMP_MUTE, val);
917 } 939 }
918} 940}
919static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 941
942static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
920{ 943{
921 const struct auto_pin_cfg *cfg = &spec->autocfg; 944 struct via_spec *spec = codec->spec;
922 int i; 945 int i;
923 946
924 for (i = 0; i < cfg->num_inputs; i++) { 947 for (i = 0; i < spec->smart51_nums; i++)
925 if (pin == cfg->inputs[i].pin) 948 if (spec->smart51_pins[i] == pin)
926 return cfg->inputs[i].type <= AUTO_PIN_LINE_IN; 949 return true;
927 } 950 return false;
928 return 0;
929}
930
931static int via_smart51_info(struct snd_kcontrol *kcontrol,
932 struct snd_ctl_elem_info *uinfo)
933{
934 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
935 uinfo->count = 1;
936 uinfo->value.integer.min = 0;
937 uinfo->value.integer.max = 1;
938 return 0;
939} 951}
940 952
941static int via_smart51_get(struct snd_kcontrol *kcontrol, 953static int via_smart51_get(struct snd_kcontrol *kcontrol,
@@ -943,23 +955,8 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
943{ 955{
944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 956 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
945 struct via_spec *spec = codec->spec; 957 struct via_spec *spec = codec->spec;
946 const struct auto_pin_cfg *cfg = &spec->autocfg;
947 int on = 1;
948 int i;
949 958
950 for (i = 0; i < cfg->num_inputs; i++) { 959 *ucontrol->value.integer.value = spec->smart51_enabled;
951 hda_nid_t nid = cfg->inputs[i].pin;
952 int ctl = snd_hda_codec_read(codec, nid, 0,
953 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
954 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
955 continue;
956 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
957 spec->hp_independent_mode && spec->codec_type != VT1718S)
958 continue; /* ignore FMic for independent HP */
959 if ((ctl & AC_PINCTL_IN_EN) && !(ctl & AC_PINCTL_OUT_EN))
960 on = 0;
961 }
962 *ucontrol->value.integer.value = on;
963 return 0; 960 return 0;
964} 961}
965 962
@@ -968,21 +965,14 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
968{ 965{
969 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 966 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
970 struct via_spec *spec = codec->spec; 967 struct via_spec *spec = codec->spec;
971 const struct auto_pin_cfg *cfg = &spec->autocfg;
972 int out_in = *ucontrol->value.integer.value 968 int out_in = *ucontrol->value.integer.value
973 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 969 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
974 int i; 970 int i;
975 971
976 for (i = 0; i < cfg->num_inputs; i++) { 972 for (i = 0; i < spec->smart51_nums; i++) {
977 hda_nid_t nid = cfg->inputs[i].pin; 973 hda_nid_t nid = spec->smart51_pins[i];
978 unsigned int parm; 974 unsigned int parm;
979 975
980 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
981 continue;
982 if (cfg->inputs[i].type == AUTO_PIN_MIC &&
983 spec->hp_independent_mode && spec->codec_type != VT1718S)
984 continue; /* don't retask FMic for independent HP */
985
986 parm = snd_hda_codec_read(codec, nid, 0, 976 parm = snd_hda_codec_read(codec, nid, 0,
987 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 977 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
988 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 978 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
@@ -994,171 +984,59 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
994 mute_aa_path(codec, 1); 984 mute_aa_path(codec, 1);
995 notify_aa_path_ctls(codec); 985 notify_aa_path_ctls(codec);
996 } 986 }
997 if (spec->codec_type == VT1718S) {
998 snd_hda_codec_amp_stereo(
999 codec, nid, HDA_OUTPUT, 0, HDA_AMP_MUTE,
1000 HDA_AMP_UNMUTE);
1001 }
1002 if (cfg->inputs[i].type == AUTO_PIN_MIC) {
1003 if (spec->codec_type == VT1708S
1004 || spec->codec_type == VT1716S) {
1005 /* input = index 1 (AOW3) */
1006 snd_hda_codec_write(
1007 codec, nid, 0,
1008 AC_VERB_SET_CONNECT_SEL, 1);
1009 snd_hda_codec_amp_stereo(
1010 codec, nid, HDA_OUTPUT,
1011 0, HDA_AMP_MUTE, HDA_AMP_UNMUTE);
1012 }
1013 }
1014 } 987 }
1015 spec->smart51_enabled = *ucontrol->value.integer.value; 988 spec->smart51_enabled = *ucontrol->value.integer.value;
1016 set_widgets_power_state(codec); 989 set_widgets_power_state(codec);
1017 return 1; 990 return 1;
1018} 991}
1019 992
1020static const struct snd_kcontrol_new via_smart51_mixer[2] = { 993static const struct snd_kcontrol_new via_smart51_mixer = {
1021 { 994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 995 .name = "Smart 5.1",
1023 .name = "Smart 5.1", 996 .count = 1,
1024 .count = 1, 997 .info = snd_ctl_boolean_mono_info,
1025 .info = via_smart51_info, 998 .get = via_smart51_get,
1026 .get = via_smart51_get, 999 .put = via_smart51_put,
1027 .put = via_smart51_put,
1028 },
1029 {
1030 .iface = NID_MAPPING,
1031 .name = "Smart 5.1",
1032 }
1033}; 1000};
1034 1001
1035static int via_smart51_build(struct via_spec *spec) 1002static int via_smart51_build(struct hda_codec *codec)
1036{ 1003{
1037 struct snd_kcontrol_new *knew; 1004 struct via_spec *spec = codec->spec;
1038 const struct auto_pin_cfg *cfg = &spec->autocfg;
1039 hda_nid_t nid;
1040 int i;
1041 1005
1042 if (!cfg) 1006 if (!spec->smart51_nums)
1043 return 0; 1007 return 0;
1044 if (cfg->line_outs > 2) 1008 if (!via_clone_control(spec, &via_smart51_mixer))
1045 return 0;
1046
1047 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1048 if (knew == NULL)
1049 return -ENOMEM; 1009 return -ENOMEM;
1050
1051 for (i = 0; i < cfg->num_inputs; i++) {
1052 nid = cfg->inputs[i].pin;
1053 if (cfg->inputs[i].type <= AUTO_PIN_LINE_IN) {
1054 knew = via_clone_control(spec, &via_smart51_mixer[1]);
1055 if (knew == NULL)
1056 return -ENOMEM;
1057 knew->subdevice = nid;
1058 break;
1059 }
1060 }
1061
1062 return 0; 1010 return 0;
1063} 1011}
1064 1012
1065/* capture mixer elements */ 1013/* check AA path's mute status */
1066static const struct snd_kcontrol_new vt1708_capture_mixer[] = { 1014static bool is_aa_path_mute(struct hda_codec *codec)
1067 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
1068 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
1069 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
1070 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
1071 {
1072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1073 /* The multiple "Capture Source" controls confuse alsamixer
1074 * So call somewhat different..
1075 */
1076 /* .name = "Capture Source", */
1077 .name = "Input Source",
1078 .count = 1,
1079 .info = via_mux_enum_info,
1080 .get = via_mux_enum_get,
1081 .put = via_mux_enum_put,
1082 },
1083 { } /* end */
1084};
1085
1086/* check AA path's mute statue */
1087static int is_aa_path_mute(struct hda_codec *codec)
1088{ 1015{
1089 int mute = 1;
1090 hda_nid_t nid_mixer;
1091 int start_idx;
1092 int end_idx;
1093 int i;
1094 struct via_spec *spec = codec->spec; 1016 struct via_spec *spec = codec->spec;
1095 /* get nid of MW0 and start & end index */ 1017 const struct hda_amp_list *p;
1096 switch (spec->codec_type) { 1018 int i, ch, v;
1097 case VT1708B_8CH: 1019
1098 case VT1708B_4CH: 1020 for (i = 0; i < spec->num_loopbacks; i++) {
1099 case VT1708S: 1021 p = &spec->loopback_list[i];
1100 case VT1716S: 1022 for (ch = 0; ch < 2; ch++) {
1101 nid_mixer = 0x16; 1023 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
1102 start_idx = 2; 1024 p->idx);
1103 end_idx = 4; 1025 if (!(v & HDA_AMP_MUTE) && v > 0)
1104 break; 1026 return false;
1105 case VT1702:
1106 nid_mixer = 0x1a;
1107 start_idx = 1;
1108 end_idx = 3;
1109 break;
1110 case VT1718S:
1111 nid_mixer = 0x21;
1112 start_idx = 1;
1113 end_idx = 3;
1114 break;
1115 case VT2002P:
1116 case VT1812:
1117 case VT1802:
1118 nid_mixer = 0x21;
1119 start_idx = 0;
1120 end_idx = 2;
1121 break;
1122 default:
1123 return 0;
1124 }
1125 /* check AA path's mute status */
1126 for (i = start_idx; i <= end_idx; i++) {
1127 unsigned int con_list = snd_hda_codec_read(
1128 codec, nid_mixer, 0, AC_VERB_GET_CONNECT_LIST, i/4*4);
1129 int shift = 8 * (i % 4);
1130 hda_nid_t nid_pin = (con_list & (0xff << shift)) >> shift;
1131 unsigned int defconf = snd_hda_codec_get_pincfg(codec, nid_pin);
1132 if (get_defcfg_connect(defconf) == AC_JACK_PORT_COMPLEX) {
1133 /* check mute status while the pin is connected */
1134 int mute_l = snd_hda_codec_amp_read(codec, nid_mixer, 0,
1135 HDA_INPUT, i) >> 7;
1136 int mute_r = snd_hda_codec_amp_read(codec, nid_mixer, 1,
1137 HDA_INPUT, i) >> 7;
1138 if (!mute_l || !mute_r) {
1139 mute = 0;
1140 break;
1141 }
1142 } 1027 }
1143 } 1028 }
1144 return mute; 1029 return true;
1145} 1030}
1146 1031
1147/* enter/exit analog low-current mode */ 1032/* enter/exit analog low-current mode */
1148static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) 1033static void analog_low_current_mode(struct hda_codec *codec)
1149{ 1034{
1150 struct via_spec *spec = codec->spec; 1035 struct via_spec *spec = codec->spec;
1151 static int saved_stream_idle = 1; /* saved stream idle status */ 1036 bool enable;
1152 int enable = is_aa_path_mute(codec); 1037 unsigned int verb, parm;
1153 unsigned int verb = 0;
1154 unsigned int parm = 0;
1155 1038
1156 if (stream_idle == -1) /* stream status did not change */ 1039 enable = is_aa_path_mute(codec) && (spec->opened_streams != 0);
1157 enable = enable && saved_stream_idle;
1158 else {
1159 enable = enable && stream_idle;
1160 saved_stream_idle = stream_idle;
1161 }
1162 1040
1163 /* decide low current mode's verb & parameter */ 1041 /* decide low current mode's verb & parameter */
1164 switch (spec->codec_type) { 1042 switch (spec->codec_type) {
@@ -1193,119 +1071,69 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1193/* 1071/*
1194 * generic initialization of ADC, input mixers and output mixers 1072 * generic initialization of ADC, input mixers and output mixers
1195 */ 1073 */
1196static const struct hda_verb vt1708_volume_init_verbs[] = { 1074static const struct hda_verb vt1708_init_verbs[] = {
1197 /*
1198 * Unmute ADC0-1 and set the default input to mic-in
1199 */
1200 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1201 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1202
1203
1204 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1205 * mixer widget
1206 */
1207 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1208 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1210 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1212 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1213
1214 /*
1215 * Set up output mixers (0x19 - 0x1b)
1216 */
1217 /* set vol=0 to output mixers */
1218 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1220 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1221
1222 /* Setup default input MW0 to PW4 */
1223 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1224 /* PW9 Output enable */
1225 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1226 /* power down jack detect function */ 1075 /* power down jack detect function */
1227 {0x1, 0xf81, 0x1}, 1076 {0x1, 0xf81, 0x1},
1228 { } 1077 { }
1229}; 1078};
1230 1079
1231static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 1080static void set_stream_open(struct hda_codec *codec, int bit, bool active)
1081{
1082 struct via_spec *spec = codec->spec;
1083
1084 if (active)
1085 spec->opened_streams |= bit;
1086 else
1087 spec->opened_streams &= ~bit;
1088 analog_low_current_mode(codec);
1089}
1090
1091static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
1232 struct hda_codec *codec, 1092 struct hda_codec *codec,
1233 struct snd_pcm_substream *substream) 1093 struct snd_pcm_substream *substream)
1234{ 1094{
1235 struct via_spec *spec = codec->spec; 1095 struct via_spec *spec = codec->spec;
1236 int idle = substream->pstr->substream_opened == 1 1096 const struct auto_pin_cfg *cfg = &spec->autocfg;
1237 && substream->ref_count == 0; 1097 int err;
1238 analog_low_current_mode(codec, idle); 1098
1239 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 1099 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
1240 hinfo); 1100 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1101 set_stream_open(codec, STREAM_MULTI_OUT, true);
1102 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1103 hinfo);
1104 if (err < 0) {
1105 set_stream_open(codec, STREAM_MULTI_OUT, false);
1106 return err;
1107 }
1108 return 0;
1241} 1109}
1242 1110
1243static void playback_multi_pcm_prep_0(struct hda_codec *codec, 1111static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
1244 unsigned int stream_tag, 1112 struct hda_codec *codec,
1245 unsigned int format, 1113 struct snd_pcm_substream *substream)
1246 struct snd_pcm_substream *substream) 1114{
1115 set_stream_open(codec, STREAM_MULTI_OUT, false);
1116 return 0;
1117}
1118
1119static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1120 struct hda_codec *codec,
1121 struct snd_pcm_substream *substream)
1247{ 1122{
1248 struct via_spec *spec = codec->spec; 1123 struct via_spec *spec = codec->spec;
1249 struct hda_multi_out *mout = &spec->multiout;
1250 const hda_nid_t *nids = mout->dac_nids;
1251 int chs = substream->runtime->channels;
1252 int i;
1253 1124
1254 mutex_lock(&codec->spdif_mutex); 1125 if (snd_BUG_ON(!spec->hp_dac_nid))
1255 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1126 return -EINVAL;
1256 if (chs == 2 && 1127 set_stream_open(codec, STREAM_INDEP_HP, true);
1257 snd_hda_is_supported_format(codec, mout->dig_out_nid, 1128 return 0;
1258 format) && 1129}
1259 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1130
1260 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1131static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1261 /* turn off SPDIF once; otherwise the IEC958 bits won't 1132 struct hda_codec *codec,
1262 * be updated */ 1133 struct snd_pcm_substream *substream)
1263 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1134{
1264 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1135 set_stream_open(codec, STREAM_INDEP_HP, false);
1265 AC_VERB_SET_DIGI_CONVERT_1, 1136 return 0;
1266 codec->spdif_ctls &
1267 ~AC_DIG1_ENABLE & 0xff);
1268 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1269 stream_tag, 0, format);
1270 /* turn on again (if needed) */
1271 if (codec->spdif_ctls & AC_DIG1_ENABLE)
1272 snd_hda_codec_write(codec, mout->dig_out_nid, 0,
1273 AC_VERB_SET_DIGI_CONVERT_1,
1274 codec->spdif_ctls & 0xff);
1275 } else {
1276 mout->dig_out_used = 0;
1277 snd_hda_codec_setup_stream(codec, mout->dig_out_nid,
1278 0, 0, 0);
1279 }
1280 }
1281 mutex_unlock(&codec->spdif_mutex);
1282
1283 /* front */
1284 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
1285 0, format);
1286
1287 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]
1288 && !spec->hp_independent_mode)
1289 /* headphone out will just decode front left/right (stereo) */
1290 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
1291 0, format);
1292
1293 /* extra outputs copied from front */
1294 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
1295 if (mout->extra_out_nid[i])
1296 snd_hda_codec_setup_stream(codec,
1297 mout->extra_out_nid[i],
1298 stream_tag, 0, format);
1299
1300 /* surrounds */
1301 for (i = 1; i < mout->num_dacs; i++) {
1302 if (chs >= (i + 1) * 2) /* independent out */
1303 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1304 i * 2, format);
1305 else /* copy front */
1306 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
1307 0, format);
1308 }
1309} 1137}
1310 1138
1311static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, 1139static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -1315,18 +1143,36 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1315 struct snd_pcm_substream *substream) 1143 struct snd_pcm_substream *substream)
1316{ 1144{
1317 struct via_spec *spec = codec->spec; 1145 struct via_spec *spec = codec->spec;
1318 struct hda_multi_out *mout = &spec->multiout;
1319 const hda_nid_t *nids = mout->dac_nids;
1320 1146
1321 if (substream->number == 0) 1147 mutex_lock(&spec->config_mutex);
1322 playback_multi_pcm_prep_0(codec, stream_tag, format, 1148 setup_playback_multi_pcm(spec);
1323 substream); 1149 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1324 else { 1150 format, substream);
1325 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1151 /* remember for dynamic DAC switch with indep-HP */
1326 spec->hp_independent_mode) 1152 spec->active_streams |= STREAM_MULTI_OUT;
1327 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1153 spec->cur_dac_stream_tag = stream_tag;
1328 stream_tag, 0, format); 1154 spec->cur_dac_format = format;
1329 } 1155 mutex_unlock(&spec->config_mutex);
1156 vt1708_start_hp_work(spec);
1157 return 0;
1158}
1159
1160static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1161 struct hda_codec *codec,
1162 unsigned int stream_tag,
1163 unsigned int format,
1164 struct snd_pcm_substream *substream)
1165{
1166 struct via_spec *spec = codec->spec;
1167
1168 mutex_lock(&spec->config_mutex);
1169 if (spec->hp_independent_mode)
1170 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1171 stream_tag, 0, format);
1172 spec->active_streams |= STREAM_INDEP_HP;
1173 spec->cur_hp_stream_tag = stream_tag;
1174 spec->cur_hp_format = format;
1175 mutex_unlock(&spec->config_mutex);
1330 vt1708_start_hp_work(spec); 1176 vt1708_start_hp_work(spec);
1331 return 0; 1177 return 0;
1332} 1178}
@@ -1336,37 +1182,26 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1336 struct snd_pcm_substream *substream) 1182 struct snd_pcm_substream *substream)
1337{ 1183{
1338 struct via_spec *spec = codec->spec; 1184 struct via_spec *spec = codec->spec;
1339 struct hda_multi_out *mout = &spec->multiout;
1340 const hda_nid_t *nids = mout->dac_nids;
1341 int i;
1342 1185
1343 if (substream->number == 0) { 1186 mutex_lock(&spec->config_mutex);
1344 for (i = 0; i < mout->num_dacs; i++) 1187 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1345 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1188 spec->active_streams &= ~STREAM_MULTI_OUT;
1346 1189 mutex_unlock(&spec->config_mutex);
1347 if (mout->hp_nid && !spec->hp_independent_mode) 1190 vt1708_stop_hp_work(spec);
1348 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1191 return 0;
1349 0, 0, 0); 1192}
1350 1193
1351 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1194static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1352 if (mout->extra_out_nid[i]) 1195 struct hda_codec *codec,
1353 snd_hda_codec_setup_stream(codec, 1196 struct snd_pcm_substream *substream)
1354 mout->extra_out_nid[i], 1197{
1355 0, 0, 0); 1198 struct via_spec *spec = codec->spec;
1356 mutex_lock(&codec->spdif_mutex); 1199
1357 if (mout->dig_out_nid && 1200 mutex_lock(&spec->config_mutex);
1358 mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1201 if (spec->hp_independent_mode)
1359 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1202 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1360 0, 0, 0); 1203 spec->active_streams &= ~STREAM_INDEP_HP;
1361 mout->dig_out_used = 0; 1204 mutex_unlock(&spec->config_mutex);
1362 }
1363 mutex_unlock(&codec->spdif_mutex);
1364 } else {
1365 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] &&
1366 spec->hp_independent_mode)
1367 snd_hda_codec_setup_stream(codec, mout->hp_nid,
1368 0, 0, 0);
1369 }
1370 vt1708_stop_hp_work(spec); 1205 vt1708_stop_hp_work(spec);
1371 return 0; 1206 return 0;
1372} 1207}
@@ -1435,47 +1270,127 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1435 return 0; 1270 return 0;
1436} 1271}
1437 1272
1438static const struct hda_pcm_stream vt1708_pcm_analog_playback = { 1273/* analog capture with dynamic ADC switching */
1439 .substreams = 2, 1274static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1275 struct hda_codec *codec,
1276 unsigned int stream_tag,
1277 unsigned int format,
1278 struct snd_pcm_substream *substream)
1279{
1280 struct via_spec *spec = codec->spec;
1281 int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
1282
1283 mutex_lock(&spec->config_mutex);
1284 spec->cur_adc = spec->adc_nids[adc_idx];
1285 spec->cur_adc_stream_tag = stream_tag;
1286 spec->cur_adc_format = format;
1287 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
1288 mutex_unlock(&spec->config_mutex);
1289 return 0;
1290}
1291
1292static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1293 struct hda_codec *codec,
1294 struct snd_pcm_substream *substream)
1295{
1296 struct via_spec *spec = codec->spec;
1297
1298 mutex_lock(&spec->config_mutex);
1299 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1300 spec->cur_adc = 0;
1301 mutex_unlock(&spec->config_mutex);
1302 return 0;
1303}
1304
1305/* re-setup the stream if running; called from input-src put */
1306static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
1307{
1308 struct via_spec *spec = codec->spec;
1309 int adc_idx = spec->inputs[cur].adc_idx;
1310 hda_nid_t adc = spec->adc_nids[adc_idx];
1311 bool ret = false;
1312
1313 mutex_lock(&spec->config_mutex);
1314 if (spec->cur_adc && spec->cur_adc != adc) {
1315 /* stream is running, let's swap the current ADC */
1316 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1317 spec->cur_adc = adc;
1318 snd_hda_codec_setup_stream(codec, adc,
1319 spec->cur_adc_stream_tag, 0,
1320 spec->cur_adc_format);
1321 ret = true;
1322 }
1323 mutex_unlock(&spec->config_mutex);
1324 return ret;
1325}
1326
1327static const struct hda_pcm_stream via_pcm_analog_playback = {
1328 .substreams = 1,
1440 .channels_min = 2, 1329 .channels_min = 2,
1441 .channels_max = 8, 1330 .channels_max = 8,
1442 .nid = 0x10, /* NID to query formats and rates */ 1331 /* NID is set in via_build_pcms */
1443 .ops = { 1332 .ops = {
1444 .open = via_playback_pcm_open, 1333 .open = via_playback_multi_pcm_open,
1334 .close = via_playback_multi_pcm_close,
1445 .prepare = via_playback_multi_pcm_prepare, 1335 .prepare = via_playback_multi_pcm_prepare,
1446 .cleanup = via_playback_multi_pcm_cleanup 1336 .cleanup = via_playback_multi_pcm_cleanup
1447 }, 1337 },
1448}; 1338};
1449 1339
1340static const struct hda_pcm_stream via_pcm_hp_playback = {
1341 .substreams = 1,
1342 .channels_min = 2,
1343 .channels_max = 2,
1344 /* NID is set in via_build_pcms */
1345 .ops = {
1346 .open = via_playback_hp_pcm_open,
1347 .close = via_playback_hp_pcm_close,
1348 .prepare = via_playback_hp_pcm_prepare,
1349 .cleanup = via_playback_hp_pcm_cleanup
1350 },
1351};
1352
1450static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1353static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1451 .substreams = 2, 1354 .substreams = 1,
1452 .channels_min = 2, 1355 .channels_min = 2,
1453 .channels_max = 8, 1356 .channels_max = 8,
1454 .nid = 0x10, /* NID to query formats and rates */ 1357 /* NID is set in via_build_pcms */
1455 /* We got noisy outputs on the right channel on VT1708 when 1358 /* We got noisy outputs on the right channel on VT1708 when
1456 * 24bit samples are used. Until any workaround is found, 1359 * 24bit samples are used. Until any workaround is found,
1457 * disable the 24bit format, so far. 1360 * disable the 24bit format, so far.
1458 */ 1361 */
1459 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1362 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1460 .ops = { 1363 .ops = {
1461 .open = via_playback_pcm_open, 1364 .open = via_playback_multi_pcm_open,
1365 .close = via_playback_multi_pcm_close,
1462 .prepare = via_playback_multi_pcm_prepare, 1366 .prepare = via_playback_multi_pcm_prepare,
1463 .cleanup = via_playback_multi_pcm_cleanup 1367 .cleanup = via_playback_multi_pcm_cleanup
1464 }, 1368 },
1465}; 1369};
1466 1370
1467static const struct hda_pcm_stream vt1708_pcm_analog_capture = { 1371static const struct hda_pcm_stream via_pcm_analog_capture = {
1468 .substreams = 2, 1372 .substreams = 1, /* will be changed in via_build_pcms() */
1469 .channels_min = 2, 1373 .channels_min = 2,
1470 .channels_max = 2, 1374 .channels_max = 2,
1471 .nid = 0x15, /* NID to query formats and rates */ 1375 /* NID is set in via_build_pcms */
1472 .ops = { 1376 .ops = {
1473 .prepare = via_capture_pcm_prepare, 1377 .prepare = via_capture_pcm_prepare,
1474 .cleanup = via_capture_pcm_cleanup 1378 .cleanup = via_capture_pcm_cleanup
1475 }, 1379 },
1476}; 1380};
1477 1381
1478static const struct hda_pcm_stream vt1708_pcm_digital_playback = { 1382static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
1383 .substreams = 1,
1384 .channels_min = 2,
1385 .channels_max = 2,
1386 /* NID is set in via_build_pcms */
1387 .ops = {
1388 .prepare = via_dyn_adc_capture_pcm_prepare,
1389 .cleanup = via_dyn_adc_capture_pcm_cleanup,
1390 },
1391};
1392
1393static const struct hda_pcm_stream via_pcm_digital_playback = {
1479 .substreams = 1, 1394 .substreams = 1,
1480 .channels_min = 2, 1395 .channels_min = 2,
1481 .channels_max = 2, 1396 .channels_max = 2,
@@ -1488,19 +1403,47 @@ static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
1488 }, 1403 },
1489}; 1404};
1490 1405
1491static const struct hda_pcm_stream vt1708_pcm_digital_capture = { 1406static const struct hda_pcm_stream via_pcm_digital_capture = {
1492 .substreams = 1, 1407 .substreams = 1,
1493 .channels_min = 2, 1408 .channels_min = 2,
1494 .channels_max = 2, 1409 .channels_max = 2,
1495}; 1410};
1496 1411
1412/*
1413 * slave controls for virtual master
1414 */
1415static const char * const via_slave_vols[] = {
1416 "Front Playback Volume",
1417 "Surround Playback Volume",
1418 "Center Playback Volume",
1419 "LFE Playback Volume",
1420 "Side Playback Volume",
1421 "Headphone Playback Volume",
1422 "Speaker Playback Volume",
1423 NULL,
1424};
1425
1426static const char * const via_slave_sws[] = {
1427 "Front Playback Switch",
1428 "Surround Playback Switch",
1429 "Center Playback Switch",
1430 "LFE Playback Switch",
1431 "Side Playback Switch",
1432 "Headphone Playback Switch",
1433 "Speaker Playback Switch",
1434 NULL,
1435};
1436
1497static int via_build_controls(struct hda_codec *codec) 1437static int via_build_controls(struct hda_codec *codec)
1498{ 1438{
1499 struct via_spec *spec = codec->spec; 1439 struct via_spec *spec = codec->spec;
1500 struct snd_kcontrol *kctl; 1440 struct snd_kcontrol *kctl;
1501 const struct snd_kcontrol_new *knew;
1502 int err, i; 1441 int err, i;
1503 1442
1443 if (spec->set_widgets_power_state)
1444 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1445 return -ENOMEM;
1446
1504 for (i = 0; i < spec->num_mixers; i++) { 1447 for (i = 0; i < spec->num_mixers; i++) {
1505 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1448 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1506 if (err < 0) 1449 if (err < 0)
@@ -1509,6 +1452,7 @@ static int via_build_controls(struct hda_codec *codec)
1509 1452
1510 if (spec->multiout.dig_out_nid) { 1453 if (spec->multiout.dig_out_nid) {
1511 err = snd_hda_create_spdif_out_ctls(codec, 1454 err = snd_hda_create_spdif_out_ctls(codec,
1455 spec->multiout.dig_out_nid,
1512 spec->multiout.dig_out_nid); 1456 spec->multiout.dig_out_nid);
1513 if (err < 0) 1457 if (err < 0)
1514 return err; 1458 return err;
@@ -1524,6 +1468,23 @@ static int via_build_controls(struct hda_codec *codec)
1524 return err; 1468 return err;
1525 } 1469 }
1526 1470
1471 /* if we have no master control, let's create it */
1472 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1473 unsigned int vmaster_tlv[4];
1474 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1475 HDA_OUTPUT, vmaster_tlv);
1476 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1477 vmaster_tlv, via_slave_vols);
1478 if (err < 0)
1479 return err;
1480 }
1481 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1482 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1483 NULL, via_slave_sws);
1484 if (err < 0)
1485 return err;
1486 }
1487
1527 /* assign Capture Source enums to NID */ 1488 /* assign Capture Source enums to NID */
1528 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1489 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1529 for (i = 0; kctl && i < kctl->count; i++) { 1490 for (i = 0; kctl && i < kctl->count; i++) {
@@ -1532,22 +1493,9 @@ static int via_build_controls(struct hda_codec *codec)
1532 return err; 1493 return err;
1533 } 1494 }
1534 1495
1535 /* other nid->control mapping */
1536 for (i = 0; i < spec->num_mixers; i++) {
1537 for (knew = spec->mixers[i]; knew->name; knew++) {
1538 if (knew->iface != NID_MAPPING)
1539 continue;
1540 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
1541 if (kctl == NULL)
1542 continue;
1543 err = snd_hda_add_nid(codec, kctl, 0,
1544 knew->subdevice);
1545 }
1546 }
1547
1548 /* init power states */ 1496 /* init power states */
1549 set_widgets_power_state(codec); 1497 set_widgets_power_state(codec);
1550 analog_low_current_mode(codec, 1); 1498 analog_low_current_mode(codec);
1551 1499
1552 via_free_kctls(codec); /* no longer needed */ 1500 via_free_kctls(codec); /* no longer needed */
1553 return 0; 1501 return 0;
@@ -1561,36 +1509,71 @@ static int via_build_pcms(struct hda_codec *codec)
1561 codec->num_pcms = 1; 1509 codec->num_pcms = 1;
1562 codec->pcm_info = info; 1510 codec->pcm_info = info;
1563 1511
1512 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1513 "%s Analog", codec->chip_name);
1564 info->name = spec->stream_name_analog; 1514 info->name = spec->stream_name_analog;
1515
1516 if (!spec->stream_analog_playback)
1517 spec->stream_analog_playback = &via_pcm_analog_playback;
1565 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1518 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1566 *(spec->stream_analog_playback); 1519 *spec->stream_analog_playback;
1567 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1520 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1568 spec->multiout.dac_nids[0]; 1521 spec->multiout.dac_nids[0];
1569 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
1570 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1571
1572 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 1522 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1573 spec->multiout.max_channels; 1523 spec->multiout.max_channels;
1574 1524
1525 if (!spec->stream_analog_capture) {
1526 if (spec->dyn_adc_switch)
1527 spec->stream_analog_capture =
1528 &via_pcm_dyn_adc_analog_capture;
1529 else
1530 spec->stream_analog_capture = &via_pcm_analog_capture;
1531 }
1532 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1533 *spec->stream_analog_capture;
1534 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1535 if (!spec->dyn_adc_switch)
1536 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1537 spec->num_adc_nids;
1538
1575 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1539 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1576 codec->num_pcms++; 1540 codec->num_pcms++;
1577 info++; 1541 info++;
1542 snprintf(spec->stream_name_digital,
1543 sizeof(spec->stream_name_digital),
1544 "%s Digital", codec->chip_name);
1578 info->name = spec->stream_name_digital; 1545 info->name = spec->stream_name_digital;
1579 info->pcm_type = HDA_PCM_TYPE_SPDIF; 1546 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1580 if (spec->multiout.dig_out_nid) { 1547 if (spec->multiout.dig_out_nid) {
1548 if (!spec->stream_digital_playback)
1549 spec->stream_digital_playback =
1550 &via_pcm_digital_playback;
1581 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1551 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1582 *(spec->stream_digital_playback); 1552 *spec->stream_digital_playback;
1583 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1553 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1584 spec->multiout.dig_out_nid; 1554 spec->multiout.dig_out_nid;
1585 } 1555 }
1586 if (spec->dig_in_nid) { 1556 if (spec->dig_in_nid) {
1557 if (!spec->stream_digital_capture)
1558 spec->stream_digital_capture =
1559 &via_pcm_digital_capture;
1587 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 1560 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1588 *(spec->stream_digital_capture); 1561 *spec->stream_digital_capture;
1589 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 1562 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1590 spec->dig_in_nid; 1563 spec->dig_in_nid;
1591 } 1564 }
1592 } 1565 }
1593 1566
1567 if (spec->hp_dac_nid) {
1568 codec->num_pcms++;
1569 info++;
1570 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1571 "%s HP", codec->chip_name);
1572 info->name = spec->stream_name_hp;
1573 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1574 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1575 spec->hp_dac_nid;
1576 }
1594 return 0; 1577 return 0;
1595} 1578}
1596 1579
@@ -1603,57 +1586,62 @@ static void via_free(struct hda_codec *codec)
1603 1586
1604 via_free_kctls(codec); 1587 via_free_kctls(codec);
1605 vt1708_stop_hp_work(spec); 1588 vt1708_stop_hp_work(spec);
1606 kfree(codec->spec); 1589 kfree(spec->bind_cap_vol);
1590 kfree(spec->bind_cap_sw);
1591 kfree(spec);
1607} 1592}
1608 1593
1609/* mute internal speaker if HP is plugged */ 1594/* mute/unmute outputs */
1610static void via_hp_automute(struct hda_codec *codec) 1595static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1596 hda_nid_t *pins, bool mute)
1611{ 1597{
1612 unsigned int present = 0; 1598 int i;
1613 struct via_spec *spec = codec->spec; 1599 for (i = 0; i < num_pins; i++) {
1614 1600 unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
1615 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1601 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1616 1602 if (parm & AC_PINCTL_IN_EN)
1617 if (!spec->hp_independent_mode) { 1603 continue;
1618 struct snd_ctl_elem_id id; 1604 if (mute)
1619 /* auto mute */ 1605 parm &= ~AC_PINCTL_OUT_EN;
1620 snd_hda_codec_amp_stereo( 1606 else
1621 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0, 1607 parm |= AC_PINCTL_OUT_EN;
1622 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1608 snd_hda_codec_write(codec, pins[i], 0,
1623 /* notify change */ 1609 AC_VERB_SET_PIN_WIDGET_CONTROL, parm);
1624 memset(&id, 0, sizeof(id));
1625 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1626 strcpy(id.name, "Front Playback Switch");
1627 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1628 &id);
1629 } 1610 }
1630} 1611}
1631 1612
1632/* mute mono out if HP or Line out is plugged */ 1613/* mute internal speaker if line-out is plugged */
1633static void via_mono_automute(struct hda_codec *codec) 1614static void via_line_automute(struct hda_codec *codec, int present)
1634{ 1615{
1635 unsigned int hp_present, lineout_present;
1636 struct via_spec *spec = codec->spec; 1616 struct via_spec *spec = codec->spec;
1637 1617
1638 if (spec->codec_type != VT1716S) 1618 if (!spec->autocfg.speaker_outs)
1639 return; 1619 return;
1640 1620 if (!present)
1641 lineout_present = snd_hda_jack_detect(codec, 1621 present = snd_hda_jack_detect(codec,
1642 spec->autocfg.line_out_pins[0]); 1622 spec->autocfg.line_out_pins[0]);
1623 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1624 spec->autocfg.speaker_pins,
1625 present);
1626}
1643 1627
1644 /* Mute Mono Out if Line Out is plugged */ 1628/* mute internal speaker if HP is plugged */
1645 if (lineout_present) { 1629static void via_hp_automute(struct hda_codec *codec)
1646 snd_hda_codec_amp_stereo( 1630{
1647 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE); 1631 int present = 0;
1648 return; 1632 int nums;
1649 } 1633 struct via_spec *spec = codec->spec;
1650 1634
1651 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1635 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0])
1636 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1652 1637
1653 if (!spec->hp_independent_mode) 1638 if (spec->smart51_enabled)
1654 snd_hda_codec_amp_stereo( 1639 nums = spec->autocfg.line_outs + spec->smart51_nums;
1655 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, 1640 else
1656 hp_present ? HDA_AMP_MUTE : 0); 1641 nums = spec->autocfg.line_outs;
1642 toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
1643
1644 via_line_automute(codec, present);
1657} 1645}
1658 1646
1659static void via_gpio_control(struct hda_codec *codec) 1647static void via_gpio_control(struct hda_codec *codec)
@@ -1678,9 +1666,9 @@ static void via_gpio_control(struct hda_codec *codec)
1678 1666
1679 if (gpio_data == 0x02) { 1667 if (gpio_data == 0x02) {
1680 /* unmute line out */ 1668 /* unmute line out */
1681 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], 1669 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1682 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 1670 AC_VERB_SET_PIN_WIDGET_CONTROL,
1683 1671 PIN_OUT);
1684 if (vol_counter & 0x20) { 1672 if (vol_counter & 0x20) {
1685 /* decrease volume */ 1673 /* decrease volume */
1686 if (vol > master_vol) 1674 if (vol > master_vol)
@@ -1697,73 +1685,12 @@ static void via_gpio_control(struct hda_codec *codec)
1697 } 1685 }
1698 } else if (!(gpio_data & 0x02)) { 1686 } else if (!(gpio_data & 0x02)) {
1699 /* mute line out */ 1687 /* mute line out */
1700 snd_hda_codec_amp_stereo(codec, 1688 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1701 spec->autocfg.line_out_pins[0], 1689 AC_VERB_SET_PIN_WIDGET_CONTROL,
1702 HDA_OUTPUT, 0, HDA_AMP_MUTE, 1690 0);
1703 HDA_AMP_MUTE);
1704 }
1705}
1706
1707/* mute Internal-Speaker if HP is plugged */
1708static void via_speaker_automute(struct hda_codec *codec)
1709{
1710 unsigned int hp_present;
1711 struct via_spec *spec = codec->spec;
1712
1713 if (!VT2002P_COMPATIBLE(spec))
1714 return;
1715
1716 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1717
1718 if (!spec->hp_independent_mode) {
1719 struct snd_ctl_elem_id id;
1720 snd_hda_codec_amp_stereo(
1721 codec, spec->autocfg.speaker_pins[0], HDA_OUTPUT, 0,
1722 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
1723 /* notify change */
1724 memset(&id, 0, sizeof(id));
1725 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1726 strcpy(id.name, "Speaker Playback Switch");
1727 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE,
1728 &id);
1729 }
1730}
1731
1732/* mute line-out and internal speaker if HP is plugged */
1733static void via_hp_bind_automute(struct hda_codec *codec)
1734{
1735 /* use long instead of int below just to avoid an internal compiler
1736 * error with gcc 4.0.x
1737 */
1738 unsigned long hp_present, present = 0;
1739 struct via_spec *spec = codec->spec;
1740 int i;
1741
1742 if (!spec->autocfg.hp_pins[0] || !spec->autocfg.line_out_pins[0])
1743 return;
1744
1745 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1746
1747 present = snd_hda_jack_detect(codec, spec->autocfg.line_out_pins[0]);
1748
1749 if (!spec->hp_independent_mode) {
1750 /* Mute Line-Outs */
1751 for (i = 0; i < spec->autocfg.line_outs; i++)
1752 snd_hda_codec_amp_stereo(
1753 codec, spec->autocfg.line_out_pins[i],
1754 HDA_OUTPUT, 0,
1755 HDA_AMP_MUTE, hp_present ? HDA_AMP_MUTE : 0);
1756 if (hp_present)
1757 present = hp_present;
1758 } 1691 }
1759 /* Speakers */
1760 for (i = 0; i < spec->autocfg.speaker_outs; i++)
1761 snd_hda_codec_amp_stereo(
1762 codec, spec->autocfg.speaker_pins[i], HDA_OUTPUT, 0,
1763 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1764} 1692}
1765 1693
1766
1767/* unsolicited event for jack sensing */ 1694/* unsolicited event for jack sensing */
1768static void via_unsol_event(struct hda_codec *codec, 1695static void via_unsol_event(struct hda_codec *codec,
1769 unsigned int res) 1696 unsigned int res)
@@ -1775,43 +1702,10 @@ static void via_unsol_event(struct hda_codec *codec,
1775 1702
1776 res &= ~VIA_JACK_EVENT; 1703 res &= ~VIA_JACK_EVENT;
1777 1704
1778 if (res == VIA_HP_EVENT) 1705 if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
1779 via_hp_automute(codec); 1706 via_hp_automute(codec);
1780 else if (res == VIA_GPIO_EVENT) 1707 else if (res == VIA_GPIO_EVENT)
1781 via_gpio_control(codec); 1708 via_gpio_control(codec);
1782 else if (res == VIA_MONO_EVENT)
1783 via_mono_automute(codec);
1784 else if (res == VIA_SPEAKER_EVENT)
1785 via_speaker_automute(codec);
1786 else if (res == VIA_BIND_HP_EVENT)
1787 via_hp_bind_automute(codec);
1788}
1789
1790static int via_init(struct hda_codec *codec)
1791{
1792 struct via_spec *spec = codec->spec;
1793 int i;
1794 for (i = 0; i < spec->num_iverbs; i++)
1795 snd_hda_sequence_write(codec, spec->init_verbs[i]);
1796
1797 /* Lydia Add for EAPD enable */
1798 if (!spec->dig_in_nid) { /* No Digital In connection */
1799 if (spec->dig_in_pin) {
1800 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1801 AC_VERB_SET_PIN_WIDGET_CONTROL,
1802 PIN_OUT);
1803 snd_hda_codec_write(codec, spec->dig_in_pin, 0,
1804 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
1805 }
1806 } else /* enable SPDIF-input pin */
1807 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
1808 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
1809
1810 /* assign slave outs */
1811 if (spec->slave_dig_outs[0])
1812 codec->slave_dig_outs = spec->slave_dig_outs;
1813
1814 return 0;
1815} 1709}
1816 1710
1817#ifdef SND_HDA_NEEDS_RESUME 1711#ifdef SND_HDA_NEEDS_RESUME
@@ -1833,11 +1727,15 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1833 1727
1834/* 1728/*
1835 */ 1729 */
1730
1731static int via_init(struct hda_codec *codec);
1732
1836static const struct hda_codec_ops via_patch_ops = { 1733static const struct hda_codec_ops via_patch_ops = {
1837 .build_controls = via_build_controls, 1734 .build_controls = via_build_controls,
1838 .build_pcms = via_build_pcms, 1735 .build_pcms = via_build_pcms,
1839 .init = via_init, 1736 .init = via_init,
1840 .free = via_free, 1737 .free = via_free,
1738 .unsol_event = via_unsol_event,
1841#ifdef SND_HDA_NEEDS_RESUME 1739#ifdef SND_HDA_NEEDS_RESUME
1842 .suspend = via_suspend, 1740 .suspend = via_suspend,
1843#endif 1741#endif
@@ -1846,237 +1744,835 @@ static const struct hda_codec_ops via_patch_ops = {
1846#endif 1744#endif
1847}; 1745};
1848 1746
1849/* fill in the dac_nids table from the parsed pin configuration */ 1747static bool is_empty_dac(struct hda_codec *codec, hda_nid_t dac)
1850static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
1851 const struct auto_pin_cfg *cfg)
1852{ 1748{
1749 struct via_spec *spec = codec->spec;
1853 int i; 1750 int i;
1854 hda_nid_t nid;
1855 1751
1856 spec->multiout.num_dacs = cfg->line_outs; 1752 for (i = 0; i < spec->multiout.num_dacs; i++) {
1753 if (spec->multiout.dac_nids[i] == dac)
1754 return false;
1755 }
1756 if (spec->hp_dac_nid == dac)
1757 return false;
1758 return true;
1759}
1760
1761static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1762 hda_nid_t target_dac, int with_aa_mix,
1763 struct nid_path *path, int depth)
1764{
1765 struct via_spec *spec = codec->spec;
1766 hda_nid_t conn[8];
1767 int i, nums;
1857 1768
1858 spec->multiout.dac_nids = spec->private_dac_nids; 1769 if (nid == spec->aa_mix_nid) {
1770 if (!with_aa_mix)
1771 return false;
1772 with_aa_mix = 2; /* mark aa-mix is included */
1773 }
1859 1774
1860 for (i = 0; i < 4; i++) { 1775 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1776 for (i = 0; i < nums; i++) {
1777 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1778 continue;
1779 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1780 /* aa-mix is requested but not included? */
1781 if (!(spec->aa_mix_nid && with_aa_mix == 1))
1782 goto found;
1783 }
1784 }
1785 if (depth >= MAX_NID_PATH_DEPTH)
1786 return false;
1787 for (i = 0; i < nums; i++) {
1788 unsigned int type;
1789 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1790 if (type == AC_WID_AUD_OUT)
1791 continue;
1792 if (__parse_output_path(codec, conn[i], target_dac,
1793 with_aa_mix, path, depth + 1))
1794 goto found;
1795 }
1796 return false;
1797
1798 found:
1799 path->path[path->depth] = conn[i];
1800 path->idx[path->depth] = i;
1801 if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
1802 path->multi[path->depth] = 1;
1803 path->depth++;
1804 return true;
1805}
1806
1807static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1808 hda_nid_t target_dac, int with_aa_mix,
1809 struct nid_path *path)
1810{
1811 if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
1812 path->path[path->depth] = nid;
1813 path->depth++;
1814 snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
1815 path->depth, path->path[0], path->path[1],
1816 path->path[2], path->path[3], path->path[4]);
1817 return true;
1818 }
1819 return false;
1820}
1821
1822static int via_auto_fill_dac_nids(struct hda_codec *codec)
1823{
1824 struct via_spec *spec = codec->spec;
1825 const struct auto_pin_cfg *cfg = &spec->autocfg;
1826 int i, dac_num;
1827 hda_nid_t nid;
1828
1829 spec->multiout.dac_nids = spec->private_dac_nids;
1830 dac_num = 0;
1831 for (i = 0; i < cfg->line_outs; i++) {
1832 hda_nid_t dac = 0;
1861 nid = cfg->line_out_pins[i]; 1833 nid = cfg->line_out_pins[i];
1862 if (nid) { 1834 if (!nid)
1863 /* config dac list */ 1835 continue;
1864 switch (i) { 1836 if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
1865 case AUTO_SEQ_FRONT: 1837 dac = spec->out_path[i].path[0];
1866 spec->private_dac_nids[i] = 0x10; 1838 if (!i && parse_output_path(codec, nid, dac, 1,
1867 break; 1839 &spec->out_mix_path))
1868 case AUTO_SEQ_CENLFE: 1840 dac = spec->out_mix_path.path[0];
1869 spec->private_dac_nids[i] = 0x12; 1841 if (dac) {
1870 break; 1842 spec->private_dac_nids[i] = dac;
1871 case AUTO_SEQ_SURROUND: 1843 dac_num++;
1872 spec->private_dac_nids[i] = 0x11;
1873 break;
1874 case AUTO_SEQ_SIDE:
1875 spec->private_dac_nids[i] = 0x13;
1876 break;
1877 }
1878 } 1844 }
1879 } 1845 }
1846 if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
1847 spec->out_path[0] = spec->out_mix_path;
1848 spec->out_mix_path.depth = 0;
1849 }
1850 spec->multiout.num_dacs = dac_num;
1851 return 0;
1852}
1853
1854static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
1855 int chs, bool check_dac, struct nid_path *path)
1856{
1857 struct via_spec *spec = codec->spec;
1858 char name[32];
1859 hda_nid_t dac, pin, sel, nid;
1860 int err;
1861
1862 dac = check_dac ? path->path[0] : 0;
1863 pin = path->path[path->depth - 1];
1864 sel = path->depth > 1 ? path->path[1] : 0;
1880 1865
1866 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1867 nid = dac;
1868 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1869 nid = pin;
1870 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1871 nid = sel;
1872 else
1873 nid = 0;
1874 if (nid) {
1875 sprintf(name, "%s Playback Volume", pfx);
1876 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1877 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1878 if (err < 0)
1879 return err;
1880 path->vol_ctl = nid;
1881 }
1882
1883 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
1884 nid = dac;
1885 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
1886 nid = pin;
1887 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
1888 nid = sel;
1889 else
1890 nid = 0;
1891 if (nid) {
1892 sprintf(name, "%s Playback Switch", pfx);
1893 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1894 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1895 if (err < 0)
1896 return err;
1897 path->mute_ctl = nid;
1898 }
1881 return 0; 1899 return 0;
1882} 1900}
1883 1901
1902static void mangle_smart51(struct hda_codec *codec)
1903{
1904 struct via_spec *spec = codec->spec;
1905 struct auto_pin_cfg *cfg = &spec->autocfg;
1906 struct auto_pin_cfg_item *ins = cfg->inputs;
1907 int i, j, nums, attr;
1908 int pins[AUTO_CFG_MAX_INS];
1909
1910 for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
1911 nums = 0;
1912 for (i = 0; i < cfg->num_inputs; i++) {
1913 unsigned int def;
1914 if (ins[i].type > AUTO_PIN_LINE_IN)
1915 continue;
1916 def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
1917 if (snd_hda_get_input_pin_attr(def) != attr)
1918 continue;
1919 for (j = 0; j < nums; j++)
1920 if (ins[pins[j]].type < ins[i].type) {
1921 memmove(pins + j + 1, pins + j,
1922 (nums - j) * sizeof(int));
1923 break;
1924 }
1925 pins[j] = i;
1926 nums++;
1927 }
1928 if (cfg->line_outs + nums < 3)
1929 continue;
1930 for (i = 0; i < nums; i++) {
1931 hda_nid_t pin = ins[pins[i]].pin;
1932 spec->smart51_pins[spec->smart51_nums++] = pin;
1933 cfg->line_out_pins[cfg->line_outs++] = pin;
1934 if (cfg->line_outs == 3)
1935 break;
1936 }
1937 return;
1938 }
1939}
1940
1941static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src)
1942{
1943 dst->vol_ctl = src->vol_ctl;
1944 dst->mute_ctl = src->mute_ctl;
1945}
1946
1884/* add playback controls from the parsed DAC table */ 1947/* add playback controls from the parsed DAC table */
1885static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 1948static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1886 const struct auto_pin_cfg *cfg)
1887{ 1949{
1888 char name[32]; 1950 struct via_spec *spec = codec->spec;
1951 struct auto_pin_cfg *cfg = &spec->autocfg;
1952 struct nid_path *path;
1889 static const char * const chname[4] = { 1953 static const char * const chname[4] = {
1890 "Front", "Surround", "C/LFE", "Side" 1954 "Front", "Surround", "C/LFE", "Side"
1891 }; 1955 };
1892 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 1956 int i, idx, err;
1893 int i, err; 1957 int old_line_outs;
1894
1895 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1896 nid = cfg->line_out_pins[i];
1897
1898 if (!nid)
1899 continue;
1900 1958
1901 nid_vol = nid_vols[i]; 1959 /* check smart51 */
1960 old_line_outs = cfg->line_outs;
1961 if (cfg->line_outs == 1)
1962 mangle_smart51(codec);
1902 1963
1903 if (i == AUTO_SEQ_CENLFE) { 1964 err = via_auto_fill_dac_nids(codec);
1904 /* Center/LFE */ 1965 if (err < 0)
1905 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1966 return err;
1906 "Center Playback Volume",
1907 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1908 HDA_OUTPUT));
1909 if (err < 0)
1910 return err;
1911 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1912 "LFE Playback Volume",
1913 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1914 HDA_OUTPUT));
1915 if (err < 0)
1916 return err;
1917 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1918 "Center Playback Switch",
1919 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
1920 HDA_OUTPUT));
1921 if (err < 0)
1922 return err;
1923 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1924 "LFE Playback Switch",
1925 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
1926 HDA_OUTPUT));
1927 if (err < 0)
1928 return err;
1929 } else if (i == AUTO_SEQ_FRONT) {
1930 /* add control to mixer index 0 */
1931 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1932 "Master Front Playback Volume",
1933 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1934 HDA_INPUT));
1935 if (err < 0)
1936 return err;
1937 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1938 "Master Front Playback Switch",
1939 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1940 HDA_INPUT));
1941 if (err < 0)
1942 return err;
1943 1967
1944 /* add control to PW3 */ 1968 if (spec->multiout.num_dacs < 3) {
1945 sprintf(name, "%s Playback Volume", chname[i]); 1969 spec->smart51_nums = 0;
1946 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1970 cfg->line_outs = old_line_outs;
1947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1971 }
1948 HDA_OUTPUT)); 1972 for (i = 0; i < cfg->line_outs; i++) {
1973 hda_nid_t pin, dac;
1974 pin = cfg->line_out_pins[i];
1975 dac = spec->multiout.dac_nids[i];
1976 if (!pin || !dac)
1977 continue;
1978 path = spec->out_path + i;
1979 if (i == HDA_CLFE) {
1980 err = create_ch_ctls(codec, "Center", 1, true, path);
1949 if (err < 0) 1981 if (err < 0)
1950 return err; 1982 return err;
1951 sprintf(name, "%s Playback Switch", chname[i]); 1983 err = create_ch_ctls(codec, "LFE", 2, true, path);
1952 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1953 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
1954 HDA_OUTPUT));
1955 if (err < 0) 1984 if (err < 0)
1956 return err; 1985 return err;
1957 } else { 1986 } else {
1958 sprintf(name, "%s Playback Volume", chname[i]); 1987 const char *pfx = chname[i];
1959 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1988 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1960 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1989 cfg->line_outs == 1)
1961 HDA_OUTPUT)); 1990 pfx = "Speaker";
1962 if (err < 0) 1991 err = create_ch_ctls(codec, pfx, 3, true, path);
1963 return err;
1964 sprintf(name, "%s Playback Switch", chname[i]);
1965 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1966 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
1967 HDA_OUTPUT));
1968 if (err < 0) 1992 if (err < 0)
1969 return err; 1993 return err;
1970 } 1994 }
1995 if (path != spec->out_path + i)
1996 copy_path_mixer_ctls(&spec->out_path[i], path);
1997 if (path == spec->out_path && spec->out_mix_path.depth)
1998 copy_path_mixer_ctls(&spec->out_mix_path, path);
1999 }
2000
2001 idx = get_connection_index(codec, spec->aa_mix_nid,
2002 spec->multiout.dac_nids[0]);
2003 if (idx >= 0) {
2004 /* add control to mixer */
2005 const char *name;
2006 name = spec->out_mix_path.depth ?
2007 "PCM Loopback Playback Volume" : "PCM Playback Volume";
2008 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2009 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2010 idx, HDA_INPUT));
2011 if (err < 0)
2012 return err;
2013 name = spec->out_mix_path.depth ?
2014 "PCM Loopback Playback Switch" : "PCM Playback Switch";
2015 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2016 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2017 idx, HDA_INPUT));
2018 if (err < 0)
2019 return err;
1971 } 2020 }
1972 2021
2022 cfg->line_outs = old_line_outs;
2023
1973 return 0; 2024 return 0;
1974} 2025}
1975 2026
1976static void create_hp_imux(struct via_spec *spec) 2027static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1977{ 2028{
1978 int i; 2029 struct via_spec *spec = codec->spec;
1979 struct hda_input_mux *imux = &spec->private_imux[1]; 2030 struct nid_path *path;
1980 static const char * const texts[] = { "OFF", "ON", NULL}; 2031 bool check_dac;
2032 int i, err;
1981 2033
1982 /* for hp mode select */ 2034 if (!pin)
1983 for (i = 0; texts[i]; i++) 2035 return 0;
1984 snd_hda_add_imux_item(imux, texts[i], i, NULL);
1985 2036
1986 spec->hp_mux = &spec->private_imux[1]; 2037 if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
2038 for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
2039 if (i < spec->multiout.num_dacs &&
2040 parse_output_path(codec, pin,
2041 spec->multiout.dac_nids[i], 0,
2042 &spec->hp_indep_path)) {
2043 spec->hp_indep_shared = i;
2044 break;
2045 }
2046 }
2047 }
2048 if (spec->hp_indep_path.depth) {
2049 spec->hp_dac_nid = spec->hp_indep_path.path[0];
2050 if (!spec->hp_indep_shared)
2051 spec->hp_path = spec->hp_indep_path;
2052 }
2053 /* optionally check front-path w/o AA-mix */
2054 if (!spec->hp_path.depth)
2055 parse_output_path(codec, pin,
2056 spec->multiout.dac_nids[HDA_FRONT], 0,
2057 &spec->hp_path);
2058
2059 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
2060 1, &spec->hp_mix_path) && !spec->hp_path.depth)
2061 return 0;
2062
2063 if (spec->hp_path.depth) {
2064 path = &spec->hp_path;
2065 check_dac = true;
2066 } else {
2067 path = &spec->hp_mix_path;
2068 check_dac = false;
2069 }
2070 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
2071 if (err < 0)
2072 return err;
2073 if (check_dac)
2074 copy_path_mixer_ctls(&spec->hp_mix_path, path);
2075 else
2076 copy_path_mixer_ctls(&spec->hp_path, path);
2077 if (spec->hp_indep_path.depth)
2078 copy_path_mixer_ctls(&spec->hp_indep_path, path);
2079 return 0;
1987} 2080}
1988 2081
1989static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 2082static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1990{ 2083{
2084 struct via_spec *spec = codec->spec;
2085 struct nid_path *path;
2086 bool check_dac;
2087 hda_nid_t pin, dac;
1991 int err; 2088 int err;
1992 2089
1993 if (!pin) 2090 pin = spec->autocfg.speaker_pins[0];
2091 if (!spec->autocfg.speaker_outs || !pin)
2092 return 0;
2093
2094 if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
2095 dac = spec->speaker_path.path[0];
2096 if (!dac)
2097 parse_output_path(codec, pin,
2098 spec->multiout.dac_nids[HDA_FRONT], 0,
2099 &spec->speaker_path);
2100 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
2101 1, &spec->speaker_mix_path) && !dac)
1994 return 0; 2102 return 0;
1995 2103
1996 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 2104 /* no AA-path for front? */
1997 spec->hp_independent_mode_index = 1; 2105 if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
2106 dac = 0;
1998 2107
1999 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2108 spec->speaker_dac_nid = dac;
2000 "Headphone Playback Volume", 2109 spec->multiout.extra_out_nid[0] = dac;
2001 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2110 if (dac) {
2111 path = &spec->speaker_path;
2112 check_dac = true;
2113 } else {
2114 path = &spec->speaker_mix_path;
2115 check_dac = false;
2116 }
2117 err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
2002 if (err < 0) 2118 if (err < 0)
2003 return err; 2119 return err;
2004 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2120 if (check_dac)
2005 "Headphone Playback Switch", 2121 copy_path_mixer_ctls(&spec->speaker_mix_path, path);
2006 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2122 else
2123 copy_path_mixer_ctls(&spec->speaker_path, path);
2124 return 0;
2125}
2126
2127#define via_aamix_ctl_info via_pin_power_ctl_info
2128
2129static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
2130 struct snd_ctl_elem_value *ucontrol)
2131{
2132 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2133 struct via_spec *spec = codec->spec;
2134 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2135 return 0;
2136}
2137
2138static void update_aamix_paths(struct hda_codec *codec, int do_mix,
2139 struct nid_path *nomix, struct nid_path *mix)
2140{
2141 if (do_mix) {
2142 activate_output_path(codec, nomix, false, false);
2143 activate_output_path(codec, mix, true, false);
2144 } else {
2145 activate_output_path(codec, mix, false, false);
2146 activate_output_path(codec, nomix, true, false);
2147 }
2148}
2149
2150static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
2151 struct snd_ctl_elem_value *ucontrol)
2152{
2153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2154 struct via_spec *spec = codec->spec;
2155 unsigned int val = ucontrol->value.enumerated.item[0];
2156
2157 if (val == spec->aamix_mode)
2158 return 0;
2159 spec->aamix_mode = val;
2160 /* update front path */
2161 update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
2162 /* update HP path */
2163 if (!spec->hp_independent_mode) {
2164 update_aamix_paths(codec, val, &spec->hp_path,
2165 &spec->hp_mix_path);
2166 }
2167 /* update speaker path */
2168 update_aamix_paths(codec, val, &spec->speaker_path,
2169 &spec->speaker_mix_path);
2170 return 1;
2171}
2172
2173static const struct snd_kcontrol_new via_aamix_ctl_enum = {
2174 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2175 .name = "Loopback Mixing",
2176 .info = via_aamix_ctl_info,
2177 .get = via_aamix_ctl_get,
2178 .put = via_aamix_ctl_put,
2179};
2180
2181static int via_auto_create_loopback_switch(struct hda_codec *codec)
2182{
2183 struct via_spec *spec = codec->spec;
2184
2185 if (!spec->aa_mix_nid || !spec->out_mix_path.depth)
2186 return 0; /* no loopback switching available */
2187 if (!via_clone_control(spec, &via_aamix_ctl_enum))
2188 return -ENOMEM;
2189 return 0;
2190}
2191
2192/* look for ADCs */
2193static int via_fill_adcs(struct hda_codec *codec)
2194{
2195 struct via_spec *spec = codec->spec;
2196 hda_nid_t nid = codec->start_nid;
2197 int i;
2198
2199 for (i = 0; i < codec->num_nodes; i++, nid++) {
2200 unsigned int wcaps = get_wcaps(codec, nid);
2201 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2202 continue;
2203 if (wcaps & AC_WCAP_DIGITAL)
2204 continue;
2205 if (!(wcaps & AC_WCAP_CONN_LIST))
2206 continue;
2207 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
2208 return -ENOMEM;
2209 spec->adc_nids[spec->num_adc_nids++] = nid;
2210 }
2211 return 0;
2212}
2213
2214/* input-src control */
2215static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
2216 struct snd_ctl_elem_info *uinfo)
2217{
2218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2219 struct via_spec *spec = codec->spec;
2220
2221 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2222 uinfo->count = 1;
2223 uinfo->value.enumerated.items = spec->num_inputs;
2224 if (uinfo->value.enumerated.item >= spec->num_inputs)
2225 uinfo->value.enumerated.item = spec->num_inputs - 1;
2226 strcpy(uinfo->value.enumerated.name,
2227 spec->inputs[uinfo->value.enumerated.item].label);
2228 return 0;
2229}
2230
2231static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
2232 struct snd_ctl_elem_value *ucontrol)
2233{
2234 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2235 struct via_spec *spec = codec->spec;
2236 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2237
2238 ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
2239 return 0;
2240}
2241
2242static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2243 struct snd_ctl_elem_value *ucontrol)
2244{
2245 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2246 struct via_spec *spec = codec->spec;
2247 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2248 hda_nid_t mux;
2249 int cur;
2250
2251 cur = ucontrol->value.enumerated.item[0];
2252 if (cur < 0 || cur >= spec->num_inputs)
2253 return -EINVAL;
2254 if (spec->cur_mux[idx] == cur)
2255 return 0;
2256 spec->cur_mux[idx] = cur;
2257 if (spec->dyn_adc_switch) {
2258 int adc_idx = spec->inputs[cur].adc_idx;
2259 mux = spec->mux_nids[adc_idx];
2260 via_dyn_adc_pcm_resetup(codec, cur);
2261 } else {
2262 mux = spec->mux_nids[idx];
2263 if (snd_BUG_ON(!mux))
2264 return -EINVAL;
2265 }
2266
2267 if (mux) {
2268 /* switch to D0 beofre change index */
2269 if (snd_hda_codec_read(codec, mux, 0,
2270 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2271 snd_hda_codec_write(codec, mux, 0,
2272 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2273 snd_hda_codec_write(codec, mux, 0,
2274 AC_VERB_SET_CONNECT_SEL,
2275 spec->inputs[cur].mux_idx);
2276 }
2277
2278 /* update jack power state */
2279 set_widgets_power_state(codec);
2280 return 0;
2281}
2282
2283static const struct snd_kcontrol_new via_input_src_ctl = {
2284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2285 /* The multiple "Capture Source" controls confuse alsamixer
2286 * So call somewhat different..
2287 */
2288 /* .name = "Capture Source", */
2289 .name = "Input Source",
2290 .info = via_mux_enum_info,
2291 .get = via_mux_enum_get,
2292 .put = via_mux_enum_put,
2293};
2294
2295static int create_input_src_ctls(struct hda_codec *codec, int count)
2296{
2297 struct via_spec *spec = codec->spec;
2298 struct snd_kcontrol_new *knew;
2299
2300 if (spec->num_inputs <= 1 || !count)
2301 return 0; /* no need for single src */
2302
2303 knew = via_clone_control(spec, &via_input_src_ctl);
2304 if (!knew)
2305 return -ENOMEM;
2306 knew->count = count;
2307 return 0;
2308}
2309
2310/* add the powersave loopback-list entry */
2311static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2312{
2313 struct hda_amp_list *list;
2314
2315 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2316 return;
2317 list = spec->loopback_list + spec->num_loopbacks;
2318 list->nid = mix;
2319 list->dir = HDA_INPUT;
2320 list->idx = idx;
2321 spec->num_loopbacks++;
2322 spec->loopback.amplist = spec->loopback_list;
2323}
2324
2325static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
2326 hda_nid_t dst)
2327{
2328 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
2329}
2330
2331/* add the input-route to the given pin */
2332static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
2333{
2334 struct via_spec *spec = codec->spec;
2335 int c, idx;
2336
2337 spec->inputs[spec->num_inputs].adc_idx = -1;
2338 spec->inputs[spec->num_inputs].pin = pin;
2339 for (c = 0; c < spec->num_adc_nids; c++) {
2340 if (spec->mux_nids[c]) {
2341 idx = get_connection_index(codec, spec->mux_nids[c],
2342 pin);
2343 if (idx < 0)
2344 continue;
2345 spec->inputs[spec->num_inputs].mux_idx = idx;
2346 } else {
2347 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
2348 continue;
2349 }
2350 spec->inputs[spec->num_inputs].adc_idx = c;
2351 /* Can primary ADC satisfy all inputs? */
2352 if (!spec->dyn_adc_switch &&
2353 spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
2354 snd_printd(KERN_INFO
2355 "via: dynamic ADC switching enabled\n");
2356 spec->dyn_adc_switch = 1;
2357 }
2358 return true;
2359 }
2360 return false;
2361}
2362
2363static int get_mux_nids(struct hda_codec *codec);
2364
2365/* parse input-routes; fill ADCs, MUXs and input-src entries */
2366static int parse_analog_inputs(struct hda_codec *codec)
2367{
2368 struct via_spec *spec = codec->spec;
2369 const struct auto_pin_cfg *cfg = &spec->autocfg;
2370 int i, err;
2371
2372 err = via_fill_adcs(codec);
2373 if (err < 0)
2374 return err;
2375 err = get_mux_nids(codec);
2007 if (err < 0) 2376 if (err < 0)
2008 return err; 2377 return err;
2009 2378
2010 create_hp_imux(spec); 2379 /* fill all input-routes */
2380 for (i = 0; i < cfg->num_inputs; i++) {
2381 if (add_input_route(codec, cfg->inputs[i].pin))
2382 spec->inputs[spec->num_inputs++].label =
2383 hda_get_autocfg_input_label(codec, cfg, i);
2384 }
2385
2386 /* check for internal loopback recording */
2387 if (spec->aa_mix_nid &&
2388 add_input_route(codec, spec->aa_mix_nid))
2389 spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
2011 2390
2012 return 0; 2391 return 0;
2013} 2392}
2014 2393
2015/* create playback/capture controls for input pins */ 2394/* create analog-loopback volume/switch controls */
2016static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, 2395static int create_loopback_ctls(struct hda_codec *codec)
2017 const struct auto_pin_cfg *cfg,
2018 hda_nid_t cap_nid,
2019 const hda_nid_t pin_idxs[],
2020 int num_idxs)
2021{ 2396{
2022 struct via_spec *spec = codec->spec; 2397 struct via_spec *spec = codec->spec;
2023 struct hda_input_mux *imux = &spec->private_imux[0]; 2398 const struct auto_pin_cfg *cfg = &spec->autocfg;
2024 int i, err, idx, type, type_idx = 0; 2399 const char *prev_label = NULL;
2400 int type_idx = 0;
2401 int i, j, err, idx;
2025 2402
2026 /* for internal loopback recording select */ 2403 if (!spec->aa_mix_nid)
2027 for (idx = 0; idx < num_idxs; idx++) { 2404 return 0;
2028 if (pin_idxs[idx] == 0xff) { 2405
2029 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL); 2406 for (i = 0; i < cfg->num_inputs; i++) {
2030 break; 2407 hda_nid_t pin = cfg->inputs[i].pin;
2408 const char *label = hda_get_autocfg_input_label(codec, cfg, i);
2409
2410 if (prev_label && !strcmp(label, prev_label))
2411 type_idx++;
2412 else
2413 type_idx = 0;
2414 prev_label = label;
2415 idx = get_connection_index(codec, spec->aa_mix_nid, pin);
2416 if (idx >= 0) {
2417 err = via_new_analog_input(spec, label, type_idx,
2418 idx, spec->aa_mix_nid);
2419 if (err < 0)
2420 return err;
2421 add_loopback_list(spec, spec->aa_mix_nid, idx);
2422 }
2423
2424 /* remember the label for smart51 control */
2425 for (j = 0; j < spec->smart51_nums; j++) {
2426 if (spec->smart51_pins[j] == pin) {
2427 spec->smart51_idxs[j] = idx;
2428 spec->smart51_labels[j] = label;
2429 break;
2430 }
2031 } 2431 }
2032 } 2432 }
2433 return 0;
2434}
2435
2436/* create mic-boost controls (if present) */
2437static int create_mic_boost_ctls(struct hda_codec *codec)
2438{
2439 struct via_spec *spec = codec->spec;
2440 const struct auto_pin_cfg *cfg = &spec->autocfg;
2441 int i, err;
2033 2442
2034 for (i = 0; i < cfg->num_inputs; i++) { 2443 for (i = 0; i < cfg->num_inputs; i++) {
2444 hda_nid_t pin = cfg->inputs[i].pin;
2445 unsigned int caps;
2035 const char *label; 2446 const char *label;
2036 type = cfg->inputs[i].type; 2447 char name[32];
2037 for (idx = 0; idx < num_idxs; idx++) 2448
2038 if (pin_idxs[idx] == cfg->inputs[i].pin) 2449 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2039 break; 2450 continue;
2040 if (idx >= num_idxs) 2451 caps = query_amp_caps(codec, pin, HDA_INPUT);
2452 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2041 continue; 2453 continue;
2042 if (i > 0 && type == cfg->inputs[i - 1].type)
2043 type_idx++;
2044 else
2045 type_idx = 0;
2046 label = hda_get_autocfg_input_label(codec, cfg, i); 2454 label = hda_get_autocfg_input_label(codec, cfg, i);
2047 if (spec->codec_type == VT1708S || 2455 snprintf(name, sizeof(name), "%s Boost Volume", label);
2048 spec->codec_type == VT1702 || 2456 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2049 spec->codec_type == VT1716S) 2457 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2050 err = via_new_analog_input(spec, label, type_idx, 2458 if (err < 0)
2051 idx+1, cap_nid); 2459 return err;
2052 else 2460 }
2053 err = via_new_analog_input(spec, label, type_idx, 2461 return 0;
2054 idx, cap_nid); 2462}
2463
2464/* create capture and input-src controls for multiple streams */
2465static int create_multi_adc_ctls(struct hda_codec *codec)
2466{
2467 struct via_spec *spec = codec->spec;
2468 int i, err;
2469
2470 /* create capture mixer elements */
2471 for (i = 0; i < spec->num_adc_nids; i++) {
2472 hda_nid_t adc = spec->adc_nids[i];
2473 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
2474 "Capture Volume", i,
2475 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2476 HDA_INPUT));
2477 if (err < 0)
2478 return err;
2479 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2480 "Capture Switch", i,
2481 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2482 HDA_INPUT));
2055 if (err < 0) 2483 if (err < 0)
2056 return err; 2484 return err;
2057 snd_hda_add_imux_item(imux, label, idx, NULL);
2058 } 2485 }
2486
2487 /* input-source control */
2488 for (i = 0; i < spec->num_adc_nids; i++)
2489 if (!spec->mux_nids[i])
2490 break;
2491 err = create_input_src_ctls(codec, i);
2492 if (err < 0)
2493 return err;
2059 return 0; 2494 return 0;
2060} 2495}
2061 2496
2062/* create playback/capture controls for input pins */ 2497/* bind capture volume/switch */
2063static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, 2498static struct snd_kcontrol_new via_bind_cap_vol_ctl =
2064 const struct auto_pin_cfg *cfg) 2499 HDA_BIND_VOL("Capture Volume", 0);
2500static struct snd_kcontrol_new via_bind_cap_sw_ctl =
2501 HDA_BIND_SW("Capture Switch", 0);
2502
2503static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
2504 struct hda_ctl_ops *ops)
2065{ 2505{
2066 static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; 2506 struct hda_bind_ctls *ctl;
2067 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, 2507 int i;
2068 ARRAY_SIZE(pin_idxs)); 2508
2509 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
2510 if (!ctl)
2511 return -ENOMEM;
2512 ctl->ops = ops;
2513 for (i = 0; i < spec->num_adc_nids; i++)
2514 ctl->values[i] =
2515 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
2516 *ctl_ret = ctl;
2517 return 0;
2069} 2518}
2070 2519
2071#ifdef CONFIG_SND_HDA_POWER_SAVE 2520/* create capture and input-src controls for dynamic ADC-switch case */
2072static const struct hda_amp_list vt1708_loopbacks[] = { 2521static int create_dyn_adc_ctls(struct hda_codec *codec)
2073 { 0x17, HDA_INPUT, 1 }, 2522{
2074 { 0x17, HDA_INPUT, 2 }, 2523 struct via_spec *spec = codec->spec;
2075 { 0x17, HDA_INPUT, 3 }, 2524 struct snd_kcontrol_new *knew;
2076 { 0x17, HDA_INPUT, 4 }, 2525 int err;
2077 { } /* end */ 2526
2078}; 2527 /* set up the bind capture ctls */
2079#endif 2528 err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
2529 if (err < 0)
2530 return err;
2531 err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
2532 if (err < 0)
2533 return err;
2534
2535 /* create capture mixer elements */
2536 knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
2537 if (!knew)
2538 return -ENOMEM;
2539 knew->private_value = (long)spec->bind_cap_vol;
2540
2541 knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
2542 if (!knew)
2543 return -ENOMEM;
2544 knew->private_value = (long)spec->bind_cap_sw;
2545
2546 /* input-source control */
2547 err = create_input_src_ctls(codec, 1);
2548 if (err < 0)
2549 return err;
2550 return 0;
2551}
2552
2553/* parse and create capture-related stuff */
2554static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
2555{
2556 struct via_spec *spec = codec->spec;
2557 int err;
2558
2559 err = parse_analog_inputs(codec);
2560 if (err < 0)
2561 return err;
2562 if (spec->dyn_adc_switch)
2563 err = create_dyn_adc_ctls(codec);
2564 else
2565 err = create_multi_adc_ctls(codec);
2566 if (err < 0)
2567 return err;
2568 err = create_loopback_ctls(codec);
2569 if (err < 0)
2570 return err;
2571 err = create_mic_boost_ctls(codec);
2572 if (err < 0)
2573 return err;
2574 return 0;
2575}
2080 2576
2081static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) 2577static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2082{ 2578{
@@ -2095,7 +2591,7 @@ static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2095 return; 2591 return;
2096} 2592}
2097 2593
2098static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol, 2594static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
2099 struct snd_ctl_elem_value *ucontrol) 2595 struct snd_ctl_elem_value *ucontrol)
2100{ 2596{
2101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -2103,13 +2599,13 @@ static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2103 2599
2104 if (spec->codec_type != VT1708) 2600 if (spec->codec_type != VT1708)
2105 return 0; 2601 return 0;
2106 spec->vt1708_jack_detectect = 2602 spec->vt1708_jack_detect =
2107 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); 2603 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2108 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect; 2604 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
2109 return 0; 2605 return 0;
2110} 2606}
2111 2607
2112static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, 2608static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
2113 struct snd_ctl_elem_value *ucontrol) 2609 struct snd_ctl_elem_value *ucontrol)
2114{ 2610{
2115 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2611 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -2118,98 +2614,150 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol,
2118 2614
2119 if (spec->codec_type != VT1708) 2615 if (spec->codec_type != VT1708)
2120 return 0; 2616 return 0;
2121 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0]; 2617 spec->vt1708_jack_detect = ucontrol->value.integer.value[0];
2122 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) 2618 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8))
2123 == !spec->vt1708_jack_detectect; 2619 == !spec->vt1708_jack_detect;
2124 if (spec->vt1708_jack_detectect) { 2620 if (spec->vt1708_jack_detect) {
2125 mute_aa_path(codec, 1); 2621 mute_aa_path(codec, 1);
2126 notify_aa_path_ctls(codec); 2622 notify_aa_path_ctls(codec);
2127 } 2623 }
2128 return change; 2624 return change;
2129} 2625}
2130 2626
2131static const struct snd_kcontrol_new vt1708_jack_detectect[] = { 2627static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2132 { 2628 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2629 .name = "Jack Detect",
2134 .name = "Jack Detect", 2630 .count = 1,
2135 .count = 1, 2631 .info = snd_ctl_boolean_mono_info,
2136 .info = snd_ctl_boolean_mono_info, 2632 .get = vt1708_jack_detect_get,
2137 .get = vt1708_jack_detectect_get, 2633 .put = vt1708_jack_detect_put,
2138 .put = vt1708_jack_detectect_put,
2139 },
2140 {} /* end */
2141}; 2634};
2142 2635
2143static int vt1708_parse_auto_config(struct hda_codec *codec) 2636static void fill_dig_outs(struct hda_codec *codec);
2637static void fill_dig_in(struct hda_codec *codec);
2638
2639static int via_parse_auto_config(struct hda_codec *codec)
2144{ 2640{
2145 struct via_spec *spec = codec->spec; 2641 struct via_spec *spec = codec->spec;
2146 int err; 2642 int err;
2147 2643
2148 /* Add HP and CD pin config connect bit re-config action */
2149 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2150 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2151
2152 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); 2644 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2153 if (err < 0) 2645 if (err < 0)
2154 return err; 2646 return err;
2155 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
2156 if (err < 0)
2157 return err;
2158 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 2647 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2159 return 0; /* can't find valid BIOS pin config */ 2648 return -EINVAL;
2160 2649
2161 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 2650 err = via_auto_create_multi_out_ctls(codec);
2162 if (err < 0) 2651 if (err < 0)
2163 return err; 2652 return err;
2164 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2653 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
2165 if (err < 0) 2654 if (err < 0)
2166 return err; 2655 return err;
2167 err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg); 2656 err = via_auto_create_speaker_ctls(codec);
2168 if (err < 0) 2657 if (err < 0)
2169 return err; 2658 return err;
2170 /* add jack detect on/off control */ 2659 err = via_auto_create_loopback_switch(codec);
2171 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect); 2660 if (err < 0)
2661 return err;
2662 err = via_auto_create_analog_input_ctls(codec);
2172 if (err < 0) 2663 if (err < 0)
2173 return err; 2664 return err;
2174 2665
2175 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2666 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2176 2667
2177 if (spec->autocfg.dig_outs) 2668 fill_dig_outs(codec);
2178 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 2669 fill_dig_in(codec);
2179 spec->dig_in_pin = VT1708_DIGIN_PIN;
2180 if (spec->autocfg.dig_in_pin)
2181 spec->dig_in_nid = VT1708_DIGIN_NID;
2182 2670
2183 if (spec->kctls.list) 2671 if (spec->kctls.list)
2184 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2672 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2185 2673
2186 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2187 2674
2188 spec->input_mux = &spec->private_imux[0]; 2675 if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
2676 err = via_hp_build(codec);
2677 if (err < 0)
2678 return err;
2679 }
2189 2680
2190 if (spec->hp_mux) 2681 err = via_smart51_build(codec);
2191 via_hp_build(codec); 2682 if (err < 0)
2683 return err;
2684
2685 /* assign slave outs */
2686 if (spec->slave_dig_outs[0])
2687 codec->slave_dig_outs = spec->slave_dig_outs;
2192 2688
2193 via_smart51_build(spec);
2194 return 1; 2689 return 1;
2195} 2690}
2196 2691
2197/* init callback for auto-configuration model -- overriding the default init */ 2692static void via_auto_init_dig_outs(struct hda_codec *codec)
2198static int via_auto_init(struct hda_codec *codec) 2693{
2694 struct via_spec *spec = codec->spec;
2695 if (spec->multiout.dig_out_nid)
2696 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2697 if (spec->slave_dig_outs[0])
2698 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2699}
2700
2701static void via_auto_init_dig_in(struct hda_codec *codec)
2199{ 2702{
2200 struct via_spec *spec = codec->spec; 2703 struct via_spec *spec = codec->spec;
2704 if (!spec->dig_in_nid)
2705 return;
2706 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2707 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2708}
2709
2710/* initialize the unsolicited events */
2711static void via_auto_init_unsol_event(struct hda_codec *codec)
2712{
2713 struct via_spec *spec = codec->spec;
2714 struct auto_pin_cfg *cfg = &spec->autocfg;
2715 unsigned int ev;
2716 int i;
2717
2718 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2719 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2720 AC_VERB_SET_UNSOLICITED_ENABLE,
2721 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2722
2723 if (cfg->speaker_pins[0])
2724 ev = VIA_LINE_EVENT;
2725 else
2726 ev = 0;
2727 for (i = 0; i < cfg->line_outs; i++) {
2728 if (cfg->line_out_pins[i] &&
2729 is_jack_detectable(codec, cfg->line_out_pins[i]))
2730 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
2731 AC_VERB_SET_UNSOLICITED_ENABLE,
2732 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2733 }
2734
2735 for (i = 0; i < cfg->num_inputs; i++) {
2736 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2737 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2738 AC_VERB_SET_UNSOLICITED_ENABLE,
2739 AC_USRSP_EN | VIA_JACK_EVENT);
2740 }
2741}
2742
2743static int via_init(struct hda_codec *codec)
2744{
2745 struct via_spec *spec = codec->spec;
2746 int i;
2747
2748 for (i = 0; i < spec->num_iverbs; i++)
2749 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2201 2750
2202 via_init(codec);
2203 via_auto_init_multi_out(codec); 2751 via_auto_init_multi_out(codec);
2204 via_auto_init_hp_out(codec); 2752 via_auto_init_hp_out(codec);
2753 via_auto_init_speaker_out(codec);
2205 via_auto_init_analog_input(codec); 2754 via_auto_init_analog_input(codec);
2755 via_auto_init_dig_outs(codec);
2756 via_auto_init_dig_in(codec);
2206 2757
2207 if (VT2002P_COMPATIBLE(spec)) { 2758 via_auto_init_unsol_event(codec);
2208 via_hp_bind_automute(codec); 2759
2209 } else { 2760 via_hp_automute(codec);
2210 via_hp_automute(codec);
2211 via_speaker_automute(codec);
2212 }
2213 2761
2214 return 0; 2762 return 0;
2215} 2763}
@@ -2266,437 +2814,36 @@ static int patch_vt1708(struct hda_codec *codec)
2266 if (spec == NULL) 2814 if (spec == NULL)
2267 return -ENOMEM; 2815 return -ENOMEM;
2268 2816
2817 spec->aa_mix_nid = 0x17;
2818
2819 /* Add HP and CD pin config connect bit re-config action */
2820 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2821 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2822
2269 /* automatic parse from the BIOS config */ 2823 /* automatic parse from the BIOS config */
2270 err = vt1708_parse_auto_config(codec); 2824 err = via_parse_auto_config(codec);
2271 if (err < 0) { 2825 if (err < 0) {
2272 via_free(codec); 2826 via_free(codec);
2273 return err; 2827 return err;
2274 } else if (!err) {
2275 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2276 "from BIOS. Using genenic mode...\n");
2277 } 2828 }
2278 2829
2830 /* add jack detect on/off control */
2831 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2832 return -ENOMEM;
2279 2833
2280 spec->stream_name_analog = "VT1708 Analog";
2281 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2282 /* disable 32bit format on VT1708 */ 2834 /* disable 32bit format on VT1708 */
2283 if (codec->vendor_id == 0x11061708) 2835 if (codec->vendor_id == 0x11061708)
2284 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; 2836 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback;
2285 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
2286
2287 spec->stream_name_digital = "VT1708 Digital";
2288 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
2289 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
2290 2837
2291 2838 spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
2292 if (!spec->adc_nids && spec->input_mux) {
2293 spec->adc_nids = vt1708_adc_nids;
2294 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
2295 get_mux_nids(codec);
2296 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
2297 spec->num_mixers++;
2298 }
2299 2839
2300 codec->patch_ops = via_patch_ops; 2840 codec->patch_ops = via_patch_ops;
2301 2841
2302 codec->patch_ops.init = via_auto_init;
2303#ifdef CONFIG_SND_HDA_POWER_SAVE
2304 spec->loopback.amplist = vt1708_loopbacks;
2305#endif
2306 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state); 2842 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2307 return 0; 2843 return 0;
2308} 2844}
2309 2845
2310/* capture mixer elements */ 2846static int patch_vt1709(struct hda_codec *codec)
2311static const struct snd_kcontrol_new vt1709_capture_mixer[] = {
2312 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
2313 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
2314 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
2315 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
2316 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
2317 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
2318 {
2319 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2320 /* The multiple "Capture Source" controls confuse alsamixer
2321 * So call somewhat different..
2322 */
2323 /* .name = "Capture Source", */
2324 .name = "Input Source",
2325 .count = 1,
2326 .info = via_mux_enum_info,
2327 .get = via_mux_enum_get,
2328 .put = via_mux_enum_put,
2329 },
2330 { } /* end */
2331};
2332
2333static const struct hda_verb vt1709_uniwill_init_verbs[] = {
2334 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE,
2335 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2336 { }
2337};
2338
2339/*
2340 * generic initialization of ADC, input mixers and output mixers
2341 */
2342static const struct hda_verb vt1709_10ch_volume_init_verbs[] = {
2343 /*
2344 * Unmute ADC0-2 and set the default input to mic-in
2345 */
2346 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2347 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2348 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2349
2350
2351 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2352 * mixer widget
2353 */
2354 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2355 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2356 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2357 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2359 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2360
2361 /*
2362 * Set up output selector (0x1a, 0x1b, 0x29)
2363 */
2364 /* set vol=0 to output mixers */
2365 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2367 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2368
2369 /*
2370 * Unmute PW3 and PW4
2371 */
2372 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2373 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2374
2375 /* Set input of PW4 as MW0 */
2376 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2377 /* PW9 Output enable */
2378 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2379 { }
2380};
2381
2382static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
2383 .substreams = 1,
2384 .channels_min = 2,
2385 .channels_max = 10,
2386 .nid = 0x10, /* NID to query formats and rates */
2387 .ops = {
2388 .open = via_playback_pcm_open,
2389 .prepare = via_playback_multi_pcm_prepare,
2390 .cleanup = via_playback_multi_pcm_cleanup,
2391 },
2392};
2393
2394static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
2395 .substreams = 1,
2396 .channels_min = 2,
2397 .channels_max = 6,
2398 .nid = 0x10, /* NID to query formats and rates */
2399 .ops = {
2400 .open = via_playback_pcm_open,
2401 .prepare = via_playback_multi_pcm_prepare,
2402 .cleanup = via_playback_multi_pcm_cleanup,
2403 },
2404};
2405
2406static const struct hda_pcm_stream vt1709_pcm_analog_capture = {
2407 .substreams = 2,
2408 .channels_min = 2,
2409 .channels_max = 2,
2410 .nid = 0x14, /* NID to query formats and rates */
2411 .ops = {
2412 .prepare = via_capture_pcm_prepare,
2413 .cleanup = via_capture_pcm_cleanup
2414 },
2415};
2416
2417static const struct hda_pcm_stream vt1709_pcm_digital_playback = {
2418 .substreams = 1,
2419 .channels_min = 2,
2420 .channels_max = 2,
2421 /* NID is set in via_build_pcms */
2422 .ops = {
2423 .open = via_dig_playback_pcm_open,
2424 .close = via_dig_playback_pcm_close
2425 },
2426};
2427
2428static const struct hda_pcm_stream vt1709_pcm_digital_capture = {
2429 .substreams = 1,
2430 .channels_min = 2,
2431 .channels_max = 2,
2432};
2433
2434static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
2435 const struct auto_pin_cfg *cfg)
2436{
2437 int i;
2438 hda_nid_t nid;
2439
2440 if (cfg->line_outs == 4) /* 10 channels */
2441 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
2442 else if (cfg->line_outs == 3) /* 6 channels */
2443 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
2444
2445 spec->multiout.dac_nids = spec->private_dac_nids;
2446
2447 if (cfg->line_outs == 4) { /* 10 channels */
2448 for (i = 0; i < cfg->line_outs; i++) {
2449 nid = cfg->line_out_pins[i];
2450 if (nid) {
2451 /* config dac list */
2452 switch (i) {
2453 case AUTO_SEQ_FRONT:
2454 /* AOW0 */
2455 spec->private_dac_nids[i] = 0x10;
2456 break;
2457 case AUTO_SEQ_CENLFE:
2458 /* AOW2 */
2459 spec->private_dac_nids[i] = 0x12;
2460 break;
2461 case AUTO_SEQ_SURROUND:
2462 /* AOW3 */
2463 spec->private_dac_nids[i] = 0x11;
2464 break;
2465 case AUTO_SEQ_SIDE:
2466 /* AOW1 */
2467 spec->private_dac_nids[i] = 0x27;
2468 break;
2469 default:
2470 break;
2471 }
2472 }
2473 }
2474 spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
2475
2476 } else if (cfg->line_outs == 3) { /* 6 channels */
2477 for (i = 0; i < cfg->line_outs; i++) {
2478 nid = cfg->line_out_pins[i];
2479 if (nid) {
2480 /* config dac list */
2481 switch (i) {
2482 case AUTO_SEQ_FRONT:
2483 /* AOW0 */
2484 spec->private_dac_nids[i] = 0x10;
2485 break;
2486 case AUTO_SEQ_CENLFE:
2487 /* AOW2 */
2488 spec->private_dac_nids[i] = 0x12;
2489 break;
2490 case AUTO_SEQ_SURROUND:
2491 /* AOW1 */
2492 spec->private_dac_nids[i] = 0x11;
2493 break;
2494 default:
2495 break;
2496 }
2497 }
2498 }
2499 }
2500
2501 return 0;
2502}
2503
2504/* add playback controls from the parsed DAC table */
2505static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2506 const struct auto_pin_cfg *cfg)
2507{
2508 char name[32];
2509 static const char * const chname[4] = {
2510 "Front", "Surround", "C/LFE", "Side"
2511 };
2512 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2513 int i, err;
2514
2515 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
2516 nid = cfg->line_out_pins[i];
2517
2518 if (!nid)
2519 continue;
2520
2521 nid_vol = nid_vols[i];
2522
2523 if (i == AUTO_SEQ_CENLFE) {
2524 /* Center/LFE */
2525 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2526 "Center Playback Volume",
2527 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2528 HDA_OUTPUT));
2529 if (err < 0)
2530 return err;
2531 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2532 "LFE Playback Volume",
2533 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2534 HDA_OUTPUT));
2535 if (err < 0)
2536 return err;
2537 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2538 "Center Playback Switch",
2539 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
2540 HDA_OUTPUT));
2541 if (err < 0)
2542 return err;
2543 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2544 "LFE Playback Switch",
2545 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
2546 HDA_OUTPUT));
2547 if (err < 0)
2548 return err;
2549 } else if (i == AUTO_SEQ_FRONT) {
2550 /* ADD control to mixer index 0 */
2551 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2552 "Master Front Playback Volume",
2553 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2554 HDA_INPUT));
2555 if (err < 0)
2556 return err;
2557 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2558 "Master Front Playback Switch",
2559 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2560 HDA_INPUT));
2561 if (err < 0)
2562 return err;
2563
2564 /* add control to PW3 */
2565 sprintf(name, "%s Playback Volume", chname[i]);
2566 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2567 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2568 HDA_OUTPUT));
2569 if (err < 0)
2570 return err;
2571 sprintf(name, "%s Playback Switch", chname[i]);
2572 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2573 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
2574 HDA_OUTPUT));
2575 if (err < 0)
2576 return err;
2577 } else if (i == AUTO_SEQ_SURROUND) {
2578 sprintf(name, "%s Playback Volume", chname[i]);
2579 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2580 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2581 HDA_OUTPUT));
2582 if (err < 0)
2583 return err;
2584 sprintf(name, "%s Playback Switch", chname[i]);
2585 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2586 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2587 HDA_OUTPUT));
2588 if (err < 0)
2589 return err;
2590 } else if (i == AUTO_SEQ_SIDE) {
2591 sprintf(name, "%s Playback Volume", chname[i]);
2592 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2593 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2594 HDA_OUTPUT));
2595 if (err < 0)
2596 return err;
2597 sprintf(name, "%s Playback Switch", chname[i]);
2598 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2599 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
2600 HDA_OUTPUT));
2601 if (err < 0)
2602 return err;
2603 }
2604 }
2605
2606 return 0;
2607}
2608
2609static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
2610{
2611 int err;
2612
2613 if (!pin)
2614 return 0;
2615
2616 if (spec->multiout.num_dacs == 5) /* 10 channels */
2617 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
2618 else if (spec->multiout.num_dacs == 3) /* 6 channels */
2619 spec->multiout.hp_nid = 0;
2620 spec->hp_independent_mode_index = 1;
2621
2622 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
2623 "Headphone Playback Volume",
2624 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2625 if (err < 0)
2626 return err;
2627 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2628 "Headphone Playback Switch",
2629 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2630 if (err < 0)
2631 return err;
2632
2633 return 0;
2634}
2635
2636/* create playback/capture controls for input pins */
2637static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec,
2638 const struct auto_pin_cfg *cfg)
2639{
2640 static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 };
2641 return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs,
2642 ARRAY_SIZE(pin_idxs));
2643}
2644
2645static int vt1709_parse_auto_config(struct hda_codec *codec)
2646{
2647 struct via_spec *spec = codec->spec;
2648 int err;
2649
2650 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2651 if (err < 0)
2652 return err;
2653 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
2654 if (err < 0)
2655 return err;
2656 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2657 return 0; /* can't find valid BIOS pin config */
2658
2659 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
2660 if (err < 0)
2661 return err;
2662 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
2663 if (err < 0)
2664 return err;
2665 err = vt1709_auto_create_analog_input_ctls(codec, &spec->autocfg);
2666 if (err < 0)
2667 return err;
2668
2669 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2670
2671 if (spec->autocfg.dig_outs)
2672 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
2673 spec->dig_in_pin = VT1709_DIGIN_PIN;
2674 if (spec->autocfg.dig_in_pin)
2675 spec->dig_in_nid = VT1709_DIGIN_NID;
2676
2677 if (spec->kctls.list)
2678 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2679
2680 spec->input_mux = &spec->private_imux[0];
2681
2682 if (spec->hp_mux)
2683 via_hp_build(codec);
2684
2685 via_smart51_build(spec);
2686 return 1;
2687}
2688
2689#ifdef CONFIG_SND_HDA_POWER_SAVE
2690static const struct hda_amp_list vt1709_loopbacks[] = {
2691 { 0x18, HDA_INPUT, 1 },
2692 { 0x18, HDA_INPUT, 2 },
2693 { 0x18, HDA_INPUT, 3 },
2694 { 0x18, HDA_INPUT, 4 },
2695 { } /* end */
2696};
2697#endif
2698
2699static int patch_vt1709_10ch(struct hda_codec *codec)
2700{ 2847{
2701 struct via_spec *spec; 2848 struct via_spec *spec;
2702 int err; 2849 int err;
@@ -2706,528 +2853,19 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
2706 if (spec == NULL) 2853 if (spec == NULL)
2707 return -ENOMEM; 2854 return -ENOMEM;
2708 2855
2709 err = vt1709_parse_auto_config(codec); 2856 spec->aa_mix_nid = 0x18;
2710 if (err < 0) {
2711 via_free(codec);
2712 return err;
2713 } else if (!err) {
2714 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2715 "Using genenic mode...\n");
2716 }
2717
2718 spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs;
2719 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2720
2721 spec->stream_name_analog = "VT1709 Analog";
2722 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
2723 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2724
2725 spec->stream_name_digital = "VT1709 Digital";
2726 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2727 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2728
2729
2730 if (!spec->adc_nids && spec->input_mux) {
2731 spec->adc_nids = vt1709_adc_nids;
2732 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2733 get_mux_nids(codec);
2734 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2735 spec->num_mixers++;
2736 }
2737
2738 codec->patch_ops = via_patch_ops;
2739
2740 codec->patch_ops.init = via_auto_init;
2741 codec->patch_ops.unsol_event = via_unsol_event;
2742#ifdef CONFIG_SND_HDA_POWER_SAVE
2743 spec->loopback.amplist = vt1709_loopbacks;
2744#endif
2745
2746 return 0;
2747}
2748/*
2749 * generic initialization of ADC, input mixers and output mixers
2750 */
2751static const struct hda_verb vt1709_6ch_volume_init_verbs[] = {
2752 /*
2753 * Unmute ADC0-2 and set the default input to mic-in
2754 */
2755 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2757 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2758
2759
2760 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2761 * mixer widget
2762 */
2763 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2764 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2765 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2766 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2767 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2768 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2769
2770 /*
2771 * Set up output selector (0x1a, 0x1b, 0x29)
2772 */
2773 /* set vol=0 to output mixers */
2774 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2775 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2776 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2777
2778 /*
2779 * Unmute PW3 and PW4
2780 */
2781 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2782 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2783
2784 /* Set input of PW4 as MW0 */
2785 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
2786 /* PW9 Output enable */
2787 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2788 { }
2789};
2790
2791static int patch_vt1709_6ch(struct hda_codec *codec)
2792{
2793 struct via_spec *spec;
2794 int err;
2795
2796 /* create a codec specific record */
2797 spec = via_new_spec(codec);
2798 if (spec == NULL)
2799 return -ENOMEM;
2800 2857
2801 err = vt1709_parse_auto_config(codec); 2858 err = via_parse_auto_config(codec);
2802 if (err < 0) { 2859 if (err < 0) {
2803 via_free(codec); 2860 via_free(codec);
2804 return err; 2861 return err;
2805 } else if (!err) {
2806 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
2807 "Using genenic mode...\n");
2808 }
2809
2810 spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs;
2811 spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs;
2812
2813 spec->stream_name_analog = "VT1709 Analog";
2814 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
2815 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
2816
2817 spec->stream_name_digital = "VT1709 Digital";
2818 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
2819 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
2820
2821
2822 if (!spec->adc_nids && spec->input_mux) {
2823 spec->adc_nids = vt1709_adc_nids;
2824 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
2825 get_mux_nids(codec);
2826 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
2827 spec->num_mixers++;
2828 } 2862 }
2829 2863
2830 codec->patch_ops = via_patch_ops; 2864 codec->patch_ops = via_patch_ops;
2831 2865
2832 codec->patch_ops.init = via_auto_init;
2833 codec->patch_ops.unsol_event = via_unsol_event;
2834#ifdef CONFIG_SND_HDA_POWER_SAVE
2835 spec->loopback.amplist = vt1709_loopbacks;
2836#endif
2837 return 0;
2838}
2839
2840/* capture mixer elements */
2841static const struct snd_kcontrol_new vt1708B_capture_mixer[] = {
2842 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
2843 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
2844 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
2845 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
2846 {
2847 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2848 /* The multiple "Capture Source" controls confuse alsamixer
2849 * So call somewhat different..
2850 */
2851 /* .name = "Capture Source", */
2852 .name = "Input Source",
2853 .count = 1,
2854 .info = via_mux_enum_info,
2855 .get = via_mux_enum_get,
2856 .put = via_mux_enum_put,
2857 },
2858 { } /* end */
2859};
2860/*
2861 * generic initialization of ADC, input mixers and output mixers
2862 */
2863static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = {
2864 /*
2865 * Unmute ADC0-1 and set the default input to mic-in
2866 */
2867 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2868 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2869
2870
2871 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2872 * mixer widget
2873 */
2874 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2875 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2876 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2877 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2878 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2879 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2880
2881 /*
2882 * Set up output mixers
2883 */
2884 /* set vol=0 to output mixers */
2885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2886 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2887 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2888
2889 /* Setup default input to PW4 */
2890 {0x1d, AC_VERB_SET_CONNECT_SEL, 0},
2891 /* PW9 Output enable */
2892 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2893 /* PW10 Input enable */
2894 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2895 { }
2896};
2897
2898static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = {
2899 /*
2900 * Unmute ADC0-1 and set the default input to mic-in
2901 */
2902 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2903 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2904
2905
2906 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
2907 * mixer widget
2908 */
2909 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
2910 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2911 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2912 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
2913 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
2914 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
2915
2916 /*
2917 * Set up output mixers
2918 */
2919 /* set vol=0 to output mixers */
2920 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2921 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2922 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2923
2924 /* Setup default input of PW4 to MW0 */
2925 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
2926 /* PW9 Output enable */
2927 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
2928 /* PW10 Input enable */
2929 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
2930 { }
2931};
2932
2933static const struct hda_verb vt1708B_uniwill_init_verbs[] = {
2934 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
2935 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
2936 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2937 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2939 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2940 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2941 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2942 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
2943 { }
2944};
2945
2946static int via_pcm_open_close(struct hda_pcm_stream *hinfo,
2947 struct hda_codec *codec,
2948 struct snd_pcm_substream *substream)
2949{
2950 int idle = substream->pstr->substream_opened == 1
2951 && substream->ref_count == 0;
2952
2953 analog_low_current_mode(codec, idle);
2954 return 0;
2955}
2956
2957static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = {
2958 .substreams = 2,
2959 .channels_min = 2,
2960 .channels_max = 8,
2961 .nid = 0x10, /* NID to query formats and rates */
2962 .ops = {
2963 .open = via_playback_pcm_open,
2964 .prepare = via_playback_multi_pcm_prepare,
2965 .cleanup = via_playback_multi_pcm_cleanup,
2966 .close = via_pcm_open_close
2967 },
2968};
2969
2970static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = {
2971 .substreams = 2,
2972 .channels_min = 2,
2973 .channels_max = 4,
2974 .nid = 0x10, /* NID to query formats and rates */
2975 .ops = {
2976 .open = via_playback_pcm_open,
2977 .prepare = via_playback_multi_pcm_prepare,
2978 .cleanup = via_playback_multi_pcm_cleanup
2979 },
2980};
2981
2982static const struct hda_pcm_stream vt1708B_pcm_analog_capture = {
2983 .substreams = 2,
2984 .channels_min = 2,
2985 .channels_max = 2,
2986 .nid = 0x13, /* NID to query formats and rates */
2987 .ops = {
2988 .open = via_pcm_open_close,
2989 .prepare = via_capture_pcm_prepare,
2990 .cleanup = via_capture_pcm_cleanup,
2991 .close = via_pcm_open_close
2992 },
2993};
2994
2995static const struct hda_pcm_stream vt1708B_pcm_digital_playback = {
2996 .substreams = 1,
2997 .channels_min = 2,
2998 .channels_max = 2,
2999 /* NID is set in via_build_pcms */
3000 .ops = {
3001 .open = via_dig_playback_pcm_open,
3002 .close = via_dig_playback_pcm_close,
3003 .prepare = via_dig_playback_pcm_prepare,
3004 .cleanup = via_dig_playback_pcm_cleanup
3005 },
3006};
3007
3008static const struct hda_pcm_stream vt1708B_pcm_digital_capture = {
3009 .substreams = 1,
3010 .channels_min = 2,
3011 .channels_max = 2,
3012};
3013
3014/* fill in the dac_nids table from the parsed pin configuration */
3015static int vt1708B_auto_fill_dac_nids(struct via_spec *spec,
3016 const struct auto_pin_cfg *cfg)
3017{
3018 int i;
3019 hda_nid_t nid;
3020
3021 spec->multiout.num_dacs = cfg->line_outs;
3022
3023 spec->multiout.dac_nids = spec->private_dac_nids;
3024
3025 for (i = 0; i < 4; i++) {
3026 nid = cfg->line_out_pins[i];
3027 if (nid) {
3028 /* config dac list */
3029 switch (i) {
3030 case AUTO_SEQ_FRONT:
3031 spec->private_dac_nids[i] = 0x10;
3032 break;
3033 case AUTO_SEQ_CENLFE:
3034 spec->private_dac_nids[i] = 0x24;
3035 break;
3036 case AUTO_SEQ_SURROUND:
3037 spec->private_dac_nids[i] = 0x11;
3038 break;
3039 case AUTO_SEQ_SIDE:
3040 spec->private_dac_nids[i] = 0x25;
3041 break;
3042 }
3043 }
3044 }
3045
3046 return 0;
3047}
3048
3049/* add playback controls from the parsed DAC table */
3050static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3051 const struct auto_pin_cfg *cfg)
3052{
3053 char name[32];
3054 static const char * const chname[4] = {
3055 "Front", "Surround", "C/LFE", "Side"
3056 };
3057 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3058 hda_nid_t nid, nid_vol = 0;
3059 int i, err;
3060
3061 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3062 nid = cfg->line_out_pins[i];
3063
3064 if (!nid)
3065 continue;
3066
3067 nid_vol = nid_vols[i];
3068
3069 if (i == AUTO_SEQ_CENLFE) {
3070 /* Center/LFE */
3071 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3072 "Center Playback Volume",
3073 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3074 HDA_OUTPUT));
3075 if (err < 0)
3076 return err;
3077 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3078 "LFE Playback Volume",
3079 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3080 HDA_OUTPUT));
3081 if (err < 0)
3082 return err;
3083 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3084 "Center Playback Switch",
3085 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3086 HDA_OUTPUT));
3087 if (err < 0)
3088 return err;
3089 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3090 "LFE Playback Switch",
3091 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3092 HDA_OUTPUT));
3093 if (err < 0)
3094 return err;
3095 } else if (i == AUTO_SEQ_FRONT) {
3096 /* add control to mixer index 0 */
3097 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3098 "Master Front Playback Volume",
3099 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3100 HDA_INPUT));
3101 if (err < 0)
3102 return err;
3103 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3104 "Master Front Playback Switch",
3105 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3106 HDA_INPUT));
3107 if (err < 0)
3108 return err;
3109
3110 /* add control to PW3 */
3111 sprintf(name, "%s Playback Volume", chname[i]);
3112 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3113 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3114 HDA_OUTPUT));
3115 if (err < 0)
3116 return err;
3117 sprintf(name, "%s Playback Switch", chname[i]);
3118 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3119 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
3120 HDA_OUTPUT));
3121 if (err < 0)
3122 return err;
3123 } else {
3124 sprintf(name, "%s Playback Volume", chname[i]);
3125 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3126 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3127 HDA_OUTPUT));
3128 if (err < 0)
3129 return err;
3130 sprintf(name, "%s Playback Switch", chname[i]);
3131 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3132 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3133 HDA_OUTPUT));
3134 if (err < 0)
3135 return err;
3136 }
3137 }
3138
3139 return 0;
3140}
3141
3142static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3143{
3144 int err;
3145
3146 if (!pin)
3147 return 0;
3148
3149 spec->multiout.hp_nid = VT1708B_HP_NID; /* AOW3 */
3150 spec->hp_independent_mode_index = 1;
3151
3152 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3153 "Headphone Playback Volume",
3154 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3155 if (err < 0)
3156 return err;
3157 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3158 "Headphone Playback Switch",
3159 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3160 if (err < 0)
3161 return err;
3162
3163 create_hp_imux(spec);
3164
3165 return 0; 2866 return 0;
3166} 2867}
3167 2868
3168/* create playback/capture controls for input pins */
3169static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec,
3170 const struct auto_pin_cfg *cfg)
3171{
3172 static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e };
3173 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3174 ARRAY_SIZE(pin_idxs));
3175}
3176
3177static int vt1708B_parse_auto_config(struct hda_codec *codec)
3178{
3179 struct via_spec *spec = codec->spec;
3180 int err;
3181
3182 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3183 if (err < 0)
3184 return err;
3185 err = vt1708B_auto_fill_dac_nids(spec, &spec->autocfg);
3186 if (err < 0)
3187 return err;
3188 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3189 return 0; /* can't find valid BIOS pin config */
3190
3191 err = vt1708B_auto_create_multi_out_ctls(spec, &spec->autocfg);
3192 if (err < 0)
3193 return err;
3194 err = vt1708B_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3195 if (err < 0)
3196 return err;
3197 err = vt1708B_auto_create_analog_input_ctls(codec, &spec->autocfg);
3198 if (err < 0)
3199 return err;
3200
3201 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3202
3203 if (spec->autocfg.dig_outs)
3204 spec->multiout.dig_out_nid = VT1708B_DIGOUT_NID;
3205 spec->dig_in_pin = VT1708B_DIGIN_PIN;
3206 if (spec->autocfg.dig_in_pin)
3207 spec->dig_in_nid = VT1708B_DIGIN_NID;
3208
3209 if (spec->kctls.list)
3210 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3211
3212 spec->input_mux = &spec->private_imux[0];
3213
3214 if (spec->hp_mux)
3215 via_hp_build(codec);
3216
3217 via_smart51_build(spec);
3218 return 1;
3219}
3220
3221#ifdef CONFIG_SND_HDA_POWER_SAVE
3222static const struct hda_amp_list vt1708B_loopbacks[] = {
3223 { 0x16, HDA_INPUT, 1 },
3224 { 0x16, HDA_INPUT, 2 },
3225 { 0x16, HDA_INPUT, 3 },
3226 { 0x16, HDA_INPUT, 4 },
3227 { } /* end */
3228};
3229#endif
3230
3231static void set_widgets_power_state_vt1708B(struct hda_codec *codec) 2869static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3232{ 2870{
3233 struct via_spec *spec = codec->spec; 2871 struct via_spec *spec = codec->spec;
@@ -3309,157 +2947,37 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3309} 2947}
3310 2948
3311static int patch_vt1708S(struct hda_codec *codec); 2949static int patch_vt1708S(struct hda_codec *codec);
3312static int patch_vt1708B_8ch(struct hda_codec *codec) 2950static int patch_vt1708B(struct hda_codec *codec)
3313{ 2951{
3314 struct via_spec *spec; 2952 struct via_spec *spec;
3315 int err; 2953 int err;
3316 2954
3317 if (get_codec_type(codec) == VT1708BCE) 2955 if (get_codec_type(codec) == VT1708BCE)
3318 return patch_vt1708S(codec); 2956 return patch_vt1708S(codec);
3319 /* create a codec specific record */
3320 spec = via_new_spec(codec);
3321 if (spec == NULL)
3322 return -ENOMEM;
3323
3324 /* automatic parse from the BIOS config */
3325 err = vt1708B_parse_auto_config(codec);
3326 if (err < 0) {
3327 via_free(codec);
3328 return err;
3329 } else if (!err) {
3330 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3331 "from BIOS. Using genenic mode...\n");
3332 }
3333
3334 spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs;
3335 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3336
3337 spec->stream_name_analog = "VT1708B Analog";
3338 spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback;
3339 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3340
3341 spec->stream_name_digital = "VT1708B Digital";
3342 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3343 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3344
3345 if (!spec->adc_nids && spec->input_mux) {
3346 spec->adc_nids = vt1708B_adc_nids;
3347 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3348 get_mux_nids(codec);
3349 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3350 spec->num_mixers++;
3351 }
3352
3353 codec->patch_ops = via_patch_ops;
3354
3355 codec->patch_ops.init = via_auto_init;
3356 codec->patch_ops.unsol_event = via_unsol_event;
3357#ifdef CONFIG_SND_HDA_POWER_SAVE
3358 spec->loopback.amplist = vt1708B_loopbacks;
3359#endif
3360
3361 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3362
3363 return 0;
3364}
3365
3366static int patch_vt1708B_4ch(struct hda_codec *codec)
3367{
3368 struct via_spec *spec;
3369 int err;
3370 2957
3371 /* create a codec specific record */ 2958 /* create a codec specific record */
3372 spec = via_new_spec(codec); 2959 spec = via_new_spec(codec);
3373 if (spec == NULL) 2960 if (spec == NULL)
3374 return -ENOMEM; 2961 return -ENOMEM;
3375 2962
2963 spec->aa_mix_nid = 0x16;
2964
3376 /* automatic parse from the BIOS config */ 2965 /* automatic parse from the BIOS config */
3377 err = vt1708B_parse_auto_config(codec); 2966 err = via_parse_auto_config(codec);
3378 if (err < 0) { 2967 if (err < 0) {
3379 via_free(codec); 2968 via_free(codec);
3380 return err; 2969 return err;
3381 } else if (!err) {
3382 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3383 "from BIOS. Using genenic mode...\n");
3384 }
3385
3386 spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs;
3387 spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs;
3388
3389 spec->stream_name_analog = "VT1708B Analog";
3390 spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback;
3391 spec->stream_analog_capture = &vt1708B_pcm_analog_capture;
3392
3393 spec->stream_name_digital = "VT1708B Digital";
3394 spec->stream_digital_playback = &vt1708B_pcm_digital_playback;
3395 spec->stream_digital_capture = &vt1708B_pcm_digital_capture;
3396
3397 if (!spec->adc_nids && spec->input_mux) {
3398 spec->adc_nids = vt1708B_adc_nids;
3399 spec->num_adc_nids = ARRAY_SIZE(vt1708B_adc_nids);
3400 get_mux_nids(codec);
3401 spec->mixers[spec->num_mixers] = vt1708B_capture_mixer;
3402 spec->num_mixers++;
3403 } 2970 }
3404 2971
3405 codec->patch_ops = via_patch_ops; 2972 codec->patch_ops = via_patch_ops;
3406 2973
3407 codec->patch_ops.init = via_auto_init;
3408 codec->patch_ops.unsol_event = via_unsol_event;
3409#ifdef CONFIG_SND_HDA_POWER_SAVE
3410 spec->loopback.amplist = vt1708B_loopbacks;
3411#endif
3412
3413 spec->set_widgets_power_state = set_widgets_power_state_vt1708B; 2974 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3414 2975
3415 return 0; 2976 return 0;
3416} 2977}
3417 2978
3418/* Patch for VT1708S */ 2979/* Patch for VT1708S */
3419 2980static const struct hda_verb vt1708S_init_verbs[] = {
3420/* capture mixer elements */
3421static const struct snd_kcontrol_new vt1708S_capture_mixer[] = {
3422 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
3423 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
3424 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
3425 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
3426 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
3427 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
3428 HDA_INPUT),
3429 {
3430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3431 /* The multiple "Capture Source" controls confuse alsamixer
3432 * So call somewhat different..
3433 */
3434 /* .name = "Capture Source", */
3435 .name = "Input Source",
3436 .count = 1,
3437 .info = via_mux_enum_info,
3438 .get = via_mux_enum_get,
3439 .put = via_mux_enum_put,
3440 },
3441 { } /* end */
3442};
3443
3444static const struct hda_verb vt1708S_volume_init_verbs[] = {
3445 /* Unmute ADC0-1 and set the default input to mic-in */
3446 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3447 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3448
3449 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the
3450 * analog-loopback mixer widget */
3451 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
3452 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3453 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3454 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3455 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3456 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
3457
3458 /* Setup default input of PW4 to MW0 */
3459 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
3460 /* PW9, PW10 Output enable */
3461 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3462 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3463 /* Enable Mic Boost Volume backdoor */ 2981 /* Enable Mic Boost Volume backdoor */
3464 {0x1, 0xf98, 0x1}, 2982 {0x1, 0xf98, 0x1},
3465 /* don't bybass mixer */ 2983 /* don't bybass mixer */
@@ -3467,277 +2985,6 @@ static const struct hda_verb vt1708S_volume_init_verbs[] = {
3467 { } 2985 { }
3468}; 2986};
3469 2987
3470static const struct hda_verb vt1708S_uniwill_init_verbs[] = {
3471 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3472 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3473 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3474 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3475 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3476 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3477 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3478 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3479 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3480 { }
3481};
3482
3483static const struct hda_verb vt1705_uniwill_init_verbs[] = {
3484 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3485 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3486 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3487 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3488 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3489 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3490 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3491 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3492 { }
3493};
3494
3495static const struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3496 .substreams = 2,
3497 .channels_min = 2,
3498 .channels_max = 8,
3499 .nid = 0x10, /* NID to query formats and rates */
3500 .ops = {
3501 .open = via_playback_pcm_open,
3502 .prepare = via_playback_multi_pcm_prepare,
3503 .cleanup = via_playback_multi_pcm_cleanup,
3504 .close = via_pcm_open_close
3505 },
3506};
3507
3508static const struct hda_pcm_stream vt1705_pcm_analog_playback = {
3509 .substreams = 2,
3510 .channels_min = 2,
3511 .channels_max = 6,
3512 .nid = 0x10, /* NID to query formats and rates */
3513 .ops = {
3514 .open = via_playback_pcm_open,
3515 .prepare = via_playback_multi_pcm_prepare,
3516 .cleanup = via_playback_multi_pcm_cleanup,
3517 .close = via_pcm_open_close
3518 },
3519};
3520
3521static const struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3522 .substreams = 2,
3523 .channels_min = 2,
3524 .channels_max = 2,
3525 .nid = 0x13, /* NID to query formats and rates */
3526 .ops = {
3527 .open = via_pcm_open_close,
3528 .prepare = via_capture_pcm_prepare,
3529 .cleanup = via_capture_pcm_cleanup,
3530 .close = via_pcm_open_close
3531 },
3532};
3533
3534static const struct hda_pcm_stream vt1708S_pcm_digital_playback = {
3535 .substreams = 1,
3536 .channels_min = 2,
3537 .channels_max = 2,
3538 /* NID is set in via_build_pcms */
3539 .ops = {
3540 .open = via_dig_playback_pcm_open,
3541 .close = via_dig_playback_pcm_close,
3542 .prepare = via_dig_playback_pcm_prepare,
3543 .cleanup = via_dig_playback_pcm_cleanup
3544 },
3545};
3546
3547/* fill in the dac_nids table from the parsed pin configuration */
3548static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3549 const struct auto_pin_cfg *cfg)
3550{
3551 int i;
3552 hda_nid_t nid;
3553
3554 spec->multiout.num_dacs = cfg->line_outs;
3555
3556 spec->multiout.dac_nids = spec->private_dac_nids;
3557
3558 for (i = 0; i < 4; i++) {
3559 nid = cfg->line_out_pins[i];
3560 if (nid) {
3561 /* config dac list */
3562 switch (i) {
3563 case AUTO_SEQ_FRONT:
3564 spec->private_dac_nids[i] = 0x10;
3565 break;
3566 case AUTO_SEQ_CENLFE:
3567 if (spec->codec->vendor_id == 0x11064397)
3568 spec->private_dac_nids[i] = 0x25;
3569 else
3570 spec->private_dac_nids[i] = 0x24;
3571 break;
3572 case AUTO_SEQ_SURROUND:
3573 spec->private_dac_nids[i] = 0x11;
3574 break;
3575 case AUTO_SEQ_SIDE:
3576 spec->private_dac_nids[i] = 0x25;
3577 break;
3578 }
3579 }
3580 }
3581
3582 /* for Smart 5.1, line/mic inputs double as output pins */
3583 if (cfg->line_outs == 1) {
3584 spec->multiout.num_dacs = 3;
3585 spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3586 if (spec->codec->vendor_id == 0x11064397)
3587 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25;
3588 else
3589 spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3590 }
3591
3592 return 0;
3593}
3594
3595/* add playback controls from the parsed DAC table */
3596static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
3597 const struct auto_pin_cfg *cfg)
3598{
3599 struct via_spec *spec = codec->spec;
3600 char name[32];
3601 static const char * const chname[4] = {
3602 "Front", "Surround", "C/LFE", "Side"
3603 };
3604 hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
3605 {0x10, 0x11, 0x25, 0} };
3606 hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
3607 {0x1C, 0x18, 0x27, 0} };
3608 hda_nid_t nid, nid_vol, nid_mute;
3609 int i, err;
3610
3611 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
3612 nid = cfg->line_out_pins[i];
3613
3614 /* for Smart 5.1, there are always at least six channels */
3615 if (!nid && i > AUTO_SEQ_CENLFE)
3616 continue;
3617
3618 if (codec->vendor_id == 0x11064397) {
3619 nid_vol = nid_vols[1][i];
3620 nid_mute = nid_mutes[1][i];
3621 } else {
3622 nid_vol = nid_vols[0][i];
3623 nid_mute = nid_mutes[0][i];
3624 }
3625 if (!nid_vol && !nid_mute)
3626 continue;
3627
3628 if (i == AUTO_SEQ_CENLFE) {
3629 /* Center/LFE */
3630 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3631 "Center Playback Volume",
3632 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
3633 HDA_OUTPUT));
3634 if (err < 0)
3635 return err;
3636 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3637 "LFE Playback Volume",
3638 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
3639 HDA_OUTPUT));
3640 if (err < 0)
3641 return err;
3642 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3643 "Center Playback Switch",
3644 HDA_COMPOSE_AMP_VAL(nid_mute,
3645 1, 0,
3646 HDA_OUTPUT));
3647 if (err < 0)
3648 return err;
3649 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3650 "LFE Playback Switch",
3651 HDA_COMPOSE_AMP_VAL(nid_mute,
3652 2, 0,
3653 HDA_OUTPUT));
3654 if (err < 0)
3655 return err;
3656 } else if (i == AUTO_SEQ_FRONT) {
3657 /* add control to mixer index 0 */
3658 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3659 "Master Front Playback Volume",
3660 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3661 HDA_INPUT));
3662 if (err < 0)
3663 return err;
3664 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3665 "Master Front Playback Switch",
3666 HDA_COMPOSE_AMP_VAL(0x16, 3, 0,
3667 HDA_INPUT));
3668 if (err < 0)
3669 return err;
3670
3671 /* Front */
3672 sprintf(name, "%s Playback Volume", chname[i]);
3673 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3674 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3675 HDA_OUTPUT));
3676 if (err < 0)
3677 return err;
3678 sprintf(name, "%s Playback Switch", chname[i]);
3679 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3680 HDA_COMPOSE_AMP_VAL(nid_mute,
3681 3, 0,
3682 HDA_OUTPUT));
3683 if (err < 0)
3684 return err;
3685 } else {
3686 sprintf(name, "%s Playback Volume", chname[i]);
3687 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
3688 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0,
3689 HDA_OUTPUT));
3690 if (err < 0)
3691 return err;
3692 sprintf(name, "%s Playback Switch", chname[i]);
3693 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
3694 HDA_COMPOSE_AMP_VAL(nid_mute,
3695 3, 0,
3696 HDA_OUTPUT));
3697 if (err < 0)
3698 return err;
3699 }
3700 }
3701
3702 return 0;
3703}
3704
3705static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
3706{
3707 int err;
3708
3709 if (!pin)
3710 return 0;
3711
3712 spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */
3713 spec->hp_independent_mode_index = 1;
3714
3715 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
3716 "Headphone Playback Volume",
3717 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
3718 if (err < 0)
3719 return err;
3720
3721 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
3722 "Headphone Playback Switch",
3723 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3724 if (err < 0)
3725 return err;
3726
3727 create_hp_imux(spec);
3728
3729 return 0;
3730}
3731
3732/* create playback/capture controls for input pins */
3733static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec,
3734 const struct auto_pin_cfg *cfg)
3735{
3736 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
3737 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
3738 ARRAY_SIZE(pin_idxs));
3739}
3740
3741/* fill out digital output widgets; one for master and one for slave outputs */ 2988/* fill out digital output widgets; one for master and one for slave outputs */
3742static void fill_dig_outs(struct hda_codec *codec) 2989static void fill_dig_outs(struct hda_codec *codec)
3743{ 2990{
@@ -3763,56 +3010,33 @@ static void fill_dig_outs(struct hda_codec *codec)
3763 } 3010 }
3764} 3011}
3765 3012
3766static int vt1708S_parse_auto_config(struct hda_codec *codec) 3013static void fill_dig_in(struct hda_codec *codec)
3767{ 3014{
3768 struct via_spec *spec = codec->spec; 3015 struct via_spec *spec = codec->spec;
3769 int err; 3016 hda_nid_t dig_nid;
3770 3017 int i, err;
3771 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
3772 if (err < 0)
3773 return err;
3774 err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg);
3775 if (err < 0)
3776 return err;
3777 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3778 return 0; /* can't find valid BIOS pin config */
3779
3780 err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
3781 if (err < 0)
3782 return err;
3783 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
3784 if (err < 0)
3785 return err;
3786 err = vt1708S_auto_create_analog_input_ctls(codec, &spec->autocfg);
3787 if (err < 0)
3788 return err;
3789
3790 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3791
3792 fill_dig_outs(codec);
3793
3794 if (spec->kctls.list)
3795 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3796
3797 spec->input_mux = &spec->private_imux[0];
3798 3018
3799 if (spec->hp_mux) 3019 if (!spec->autocfg.dig_in_pin)
3800 via_hp_build(codec); 3020 return;
3801 3021
3802 via_smart51_build(spec); 3022 dig_nid = codec->start_nid;
3803 return 1; 3023 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
3024 unsigned int wcaps = get_wcaps(codec, dig_nid);
3025 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
3026 continue;
3027 if (!(wcaps & AC_WCAP_DIGITAL))
3028 continue;
3029 if (!(wcaps & AC_WCAP_CONN_LIST))
3030 continue;
3031 err = get_connection_index(codec, dig_nid,
3032 spec->autocfg.dig_in_pin);
3033 if (err >= 0) {
3034 spec->dig_in_nid = dig_nid;
3035 break;
3036 }
3037 }
3804} 3038}
3805 3039
3806#ifdef CONFIG_SND_HDA_POWER_SAVE
3807static const struct hda_amp_list vt1708S_loopbacks[] = {
3808 { 0x16, HDA_INPUT, 1 },
3809 { 0x16, HDA_INPUT, 2 },
3810 { 0x16, HDA_INPUT, 3 },
3811 { 0x16, HDA_INPUT, 4 },
3812 { } /* end */
3813};
3814#endif
3815
3816static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin, 3040static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
3817 int offset, int num_steps, int step_size) 3041 int offset, int num_steps, int step_size)
3818{ 3042{
@@ -3833,62 +3057,21 @@ static int patch_vt1708S(struct hda_codec *codec)
3833 if (spec == NULL) 3057 if (spec == NULL)
3834 return -ENOMEM; 3058 return -ENOMEM;
3835 3059
3060 spec->aa_mix_nid = 0x16;
3061 override_mic_boost(codec, 0x1a, 0, 3, 40);
3062 override_mic_boost(codec, 0x1e, 0, 3, 40);
3063
3836 /* automatic parse from the BIOS config */ 3064 /* automatic parse from the BIOS config */
3837 err = vt1708S_parse_auto_config(codec); 3065 err = via_parse_auto_config(codec);
3838 if (err < 0) { 3066 if (err < 0) {
3839 via_free(codec); 3067 via_free(codec);
3840 return err; 3068 return err;
3841 } else if (!err) {
3842 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3843 "from BIOS. Using genenic mode...\n");
3844 } 3069 }
3845 3070
3846 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3071 spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
3847 if (codec->vendor_id == 0x11064397)
3848 spec->init_verbs[spec->num_iverbs++] =
3849 vt1705_uniwill_init_verbs;
3850 else
3851 spec->init_verbs[spec->num_iverbs++] =
3852 vt1708S_uniwill_init_verbs;
3853
3854 if (codec->vendor_id == 0x11060440)
3855 spec->stream_name_analog = "VT1818S Analog";
3856 else if (codec->vendor_id == 0x11064397)
3857 spec->stream_name_analog = "VT1705 Analog";
3858 else
3859 spec->stream_name_analog = "VT1708S Analog";
3860 if (codec->vendor_id == 0x11064397)
3861 spec->stream_analog_playback = &vt1705_pcm_analog_playback;
3862 else
3863 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
3864 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
3865
3866 if (codec->vendor_id == 0x11060440)
3867 spec->stream_name_digital = "VT1818S Digital";
3868 else if (codec->vendor_id == 0x11064397)
3869 spec->stream_name_digital = "VT1705 Digital";
3870 else
3871 spec->stream_name_digital = "VT1708S Digital";
3872 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
3873
3874 if (!spec->adc_nids && spec->input_mux) {
3875 spec->adc_nids = vt1708S_adc_nids;
3876 spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids);
3877 get_mux_nids(codec);
3878 override_mic_boost(codec, 0x1a, 0, 3, 40);
3879 override_mic_boost(codec, 0x1e, 0, 3, 40);
3880 spec->mixers[spec->num_mixers] = vt1708S_capture_mixer;
3881 spec->num_mixers++;
3882 }
3883 3072
3884 codec->patch_ops = via_patch_ops; 3073 codec->patch_ops = via_patch_ops;
3885 3074
3886 codec->patch_ops.init = via_auto_init;
3887 codec->patch_ops.unsol_event = via_unsol_event;
3888#ifdef CONFIG_SND_HDA_POWER_SAVE
3889 spec->loopback.amplist = vt1708S_loopbacks;
3890#endif
3891
3892 /* correct names for VT1708BCE */ 3075 /* correct names for VT1708BCE */
3893 if (get_codec_type(codec) == VT1708BCE) { 3076 if (get_codec_type(codec) == VT1708BCE) {
3894 kfree(codec->chip_name); 3077 kfree(codec->chip_name);
@@ -3896,13 +3079,6 @@ static int patch_vt1708S(struct hda_codec *codec)
3896 snprintf(codec->bus->card->mixername, 3079 snprintf(codec->bus->card->mixername,
3897 sizeof(codec->bus->card->mixername), 3080 sizeof(codec->bus->card->mixername),
3898 "%s %s", codec->vendor_name, codec->chip_name); 3081 "%s %s", codec->vendor_name, codec->chip_name);
3899 spec->stream_name_analog = "VT1708BCE Analog";
3900 spec->stream_name_digital = "VT1708BCE Digital";
3901 }
3902 /* correct names for VT1818S */
3903 if (codec->vendor_id == 0x11060440) {
3904 spec->stream_name_analog = "VT1818S Analog";
3905 spec->stream_name_digital = "VT1818S Digital";
3906 } 3082 }
3907 /* correct names for VT1705 */ 3083 /* correct names for VT1705 */
3908 if (codec->vendor_id == 0x11064397) { 3084 if (codec->vendor_id == 0x11064397) {
@@ -3918,55 +3094,7 @@ static int patch_vt1708S(struct hda_codec *codec)
3918 3094
3919/* Patch for VT1702 */ 3095/* Patch for VT1702 */
3920 3096
3921/* capture mixer elements */ 3097static const struct hda_verb vt1702_init_verbs[] = {
3922static const struct snd_kcontrol_new vt1702_capture_mixer[] = {
3923 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT),
3924 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT),
3925 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT),
3926 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT),
3927 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT),
3928 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT),
3929 HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0,
3930 HDA_INPUT),
3931 {
3932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3933 /* The multiple "Capture Source" controls confuse alsamixer
3934 * So call somewhat different..
3935 */
3936 /* .name = "Capture Source", */
3937 .name = "Input Source",
3938 .count = 1,
3939 .info = via_mux_enum_info,
3940 .get = via_mux_enum_get,
3941 .put = via_mux_enum_put,
3942 },
3943 { } /* end */
3944};
3945
3946static const struct hda_verb vt1702_volume_init_verbs[] = {
3947 /*
3948 * Unmute ADC0-1 and set the default input to mic-in
3949 */
3950 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3951 {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3952 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3953
3954
3955 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3956 * mixer widget
3957 */
3958 /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */
3959 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3960 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3961 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
3962 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
3963 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3964
3965 /* Setup default input of PW4 to MW0 */
3966 {0x17, AC_VERB_SET_CONNECT_SEL, 0x1},
3967 /* PW6 PW7 Output enable */
3968 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3969 {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
3970 /* mixer enable */ 3098 /* mixer enable */
3971 {0x1, 0xF88, 0x3}, 3099 {0x1, 0xF88, 0x3},
3972 /* GPIO 0~2 */ 3100 /* GPIO 0~2 */
@@ -3974,202 +3102,6 @@ static const struct hda_verb vt1702_volume_init_verbs[] = {
3974 { } 3102 { }
3975}; 3103};
3976 3104
3977static const struct hda_verb vt1702_uniwill_init_verbs[] = {
3978 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE,
3979 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3980 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3981 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3982 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3984 { }
3985};
3986
3987static const struct hda_pcm_stream vt1702_pcm_analog_playback = {
3988 .substreams = 2,
3989 .channels_min = 2,
3990 .channels_max = 2,
3991 .nid = 0x10, /* NID to query formats and rates */
3992 .ops = {
3993 .open = via_playback_pcm_open,
3994 .prepare = via_playback_multi_pcm_prepare,
3995 .cleanup = via_playback_multi_pcm_cleanup,
3996 .close = via_pcm_open_close
3997 },
3998};
3999
4000static const struct hda_pcm_stream vt1702_pcm_analog_capture = {
4001 .substreams = 3,
4002 .channels_min = 2,
4003 .channels_max = 2,
4004 .nid = 0x12, /* NID to query formats and rates */
4005 .ops = {
4006 .open = via_pcm_open_close,
4007 .prepare = via_capture_pcm_prepare,
4008 .cleanup = via_capture_pcm_cleanup,
4009 .close = via_pcm_open_close
4010 },
4011};
4012
4013static const struct hda_pcm_stream vt1702_pcm_digital_playback = {
4014 .substreams = 2,
4015 .channels_min = 2,
4016 .channels_max = 2,
4017 /* NID is set in via_build_pcms */
4018 .ops = {
4019 .open = via_dig_playback_pcm_open,
4020 .close = via_dig_playback_pcm_close,
4021 .prepare = via_dig_playback_pcm_prepare,
4022 .cleanup = via_dig_playback_pcm_cleanup
4023 },
4024};
4025
4026/* fill in the dac_nids table from the parsed pin configuration */
4027static int vt1702_auto_fill_dac_nids(struct via_spec *spec,
4028 const struct auto_pin_cfg *cfg)
4029{
4030 spec->multiout.num_dacs = 1;
4031 spec->multiout.dac_nids = spec->private_dac_nids;
4032
4033 if (cfg->line_out_pins[0]) {
4034 /* config dac list */
4035 spec->private_dac_nids[0] = 0x10;
4036 }
4037
4038 return 0;
4039}
4040
4041/* add playback controls from the parsed DAC table */
4042static int vt1702_auto_create_line_out_ctls(struct via_spec *spec,
4043 const struct auto_pin_cfg *cfg)
4044{
4045 int err;
4046
4047 if (!cfg->line_out_pins[0])
4048 return -1;
4049
4050 /* add control to mixer index 0 */
4051 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4052 "Master Front Playback Volume",
4053 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4054 if (err < 0)
4055 return err;
4056 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4057 "Master Front Playback Switch",
4058 HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT));
4059 if (err < 0)
4060 return err;
4061
4062 /* Front */
4063 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4064 "Front Playback Volume",
4065 HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT));
4066 if (err < 0)
4067 return err;
4068 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4069 "Front Playback Switch",
4070 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT));
4071 if (err < 0)
4072 return err;
4073
4074 return 0;
4075}
4076
4077static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4078{
4079 int err, i;
4080 struct hda_input_mux *imux;
4081 static const char * const texts[] = { "ON", "OFF", NULL};
4082 if (!pin)
4083 return 0;
4084 spec->multiout.hp_nid = 0x1D;
4085 spec->hp_independent_mode_index = 0;
4086
4087 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4088 "Headphone Playback Volume",
4089 HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT));
4090 if (err < 0)
4091 return err;
4092
4093 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4094 "Headphone Playback Switch",
4095 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4096 if (err < 0)
4097 return err;
4098
4099 imux = &spec->private_imux[1];
4100
4101 /* for hp mode select */
4102 for (i = 0; texts[i]; i++)
4103 snd_hda_add_imux_item(imux, texts[i], i, NULL);
4104
4105 spec->hp_mux = &spec->private_imux[1];
4106 return 0;
4107}
4108
4109/* create playback/capture controls for input pins */
4110static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec,
4111 const struct auto_pin_cfg *cfg)
4112{
4113 static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff };
4114 return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs,
4115 ARRAY_SIZE(pin_idxs));
4116}
4117
4118static int vt1702_parse_auto_config(struct hda_codec *codec)
4119{
4120 struct via_spec *spec = codec->spec;
4121 int err;
4122
4123 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4124 if (err < 0)
4125 return err;
4126 err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg);
4127 if (err < 0)
4128 return err;
4129 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4130 return 0; /* can't find valid BIOS pin config */
4131
4132 err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg);
4133 if (err < 0)
4134 return err;
4135 err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4136 if (err < 0)
4137 return err;
4138 /* limit AA path volume to 0 dB */
4139 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
4140 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4141 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4142 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4143 (1 << AC_AMPCAP_MUTE_SHIFT));
4144 err = vt1702_auto_create_analog_input_ctls(codec, &spec->autocfg);
4145 if (err < 0)
4146 return err;
4147
4148 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4149
4150 fill_dig_outs(codec);
4151
4152 if (spec->kctls.list)
4153 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4154
4155 spec->input_mux = &spec->private_imux[0];
4156
4157 if (spec->hp_mux)
4158 via_hp_build(codec);
4159
4160 return 1;
4161}
4162
4163#ifdef CONFIG_SND_HDA_POWER_SAVE
4164static const struct hda_amp_list vt1702_loopbacks[] = {
4165 { 0x1A, HDA_INPUT, 1 },
4166 { 0x1A, HDA_INPUT, 2 },
4167 { 0x1A, HDA_INPUT, 3 },
4168 { 0x1A, HDA_INPUT, 4 },
4169 { } /* end */
4170};
4171#endif
4172
4173static void set_widgets_power_state_vt1702(struct hda_codec *codec) 3105static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4174{ 3106{
4175 int imux_is_smixer = 3107 int imux_is_smixer =
@@ -4211,393 +3143,41 @@ static int patch_vt1702(struct hda_codec *codec)
4211 if (spec == NULL) 3143 if (spec == NULL)
4212 return -ENOMEM; 3144 return -ENOMEM;
4213 3145
3146 spec->aa_mix_nid = 0x1a;
3147
3148 /* limit AA path volume to 0 dB */
3149 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
3150 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3151 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3152 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3153 (1 << AC_AMPCAP_MUTE_SHIFT));
3154
4214 /* automatic parse from the BIOS config */ 3155 /* automatic parse from the BIOS config */
4215 err = vt1702_parse_auto_config(codec); 3156 err = via_parse_auto_config(codec);
4216 if (err < 0) { 3157 if (err < 0) {
4217 via_free(codec); 3158 via_free(codec);
4218 return err; 3159 return err;
4219 } else if (!err) {
4220 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4221 "from BIOS. Using genenic mode...\n");
4222 } 3160 }
4223 3161
4224 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs; 3162 spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
4225 spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs;
4226
4227 spec->stream_name_analog = "VT1702 Analog";
4228 spec->stream_analog_playback = &vt1702_pcm_analog_playback;
4229 spec->stream_analog_capture = &vt1702_pcm_analog_capture;
4230
4231 spec->stream_name_digital = "VT1702 Digital";
4232 spec->stream_digital_playback = &vt1702_pcm_digital_playback;
4233
4234 if (!spec->adc_nids && spec->input_mux) {
4235 spec->adc_nids = vt1702_adc_nids;
4236 spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids);
4237 get_mux_nids(codec);
4238 spec->mixers[spec->num_mixers] = vt1702_capture_mixer;
4239 spec->num_mixers++;
4240 }
4241 3163
4242 codec->patch_ops = via_patch_ops; 3164 codec->patch_ops = via_patch_ops;
4243 3165
4244 codec->patch_ops.init = via_auto_init;
4245 codec->patch_ops.unsol_event = via_unsol_event;
4246#ifdef CONFIG_SND_HDA_POWER_SAVE
4247 spec->loopback.amplist = vt1702_loopbacks;
4248#endif
4249
4250 spec->set_widgets_power_state = set_widgets_power_state_vt1702; 3166 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4251 return 0; 3167 return 0;
4252} 3168}
4253 3169
4254/* Patch for VT1718S */ 3170/* Patch for VT1718S */
4255 3171
4256/* capture mixer elements */ 3172static const struct hda_verb vt1718S_init_verbs[] = {
4257static const struct snd_kcontrol_new vt1718S_capture_mixer[] = {
4258 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
4259 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
4260 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
4261 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
4262 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
4263 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
4264 HDA_INPUT),
4265 {
4266 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4267 /* The multiple "Capture Source" controls confuse alsamixer
4268 * So call somewhat different..
4269 */
4270 .name = "Input Source",
4271 .count = 2,
4272 .info = via_mux_enum_info,
4273 .get = via_mux_enum_get,
4274 .put = via_mux_enum_put,
4275 },
4276 { } /* end */
4277};
4278
4279static const struct hda_verb vt1718S_volume_init_verbs[] = {
4280 /*
4281 * Unmute ADC0-1 and set the default input to mic-in
4282 */
4283 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4284 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4285
4286 /* Enable MW0 adjust Gain 5 */ 3173 /* Enable MW0 adjust Gain 5 */
4287 {0x1, 0xfb2, 0x10}, 3174 {0x1, 0xfb2, 0x10},
4288 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4289 * mixer widget
4290 */
4291 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4292 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4293 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4294 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4295 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4296 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
4297 /* PW9 PW10 Output enable */
4298 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4299 {0x2e, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
4300 /* PW11 Input enable */
4301 {0x2f, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_IN_EN},
4302 /* Enable Boost Volume backdoor */ 3175 /* Enable Boost Volume backdoor */
4303 {0x1, 0xf88, 0x8}, 3176 {0x1, 0xf88, 0x8},
4304 /* MW0/1/2/3/4: un-mute index 0 (AOWx), mute index 1 (MW9) */
4305 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4306 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4307 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4308 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4309 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4310 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4311 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4312 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4313 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4314 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4315 /* set MUX1 = 2 (AOW4), MUX2 = 1 (AOW3) */
4316 {0x34, AC_VERB_SET_CONNECT_SEL, 0x2},
4317 {0x35, AC_VERB_SET_CONNECT_SEL, 0x1},
4318 { }
4319};
4320 3177
4321
4322static const struct hda_verb vt1718S_uniwill_init_verbs[] = {
4323 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
4324 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4325 {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4326 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4327 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4328 {0x27, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4329 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4330 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4331 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4332 { } 3178 { }
4333}; 3179};
4334 3180
4335static const struct hda_pcm_stream vt1718S_pcm_analog_playback = {
4336 .substreams = 2,
4337 .channels_min = 2,
4338 .channels_max = 10,
4339 .nid = 0x8, /* NID to query formats and rates */
4340 .ops = {
4341 .open = via_playback_pcm_open,
4342 .prepare = via_playback_multi_pcm_prepare,
4343 .cleanup = via_playback_multi_pcm_cleanup,
4344 .close = via_pcm_open_close,
4345 },
4346};
4347
4348static const struct hda_pcm_stream vt1718S_pcm_analog_capture = {
4349 .substreams = 2,
4350 .channels_min = 2,
4351 .channels_max = 2,
4352 .nid = 0x10, /* NID to query formats and rates */
4353 .ops = {
4354 .open = via_pcm_open_close,
4355 .prepare = via_capture_pcm_prepare,
4356 .cleanup = via_capture_pcm_cleanup,
4357 .close = via_pcm_open_close,
4358 },
4359};
4360
4361static const struct hda_pcm_stream vt1718S_pcm_digital_playback = {
4362 .substreams = 2,
4363 .channels_min = 2,
4364 .channels_max = 2,
4365 /* NID is set in via_build_pcms */
4366 .ops = {
4367 .open = via_dig_playback_pcm_open,
4368 .close = via_dig_playback_pcm_close,
4369 .prepare = via_dig_playback_pcm_prepare,
4370 .cleanup = via_dig_playback_pcm_cleanup
4371 },
4372};
4373
4374static const struct hda_pcm_stream vt1718S_pcm_digital_capture = {
4375 .substreams = 1,
4376 .channels_min = 2,
4377 .channels_max = 2,
4378};
4379
4380/* fill in the dac_nids table from the parsed pin configuration */
4381static int vt1718S_auto_fill_dac_nids(struct via_spec *spec,
4382 const struct auto_pin_cfg *cfg)
4383{
4384 int i;
4385 hda_nid_t nid;
4386
4387 spec->multiout.num_dacs = cfg->line_outs;
4388
4389 spec->multiout.dac_nids = spec->private_dac_nids;
4390
4391 for (i = 0; i < 4; i++) {
4392 nid = cfg->line_out_pins[i];
4393 if (nid) {
4394 /* config dac list */
4395 switch (i) {
4396 case AUTO_SEQ_FRONT:
4397 spec->private_dac_nids[i] = 0x8;
4398 break;
4399 case AUTO_SEQ_CENLFE:
4400 spec->private_dac_nids[i] = 0xa;
4401 break;
4402 case AUTO_SEQ_SURROUND:
4403 spec->private_dac_nids[i] = 0x9;
4404 break;
4405 case AUTO_SEQ_SIDE:
4406 spec->private_dac_nids[i] = 0xb;
4407 break;
4408 }
4409 }
4410 }
4411
4412 return 0;
4413}
4414
4415/* add playback controls from the parsed DAC table */
4416static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4417 const struct auto_pin_cfg *cfg)
4418{
4419 char name[32];
4420 static const char * const chname[4] = {
4421 "Front", "Surround", "C/LFE", "Side"
4422 };
4423 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4424 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4425 hda_nid_t nid, nid_vol, nid_mute = 0;
4426 int i, err;
4427
4428 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
4429 nid = cfg->line_out_pins[i];
4430
4431 if (!nid)
4432 continue;
4433 nid_vol = nid_vols[i];
4434 nid_mute = nid_mutes[i];
4435
4436 if (i == AUTO_SEQ_CENLFE) {
4437 /* Center/LFE */
4438 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4439 "Center Playback Volume",
4440 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0,
4441 HDA_OUTPUT));
4442 if (err < 0)
4443 return err;
4444 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4445 "LFE Playback Volume",
4446 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0,
4447 HDA_OUTPUT));
4448 if (err < 0)
4449 return err;
4450 err = via_add_control(
4451 spec, VIA_CTL_WIDGET_MUTE,
4452 "Center Playback Switch",
4453 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4454 HDA_OUTPUT));
4455 if (err < 0)
4456 return err;
4457 err = via_add_control(
4458 spec, VIA_CTL_WIDGET_MUTE,
4459 "LFE Playback Switch",
4460 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4461 HDA_OUTPUT));
4462 if (err < 0)
4463 return err;
4464 } else if (i == AUTO_SEQ_FRONT) {
4465 /* add control to mixer index 0 */
4466 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4467 "Master Front Playback Volume",
4468 HDA_COMPOSE_AMP_VAL(0x21, 3, 5,
4469 HDA_INPUT));
4470 if (err < 0)
4471 return err;
4472 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4473 "Master Front Playback Switch",
4474 HDA_COMPOSE_AMP_VAL(0x21, 3, 5,
4475 HDA_INPUT));
4476 if (err < 0)
4477 return err;
4478 /* Front */
4479 sprintf(name, "%s Playback Volume", chname[i]);
4480 err = via_add_control(
4481 spec, VIA_CTL_WIDGET_VOL, name,
4482 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4483 if (err < 0)
4484 return err;
4485 sprintf(name, "%s Playback Switch", chname[i]);
4486 err = via_add_control(
4487 spec, VIA_CTL_WIDGET_MUTE, name,
4488 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4489 HDA_OUTPUT));
4490 if (err < 0)
4491 return err;
4492 } else {
4493 sprintf(name, "%s Playback Volume", chname[i]);
4494 err = via_add_control(
4495 spec, VIA_CTL_WIDGET_VOL, name,
4496 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
4497 if (err < 0)
4498 return err;
4499 sprintf(name, "%s Playback Switch", chname[i]);
4500 err = via_add_control(
4501 spec, VIA_CTL_WIDGET_MUTE, name,
4502 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
4503 HDA_OUTPUT));
4504 if (err < 0)
4505 return err;
4506 }
4507 }
4508 return 0;
4509}
4510
4511static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4512{
4513 int err;
4514
4515 if (!pin)
4516 return 0;
4517
4518 spec->multiout.hp_nid = 0xc; /* AOW4 */
4519 spec->hp_independent_mode_index = 1;
4520
4521 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
4522 "Headphone Playback Volume",
4523 HDA_COMPOSE_AMP_VAL(0xc, 3, 0, HDA_OUTPUT));
4524 if (err < 0)
4525 return err;
4526
4527 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
4528 "Headphone Playback Switch",
4529 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
4530 if (err < 0)
4531 return err;
4532
4533 create_hp_imux(spec);
4534 return 0;
4535}
4536
4537/* create playback/capture controls for input pins */
4538static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec,
4539 const struct auto_pin_cfg *cfg)
4540{
4541 static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff };
4542 return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
4543 ARRAY_SIZE(pin_idxs));
4544}
4545
4546static int vt1718S_parse_auto_config(struct hda_codec *codec)
4547{
4548 struct via_spec *spec = codec->spec;
4549 int err;
4550
4551 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
4552
4553 if (err < 0)
4554 return err;
4555 err = vt1718S_auto_fill_dac_nids(spec, &spec->autocfg);
4556 if (err < 0)
4557 return err;
4558 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
4559 return 0; /* can't find valid BIOS pin config */
4560
4561 err = vt1718S_auto_create_multi_out_ctls(spec, &spec->autocfg);
4562 if (err < 0)
4563 return err;
4564 err = vt1718S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
4565 if (err < 0)
4566 return err;
4567 err = vt1718S_auto_create_analog_input_ctls(codec, &spec->autocfg);
4568 if (err < 0)
4569 return err;
4570
4571 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
4572
4573 fill_dig_outs(codec);
4574
4575 if (spec->autocfg.dig_in_pin && codec->vendor_id == 0x11060428)
4576 spec->dig_in_nid = 0x13;
4577
4578 if (spec->kctls.list)
4579 spec->mixers[spec->num_mixers++] = spec->kctls.list;
4580
4581 spec->input_mux = &spec->private_imux[0];
4582
4583 if (spec->hp_mux)
4584 via_hp_build(codec);
4585
4586 via_smart51_build(spec);
4587
4588 return 1;
4589}
4590
4591#ifdef CONFIG_SND_HDA_POWER_SAVE
4592static const struct hda_amp_list vt1718S_loopbacks[] = {
4593 { 0x21, HDA_INPUT, 1 },
4594 { 0x21, HDA_INPUT, 2 },
4595 { 0x21, HDA_INPUT, 3 },
4596 { 0x21, HDA_INPUT, 4 },
4597 { } /* end */
4598};
4599#endif
4600
4601static void set_widgets_power_state_vt1718S(struct hda_codec *codec) 3181static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4602{ 3182{
4603 struct via_spec *spec = codec->spec; 3183 struct via_spec *spec = codec->spec;
@@ -4664,6 +3244,41 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4664 } 3244 }
4665} 3245}
4666 3246
3247/* Add a connection to the primary DAC from AA-mixer for some codecs
3248 * This isn't listed from the raw info, but the chip has a secret connection.
3249 */
3250static int add_secret_dac_path(struct hda_codec *codec)
3251{
3252 struct via_spec *spec = codec->spec;
3253 int i, nums;
3254 hda_nid_t conn[8];
3255 hda_nid_t nid;
3256
3257 if (!spec->aa_mix_nid)
3258 return 0;
3259 nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
3260 ARRAY_SIZE(conn) - 1);
3261 for (i = 0; i < nums; i++) {
3262 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
3263 return 0;
3264 }
3265
3266 /* find the primary DAC and add to the connection list */
3267 nid = codec->start_nid;
3268 for (i = 0; i < codec->num_nodes; i++, nid++) {
3269 unsigned int caps = get_wcaps(codec, nid);
3270 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
3271 !(caps & AC_WCAP_DIGITAL)) {
3272 conn[nums++] = nid;
3273 return snd_hda_override_conn_list(codec,
3274 spec->aa_mix_nid,
3275 nums, conn);
3276 }
3277 }
3278 return 0;
3279}
3280
3281
4667static int patch_vt1718S(struct hda_codec *codec) 3282static int patch_vt1718S(struct hda_codec *codec)
4668{ 3283{
4669 struct via_spec *spec; 3284 struct via_spec *spec;
@@ -4674,57 +3289,22 @@ static int patch_vt1718S(struct hda_codec *codec)
4674 if (spec == NULL) 3289 if (spec == NULL)
4675 return -ENOMEM; 3290 return -ENOMEM;
4676 3291
3292 spec->aa_mix_nid = 0x21;
3293 override_mic_boost(codec, 0x2b, 0, 3, 40);
3294 override_mic_boost(codec, 0x29, 0, 3, 40);
3295 add_secret_dac_path(codec);
3296
4677 /* automatic parse from the BIOS config */ 3297 /* automatic parse from the BIOS config */
4678 err = vt1718S_parse_auto_config(codec); 3298 err = via_parse_auto_config(codec);
4679 if (err < 0) { 3299 if (err < 0) {
4680 via_free(codec); 3300 via_free(codec);
4681 return err; 3301 return err;
4682 } else if (!err) {
4683 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4684 "from BIOS. Using genenic mode...\n");
4685 } 3302 }
4686 3303
4687 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs; 3304 spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
4688 spec->init_verbs[spec->num_iverbs++] = vt1718S_uniwill_init_verbs;
4689
4690 if (codec->vendor_id == 0x11060441)
4691 spec->stream_name_analog = "VT2020 Analog";
4692 else if (codec->vendor_id == 0x11064441)
4693 spec->stream_name_analog = "VT1828S Analog";
4694 else
4695 spec->stream_name_analog = "VT1718S Analog";
4696 spec->stream_analog_playback = &vt1718S_pcm_analog_playback;
4697 spec->stream_analog_capture = &vt1718S_pcm_analog_capture;
4698
4699 if (codec->vendor_id == 0x11060441)
4700 spec->stream_name_digital = "VT2020 Digital";
4701 else if (codec->vendor_id == 0x11064441)
4702 spec->stream_name_digital = "VT1828S Digital";
4703 else
4704 spec->stream_name_digital = "VT1718S Digital";
4705 spec->stream_digital_playback = &vt1718S_pcm_digital_playback;
4706 if (codec->vendor_id == 0x11060428 || codec->vendor_id == 0x11060441)
4707 spec->stream_digital_capture = &vt1718S_pcm_digital_capture;
4708
4709 if (!spec->adc_nids && spec->input_mux) {
4710 spec->adc_nids = vt1718S_adc_nids;
4711 spec->num_adc_nids = ARRAY_SIZE(vt1718S_adc_nids);
4712 get_mux_nids(codec);
4713 override_mic_boost(codec, 0x2b, 0, 3, 40);
4714 override_mic_boost(codec, 0x29, 0, 3, 40);
4715 spec->mixers[spec->num_mixers] = vt1718S_capture_mixer;
4716 spec->num_mixers++;
4717 }
4718 3305
4719 codec->patch_ops = via_patch_ops; 3306 codec->patch_ops = via_patch_ops;
4720 3307
4721 codec->patch_ops.init = via_auto_init;
4722 codec->patch_ops.unsol_event = via_unsol_event;
4723
4724#ifdef CONFIG_SND_HDA_POWER_SAVE
4725 spec->loopback.amplist = vt1718S_loopbacks;
4726#endif
4727
4728 spec->set_widgets_power_state = set_widgets_power_state_vt1718S; 3308 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4729 3309
4730 return 0; 3310 return 0;
@@ -4770,26 +3350,6 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4770 return 1; 3350 return 1;
4771} 3351}
4772 3352
4773/* capture mixer elements */
4774static const struct snd_kcontrol_new vt1716S_capture_mixer[] = {
4775 HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT),
4776 HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT),
4777 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT),
4778 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT),
4779 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x1A, 0x0, HDA_INPUT),
4780 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x1E, 0x0,
4781 HDA_INPUT),
4782 {
4783 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4784 .name = "Input Source",
4785 .count = 1,
4786 .info = via_mux_enum_info,
4787 .get = via_mux_enum_get,
4788 .put = via_mux_enum_put,
4789 },
4790 { } /* end */
4791};
4792
4793static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { 3353static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4794 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 3354 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4795 { 3355 {
@@ -4811,45 +3371,7 @@ static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4811 { } /* end */ 3371 { } /* end */
4812}; 3372};
4813 3373
4814static const struct hda_verb vt1716S_volume_init_verbs[] = { 3374static const struct hda_verb vt1716S_init_verbs[] = {
4815 /*
4816 * Unmute ADC0-1 and set the default input to mic-in
4817 */
4818 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4820
4821
4822 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
4823 * mixer widget
4824 */
4825 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
4826 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4828 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4831
4832 /* MUX Indices: Stereo Mixer = 5 */
4833 {0x17, AC_VERB_SET_CONNECT_SEL, 0x5},
4834
4835 /* Setup default input of PW4 to MW0 */
4836 {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0},
4837
4838 /* Setup default input of SW1 as MW0 */
4839 {0x18, AC_VERB_SET_CONNECT_SEL, 0x1},
4840
4841 /* Setup default input of SW4 as AOW0 */
4842 {0x28, AC_VERB_SET_CONNECT_SEL, 0x1},
4843
4844 /* PW9 PW10 Output enable */
4845 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4846 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4847
4848 /* Unmute SW1, PW12 */
4849 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4850 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4851 /* PW12 Output enable */
4852 {0x2a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
4853 /* Enable Boost Volume backdoor */ 3375 /* Enable Boost Volume backdoor */
4854 {0x1, 0xf8a, 0x80}, 3376 {0x1, 0xf8a, 0x80},
4855 /* don't bybass mixer */ 3377 /* don't bybass mixer */
@@ -4859,272 +3381,6 @@ static const struct hda_verb vt1716S_volume_init_verbs[] = {
4859 { } 3381 { }
4860}; 3382};
4861 3383
4862
4863static const struct hda_verb vt1716S_uniwill_init_verbs[] = {
4864 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
4865 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
4866 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4867 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4868 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4869 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE,
4870 AC_USRSP_EN | VIA_MONO_EVENT | VIA_JACK_EVENT},
4871 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4872 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
4873 { }
4874};
4875
4876static const struct hda_pcm_stream vt1716S_pcm_analog_playback = {
4877 .substreams = 2,
4878 .channels_min = 2,
4879 .channels_max = 6,
4880 .nid = 0x10, /* NID to query formats and rates */
4881 .ops = {
4882 .open = via_playback_pcm_open,
4883 .prepare = via_playback_multi_pcm_prepare,
4884 .cleanup = via_playback_multi_pcm_cleanup,
4885 .close = via_pcm_open_close,
4886 },
4887};
4888
4889static const struct hda_pcm_stream vt1716S_pcm_analog_capture = {
4890 .substreams = 2,
4891 .channels_min = 2,
4892 .channels_max = 2,
4893 .nid = 0x13, /* NID to query formats and rates */
4894 .ops = {
4895 .open = via_pcm_open_close,
4896 .prepare = via_capture_pcm_prepare,
4897 .cleanup = via_capture_pcm_cleanup,
4898 .close = via_pcm_open_close,
4899 },
4900};
4901
4902static const struct hda_pcm_stream vt1716S_pcm_digital_playback = {
4903 .substreams = 2,
4904 .channels_min = 2,
4905 .channels_max = 2,
4906 /* NID is set in via_build_pcms */
4907 .ops = {
4908 .open = via_dig_playback_pcm_open,
4909 .close = via_dig_playback_pcm_close,
4910 .prepare = via_dig_playback_pcm_prepare,
4911 .cleanup = via_dig_playback_pcm_cleanup
4912 },
4913};
4914
4915/* fill in the dac_nids table from the parsed pin configuration */
4916static int vt1716S_auto_fill_dac_nids(struct via_spec *spec,
4917 const struct auto_pin_cfg *cfg)
4918{ int i;
4919 hda_nid_t nid;
4920
4921 spec->multiout.num_dacs = cfg->line_outs;
4922
4923 spec->multiout.dac_nids = spec->private_dac_nids;
4924
4925 for (i = 0; i < 3; i++) {
4926 nid = cfg->line_out_pins[i];
4927 if (nid) {
4928 /* config dac list */
4929 switch (i) {
4930 case AUTO_SEQ_FRONT:
4931 spec->private_dac_nids[i] = 0x10;
4932 break;
4933 case AUTO_SEQ_CENLFE:
4934 spec->private_dac_nids[i] = 0x25;
4935 break;
4936 case AUTO_SEQ_SURROUND:
4937 spec->private_dac_nids[i] = 0x11;
4938 break;
4939 }
4940 }
4941 }
4942
4943 return 0;
4944}
4945
4946/* add playback controls from the parsed DAC table */
4947static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
4948 const struct auto_pin_cfg *cfg)
4949{
4950 char name[32];
4951 static const char * const chname[3] = {
4952 "Front", "Surround", "C/LFE"
4953 };
4954 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
4955 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
4956 hda_nid_t nid, nid_vol, nid_mute;
4957 int i, err;
4958
4959 for (i = 0; i <= AUTO_SEQ_CENLFE; i++) {
4960 nid = cfg->line_out_pins[i];
4961
4962 if (!nid)
4963 continue;
4964
4965 nid_vol = nid_vols[i];
4966 nid_mute = nid_mutes[i];
4967
4968 if (i == AUTO_SEQ_CENLFE) {
4969 err = via_add_control(
4970 spec, VIA_CTL_WIDGET_VOL,
4971 "Center Playback Volume",
4972 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
4973 if (err < 0)
4974 return err;
4975 err = via_add_control(
4976 spec, VIA_CTL_WIDGET_VOL,
4977 "LFE Playback Volume",
4978 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
4979 if (err < 0)
4980 return err;
4981 err = via_add_control(
4982 spec, VIA_CTL_WIDGET_MUTE,
4983 "Center Playback Switch",
4984 HDA_COMPOSE_AMP_VAL(nid_mute, 1, 0,
4985 HDA_OUTPUT));
4986 if (err < 0)
4987 return err;
4988 err = via_add_control(
4989 spec, VIA_CTL_WIDGET_MUTE,
4990 "LFE Playback Switch",
4991 HDA_COMPOSE_AMP_VAL(nid_mute, 2, 0,
4992 HDA_OUTPUT));
4993 if (err < 0)
4994 return err;
4995 } else if (i == AUTO_SEQ_FRONT) {
4996
4997 err = via_add_control(
4998 spec, VIA_CTL_WIDGET_VOL,
4999 "Master Front Playback Volume",
5000 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5001 if (err < 0)
5002 return err;
5003 err = via_add_control(
5004 spec, VIA_CTL_WIDGET_MUTE,
5005 "Master Front Playback Switch",
5006 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_INPUT));
5007 if (err < 0)
5008 return err;
5009
5010 sprintf(name, "%s Playback Volume", chname[i]);
5011 err = via_add_control(
5012 spec, VIA_CTL_WIDGET_VOL, name,
5013 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5014 if (err < 0)
5015 return err;
5016 sprintf(name, "%s Playback Switch", chname[i]);
5017 err = via_add_control(
5018 spec, VIA_CTL_WIDGET_MUTE, name,
5019 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5020 HDA_OUTPUT));
5021 if (err < 0)
5022 return err;
5023 } else {
5024 sprintf(name, "%s Playback Volume", chname[i]);
5025 err = via_add_control(
5026 spec, VIA_CTL_WIDGET_VOL, name,
5027 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
5028 if (err < 0)
5029 return err;
5030 sprintf(name, "%s Playback Switch", chname[i]);
5031 err = via_add_control(
5032 spec, VIA_CTL_WIDGET_MUTE, name,
5033 HDA_COMPOSE_AMP_VAL(nid_mute, 3, 0,
5034 HDA_OUTPUT));
5035 if (err < 0)
5036 return err;
5037 }
5038 }
5039 return 0;
5040}
5041
5042static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5043{
5044 int err;
5045
5046 if (!pin)
5047 return 0;
5048
5049 spec->multiout.hp_nid = 0x25; /* AOW3 */
5050 spec->hp_independent_mode_index = 1;
5051
5052 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5053 "Headphone Playback Volume",
5054 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5055 if (err < 0)
5056 return err;
5057
5058 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5059 "Headphone Playback Switch",
5060 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5061 if (err < 0)
5062 return err;
5063
5064 create_hp_imux(spec);
5065 return 0;
5066}
5067
5068/* create playback/capture controls for input pins */
5069static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec,
5070 const struct auto_pin_cfg *cfg)
5071{
5072 static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff };
5073 return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs,
5074 ARRAY_SIZE(pin_idxs));
5075}
5076
5077static int vt1716S_parse_auto_config(struct hda_codec *codec)
5078{
5079 struct via_spec *spec = codec->spec;
5080 int err;
5081
5082 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5083 if (err < 0)
5084 return err;
5085 err = vt1716S_auto_fill_dac_nids(spec, &spec->autocfg);
5086 if (err < 0)
5087 return err;
5088 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5089 return 0; /* can't find valid BIOS pin config */
5090
5091 err = vt1716S_auto_create_multi_out_ctls(spec, &spec->autocfg);
5092 if (err < 0)
5093 return err;
5094 err = vt1716S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5095 if (err < 0)
5096 return err;
5097 err = vt1716S_auto_create_analog_input_ctls(codec, &spec->autocfg);
5098 if (err < 0)
5099 return err;
5100
5101 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5102
5103 fill_dig_outs(codec);
5104
5105 if (spec->kctls.list)
5106 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5107
5108 spec->input_mux = &spec->private_imux[0];
5109
5110 if (spec->hp_mux)
5111 via_hp_build(codec);
5112
5113 via_smart51_build(spec);
5114
5115 return 1;
5116}
5117
5118#ifdef CONFIG_SND_HDA_POWER_SAVE
5119static const struct hda_amp_list vt1716S_loopbacks[] = {
5120 { 0x16, HDA_INPUT, 1 },
5121 { 0x16, HDA_INPUT, 2 },
5122 { 0x16, HDA_INPUT, 3 },
5123 { 0x16, HDA_INPUT, 4 },
5124 { } /* end */
5125};
5126#endif
5127
5128static void set_widgets_power_state_vt1716S(struct hda_codec *codec) 3384static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
5129{ 3385{
5130 struct via_spec *spec = codec->spec; 3386 struct via_spec *spec = codec->spec;
@@ -5228,35 +3484,18 @@ static int patch_vt1716S(struct hda_codec *codec)
5228 if (spec == NULL) 3484 if (spec == NULL)
5229 return -ENOMEM; 3485 return -ENOMEM;
5230 3486
3487 spec->aa_mix_nid = 0x16;
3488 override_mic_boost(codec, 0x1a, 0, 3, 40);
3489 override_mic_boost(codec, 0x1e, 0, 3, 40);
3490
5231 /* automatic parse from the BIOS config */ 3491 /* automatic parse from the BIOS config */
5232 err = vt1716S_parse_auto_config(codec); 3492 err = via_parse_auto_config(codec);
5233 if (err < 0) { 3493 if (err < 0) {
5234 via_free(codec); 3494 via_free(codec);
5235 return err; 3495 return err;
5236 } else if (!err) {
5237 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5238 "from BIOS. Using genenic mode...\n");
5239 } 3496 }
5240 3497
5241 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs; 3498 spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
5242 spec->init_verbs[spec->num_iverbs++] = vt1716S_uniwill_init_verbs;
5243
5244 spec->stream_name_analog = "VT1716S Analog";
5245 spec->stream_analog_playback = &vt1716S_pcm_analog_playback;
5246 spec->stream_analog_capture = &vt1716S_pcm_analog_capture;
5247
5248 spec->stream_name_digital = "VT1716S Digital";
5249 spec->stream_digital_playback = &vt1716S_pcm_digital_playback;
5250
5251 if (!spec->adc_nids && spec->input_mux) {
5252 spec->adc_nids = vt1716S_adc_nids;
5253 spec->num_adc_nids = ARRAY_SIZE(vt1716S_adc_nids);
5254 get_mux_nids(codec);
5255 override_mic_boost(codec, 0x1a, 0, 3, 40);
5256 override_mic_boost(codec, 0x1e, 0, 3, 40);
5257 spec->mixers[spec->num_mixers] = vt1716S_capture_mixer;
5258 spec->num_mixers++;
5259 }
5260 3499
5261 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer; 3500 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5262 spec->num_mixers++; 3501 spec->num_mixers++;
@@ -5265,354 +3504,32 @@ static int patch_vt1716S(struct hda_codec *codec)
5265 3504
5266 codec->patch_ops = via_patch_ops; 3505 codec->patch_ops = via_patch_ops;
5267 3506
5268 codec->patch_ops.init = via_auto_init;
5269 codec->patch_ops.unsol_event = via_unsol_event;
5270
5271#ifdef CONFIG_SND_HDA_POWER_SAVE
5272 spec->loopback.amplist = vt1716S_loopbacks;
5273#endif
5274
5275 spec->set_widgets_power_state = set_widgets_power_state_vt1716S; 3507 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5276 return 0; 3508 return 0;
5277} 3509}
5278 3510
5279/* for vt2002P */ 3511/* for vt2002P */
5280 3512
5281/* capture mixer elements */ 3513static const struct hda_verb vt2002P_init_verbs[] = {
5282static const struct snd_kcontrol_new vt2002P_capture_mixer[] = {
5283 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5284 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5285 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5286 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5287 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5288 HDA_CODEC_VOLUME("Front Mic Boost Capture Volume", 0x29, 0x0,
5289 HDA_INPUT),
5290 {
5291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5292 /* The multiple "Capture Source" controls confuse alsamixer
5293 * So call somewhat different..
5294 */
5295 /* .name = "Capture Source", */
5296 .name = "Input Source",
5297 .count = 2,
5298 .info = via_mux_enum_info,
5299 .get = via_mux_enum_get,
5300 .put = via_mux_enum_put,
5301 },
5302 { } /* end */
5303};
5304
5305static const struct hda_verb vt2002P_volume_init_verbs[] = {
5306 /* Class-D speaker related verbs */ 3514 /* Class-D speaker related verbs */
5307 {0x1, 0xfe0, 0x4}, 3515 {0x1, 0xfe0, 0x4},
5308 {0x1, 0xfe9, 0x80}, 3516 {0x1, 0xfe9, 0x80},
5309 {0x1, 0xfe2, 0x22}, 3517 {0x1, 0xfe2, 0x22},
5310 /*
5311 * Unmute ADC0-1 and set the default input to mic-in
5312 */
5313 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5314 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5315
5316
5317 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5318 * mixer widget
5319 */
5320 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5321 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5322 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5323 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5324 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5325 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5326
5327 /* MUX Indices: Mic = 0 */
5328 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5329 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5330
5331 /* PW9 Output enable */
5332 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5333
5334 /* Enable Boost Volume backdoor */ 3518 /* Enable Boost Volume backdoor */
5335 {0x1, 0xfb9, 0x24}, 3519 {0x1, 0xfb9, 0x24},
5336
5337 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5340 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5341 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5342 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5343 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5344 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5345 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5346
5347 /* set MUX0/1/4/8 = 0 (AOW0) */
5348 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5349 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5350 {0x37, AC_VERB_SET_CONNECT_SEL, 0},
5351 {0x3b, AC_VERB_SET_CONNECT_SEL, 0},
5352
5353 /* set PW0 index=0 (MW0) */
5354 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5355
5356 /* Enable AOW0 to MW9 */ 3520 /* Enable AOW0 to MW9 */
5357 {0x1, 0xfb8, 0x88}, 3521 {0x1, 0xfb8, 0x88},
5358 { } 3522 { }
5359}; 3523};
5360static const struct hda_verb vt1802_volume_init_verbs[] = {
5361 /*
5362 * Unmute ADC0-1 and set the default input to mic-in
5363 */
5364 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5365 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5366
5367
5368 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5369 * mixer widget
5370 */
5371 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5372 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5373 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5374 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5376 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5377
5378 /* MUX Indices: Mic = 0 */
5379 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5380 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5381
5382 /* PW9 Output enable */
5383 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5384 3524
3525static const struct hda_verb vt1802_init_verbs[] = {
5385 /* Enable Boost Volume backdoor */ 3526 /* Enable Boost Volume backdoor */
5386 {0x1, 0xfb9, 0x24}, 3527 {0x1, 0xfb9, 0x24},
5387
5388 /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5389 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5390 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5391 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5392 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5393 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5395 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5396 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5397
5398 /* set MUX0/1/4/8 = 0 (AOW0) */
5399 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5400 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5401 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5402 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5403
5404 /* set PW0 index=0 (MW0) */
5405 {0x24, AC_VERB_SET_CONNECT_SEL, 0},
5406
5407 /* Enable AOW0 to MW9 */ 3528 /* Enable AOW0 to MW9 */
5408 {0x1, 0xfb8, 0x88}, 3529 {0x1, 0xfb8, 0x88},
5409 { } 3530 { }
5410}; 3531};
5411 3532
5412
5413static const struct hda_verb vt2002P_uniwill_init_verbs[] = {
5414 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5415 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5416 {0x26, AC_VERB_SET_UNSOLICITED_ENABLE,
5417 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5418 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5419 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5420 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5421 { }
5422};
5423static const struct hda_verb vt1802_uniwill_init_verbs[] = {
5424 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE,
5425 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5426 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5427 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5428 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5429 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5430 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5431 { }
5432};
5433
5434static const struct hda_pcm_stream vt2002P_pcm_analog_playback = {
5435 .substreams = 2,
5436 .channels_min = 2,
5437 .channels_max = 2,
5438 .nid = 0x8, /* NID to query formats and rates */
5439 .ops = {
5440 .open = via_playback_pcm_open,
5441 .prepare = via_playback_multi_pcm_prepare,
5442 .cleanup = via_playback_multi_pcm_cleanup,
5443 .close = via_pcm_open_close,
5444 },
5445};
5446
5447static const struct hda_pcm_stream vt2002P_pcm_analog_capture = {
5448 .substreams = 2,
5449 .channels_min = 2,
5450 .channels_max = 2,
5451 .nid = 0x10, /* NID to query formats and rates */
5452 .ops = {
5453 .open = via_pcm_open_close,
5454 .prepare = via_capture_pcm_prepare,
5455 .cleanup = via_capture_pcm_cleanup,
5456 .close = via_pcm_open_close,
5457 },
5458};
5459
5460static const struct hda_pcm_stream vt2002P_pcm_digital_playback = {
5461 .substreams = 1,
5462 .channels_min = 2,
5463 .channels_max = 2,
5464 /* NID is set in via_build_pcms */
5465 .ops = {
5466 .open = via_dig_playback_pcm_open,
5467 .close = via_dig_playback_pcm_close,
5468 .prepare = via_dig_playback_pcm_prepare,
5469 .cleanup = via_dig_playback_pcm_cleanup
5470 },
5471};
5472
5473/* fill in the dac_nids table from the parsed pin configuration */
5474static int vt2002P_auto_fill_dac_nids(struct via_spec *spec,
5475 const struct auto_pin_cfg *cfg)
5476{
5477 spec->multiout.num_dacs = 1;
5478 spec->multiout.dac_nids = spec->private_dac_nids;
5479 if (cfg->line_out_pins[0])
5480 spec->private_dac_nids[0] = 0x8;
5481 return 0;
5482}
5483
5484/* add playback controls from the parsed DAC table */
5485static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec,
5486 const struct auto_pin_cfg *cfg)
5487{
5488 int err;
5489 hda_nid_t sw_nid;
5490
5491 if (!cfg->line_out_pins[0])
5492 return -1;
5493
5494 if (spec->codec_type == VT1802)
5495 sw_nid = 0x28;
5496 else
5497 sw_nid = 0x26;
5498
5499 /* Line-Out: PortE */
5500 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5501 "Master Front Playback Volume",
5502 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5503 if (err < 0)
5504 return err;
5505 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5506 "Master Front Playback Switch",
5507 HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT));
5508 if (err < 0)
5509 return err;
5510
5511 return 0;
5512}
5513
5514static int vt2002P_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5515{
5516 int err;
5517
5518 if (!pin)
5519 return 0;
5520
5521 spec->multiout.hp_nid = 0x9;
5522 spec->hp_independent_mode_index = 1;
5523
5524 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5525 "Headphone Playback Volume",
5526 HDA_COMPOSE_AMP_VAL(
5527 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5528 if (err < 0)
5529 return err;
5530
5531 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5532 "Headphone Playback Switch",
5533 HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT));
5534 if (err < 0)
5535 return err;
5536
5537 create_hp_imux(spec);
5538 return 0;
5539}
5540
5541/* create playback/capture controls for input pins */
5542static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec,
5543 const struct auto_pin_cfg *cfg)
5544{
5545 struct via_spec *spec = codec->spec;
5546 struct hda_input_mux *imux = &spec->private_imux[0];
5547 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff };
5548 int err;
5549
5550 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
5551 ARRAY_SIZE(pin_idxs));
5552 if (err < 0)
5553 return err;
5554 /* build volume/mute control of loopback */
5555 err = via_new_analog_input(spec, "Stereo Mixer", 0, 3, 0x21);
5556 if (err < 0)
5557 return err;
5558
5559 /* for digital mic select */
5560 snd_hda_add_imux_item(imux, "Digital Mic", 4, NULL);
5561
5562 return 0;
5563}
5564
5565static int vt2002P_parse_auto_config(struct hda_codec *codec)
5566{
5567 struct via_spec *spec = codec->spec;
5568 int err;
5569
5570
5571 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
5572 if (err < 0)
5573 return err;
5574
5575 err = vt2002P_auto_fill_dac_nids(spec, &spec->autocfg);
5576 if (err < 0)
5577 return err;
5578
5579 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
5580 return 0; /* can't find valid BIOS pin config */
5581
5582 err = vt2002P_auto_create_multi_out_ctls(spec, &spec->autocfg);
5583 if (err < 0)
5584 return err;
5585 err = vt2002P_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
5586 if (err < 0)
5587 return err;
5588 err = vt2002P_auto_create_analog_input_ctls(codec, &spec->autocfg);
5589 if (err < 0)
5590 return err;
5591
5592 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5593
5594 fill_dig_outs(codec);
5595
5596 if (spec->kctls.list)
5597 spec->mixers[spec->num_mixers++] = spec->kctls.list;
5598
5599 spec->input_mux = &spec->private_imux[0];
5600
5601 if (spec->hp_mux)
5602 via_hp_build(codec);
5603
5604 return 1;
5605}
5606
5607#ifdef CONFIG_SND_HDA_POWER_SAVE
5608static const struct hda_amp_list vt2002P_loopbacks[] = {
5609 { 0x21, HDA_INPUT, 0 },
5610 { 0x21, HDA_INPUT, 1 },
5611 { 0x21, HDA_INPUT, 2 },
5612 { } /* end */
5613};
5614#endif
5615
5616static void set_widgets_power_state_vt2002P(struct hda_codec *codec) 3533static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5617{ 3534{
5618 struct via_spec *spec = codec->spec; 3535 struct via_spec *spec = codec->spec;
@@ -5735,334 +3652,39 @@ static int patch_vt2002P(struct hda_codec *codec)
5735 if (spec == NULL) 3652 if (spec == NULL)
5736 return -ENOMEM; 3653 return -ENOMEM;
5737 3654
3655 spec->aa_mix_nid = 0x21;
3656 override_mic_boost(codec, 0x2b, 0, 3, 40);
3657 override_mic_boost(codec, 0x29, 0, 3, 40);
3658 add_secret_dac_path(codec);
3659
5738 /* automatic parse from the BIOS config */ 3660 /* automatic parse from the BIOS config */
5739 err = vt2002P_parse_auto_config(codec); 3661 err = via_parse_auto_config(codec);
5740 if (err < 0) { 3662 if (err < 0) {
5741 via_free(codec); 3663 via_free(codec);
5742 return err; 3664 return err;
5743 } else if (!err) {
5744 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5745 "from BIOS. Using genenic mode...\n");
5746 } 3665 }
5747 3666
5748 if (spec->codec_type == VT1802) 3667 if (spec->codec_type == VT1802)
5749 spec->init_verbs[spec->num_iverbs++] = 3668 spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
5750 vt1802_volume_init_verbs;
5751 else
5752 spec->init_verbs[spec->num_iverbs++] =
5753 vt2002P_volume_init_verbs;
5754
5755 if (spec->codec_type == VT1802)
5756 spec->init_verbs[spec->num_iverbs++] =
5757 vt1802_uniwill_init_verbs;
5758 else 3669 else
5759 spec->init_verbs[spec->num_iverbs++] = 3670 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
5760 vt2002P_uniwill_init_verbs;
5761
5762 if (spec->codec_type == VT1802)
5763 spec->stream_name_analog = "VT1802 Analog";
5764 else
5765 spec->stream_name_analog = "VT2002P Analog";
5766 spec->stream_analog_playback = &vt2002P_pcm_analog_playback;
5767 spec->stream_analog_capture = &vt2002P_pcm_analog_capture;
5768
5769 if (spec->codec_type == VT1802)
5770 spec->stream_name_digital = "VT1802 Digital";
5771 else
5772 spec->stream_name_digital = "VT2002P Digital";
5773 spec->stream_digital_playback = &vt2002P_pcm_digital_playback;
5774
5775 if (!spec->adc_nids && spec->input_mux) {
5776 spec->adc_nids = vt2002P_adc_nids;
5777 spec->num_adc_nids = ARRAY_SIZE(vt2002P_adc_nids);
5778 get_mux_nids(codec);
5779 override_mic_boost(codec, 0x2b, 0, 3, 40);
5780 override_mic_boost(codec, 0x29, 0, 3, 40);
5781 spec->mixers[spec->num_mixers] = vt2002P_capture_mixer;
5782 spec->num_mixers++;
5783 }
5784 3671
5785 codec->patch_ops = via_patch_ops; 3672 codec->patch_ops = via_patch_ops;
5786 3673
5787 codec->patch_ops.init = via_auto_init;
5788 codec->patch_ops.unsol_event = via_unsol_event;
5789
5790#ifdef CONFIG_SND_HDA_POWER_SAVE
5791 spec->loopback.amplist = vt2002P_loopbacks;
5792#endif
5793
5794 spec->set_widgets_power_state = set_widgets_power_state_vt2002P; 3674 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5795 return 0; 3675 return 0;
5796} 3676}
5797 3677
5798/* for vt1812 */ 3678/* for vt1812 */
5799 3679
5800/* capture mixer elements */ 3680static const struct hda_verb vt1812_init_verbs[] = {
5801static const struct snd_kcontrol_new vt1812_capture_mixer[] = {
5802 HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT),
5803 HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT),
5804 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT),
5805 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x11, 0x0, HDA_INPUT),
5806 HDA_CODEC_MUTE("Mic Boost Capture Volume", 0x2b, 0x0, HDA_INPUT),
5807 HDA_CODEC_MUTE("Front Mic Boost Capture Volume", 0x29, 0x0,
5808 HDA_INPUT),
5809 {
5810 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5811 /* The multiple "Capture Source" controls confuse alsamixer
5812 * So call somewhat different..
5813 */
5814 .name = "Input Source",
5815 .count = 2,
5816 .info = via_mux_enum_info,
5817 .get = via_mux_enum_get,
5818 .put = via_mux_enum_put,
5819 },
5820 { } /* end */
5821};
5822
5823static const struct hda_verb vt1812_volume_init_verbs[] = {
5824 /*
5825 * Unmute ADC0-1 and set the default input to mic-in
5826 */
5827 {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5828 {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5829
5830
5831 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
5832 * mixer widget
5833 */
5834 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
5835 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5836 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5837 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5838 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5839 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5840
5841 /* MUX Indices: Mic = 0 */
5842 {0x1e, AC_VERB_SET_CONNECT_SEL, 0},
5843 {0x1f, AC_VERB_SET_CONNECT_SEL, 0},
5844
5845 /* PW9 Output enable */
5846 {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN},
5847
5848 /* Enable Boost Volume backdoor */ 3681 /* Enable Boost Volume backdoor */
5849 {0x1, 0xfb9, 0x24}, 3682 {0x1, 0xfb9, 0x24},
5850
5851 /* MW0/1/4/13/15: un-mute index 0 (MUXx), un-mute index 1 (MW9) */
5852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5854 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5855 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5856 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5857 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5858 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5859 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5860 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5861 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5862
5863 /* set MUX0/1/4/13/15 = 0 (AOW0) */
5864 {0x34, AC_VERB_SET_CONNECT_SEL, 0},
5865 {0x35, AC_VERB_SET_CONNECT_SEL, 0},
5866 {0x38, AC_VERB_SET_CONNECT_SEL, 0},
5867 {0x3c, AC_VERB_SET_CONNECT_SEL, 0},
5868 {0x3d, AC_VERB_SET_CONNECT_SEL, 0},
5869
5870 /* Enable AOW0 to MW9 */ 3683 /* Enable AOW0 to MW9 */
5871 {0x1, 0xfb8, 0xa8}, 3684 {0x1, 0xfb8, 0xa8},
5872 { } 3685 { }
5873}; 3686};
5874 3687
5875
5876static const struct hda_verb vt1812_uniwill_init_verbs[] = {
5877 {0x33, AC_VERB_SET_UNSOLICITED_ENABLE,
5878 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5879 {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT },
5880 {0x28, AC_VERB_SET_UNSOLICITED_ENABLE,
5881 AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT},
5882 {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5883 {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5884 {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
5885 { }
5886};
5887
5888static const struct hda_pcm_stream vt1812_pcm_analog_playback = {
5889 .substreams = 2,
5890 .channels_min = 2,
5891 .channels_max = 2,
5892 .nid = 0x8, /* NID to query formats and rates */
5893 .ops = {
5894 .open = via_playback_pcm_open,
5895 .prepare = via_playback_multi_pcm_prepare,
5896 .cleanup = via_playback_multi_pcm_cleanup,
5897 .close = via_pcm_open_close,
5898 },
5899};
5900
5901static const struct hda_pcm_stream vt1812_pcm_analog_capture = {
5902 .substreams = 2,
5903 .channels_min = 2,
5904 .channels_max = 2,
5905 .nid = 0x10, /* NID to query formats and rates */
5906 .ops = {
5907 .open = via_pcm_open_close,
5908 .prepare = via_capture_pcm_prepare,
5909 .cleanup = via_capture_pcm_cleanup,
5910 .close = via_pcm_open_close,
5911 },
5912};
5913
5914static const struct hda_pcm_stream vt1812_pcm_digital_playback = {
5915 .substreams = 1,
5916 .channels_min = 2,
5917 .channels_max = 2,
5918 /* NID is set in via_build_pcms */
5919 .ops = {
5920 .open = via_dig_playback_pcm_open,
5921 .close = via_dig_playback_pcm_close,
5922 .prepare = via_dig_playback_pcm_prepare,
5923 .cleanup = via_dig_playback_pcm_cleanup
5924 },
5925};
5926/* fill in the dac_nids table from the parsed pin configuration */
5927static int vt1812_auto_fill_dac_nids(struct via_spec *spec,
5928 const struct auto_pin_cfg *cfg)
5929{
5930 spec->multiout.num_dacs = 1;
5931 spec->multiout.dac_nids = spec->private_dac_nids;
5932 if (cfg->line_out_pins[0])
5933 spec->private_dac_nids[0] = 0x8;
5934 return 0;
5935}
5936
5937
5938/* add playback controls from the parsed DAC table */
5939static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec,
5940 const struct auto_pin_cfg *cfg)
5941{
5942 int err;
5943
5944 if (!cfg->line_out_pins[0])
5945 return -1;
5946
5947 /* Line-Out: PortE */
5948 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5949 "Front Playback Volume",
5950 HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT));
5951 if (err < 0)
5952 return err;
5953 err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE,
5954 "Front Playback Switch",
5955 HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT));
5956 if (err < 0)
5957 return err;
5958
5959 return 0;
5960}
5961
5962static int vt1812_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
5963{
5964 int err;
5965
5966 if (!pin)
5967 return 0;
5968
5969 spec->multiout.hp_nid = 0x9;
5970 spec->hp_independent_mode_index = 1;
5971
5972
5973 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
5974 "Headphone Playback Volume",
5975 HDA_COMPOSE_AMP_VAL(
5976 spec->multiout.hp_nid, 3, 0, HDA_OUTPUT));
5977 if (err < 0)
5978 return err;
5979
5980 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
5981 "Headphone Playback Switch",
5982 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5983 if (err < 0)
5984 return err;
5985
5986 create_hp_imux(spec);
5987 return 0;
5988}
5989
5990/* create playback/capture controls for input pins */
5991static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec,
5992 const struct auto_pin_cfg *cfg)
5993{
5994 struct via_spec *spec = codec->spec;
5995 struct hda_input_mux *imux = &spec->private_imux[0];
5996 static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff };
5997 int err;
5998
5999 err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs,
6000 ARRAY_SIZE(pin_idxs));
6001 if (err < 0)
6002 return err;
6003
6004 /* build volume/mute control of loopback */
6005 err = via_new_analog_input(spec, "Stereo Mixer", 0, 5, 0x21);
6006 if (err < 0)
6007 return err;
6008
6009 /* for digital mic select */
6010 snd_hda_add_imux_item(imux, "Digital Mic", 6, NULL);
6011
6012 return 0;
6013}
6014
6015static int vt1812_parse_auto_config(struct hda_codec *codec)
6016{
6017 struct via_spec *spec = codec->spec;
6018 int err;
6019
6020
6021 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
6022 if (err < 0)
6023 return err;
6024 fill_dig_outs(codec);
6025 err = vt1812_auto_fill_dac_nids(spec, &spec->autocfg);
6026 if (err < 0)
6027 return err;
6028
6029 if (!spec->autocfg.line_outs && !spec->autocfg.hp_outs)
6030 return 0; /* can't find valid BIOS pin config */
6031
6032 err = vt1812_auto_create_multi_out_ctls(spec, &spec->autocfg);
6033 if (err < 0)
6034 return err;
6035 err = vt1812_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
6036 if (err < 0)
6037 return err;
6038 err = vt1812_auto_create_analog_input_ctls(codec, &spec->autocfg);
6039 if (err < 0)
6040 return err;
6041
6042 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
6043
6044 fill_dig_outs(codec);
6045
6046 if (spec->kctls.list)
6047 spec->mixers[spec->num_mixers++] = spec->kctls.list;
6048
6049 spec->input_mux = &spec->private_imux[0];
6050
6051 if (spec->hp_mux)
6052 via_hp_build(codec);
6053
6054 return 1;
6055}
6056
6057#ifdef CONFIG_SND_HDA_POWER_SAVE
6058static const struct hda_amp_list vt1812_loopbacks[] = {
6059 { 0x21, HDA_INPUT, 0 },
6060 { 0x21, HDA_INPUT, 1 },
6061 { 0x21, HDA_INPUT, 2 },
6062 { } /* end */
6063};
6064#endif
6065
6066static void set_widgets_power_state_vt1812(struct hda_codec *codec) 3688static void set_widgets_power_state_vt1812(struct hda_codec *codec)
6067{ 3689{
6068 struct via_spec *spec = codec->spec; 3690 struct via_spec *spec = codec->spec;
@@ -6166,47 +3788,22 @@ static int patch_vt1812(struct hda_codec *codec)
6166 if (spec == NULL) 3788 if (spec == NULL)
6167 return -ENOMEM; 3789 return -ENOMEM;
6168 3790
3791 spec->aa_mix_nid = 0x21;
3792 override_mic_boost(codec, 0x2b, 0, 3, 40);
3793 override_mic_boost(codec, 0x29, 0, 3, 40);
3794 add_secret_dac_path(codec);
3795
6169 /* automatic parse from the BIOS config */ 3796 /* automatic parse from the BIOS config */
6170 err = vt1812_parse_auto_config(codec); 3797 err = via_parse_auto_config(codec);
6171 if (err < 0) { 3798 if (err < 0) {
6172 via_free(codec); 3799 via_free(codec);
6173 return err; 3800 return err;
6174 } else if (!err) {
6175 printk(KERN_INFO "hda_codec: Cannot set up configuration "
6176 "from BIOS. Using genenic mode...\n");
6177 } 3801 }
6178 3802
6179 3803 spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
6180 spec->init_verbs[spec->num_iverbs++] = vt1812_volume_init_verbs;
6181 spec->init_verbs[spec->num_iverbs++] = vt1812_uniwill_init_verbs;
6182
6183 spec->stream_name_analog = "VT1812 Analog";
6184 spec->stream_analog_playback = &vt1812_pcm_analog_playback;
6185 spec->stream_analog_capture = &vt1812_pcm_analog_capture;
6186
6187 spec->stream_name_digital = "VT1812 Digital";
6188 spec->stream_digital_playback = &vt1812_pcm_digital_playback;
6189
6190
6191 if (!spec->adc_nids && spec->input_mux) {
6192 spec->adc_nids = vt1812_adc_nids;
6193 spec->num_adc_nids = ARRAY_SIZE(vt1812_adc_nids);
6194 get_mux_nids(codec);
6195 override_mic_boost(codec, 0x2b, 0, 3, 40);
6196 override_mic_boost(codec, 0x29, 0, 3, 40);
6197 spec->mixers[spec->num_mixers] = vt1812_capture_mixer;
6198 spec->num_mixers++;
6199 }
6200 3804
6201 codec->patch_ops = via_patch_ops; 3805 codec->patch_ops = via_patch_ops;
6202 3806
6203 codec->patch_ops.init = via_auto_init;
6204 codec->patch_ops.unsol_event = via_unsol_event;
6205
6206#ifdef CONFIG_SND_HDA_POWER_SAVE
6207 spec->loopback.amplist = vt1812_loopbacks;
6208#endif
6209
6210 spec->set_widgets_power_state = set_widgets_power_state_vt1812; 3807 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
6211 return 0; 3808 return 0;
6212} 3809}
@@ -6220,37 +3817,37 @@ static const struct hda_codec_preset snd_hda_preset_via[] = {
6220 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 3817 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
6221 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708}, 3818 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
6222 { .id = 0x1106e710, .name = "VT1709 10-Ch", 3819 { .id = 0x1106e710, .name = "VT1709 10-Ch",
6223 .patch = patch_vt1709_10ch}, 3820 .patch = patch_vt1709},
6224 { .id = 0x1106e711, .name = "VT1709 10-Ch", 3821 { .id = 0x1106e711, .name = "VT1709 10-Ch",
6225 .patch = patch_vt1709_10ch}, 3822 .patch = patch_vt1709},
6226 { .id = 0x1106e712, .name = "VT1709 10-Ch", 3823 { .id = 0x1106e712, .name = "VT1709 10-Ch",
6227 .patch = patch_vt1709_10ch}, 3824 .patch = patch_vt1709},
6228 { .id = 0x1106e713, .name = "VT1709 10-Ch", 3825 { .id = 0x1106e713, .name = "VT1709 10-Ch",
6229 .patch = patch_vt1709_10ch}, 3826 .patch = patch_vt1709},
6230 { .id = 0x1106e714, .name = "VT1709 6-Ch", 3827 { .id = 0x1106e714, .name = "VT1709 6-Ch",
6231 .patch = patch_vt1709_6ch}, 3828 .patch = patch_vt1709},
6232 { .id = 0x1106e715, .name = "VT1709 6-Ch", 3829 { .id = 0x1106e715, .name = "VT1709 6-Ch",
6233 .patch = patch_vt1709_6ch}, 3830 .patch = patch_vt1709},
6234 { .id = 0x1106e716, .name = "VT1709 6-Ch", 3831 { .id = 0x1106e716, .name = "VT1709 6-Ch",
6235 .patch = patch_vt1709_6ch}, 3832 .patch = patch_vt1709},
6236 { .id = 0x1106e717, .name = "VT1709 6-Ch", 3833 { .id = 0x1106e717, .name = "VT1709 6-Ch",
6237 .patch = patch_vt1709_6ch}, 3834 .patch = patch_vt1709},
6238 { .id = 0x1106e720, .name = "VT1708B 8-Ch", 3835 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
6239 .patch = patch_vt1708B_8ch}, 3836 .patch = patch_vt1708B},
6240 { .id = 0x1106e721, .name = "VT1708B 8-Ch", 3837 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
6241 .patch = patch_vt1708B_8ch}, 3838 .patch = patch_vt1708B},
6242 { .id = 0x1106e722, .name = "VT1708B 8-Ch", 3839 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
6243 .patch = patch_vt1708B_8ch}, 3840 .patch = patch_vt1708B},
6244 { .id = 0x1106e723, .name = "VT1708B 8-Ch", 3841 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
6245 .patch = patch_vt1708B_8ch}, 3842 .patch = patch_vt1708B},
6246 { .id = 0x1106e724, .name = "VT1708B 4-Ch", 3843 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
6247 .patch = patch_vt1708B_4ch}, 3844 .patch = patch_vt1708B},
6248 { .id = 0x1106e725, .name = "VT1708B 4-Ch", 3845 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
6249 .patch = patch_vt1708B_4ch}, 3846 .patch = patch_vt1708B},
6250 { .id = 0x1106e726, .name = "VT1708B 4-Ch", 3847 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
6251 .patch = patch_vt1708B_4ch}, 3848 .patch = patch_vt1708B},
6252 { .id = 0x1106e727, .name = "VT1708B 4-Ch", 3849 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
6253 .patch = patch_vt1708B_4ch}, 3850 .patch = patch_vt1708B},
6254 { .id = 0x11060397, .name = "VT1708S", 3851 { .id = 0x11060397, .name = "VT1708S",
6255 .patch = patch_vt1708S}, 3852 .patch = patch_vt1708S},
6256 { .id = 0x11061397, .name = "VT1708S", 3853 { .id = 0x11061397, .name = "VT1708S",