aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/Kconfig54
-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.c688
-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.c570
-rw-r--r--sound/pci/hda/hda_codec.h49
-rw-r--r--sound/pci/hda/hda_eld.c165
-rw-r--r--sound/pci/hda/hda_intel.c729
-rw-r--r--sound/pci/hda/hda_local.h20
-rw-r--r--sound/pci/hda/hda_proc.c4
-rw-r--r--sound/pci/hda/patch_analog.c11
-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.c758
-rw-r--r--sound/pci/hda/patch_cmedia.c17
-rw-r--r--sound/pci/hda/patch_conexant.c184
-rw-r--r--sound/pci/hda/patch_hdmi.c766
-rw-r--r--sound/pci/hda/patch_realtek.c18328
-rw-r--r--sound/pci/hda/patch_sigmatel.c408
-rw-r--r--sound/pci/hda/patch_via.c6158
29 files changed, 20715 insertions, 21639 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 0ea5cc60ac7..522c4fd958d 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
@@ -71,6 +84,20 @@ config SND_HDA_PATCH_LOADER
71 84
72 This option turns on hwdep and reconfig features automatically. 85 This option turns on hwdep and reconfig features automatically.
73 86
87config SND_HDA_PLATFORM_DRIVER
88 bool "Build platform driver interface for HD-audio driver"
89 help
90 Say Y here to build a platform driver interface for HD-audio driver.
91 This interface can be used by platforms which have an Azalia
92 controller not installed on a PCI bus.
93
94config SND_HDA_PLATFORM_NVIDIA_TEGRA
95 bool "Build NVIDIA Tegra platform driver interface for HD-audio driver"
96 depends on SND_HDA_PLATFORM_DRIVER
97 help
98 Say Y here to build NVIDIA Tegra platform driver interface for
99 HD-audio driver.
100
74config SND_HDA_CODEC_REALTEK 101config SND_HDA_CODEC_REALTEK
75 bool "Build Realtek HD-audio codec support" 102 bool "Build Realtek HD-audio codec support"
76 default y 103 default y
@@ -83,6 +110,19 @@ config SND_HDA_CODEC_REALTEK
83 snd-hda-codec-realtek. 110 snd-hda-codec-realtek.
84 This module is automatically loaded at probing. 111 This module is automatically loaded at probing.
85 112
113config SND_HDA_ENABLE_REALTEK_QUIRKS
114 bool "Build static quirks for Realtek codecs"
115 depends on SND_HDA_CODEC_REALTEK
116 default y
117 help
118 Say Y here to build the static quirks codes for Realtek codecs.
119 If you need the "model" preset that the default BIOS auto-parser
120 can't handle, turn this option on.
121
122 If your device works with model=auto option, basically you don't
123 need the quirk code. By turning this off, you can reduce the
124 module size quite a lot.
125
86config SND_HDA_CODEC_ANALOG 126config SND_HDA_CODEC_ANALOG
87 bool "Build Analog Device HD-audio codec support" 127 bool "Build Analog Device HD-audio codec support"
88 default y 128 default y
@@ -171,6 +211,19 @@ config SND_HDA_CODEC_CA0110
171 snd-hda-codec-ca0110. 211 snd-hda-codec-ca0110.
172 This module is automatically loaded at probing. 212 This module is automatically loaded at probing.
173 213
214config SND_HDA_CODEC_CA0132
215 bool "Build Creative CA0132 codec support"
216 depends on SND_HDA_INTEL
217 default y
218 help
219 Say Y here to include Creative CA0132 codec support in
220 snd-hda-intel driver.
221
222 When the HD-audio driver is built as a module, the codec
223 support code is also built as another module,
224 snd-hda-codec-ca0132.
225 This module is automatically loaded at probing.
226
174config SND_HDA_CODEC_CMEDIA 227config SND_HDA_CODEC_CMEDIA
175 bool "Build C-Media HD-audio codec support" 228 bool "Build C-Media HD-audio codec support"
176 default y 229 default y
@@ -204,6 +257,7 @@ config SND_HDA_GENERIC
204 257
205config SND_HDA_POWER_SAVE 258config SND_HDA_POWER_SAVE
206 bool "Aggressive power-saving on HD-audio" 259 bool "Aggressive power-saving on HD-audio"
260 depends on PM
207 help 261 help
208 Say Y here to enable more aggressive power-saving mode on 262 Say Y here to enable more aggressive power-saving mode on
209 HD-audio driver. The power-saving timeout can be configured 263 HD-audio driver. The power-saving timeout can be configured
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 17ef3658f34..87365d5ea2a 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 00000000000..21ec2cb100b
--- /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 00000000000..8d2097d7764
--- /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 00000000000..2e5876ce71f
--- /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 .cap_mixer = 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_beep_mixer },
496 .cap_mixer = alc268_capture_alt_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_beep_mixer },
511 .cap_mixer = alc268_capture_alt_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_beep_mixer },
529 .cap_mixer = alc268_capture_alt_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_beep_mixer },
547 .cap_mixer = alc268_capture_alt_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, alc268_beep_mixer},
565 .cap_mixer = alc268_capture_nosrc_mixer,
566 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
567 alc268_acer_aspire_one_verbs },
568 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
569 .dac_nids = alc268_dac_nids,
570 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
571 .adc_nids = alc268_adc_nids_alt,
572 .capsrc_nids = alc268_capsrc_nids,
573 .hp_nid = 0x03,
574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
575 .channel_mode = alc268_modes,
576 .unsol_event = alc_sku_unsol_event,
577 .setup = alc268_acer_lc_setup,
578 .init_hook = alc_inithook,
579 },
580 [ALC268_DELL] = {
581 .mixers = { alc268_dell_mixer, alc268_beep_mixer},
582 .cap_mixer = alc268_capture_nosrc_mixer,
583 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
584 alc268_dell_verbs },
585 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
586 .dac_nids = alc268_dac_nids,
587 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
588 .adc_nids = alc268_adc_nids_alt,
589 .capsrc_nids = alc268_capsrc_nids,
590 .hp_nid = 0x02,
591 .num_channel_mode = ARRAY_SIZE(alc268_modes),
592 .channel_mode = alc268_modes,
593 .unsol_event = alc_sku_unsol_event,
594 .setup = alc268_dell_setup,
595 .init_hook = alc_inithook,
596 },
597 [ALC268_ZEPTO] = {
598 .mixers = { alc268_base_mixer, alc268_beep_mixer },
599 .cap_mixer = alc268_capture_alt_mixer,
600 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
601 alc268_toshiba_verbs },
602 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
603 .dac_nids = alc268_dac_nids,
604 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
605 .adc_nids = alc268_adc_nids_alt,
606 .capsrc_nids = alc268_capsrc_nids,
607 .hp_nid = 0x03,
608 .dig_out_nid = ALC268_DIGOUT_NID,
609 .num_channel_mode = ARRAY_SIZE(alc268_modes),
610 .channel_mode = alc268_modes,
611 .input_mux = &alc268_capture_source,
612 .unsol_event = alc_sku_unsol_event,
613 .setup = alc268_toshiba_setup,
614 .init_hook = alc_inithook,
615 },
616#ifdef CONFIG_SND_DEBUG
617 [ALC268_TEST] = {
618 .mixers = { alc268_test_mixer },
619 .cap_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 00000000000..9aeeb326460
--- /dev/null
+++ b/sound/pci/hda/alc269_quirks.c
@@ -0,0 +1,688 @@
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, 0x1723, "ASUS P80", ALC269_AMIC),
535 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
536 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
537 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
538 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
539 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
540 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
541 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
542 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
543 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
544 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
545 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
546 {}
547};
548
549static const struct alc_config_preset alc269_presets[] = {
550 [ALC269_BASIC] = {
551 .mixers = { alc269_base_mixer },
552 .init_verbs = { alc269_init_verbs },
553 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
554 .dac_nids = alc269_dac_nids,
555 .hp_nid = 0x03,
556 .num_channel_mode = ARRAY_SIZE(alc269_modes),
557 .channel_mode = alc269_modes,
558 .input_mux = &alc269_capture_source,
559 },
560 [ALC269_QUANTA_FL1] = {
561 .mixers = { alc269_quanta_fl1_mixer },
562 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
563 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
564 .dac_nids = alc269_dac_nids,
565 .hp_nid = 0x03,
566 .num_channel_mode = ARRAY_SIZE(alc269_modes),
567 .channel_mode = alc269_modes,
568 .input_mux = &alc269_capture_source,
569 .unsol_event = alc269_quanta_fl1_unsol_event,
570 .setup = alc269_quanta_fl1_setup,
571 .init_hook = alc269_quanta_fl1_init_hook,
572 },
573 [ALC269_AMIC] = {
574 .mixers = { alc269_laptop_mixer },
575 .cap_mixer = alc269_laptop_analog_capture_mixer,
576 .init_verbs = { alc269_init_verbs,
577 alc269_laptop_amic_init_verbs },
578 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
579 .dac_nids = alc269_dac_nids,
580 .adc_nids = alc269_adc_nids,
581 .capsrc_nids = alc269_capsrc_nids,
582 .num_adc_nids = ARRAY_SIZE(alc269_adc_nids),
583 .hp_nid = 0x03,
584 .num_channel_mode = ARRAY_SIZE(alc269_modes),
585 .channel_mode = alc269_modes,
586 .unsol_event = alc_sku_unsol_event,
587 .setup = alc269_laptop_amic_setup,
588 .init_hook = alc_inithook,
589 },
590 [ALC269_DMIC] = {
591 .mixers = { alc269_laptop_mixer },
592 .cap_mixer = alc269_laptop_digital_capture_mixer,
593 .init_verbs = { alc269_init_verbs,
594 alc269_laptop_dmic_init_verbs },
595 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
596 .dac_nids = alc269_dac_nids,
597 .adc_nids = alc269_adc_nids,
598 .capsrc_nids = alc269_capsrc_nids,
599 .num_adc_nids = ARRAY_SIZE(alc269_adc_nids),
600 .hp_nid = 0x03,
601 .num_channel_mode = ARRAY_SIZE(alc269_modes),
602 .channel_mode = alc269_modes,
603 .unsol_event = alc_sku_unsol_event,
604 .setup = alc269_laptop_dmic_setup,
605 .init_hook = alc_inithook,
606 },
607 [ALC269VB_AMIC] = {
608 .mixers = { alc269vb_laptop_mixer },
609 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
610 .init_verbs = { alc269vb_init_verbs,
611 alc269vb_laptop_amic_init_verbs },
612 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
613 .dac_nids = alc269_dac_nids,
614 .adc_nids = alc269vb_adc_nids,
615 .capsrc_nids = alc269vb_capsrc_nids,
616 .num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids),
617 .hp_nid = 0x03,
618 .num_channel_mode = ARRAY_SIZE(alc269_modes),
619 .channel_mode = alc269_modes,
620 .unsol_event = alc_sku_unsol_event,
621 .setup = alc269vb_laptop_amic_setup,
622 .init_hook = alc_inithook,
623 },
624 [ALC269VB_DMIC] = {
625 .mixers = { alc269vb_laptop_mixer },
626 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
627 .init_verbs = { alc269vb_init_verbs,
628 alc269vb_laptop_dmic_init_verbs },
629 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
630 .dac_nids = alc269_dac_nids,
631 .adc_nids = alc269vb_adc_nids,
632 .capsrc_nids = alc269vb_capsrc_nids,
633 .num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids),
634 .hp_nid = 0x03,
635 .num_channel_mode = ARRAY_SIZE(alc269_modes),
636 .channel_mode = alc269_modes,
637 .unsol_event = alc_sku_unsol_event,
638 .setup = alc269vb_laptop_dmic_setup,
639 .init_hook = alc_inithook,
640 },
641 [ALC269_FUJITSU] = {
642 .mixers = { alc269_fujitsu_mixer },
643 .cap_mixer = alc269_laptop_digital_capture_mixer,
644 .init_verbs = { alc269_init_verbs,
645 alc269_laptop_dmic_init_verbs },
646 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
647 .dac_nids = alc269_dac_nids,
648 .adc_nids = alc269_adc_nids,
649 .capsrc_nids = alc269_capsrc_nids,
650 .hp_nid = 0x03,
651 .num_channel_mode = ARRAY_SIZE(alc269_modes),
652 .channel_mode = alc269_modes,
653 .unsol_event = alc_sku_unsol_event,
654 .setup = alc269_laptop_dmic_setup,
655 .init_hook = alc_inithook,
656 },
657 [ALC269_LIFEBOOK] = {
658 .mixers = { alc269_lifebook_mixer },
659 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
660 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
661 .dac_nids = alc269_dac_nids,
662 .hp_nid = 0x03,
663 .num_channel_mode = ARRAY_SIZE(alc269_modes),
664 .channel_mode = alc269_modes,
665 .input_mux = &alc269_capture_source,
666 .unsol_event = alc269_lifebook_unsol_event,
667 .setup = alc269_lifebook_setup,
668 .init_hook = alc269_lifebook_init_hook,
669 },
670 [ALC271_ACER] = {
671 .mixers = { alc269_asus_mixer },
672 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
673 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
674 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
675 .dac_nids = alc269_dac_nids,
676 .adc_nids = alc262_dmic_adc_nids,
677 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
678 .capsrc_nids = alc262_dmic_capsrc_nids,
679 .num_channel_mode = ARRAY_SIZE(alc269_modes),
680 .channel_mode = alc269_modes,
681 .input_mux = &alc269_capture_source,
682 .dig_out_nid = ALC880_DIGOUT_NID,
683 .unsol_event = alc_sku_unsol_event,
684 .setup = alc269vb_laptop_dmic_setup,
685 .init_hook = alc_inithook,
686 },
687};
688
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c
new file mode 100644
index 00000000000..e69a6ea3083
--- /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 00000000000..0eeb227c7bc
--- /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 00000000000..d719ec6350e
--- /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 00000000000..8f28450f41f
--- /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 00000000000..c844d2b5998
--- /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 00000000000..617d04723b8
--- /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 00000000000..2be1129cf45
--- /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 45b4a8d70e0..91b2e468917 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -91,8 +91,10 @@ EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
91#ifdef CONFIG_SND_HDA_POWER_SAVE 91#ifdef CONFIG_SND_HDA_POWER_SAVE
92static void hda_power_work(struct work_struct *work); 92static void hda_power_work(struct work_struct *work);
93static void hda_keep_power_on(struct hda_codec *codec); 93static void hda_keep_power_on(struct hda_codec *codec);
94#define hda_codec_is_power_on(codec) ((codec)->power_on)
94#else 95#else
95static inline void hda_keep_power_on(struct hda_codec *codec) {} 96static inline void hda_keep_power_on(struct hda_codec *codec) {}
97#define hda_codec_is_power_on(codec) 1
96#endif 98#endif
97 99
98/** 100/**
@@ -243,7 +245,8 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
243{ 245{
244 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm); 246 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
245 unsigned int res; 247 unsigned int res;
246 codec_exec_verb(codec, cmd, &res); 248 if (codec_exec_verb(codec, cmd, &res))
249 return -1;
247 return res; 250 return res;
248} 251}
249EXPORT_SYMBOL_HDA(snd_hda_codec_read); 252EXPORT_SYMBOL_HDA(snd_hda_codec_read);
@@ -307,63 +310,107 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
307} 310}
308EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); 311EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
309 312
310static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 313/* look up the cached results */
311 hda_nid_t *conn_list, int max_conns); 314static 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); 315{
313static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 316 int i, len;
314 hda_nid_t *src, int len); 317 for (i = 0; i < array->used; ) {
318 hda_nid_t *p = snd_array_elem(array, i);
319 if (nid == *p)
320 return p;
321 len = p[1];
322 i += len + 2;
323 }
324 return NULL;
325}
315 326
316/** 327/**
317 * snd_hda_get_connections - get connection list 328 * snd_hda_get_conn_list - get connection list
318 * @codec: the HDA codec 329 * @codec: the HDA codec
319 * @nid: NID to parse 330 * @nid: NID to parse
320 * @conn_list: connection list array 331 * @listp: the pointer to store NID list
321 * @max_conns: max. number of connections to store
322 * 332 *
323 * Parses the connection list of the given widget and stores the list 333 * Parses the connection list of the given widget and stores the list
324 * of NIDs. 334 * of NIDs.
325 * 335 *
326 * Returns the number of connections, or a negative error code. 336 * Returns the number of connections, or a negative error code.
327 */ 337 */
328int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 338int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
329 hda_nid_t *conn_list, int max_conns) 339 const hda_nid_t **listp)
330{ 340{
331 struct snd_array *array = &codec->conn_lists; 341 struct snd_array *array = &codec->conn_lists;
332 int i, len, old_used; 342 int len, err;
333 hda_nid_t list[HDA_MAX_CONNECTIONS]; 343 hda_nid_t list[HDA_MAX_CONNECTIONS];
344 hda_nid_t *p;
345 bool added = false;
334 346
335 /* look up the cached results */ 347 again:
336 for (i = 0; i < array->used; ) { 348 /* if the connection-list is already cached, read it */
337 hda_nid_t *p = snd_array_elem(array, i); 349 p = lookup_conn_list(array, nid);
338 len = p[1]; 350 if (p) {
339 if (nid == *p) 351 if (listp)
340 return copy_conn_list(nid, conn_list, max_conns, 352 *listp = p + 2;
341 p + 2, len); 353 return p[1];
342 i += len + 2;
343 } 354 }
355 if (snd_BUG_ON(added))
356 return -EINVAL;
344 357
345 len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); 358 /* read the connection and add to the cache */
359 len = snd_hda_get_raw_connections(codec, nid, list, HDA_MAX_CONNECTIONS);
346 if (len < 0) 360 if (len < 0)
347 return len; 361 return len;
362 err = snd_hda_override_conn_list(codec, nid, len, list);
363 if (err < 0)
364 return err;
365 added = true;
366 goto again;
367}
368EXPORT_SYMBOL_HDA(snd_hda_get_conn_list);
348 369
349 /* add to the cache */ 370/**
350 old_used = array->used; 371 * snd_hda_get_connections - copy connection list
351 if (!add_conn_list(array, nid) || !add_conn_list(array, len)) 372 * @codec: the HDA codec
352 goto error_add; 373 * @nid: NID to parse
353 for (i = 0; i < len; i++) 374 * @conn_list: connection list array
354 if (!add_conn_list(array, list[i])) 375 * @max_conns: max. number of connections to store
355 goto error_add; 376 *
377 * Parses the connection list of the given widget and stores the list
378 * of NIDs.
379 *
380 * Returns the number of connections, or a negative error code.
381 */
382int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
383 hda_nid_t *conn_list, int max_conns)
384{
385 const hda_nid_t *list;
386 int len = snd_hda_get_conn_list(codec, nid, &list);
356 387
357 return copy_conn_list(nid, conn_list, max_conns, list, len); 388 if (len <= 0)
358 389 return len;
359 error_add: 390 if (len > max_conns) {
360 array->used = old_used; 391 snd_printk(KERN_ERR "hda_codec: "
361 return -ENOMEM; 392 "Too many connections %d for NID 0x%x\n",
393 len, nid);
394 return -EINVAL;
395 }
396 memcpy(conn_list, list, len * sizeof(hda_nid_t));
397 return len;
362} 398}
363EXPORT_SYMBOL_HDA(snd_hda_get_connections); 399EXPORT_SYMBOL_HDA(snd_hda_get_connections);
364 400
365static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 401/**
366 hda_nid_t *conn_list, int max_conns) 402 * snd_hda_get_raw_connections - copy connection list without cache
403 * @codec: the HDA codec
404 * @nid: NID to parse
405 * @conn_list: connection list array
406 * @max_conns: max. number of connections to store
407 *
408 * Like snd_hda_get_connections(), copy the connection list but without
409 * checking through the connection-list cache.
410 * Currently called only from hda_proc.c, so not exported.
411 */
412int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
413 hda_nid_t *conn_list, int max_conns)
367{ 414{
368 unsigned int parm; 415 unsigned int parm;
369 int i, conn_len, conns; 416 int i, conn_len, conns;
@@ -376,11 +423,8 @@ static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
376 423
377 wcaps = get_wcaps(codec, nid); 424 wcaps = get_wcaps(codec, nid);
378 if (!(wcaps & AC_WCAP_CONN_LIST) && 425 if (!(wcaps & AC_WCAP_CONN_LIST) &&
379 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { 426 get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
380 snd_printk(KERN_WARNING "hda_codec: " 427 return 0;
381 "connection list not available for 0x%x\n", nid);
382 return -EINVAL;
383 }
384 428
385 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 429 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
386 if (parm & AC_CLIST_LONG) { 430 if (parm & AC_CLIST_LONG) {
@@ -470,18 +514,81 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
470 return true; 514 return true;
471} 515}
472 516
473static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, 517/**
474 hda_nid_t *src, int len) 518 * snd_hda_override_conn_list - add/modify the connection-list to cache
519 * @codec: the HDA codec
520 * @nid: NID to parse
521 * @len: number of connection list entries
522 * @list: the list of connection entries
523 *
524 * Add or modify the given connection-list to the cache. If the corresponding
525 * cache already exists, invalidate it and append a new one.
526 *
527 * Returns zero or a negative error code.
528 */
529int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
530 const hda_nid_t *list)
475{ 531{
476 if (len > max_dst) { 532 struct snd_array *array = &codec->conn_lists;
477 snd_printk(KERN_ERR "hda_codec: " 533 hda_nid_t *p;
478 "Too many connections %d for NID 0x%x\n", 534 int i, old_used;
479 len, nid); 535
480 return -EINVAL; 536 p = lookup_conn_list(array, nid);
537 if (p)
538 *p = -1; /* invalidate the old entry */
539
540 old_used = array->used;
541 if (!add_conn_list(array, nid) || !add_conn_list(array, len))
542 goto error_add;
543 for (i = 0; i < len; i++)
544 if (!add_conn_list(array, list[i]))
545 goto error_add;
546 return 0;
547
548 error_add:
549 array->used = old_used;
550 return -ENOMEM;
551}
552EXPORT_SYMBOL_HDA(snd_hda_override_conn_list);
553
554/**
555 * snd_hda_get_conn_index - get the connection index of the given NID
556 * @codec: the HDA codec
557 * @mux: NID containing the list
558 * @nid: NID to select
559 * @recursive: 1 when searching NID recursively, otherwise 0
560 *
561 * Parses the connection list of the widget @mux and checks whether the
562 * widget @nid is present. If it is, return the connection index.
563 * Otherwise it returns -1.
564 */
565int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
566 hda_nid_t nid, int recursive)
567{
568 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
569 int i, nums;
570
571 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
572 for (i = 0; i < nums; i++)
573 if (conn[i] == nid)
574 return i;
575 if (!recursive)
576 return -1;
577 if (recursive > 5) {
578 snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
579 return -1;
481 } 580 }
482 memcpy(dst, src, len * sizeof(hda_nid_t)); 581 recursive++;
483 return len; 582 for (i = 0; i < nums; i++) {
583 unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
584 if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
585 continue;
586 if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
587 return i;
588 }
589 return -1;
484} 590}
591EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
485 592
486/** 593/**
487 * snd_hda_queue_unsol_event - add an unsolicited event to queue 594 * snd_hda_queue_unsol_event - add an unsolicited event to queue
@@ -658,7 +765,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
658 765
659 snprintf(bus->workq_name, sizeof(bus->workq_name), 766 snprintf(bus->workq_name, sizeof(bus->workq_name),
660 "hd-audio%d", card->number); 767 "hd-audio%d", card->number);
661 bus->workq = create_singlethread_workqueue(bus->workq_name); 768 bus->workq = create_freezable_workqueue(bus->workq_name);
662 if (!bus->workq) { 769 if (!bus->workq) {
663 snd_printk(KERN_ERR "cannot create workqueue %s\n", 770 snd_printk(KERN_ERR "cannot create workqueue %s\n",
664 bus->workq_name); 771 bus->workq_name);
@@ -1000,7 +1107,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec)
1000} 1107}
1001EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); 1108EXPORT_SYMBOL_HDA(snd_hda_shutup_pins);
1002 1109
1003#ifdef SND_HDA_NEEDS_RESUME 1110#ifdef CONFIG_PM
1004/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ 1111/* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
1005static void restore_shutup_pins(struct hda_codec *codec) 1112static void restore_shutup_pins(struct hda_codec *codec)
1006{ 1113{
@@ -1083,6 +1190,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
1083 snd_array_free(&codec->mixers); 1190 snd_array_free(&codec->mixers);
1084 snd_array_free(&codec->nids); 1191 snd_array_free(&codec->nids);
1085 snd_array_free(&codec->conn_lists); 1192 snd_array_free(&codec->conn_lists);
1193 snd_array_free(&codec->spdif_out);
1086 codec->bus->caddr_tbl[codec->addr] = NULL; 1194 codec->bus->caddr_tbl[codec->addr] = NULL;
1087 if (codec->patch_ops.free) 1195 if (codec->patch_ops.free)
1088 codec->patch_ops.free(codec); 1196 codec->patch_ops.free(codec);
@@ -1144,6 +1252,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
1144 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); 1252 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
1145 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); 1253 snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
1146 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); 1254 snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64);
1255 snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
1147 if (codec->bus->modelname) { 1256 if (codec->bus->modelname) {
1148 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); 1257 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
1149 if (!codec->modelname) { 1258 if (!codec->modelname) {
@@ -1396,7 +1505,7 @@ static void purify_inactive_streams(struct hda_codec *codec)
1396 } 1505 }
1397} 1506}
1398 1507
1399#ifdef SND_HDA_NEEDS_RESUME 1508#ifdef CONFIG_PM
1400/* clean up all streams; called from suspend */ 1509/* clean up all streams; called from suspend */
1401static void hda_cleanup_all_streams(struct hda_codec *codec) 1510static void hda_cleanup_all_streams(struct hda_codec *codec)
1402{ 1511{
@@ -1735,7 +1844,7 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1735} 1844}
1736EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo); 1845EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
1737 1846
1738#ifdef SND_HDA_NEEDS_RESUME 1847#ifdef CONFIG_PM
1739/** 1848/**
1740 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache 1849 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
1741 * @codec: HD-audio codec 1850 * @codec: HD-audio codec
@@ -1765,7 +1874,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
1765 } 1874 }
1766} 1875}
1767EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp); 1876EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
1768#endif /* SND_HDA_NEEDS_RESUME */ 1877#endif /* CONFIG_PM */
1769 1878
1770static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir, 1879static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
1771 unsigned int ofs) 1880 unsigned int ofs)
@@ -2187,6 +2296,39 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2187 return 0; 2296 return 0;
2188} 2297}
2189 2298
2299typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *);
2300
2301/* apply the function to all matching slave ctls in the mixer list */
2302static int map_slaves(struct hda_codec *codec, const char * const *slaves,
2303 map_slave_func_t func, void *data)
2304{
2305 struct hda_nid_item *items;
2306 const char * const *s;
2307 int i, err;
2308
2309 items = codec->mixers.list;
2310 for (i = 0; i < codec->mixers.used; i++) {
2311 struct snd_kcontrol *sctl = items[i].kctl;
2312 if (!sctl || !sctl->id.name ||
2313 sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
2314 continue;
2315 for (s = slaves; *s; s++) {
2316 if (!strcmp(sctl->id.name, *s)) {
2317 err = func(data, sctl);
2318 if (err)
2319 return err;
2320 break;
2321 }
2322 }
2323 }
2324 return 0;
2325}
2326
2327static int check_slave_present(void *data, struct snd_kcontrol *sctl)
2328{
2329 return 1;
2330}
2331
2190/** 2332/**
2191 * snd_hda_add_vmaster - create a virtual master control and add slaves 2333 * snd_hda_add_vmaster - create a virtual master control and add slaves
2192 * @codec: HD-audio codec 2334 * @codec: HD-audio codec
@@ -2207,12 +2349,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2207 unsigned int *tlv, const char * const *slaves) 2349 unsigned int *tlv, const char * const *slaves)
2208{ 2350{
2209 struct snd_kcontrol *kctl; 2351 struct snd_kcontrol *kctl;
2210 const char * const *s;
2211 int err; 2352 int err;
2212 2353
2213 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) 2354 err = map_slaves(codec, slaves, check_slave_present, NULL);
2214 ; 2355 if (err != 1) {
2215 if (!*s) {
2216 snd_printdd("No slave found for %s\n", name); 2356 snd_printdd("No slave found for %s\n", name);
2217 return 0; 2357 return 0;
2218 } 2358 }
@@ -2223,23 +2363,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2223 if (err < 0) 2363 if (err < 0)
2224 return err; 2364 return err;
2225 2365
2226 for (s = slaves; *s; s++) { 2366 err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave,
2227 struct snd_kcontrol *sctl; 2367 kctl);
2228 int i = 0; 2368 if (err < 0)
2229 for (;;) { 2369 return err;
2230 sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
2231 if (!sctl) {
2232 if (!i)
2233 snd_printdd("Cannot find slave %s, "
2234 "skipped\n", *s);
2235 break;
2236 }
2237 err = snd_ctl_add_slave(kctl, sctl);
2238 if (err < 0)
2239 return err;
2240 i++;
2241 }
2242 }
2243 return 0; 2370 return 0;
2244} 2371}
2245EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); 2372EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
@@ -2555,11 +2682,13 @@ static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2555 struct snd_ctl_elem_value *ucontrol) 2682 struct snd_ctl_elem_value *ucontrol)
2556{ 2683{
2557 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2684 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2685 int idx = kcontrol->private_value;
2686 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2558 2687
2559 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff; 2688 ucontrol->value.iec958.status[0] = spdif->status & 0xff;
2560 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff; 2689 ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
2561 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff; 2690 ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
2562 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff; 2691 ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
2563 2692
2564 return 0; 2693 return 0;
2565} 2694}
@@ -2644,23 +2773,23 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2644 struct snd_ctl_elem_value *ucontrol) 2773 struct snd_ctl_elem_value *ucontrol)
2645{ 2774{
2646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2775 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2647 hda_nid_t nid = kcontrol->private_value; 2776 int idx = kcontrol->private_value;
2777 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2778 hda_nid_t nid = spdif->nid;
2648 unsigned short val; 2779 unsigned short val;
2649 int change; 2780 int change;
2650 2781
2651 mutex_lock(&codec->spdif_mutex); 2782 mutex_lock(&codec->spdif_mutex);
2652 codec->spdif_status = ucontrol->value.iec958.status[0] | 2783 spdif->status = ucontrol->value.iec958.status[0] |
2653 ((unsigned int)ucontrol->value.iec958.status[1] << 8) | 2784 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2654 ((unsigned int)ucontrol->value.iec958.status[2] << 16) | 2785 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2655 ((unsigned int)ucontrol->value.iec958.status[3] << 24); 2786 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2656 val = convert_from_spdif_status(codec->spdif_status); 2787 val = convert_from_spdif_status(spdif->status);
2657 val |= codec->spdif_ctls & 1; 2788 val |= spdif->ctls & 1;
2658 change = codec->spdif_ctls != val; 2789 change = spdif->ctls != val;
2659 codec->spdif_ctls = val; 2790 spdif->ctls = val;
2660 2791 if (change && nid != (u16)-1)
2661 if (change)
2662 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff); 2792 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
2663
2664 mutex_unlock(&codec->spdif_mutex); 2793 mutex_unlock(&codec->spdif_mutex);
2665 return change; 2794 return change;
2666} 2795}
@@ -2671,37 +2800,65 @@ static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2671 struct snd_ctl_elem_value *ucontrol) 2800 struct snd_ctl_elem_value *ucontrol)
2672{ 2801{
2673 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2802 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2803 int idx = kcontrol->private_value;
2804 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2674 2805
2675 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; 2806 ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
2676 return 0; 2807 return 0;
2677} 2808}
2678 2809
2810static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
2811 int dig1, int dig2)
2812{
2813 set_dig_out_convert(codec, nid, dig1, dig2);
2814 /* unmute amp switch (if any) */
2815 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2816 (dig1 & AC_DIG1_ENABLE))
2817 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2818 HDA_AMP_MUTE, 0);
2819}
2820
2679static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, 2821static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2680 struct snd_ctl_elem_value *ucontrol) 2822 struct snd_ctl_elem_value *ucontrol)
2681{ 2823{
2682 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2824 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2683 hda_nid_t nid = kcontrol->private_value; 2825 int idx = kcontrol->private_value;
2826 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2827 hda_nid_t nid = spdif->nid;
2684 unsigned short val; 2828 unsigned short val;
2685 int change; 2829 int change;
2686 2830
2687 mutex_lock(&codec->spdif_mutex); 2831 mutex_lock(&codec->spdif_mutex);
2688 val = codec->spdif_ctls & ~AC_DIG1_ENABLE; 2832 val = spdif->ctls & ~AC_DIG1_ENABLE;
2689 if (ucontrol->value.integer.value[0]) 2833 if (ucontrol->value.integer.value[0])
2690 val |= AC_DIG1_ENABLE; 2834 val |= AC_DIG1_ENABLE;
2691 change = codec->spdif_ctls != val; 2835 change = spdif->ctls != val;
2692 if (change) { 2836 spdif->ctls = val;
2693 codec->spdif_ctls = val; 2837 if (change && nid != (u16)-1)
2694 set_dig_out_convert(codec, nid, val & 0xff, -1); 2838 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); 2839 mutex_unlock(&codec->spdif_mutex);
2702 return change; 2840 return change;
2703} 2841}
2704 2842
2843int snd_hda_hdmi_decode_info(struct snd_kcontrol *kcontrol,
2844 struct snd_ctl_elem_info *uinfo)
2845{
2846 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2847 uinfo->count = 1;
2848 uinfo->value.integer.min = 0;
2849 uinfo->value.integer.max = 0xFFFFFFFF;
2850 return 0;
2851}
2852
2853static int snd_hda_hdmi_decode_get(struct snd_kcontrol *kcontrol,
2854 struct snd_ctl_elem_value *ucontrol)
2855{
2856 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2857
2858 ucontrol->value.integer.value[0] = codec->recv_dec_cap;
2859 return 0;
2860}
2861
2705static struct snd_kcontrol_new dig_mixes[] = { 2862static struct snd_kcontrol_new dig_mixes[] = {
2706 { 2863 {
2707 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2864 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -2731,6 +2888,12 @@ static struct snd_kcontrol_new dig_mixes[] = {
2731 .get = snd_hda_spdif_out_switch_get, 2888 .get = snd_hda_spdif_out_switch_get,
2732 .put = snd_hda_spdif_out_switch_put, 2889 .put = snd_hda_spdif_out_switch_put,
2733 }, 2890 },
2891 {
2892 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2893 .name = "HDA Decode Capability",
2894 .info = snd_hda_hdmi_decode_info,
2895 .get = snd_hda_hdmi_decode_get,
2896 },
2734 { } /* end */ 2897 { } /* end */
2735}; 2898};
2736 2899
@@ -2744,36 +2907,79 @@ static struct snd_kcontrol_new dig_mixes[] = {
2744 * 2907 *
2745 * Returns 0 if successful, or a negative error code. 2908 * Returns 0 if successful, or a negative error code.
2746 */ 2909 */
2747int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) 2910int snd_hda_create_spdif_out_ctls(struct hda_codec *codec,
2911 hda_nid_t associated_nid,
2912 hda_nid_t cvt_nid)
2748{ 2913{
2749 int err; 2914 int err;
2750 struct snd_kcontrol *kctl; 2915 struct snd_kcontrol *kctl;
2751 struct snd_kcontrol_new *dig_mix; 2916 struct snd_kcontrol_new *dig_mix;
2752 int idx; 2917 int idx;
2918 struct hda_spdif_out *spdif;
2753 2919
2754 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); 2920 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2755 if (idx < 0) { 2921 if (idx < 0) {
2756 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2922 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2757 return -EBUSY; 2923 return -EBUSY;
2758 } 2924 }
2925 spdif = snd_array_new(&codec->spdif_out);
2759 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 2926 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2760 kctl = snd_ctl_new1(dig_mix, codec); 2927 kctl = snd_ctl_new1(dig_mix, codec);
2761 if (!kctl) 2928 if (!kctl)
2762 return -ENOMEM; 2929 return -ENOMEM;
2763 kctl->id.index = idx; 2930 kctl->id.index = idx;
2764 kctl->private_value = nid; 2931 kctl->private_value = codec->spdif_out.used - 1;
2765 err = snd_hda_ctl_add(codec, nid, kctl); 2932 err = snd_hda_ctl_add(codec, associated_nid, kctl);
2766 if (err < 0) 2933 if (err < 0)
2767 return err; 2934 return err;
2768 } 2935 }
2769 codec->spdif_ctls = 2936 spdif->nid = cvt_nid;
2770 snd_hda_codec_read(codec, nid, 0, 2937 spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0,
2771 AC_VERB_GET_DIGI_CONVERT_1, 0); 2938 AC_VERB_GET_DIGI_CONVERT_1, 0);
2772 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 2939 spdif->status = convert_to_spdif_status(spdif->ctls);
2773 return 0; 2940 return 0;
2774} 2941}
2775EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls); 2942EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
2776 2943
2944struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
2945 hda_nid_t nid)
2946{
2947 int i;
2948 for (i = 0; i < codec->spdif_out.used; i++) {
2949 struct hda_spdif_out *spdif =
2950 snd_array_elem(&codec->spdif_out, i);
2951 if (spdif->nid == nid)
2952 return spdif;
2953 }
2954 return NULL;
2955}
2956EXPORT_SYMBOL_HDA(snd_hda_spdif_out_of_nid);
2957
2958void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
2959{
2960 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2961
2962 mutex_lock(&codec->spdif_mutex);
2963 spdif->nid = (u16)-1;
2964 mutex_unlock(&codec->spdif_mutex);
2965}
2966EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_unassign);
2967
2968void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
2969{
2970 struct hda_spdif_out *spdif = snd_array_elem(&codec->spdif_out, idx);
2971 unsigned short val;
2972
2973 mutex_lock(&codec->spdif_mutex);
2974 if (spdif->nid != nid) {
2975 spdif->nid = nid;
2976 val = spdif->ctls;
2977 set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
2978 }
2979 mutex_unlock(&codec->spdif_mutex);
2980}
2981EXPORT_SYMBOL_HDA(snd_hda_spdif_ctls_assign);
2982
2777/* 2983/*
2778 * SPDIF sharing with analog output 2984 * SPDIF sharing with analog output
2779 */ 2985 */
@@ -2925,7 +3131,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2925} 3131}
2926EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls); 3132EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
2927 3133
2928#ifdef SND_HDA_NEEDS_RESUME 3134#ifdef CONFIG_PM
2929/* 3135/*
2930 * command cache 3136 * command cache
2931 */ 3137 */
@@ -3042,53 +3248,32 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
3042 seq->param); 3248 seq->param);
3043} 3249}
3044EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache); 3250EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
3045#endif /* SND_HDA_NEEDS_RESUME */ 3251#endif /* CONFIG_PM */
3046 3252
3047/* 3253void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
3048 * set power state of the codec 3254 unsigned int power_state,
3049 */ 3255 bool eapd_workaround)
3050static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3051 unsigned int power_state)
3052{ 3256{
3053 hda_nid_t nid; 3257 hda_nid_t nid = codec->start_nid;
3054 int i; 3258 int i;
3055 3259
3056 /* this delay seems necessary to avoid click noise at power-down */
3057 if (power_state == AC_PWRST_D3)
3058 msleep(100);
3059 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3060 power_state);
3061 /* partial workaround for "azx_get_response timeout" */
3062 if (power_state == AC_PWRST_D0 &&
3063 (codec->vendor_id & 0xffff0000) == 0x14f10000)
3064 msleep(10);
3065
3066 nid = codec->start_nid;
3067 for (i = 0; i < codec->num_nodes; i++, nid++) { 3260 for (i = 0; i < codec->num_nodes; i++, nid++) {
3068 unsigned int wcaps = get_wcaps(codec, nid); 3261 unsigned int wcaps = get_wcaps(codec, nid);
3069 if (wcaps & AC_WCAP_POWER) { 3262 if (!(wcaps & AC_WCAP_POWER))
3070 unsigned int wid_type = get_wcaps_type(wcaps); 3263 continue;
3071 if (power_state == AC_PWRST_D3 && 3264 /* don't power down the widget if it controls eapd and
3072 wid_type == AC_WID_PIN) { 3265 * EAPD_BTLENABLE is set.
3073 unsigned int pincap; 3266 */
3074 /* 3267 if (eapd_workaround && power_state == AC_PWRST_D3 &&
3075 * don't power down the widget if it controls 3268 get_wcaps_type(wcaps) == AC_WID_PIN &&
3076 * eapd and EAPD_BTLENABLE is set. 3269 (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
3077 */ 3270 int eapd = snd_hda_codec_read(codec, nid, 0,
3078 pincap = snd_hda_query_pin_caps(codec, nid);
3079 if (pincap & AC_PINCAP_EAPD) {
3080 int eapd = snd_hda_codec_read(codec,
3081 nid, 0,
3082 AC_VERB_GET_EAPD_BTLENABLE, 0); 3271 AC_VERB_GET_EAPD_BTLENABLE, 0);
3083 eapd &= 0x02; 3272 if (eapd & 0x02)
3084 if (eapd) 3273 continue;
3085 continue;
3086 }
3087 }
3088 snd_hda_codec_write(codec, nid, 0,
3089 AC_VERB_SET_POWER_STATE,
3090 power_state);
3091 } 3274 }
3275 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
3276 power_state);
3092 } 3277 }
3093 3278
3094 if (power_state == AC_PWRST_D0) { 3279 if (power_state == AC_PWRST_D0) {
@@ -3101,10 +3286,30 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3101 AC_VERB_GET_POWER_STATE, 0); 3286 AC_VERB_GET_POWER_STATE, 0);
3102 if (state == power_state) 3287 if (state == power_state)
3103 break; 3288 break;
3104 msleep(1); 3289 mdelay(1);
3105 } while (time_after_eq(end_time, jiffies)); 3290 } while (time_after_eq(end_time, jiffies));
3106 } 3291 }
3107} 3292}
3293EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
3294
3295/*
3296 * set power state of the codec
3297 */
3298static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3299 unsigned int power_state)
3300{
3301 if (codec->patch_ops.set_power_state) {
3302 codec->patch_ops.set_power_state(codec, fg, power_state);
3303 return;
3304 }
3305
3306 /* this delay seems necessary to avoid click noise at power-down */
3307 if (power_state == AC_PWRST_D3)
3308 msleep(100);
3309 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3310 power_state);
3311 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
3312}
3108 3313
3109#ifdef CONFIG_SND_HDA_HWDEP 3314#ifdef CONFIG_SND_HDA_HWDEP
3110/* execute additional init verbs */ 3315/* execute additional init verbs */
@@ -3117,7 +3322,7 @@ static void hda_exec_init_verbs(struct hda_codec *codec)
3117static inline void hda_exec_init_verbs(struct hda_codec *codec) {} 3322static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
3118#endif 3323#endif
3119 3324
3120#ifdef SND_HDA_NEEDS_RESUME 3325#ifdef CONFIG_PM
3121/* 3326/*
3122 * call suspend and power-down; used both from PM and power-save 3327 * call suspend and power-down; used both from PM and power-save
3123 */ 3328 */
@@ -3158,7 +3363,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3158 snd_hda_codec_resume_cache(codec); 3363 snd_hda_codec_resume_cache(codec);
3159 } 3364 }
3160} 3365}
3161#endif /* SND_HDA_NEEDS_RESUME */ 3366#endif /* CONFIG_PM */
3162 3367
3163 3368
3164/** 3369/**
@@ -3356,7 +3561,7 @@ static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
3356 * 3561 *
3357 * Returns 0 if successful, otherwise a negative error code. 3562 * Returns 0 if successful, otherwise a negative error code.
3358 */ 3563 */
3359static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 3564int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3360 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 3565 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
3361{ 3566{
3362 unsigned int i, val, wcaps; 3567 unsigned int i, val, wcaps;
@@ -3448,6 +3653,7 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
3448 3653
3449 return 0; 3654 return 0;
3450} 3655}
3656EXPORT_SYMBOL_HDA(snd_hda_query_supported_pcm);
3451 3657
3452/** 3658/**
3453 * snd_hda_is_supported_format - Check the validity of the format 3659 * snd_hda_is_supported_format - Check the validity of the format
@@ -3913,9 +4119,6 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
3913EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls); 4119EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
3914 4120
3915#ifdef CONFIG_SND_HDA_POWER_SAVE 4121#ifdef CONFIG_SND_HDA_POWER_SAVE
3916static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3917 unsigned int power_state);
3918
3919static void hda_power_work(struct work_struct *work) 4122static void hda_power_work(struct work_struct *work)
3920{ 4123{
3921 struct hda_codec *codec = 4124 struct hda_codec *codec =
@@ -4177,10 +4380,12 @@ EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
4177static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, 4380static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4178 unsigned int stream_tag, unsigned int format) 4381 unsigned int stream_tag, unsigned int format)
4179{ 4382{
4383 struct hda_spdif_out *spdif = snd_hda_spdif_out_of_nid(codec, nid);
4384
4180 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 4385 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
4181 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4386 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4182 set_dig_out_convert(codec, nid, 4387 set_dig_out_convert(codec, nid,
4183 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 4388 spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
4184 -1); 4389 -1);
4185 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 4390 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
4186 if (codec->slave_dig_outs) { 4391 if (codec->slave_dig_outs) {
@@ -4190,9 +4395,9 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
4190 format); 4395 format);
4191 } 4396 }
4192 /* turn on again (if needed) */ 4397 /* turn on again (if needed) */
4193 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 4398 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
4194 set_dig_out_convert(codec, nid, 4399 set_dig_out_convert(codec, nid,
4195 codec->spdif_ctls & 0xff, -1); 4400 spdif->ctls & 0xff, -1);
4196} 4401}
4197 4402
4198static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) 4403static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
@@ -4216,11 +4421,8 @@ void snd_hda_bus_reboot_notify(struct hda_bus *bus)
4216 if (!bus) 4421 if (!bus)
4217 return; 4422 return;
4218 list_for_each_entry(codec, &bus->codec_list, list) { 4423 list_for_each_entry(codec, &bus->codec_list, list) {
4219#ifdef CONFIG_SND_HDA_POWER_SAVE 4424 if (hda_codec_is_power_on(codec) &&
4220 if (!codec->power_on) 4425 codec->patch_ops.reboot_notify)
4221 continue;
4222#endif
4223 if (codec->patch_ops.reboot_notify)
4224 codec->patch_ops.reboot_notify(codec); 4426 codec->patch_ops.reboot_notify(codec);
4225 } 4427 }
4226} 4428}
@@ -4348,6 +4550,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4348{ 4550{
4349 const hda_nid_t *nids = mout->dac_nids; 4551 const hda_nid_t *nids = mout->dac_nids;
4350 int chs = substream->runtime->channels; 4552 int chs = substream->runtime->channels;
4553 struct hda_spdif_out *spdif =
4554 snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
4351 int i; 4555 int i;
4352 4556
4353 mutex_lock(&codec->spdif_mutex); 4557 mutex_lock(&codec->spdif_mutex);
@@ -4356,7 +4560,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
4356 if (chs == 2 && 4560 if (chs == 2 &&
4357 snd_hda_is_supported_format(codec, mout->dig_out_nid, 4561 snd_hda_is_supported_format(codec, mout->dig_out_nid,
4358 format) && 4562 format) &&
4359 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 4563 !(spdif->status & IEC958_AES0_NONAUDIO)) {
4360 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 4564 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
4361 setup_dig_out_stream(codec, mout->dig_out_nid, 4565 setup_dig_out_stream(codec, mout->dig_out_nid,
4362 stream_tag, format); 4566 stream_tag, format);
@@ -4528,7 +4732,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4528 unsigned int wid_caps = get_wcaps(codec, nid); 4732 unsigned int wid_caps = get_wcaps(codec, nid);
4529 unsigned int wid_type = get_wcaps_type(wid_caps); 4733 unsigned int wid_type = get_wcaps_type(wid_caps);
4530 unsigned int def_conf; 4734 unsigned int def_conf;
4531 short assoc, loc; 4735 short assoc, loc, conn, dev;
4532 4736
4533 /* read all default configuration for pin complex */ 4737 /* read all default configuration for pin complex */
4534 if (wid_type != AC_WID_PIN) 4738 if (wid_type != AC_WID_PIN)
@@ -4538,10 +4742,19 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4538 continue; 4742 continue;
4539 4743
4540 def_conf = snd_hda_codec_get_pincfg(codec, nid); 4744 def_conf = snd_hda_codec_get_pincfg(codec, nid);
4541 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 4745 conn = get_defcfg_connect(def_conf);
4746 if (conn == AC_JACK_PORT_NONE)
4542 continue; 4747 continue;
4543 loc = get_defcfg_location(def_conf); 4748 loc = get_defcfg_location(def_conf);
4544 switch (get_defcfg_device(def_conf)) { 4749 dev = get_defcfg_device(def_conf);
4750
4751 /* workaround for buggy BIOS setups */
4752 if (dev == AC_JACK_LINE_OUT) {
4753 if (conn == AC_JACK_PORT_FIXED)
4754 dev = AC_JACK_SPEAKER;
4755 }
4756
4757 switch (dev) {
4545 case AC_JACK_LINE_OUT: 4758 case AC_JACK_LINE_OUT:
4546 seq = get_defcfg_sequence(def_conf); 4759 seq = get_defcfg_sequence(def_conf);
4547 assoc = get_defcfg_association(def_conf); 4760 assoc = get_defcfg_association(def_conf);
@@ -4908,11 +5121,10 @@ int snd_hda_suspend(struct hda_bus *bus)
4908 struct hda_codec *codec; 5121 struct hda_codec *codec;
4909 5122
4910 list_for_each_entry(codec, &bus->codec_list, list) { 5123 list_for_each_entry(codec, &bus->codec_list, list) {
4911#ifdef CONFIG_SND_HDA_POWER_SAVE 5124 if (hda_codec_is_power_on(codec))
4912 if (!codec->power_on) 5125 hda_call_codec_suspend(codec);
4913 continue; 5126 if (codec->patch_ops.post_suspend)
4914#endif 5127 codec->patch_ops.post_suspend(codec);
4915 hda_call_codec_suspend(codec);
4916 } 5128 }
4917 return 0; 5129 return 0;
4918} 5130}
@@ -4932,6 +5144,8 @@ int snd_hda_resume(struct hda_bus *bus)
4932 struct hda_codec *codec; 5144 struct hda_codec *codec;
4933 5145
4934 list_for_each_entry(codec, &bus->codec_list, list) { 5146 list_for_each_entry(codec, &bus->codec_list, list) {
5147 if (codec->patch_ops.pre_resume)
5148 codec->patch_ops.pre_resume(codec);
4935 if (snd_hda_codec_needs_resume(codec)) 5149 if (snd_hda_codec_needs_resume(codec))
4936 hda_call_codec_resume(codec); 5150 hda_call_codec_resume(codec);
4937 } 5151 }
@@ -4957,17 +5171,15 @@ void *snd_array_new(struct snd_array *array)
4957{ 5171{
4958 if (array->used >= array->alloced) { 5172 if (array->used >= array->alloced) {
4959 int num = array->alloced + array->alloc_align; 5173 int num = array->alloced + array->alloc_align;
5174 int size = (num + 1) * array->elem_size;
5175 int oldsize = array->alloced * array->elem_size;
4960 void *nlist; 5176 void *nlist;
4961 if (snd_BUG_ON(num >= 4096)) 5177 if (snd_BUG_ON(num >= 4096))
4962 return NULL; 5178 return NULL;
4963 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL); 5179 nlist = krealloc(array->list, size, GFP_KERNEL);
4964 if (!nlist) 5180 if (!nlist)
4965 return NULL; 5181 return NULL;
4966 if (array->list) { 5182 memset(nlist + oldsize, 0, size - oldsize);
4967 memcpy(nlist, array->list,
4968 array->elem_size * array->alloced);
4969 kfree(array->list);
4970 }
4971 array->list = nlist; 5183 array->list = nlist;
4972 array->alloced = num; 5184 array->alloced = num;
4973 } 5185 }
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 59c97306c1d..1c5dc6d73d6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -21,15 +21,13 @@
21#ifndef __SOUND_HDA_CODEC_H 21#ifndef __SOUND_HDA_CODEC_H
22#define __SOUND_HDA_CODEC_H 22#define __SOUND_HDA_CODEC_H
23 23
24#include <linux/platform_device.h>
25
24#include <sound/info.h> 26#include <sound/info.h>
25#include <sound/control.h> 27#include <sound/control.h>
26#include <sound/pcm.h> 28#include <sound/pcm.h>
27#include <sound/hwdep.h> 29#include <sound/hwdep.h>
28 30
29#if defined(CONFIG_PM) || defined(CONFIG_SND_HDA_POWER_SAVE)
30#define SND_HDA_NEEDS_RESUME /* resume control code is required */
31#endif
32
33/* 31/*
34 * nodes 32 * nodes
35 */ 33 */
@@ -621,6 +619,7 @@ struct hda_bus_ops {
621struct hda_bus_template { 619struct hda_bus_template {
622 void *private_data; 620 void *private_data;
623 struct pci_dev *pci; 621 struct pci_dev *pci;
622 struct platform_device *pdev;
624 const char *modelname; 623 const char *modelname;
625 int *power_save; 624 int *power_save;
626 struct hda_bus_ops ops; 625 struct hda_bus_ops ops;
@@ -704,8 +703,12 @@ struct hda_codec_ops {
704 int (*init)(struct hda_codec *codec); 703 int (*init)(struct hda_codec *codec);
705 void (*free)(struct hda_codec *codec); 704 void (*free)(struct hda_codec *codec);
706 void (*unsol_event)(struct hda_codec *codec, unsigned int res); 705 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
707#ifdef SND_HDA_NEEDS_RESUME 706 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
707 unsigned int power_state);
708#ifdef CONFIG_PM
708 int (*suspend)(struct hda_codec *codec, pm_message_t state); 709 int (*suspend)(struct hda_codec *codec, pm_message_t state);
710 int (*post_suspend)(struct hda_codec *codec);
711 int (*pre_resume)(struct hda_codec *codec);
709 int (*resume)(struct hda_codec *codec); 712 int (*resume)(struct hda_codec *codec);
710#endif 713#endif
711#ifdef CONFIG_SND_HDA_POWER_SAVE 714#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -829,8 +832,7 @@ struct hda_codec {
829 832
830 struct mutex spdif_mutex; 833 struct mutex spdif_mutex;
831 struct mutex control_mutex; 834 struct mutex control_mutex;
832 unsigned int spdif_status; /* IEC958 status bits */ 835 struct snd_array spdif_out;
833 unsigned short spdif_ctls; /* SPDIF control bits */
834 unsigned int spdif_in_enable; /* SPDIF input enable? */ 836 unsigned int spdif_in_enable; /* SPDIF input enable? */
835 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 837 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
836 struct snd_array init_pins; /* initial (BIOS) pin configurations */ 838 struct snd_array init_pins; /* initial (BIOS) pin configurations */
@@ -865,6 +867,7 @@ struct hda_codec {
865 unsigned long power_jiffies; 867 unsigned long power_jiffies;
866#endif 868#endif
867 869
870 unsigned int recv_dec_cap;
868 /* codec-specific additional proc output */ 871 /* codec-specific additional proc output */
869 void (*proc_widget_hook)(struct snd_info_buffer *buffer, 872 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
870 struct hda_codec *codec, hda_nid_t nid); 873 struct hda_codec *codec, hda_nid_t nid);
@@ -904,6 +907,16 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
904 hda_nid_t *start_id); 907 hda_nid_t *start_id);
905int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, 908int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
906 hda_nid_t *conn_list, int max_conns); 909 hda_nid_t *conn_list, int max_conns);
910int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
911 hda_nid_t *conn_list, int max_conns);
912int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
913 const hda_nid_t **listp);
914int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
915 const hda_nid_t *list);
916int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
917 hda_nid_t nid, int recursive);
918int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
919 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
907 920
908struct hda_verb { 921struct hda_verb {
909 hda_nid_t nid; 922 hda_nid_t nid;
@@ -918,7 +931,7 @@ void snd_hda_sequence_write(struct hda_codec *codec,
918int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex); 931int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex);
919 932
920/* cached write */ 933/* cached write */
921#ifdef SND_HDA_NEEDS_RESUME 934#ifdef CONFIG_PM
922int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 935int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
923 int direct, unsigned int verb, unsigned int parm); 936 int direct, unsigned int verb, unsigned int parm);
924void snd_hda_sequence_write_cache(struct hda_codec *codec, 937void snd_hda_sequence_write_cache(struct hda_codec *codec,
@@ -947,6 +960,17 @@ int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
947 hda_nid_t nid, unsigned int cfg); /* for hwdep */ 960 hda_nid_t nid, unsigned int cfg); /* for hwdep */
948void snd_hda_shutup_pins(struct hda_codec *codec); 961void snd_hda_shutup_pins(struct hda_codec *codec);
949 962
963/* SPDIF controls */
964struct hda_spdif_out {
965 hda_nid_t nid; /* Converter nid values relate to */
966 unsigned int status; /* IEC958 status bits */
967 unsigned short ctls; /* SPDIF control bits */
968};
969struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
970 hda_nid_t nid);
971void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
972void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
973
950/* 974/*
951 * Mixer 975 * Mixer
952 */ 976 */
@@ -988,6 +1012,9 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
988 */ 1012 */
989void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); 1013void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
990void snd_hda_bus_reboot_notify(struct hda_bus *bus); 1014void snd_hda_bus_reboot_notify(struct hda_bus *bus);
1015void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
1016 unsigned int power_state,
1017 bool eapd_workaround);
991 1018
992/* 1019/*
993 * power management 1020 * power management
@@ -997,17 +1024,15 @@ int snd_hda_suspend(struct hda_bus *bus);
997int snd_hda_resume(struct hda_bus *bus); 1024int snd_hda_resume(struct hda_bus *bus);
998#endif 1025#endif
999 1026
1000#ifdef CONFIG_SND_HDA_POWER_SAVE
1001static inline 1027static inline
1002int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid) 1028int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1003{ 1029{
1030#ifdef CONFIG_SND_HDA_POWER_SAVE
1004 if (codec->patch_ops.check_power_status) 1031 if (codec->patch_ops.check_power_status)
1005 return codec->patch_ops.check_power_status(codec, nid); 1032 return codec->patch_ops.check_power_status(codec, nid);
1033#endif
1006 return 0; 1034 return 0;
1007} 1035}
1008#else
1009#define hda_call_check_power_status(codec, nid) 0
1010#endif
1011 1036
1012/* 1037/*
1013 * get widget information 1038 * get widget information
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index e3e853153d1..ad760f90053 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -144,17 +144,25 @@ static int cea_sampling_frequencies[8] = {
144 SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ 144 SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
145}; 145};
146 146
147static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, 147static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
148 int byte_index) 148 int byte_index)
149{ 149{
150 unsigned int val; 150 unsigned int val;
151 151
152 val = snd_hda_codec_read(codec, nid, 0, 152 val = snd_hda_codec_read(codec, nid, 0,
153 AC_VERB_GET_HDMI_ELDD, byte_index); 153 AC_VERB_GET_HDMI_ELDD, byte_index);
154
155#ifdef BE_PARANOID 154#ifdef BE_PARANOID
156 printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); 155 printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
157#endif 156#endif
157 return val;
158}
159
160static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
161 int byte_index)
162{
163 unsigned int val;
164
165 val = hdmi_get_eld_data(codec, nid, byte_index);
158 166
159 if ((val & AC_ELDD_ELD_VALID) == 0) { 167 if ((val & AC_ELDD_ELD_VALID) == 0) {
160 snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", 168 snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
@@ -305,6 +313,79 @@ static int hdmi_update_eld(struct hdmi_eld *e,
305 buf + ELD_FIXED_BYTES + mnl + 3 * i); 313 buf + ELD_FIXED_BYTES + mnl + 3 * i);
306 } 314 }
307 315
316 e->eld_valid = true;
317 return 0;
318
319out_fail:
320 return -EINVAL;
321}
322
323#define GET_BITS(val, lowbit, bits) \
324({ \
325 BUILD_BUG_ON(lowbit > 7); \
326 BUILD_BUG_ON(bits > 8); \
327 BUILD_BUG_ON(bits <= 0); \
328 \
329 (val >> (lowbit)) & ((1 << (bits)) - 1); \
330})
331
332/* update ELD information relevant for getting PCM info */
333static int hdmi_update_lpcm_sad_eld (struct hda_codec *codec, hda_nid_t nid,
334 struct hdmi_eld *e, int size)
335{
336 int i, j;
337 u32 val, sad_base;
338 struct cea_sad *a;
339
340 val = hdmi_get_eld_byte(codec, nid, 0);
341 e->eld_ver = GET_BITS(val, 3, 5);
342 if (e->eld_ver != ELD_VER_CEA_861D &&
343 e->eld_ver != ELD_VER_PARTIAL) {
344 snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
345 e->eld_ver);
346 goto out_fail;
347 }
348
349 val = hdmi_get_eld_byte(codec, nid, 4);
350 sad_base = GET_BITS(val, 0, 5);
351 sad_base += ELD_FIXED_BYTES;
352
353 val = hdmi_get_eld_byte(codec, nid, 5);
354 e->sad_count = GET_BITS(val, 4, 4);
355
356 for (i = 0; i < e->sad_count; i++, sad_base += 3) {
357 if ((sad_base + 3) > size) {
358 snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
359 goto out_fail;
360 }
361 a = &e->sad[i];
362
363 val = hdmi_get_eld_byte(codec, nid, sad_base);
364 a->format = GET_BITS(val, 3, 4);
365 a->channels = GET_BITS(val, 0, 3);
366 a->channels++;
367
368 a->rates = 0;
369 a->sample_bits = 0;
370 a->max_bitrate = 0;
371
372 if (a->format != AUDIO_CODING_TYPE_LPCM)
373 continue;
374
375 val = hdmi_get_eld_byte(codec, nid, sad_base + 1);
376 val = GET_BITS(val, 0, 7);
377 for (j = 0; j < 7; j++)
378 if (val & (1 << j))
379 a->rates |= cea_sampling_frequencies[j + 1];
380
381 val = hdmi_get_eld_byte(codec, nid, sad_base + 2);
382 val = GET_BITS(val, 0, 3);
383 for (j = 0; j < 3; j++)
384 if (val & (1 << j))
385 a->sample_bits |= cea_sample_sizes[j + 1];
386 }
387
388 e->lpcm_sad_ready = 1;
308 return 0; 389 return 0;
309 390
310out_fail: 391out_fail:
@@ -326,9 +407,6 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
326 int size; 407 int size;
327 unsigned char *buf; 408 unsigned char *buf;
328 409
329 if (!eld->eld_valid)
330 return -ENOENT;
331
332 size = snd_hdmi_get_eld_size(codec, nid); 410 size = snd_hdmi_get_eld_size(codec, nid);
333 if (size == 0) { 411 if (size == 0) {
334 /* wfg: workaround for ASUS P5E-VM HDMI board */ 412 /* wfg: workaround for ASUS P5E-VM HDMI board */
@@ -340,15 +418,42 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
340 return -ERANGE; 418 return -ERANGE;
341 } 419 }
342 420
421 if (!eld->lpcm_sad_ready)
422 hdmi_update_lpcm_sad_eld(codec, nid, eld, size);
423
424 codec->recv_dec_cap = 0;
425 for (i = 0; i < eld->sad_count; i++) {
426 if (eld->sad[i].format == AUDIO_CODING_TYPE_AC3) {
427 codec->recv_dec_cap |= (1 << AUDIO_CODING_TYPE_AC3);
428 } else if (eld->sad[i].format == AUDIO_CODING_TYPE_DTS) {
429 codec->recv_dec_cap |= (1 << AUDIO_CODING_TYPE_DTS);
430 }
431 }
432
343 buf = kmalloc(size, GFP_KERNEL); 433 buf = kmalloc(size, GFP_KERNEL);
344 if (!buf) 434 if (!buf)
345 return -ENOMEM; 435 return -ENOMEM;
346 436
347 for (i = 0; i < size; i++) 437 for (i = 0; i < size; i++) {
348 buf[i] = hdmi_get_eld_byte(codec, nid, i); 438 unsigned int val = hdmi_get_eld_data(codec, nid, i);
439 if (!(val & AC_ELDD_ELD_VALID)) {
440 if (!i) {
441 snd_printd(KERN_INFO
442 "HDMI: invalid ELD data\n");
443 ret = -EINVAL;
444 goto error;
445 }
446 snd_printd(KERN_INFO
447 "HDMI: invalid ELD data byte %d\n", i);
448 val = 0;
449 } else
450 val &= AC_ELDD_ELD_DATA;
451 buf[i] = val;
452 }
349 453
350 ret = hdmi_update_eld(eld, buf, size); 454 ret = hdmi_update_eld(eld, buf, size);
351 455
456error:
352 kfree(buf); 457 kfree(buf);
353 return ret; 458 return ret;
354} 459}
@@ -580,43 +685,45 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
580#endif /* CONFIG_PROC_FS */ 685#endif /* CONFIG_PROC_FS */
581 686
582/* update PCM info based on ELD */ 687/* update PCM info based on ELD */
583void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 688void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
584 struct hda_pcm_stream *codec_pars) 689 struct hda_pcm_stream *hinfo)
585{ 690{
691 u32 rates;
692 u64 formats;
693 unsigned int maxbps;
694 unsigned int channels_max;
586 int i; 695 int i;
587 696
588 /* assume basic audio support (the basic audio flag is not in ELD; 697 /* assume basic audio support (the basic audio flag is not in ELD;
589 * however, all audio capable sinks are required to support basic 698 * however, all audio capable sinks are required to support basic
590 * audio) */ 699 * audio) */
591 pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 700 rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
592 pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; 701 SNDRV_PCM_RATE_48000;
593 pcm->maxbps = 16; 702 formats = SNDRV_PCM_FMTBIT_S16_LE;
594 pcm->channels_max = 2; 703 maxbps = 16;
704 channels_max = 2;
595 for (i = 0; i < eld->sad_count; i++) { 705 for (i = 0; i < eld->sad_count; i++) {
596 struct cea_sad *a = &eld->sad[i]; 706 struct cea_sad *a = &eld->sad[i];
597 pcm->rates |= a->rates; 707 rates |= a->rates;
598 if (a->channels > pcm->channels_max) 708 if (a->channels > channels_max)
599 pcm->channels_max = a->channels; 709 channels_max = a->channels;
600 if (a->format == AUDIO_CODING_TYPE_LPCM) { 710 if (a->format == AUDIO_CODING_TYPE_LPCM) {
601 if (a->sample_bits & AC_SUPPCM_BITS_20) { 711 if (a->sample_bits & AC_SUPPCM_BITS_20) {
602 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 712 formats |= SNDRV_PCM_FMTBIT_S32_LE;
603 if (pcm->maxbps < 20) 713 if (maxbps < 20)
604 pcm->maxbps = 20; 714 maxbps = 20;
605 } 715 }
606 if (a->sample_bits & AC_SUPPCM_BITS_24) { 716 if (a->sample_bits & AC_SUPPCM_BITS_24) {
607 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 717 formats |= SNDRV_PCM_FMTBIT_S32_LE;
608 if (pcm->maxbps < 24) 718 if (maxbps < 24)
609 pcm->maxbps = 24; 719 maxbps = 24;
610 } 720 }
611 } 721 }
612 } 722 }
613 723
614 if (!codec_pars)
615 return;
616
617 /* restrict the parameters by the values the codec provides */ 724 /* restrict the parameters by the values the codec provides */
618 pcm->rates &= codec_pars->rates; 725 hinfo->rates &= rates;
619 pcm->formats &= codec_pars->formats; 726 hinfo->formats &= formats;
620 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 727 hinfo->maxbps = min(hinfo->maxbps, maxbps);
621 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 728 hinfo->channels_max = min(hinfo->channels_max, channels_max);
622} 729}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 486f6deb3ee..d88e598388c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -46,10 +46,13 @@
46#include <linux/pci.h> 46#include <linux/pci.h>
47#include <linux/mutex.h> 47#include <linux/mutex.h>
48#include <linux/reboot.h> 48#include <linux/reboot.h>
49#include <linux/clk.h>
49#include <sound/core.h> 50#include <sound/core.h>
50#include <sound/initval.h> 51#include <sound/initval.h>
51#include "hda_codec.h" 52#include "hda_codec.h"
52 53#include <linux/gpio.h>
54#include "../../../arch/arm/mach-tegra/gpio-names.h"
55#include "../../../arch/arm/mach-tegra/board-cardhu.h"
53 56
54static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
55static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 58static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -177,7 +180,8 @@ MODULE_DESCRIPTION("Intel HDA driver");
177#define ICH6_REG_INTCTL 0x20 180#define ICH6_REG_INTCTL 0x20
178#define ICH6_REG_INTSTS 0x24 181#define ICH6_REG_INTSTS 0x24
179#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */ 182#define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */
180#define ICH6_REG_SYNC 0x34 183#define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */
184#define ICH6_REG_SSYNC 0x38
181#define ICH6_REG_CORBLBASE 0x40 185#define ICH6_REG_CORBLBASE 0x40
182#define ICH6_REG_CORBUBASE 0x44 186#define ICH6_REG_CORBUBASE 0x44
183#define ICH6_REG_CORBWP 0x48 187#define ICH6_REG_CORBWP 0x48
@@ -320,6 +324,32 @@ enum {
320#define NVIDIA_HDA_OSTRM_COH 0x4c 324#define NVIDIA_HDA_OSTRM_COH 0x4c
321#define NVIDIA_HDA_ENABLE_COHBIT 0x01 325#define NVIDIA_HDA_ENABLE_COHBIT 0x01
322 326
327#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
328/* Defines for Nvidia Tegra HDA support */
329#define NVIDIA_TEGRA_HDA_BAR0_OFFSET 0x8000
330
331#define NVIDIA_TEGRA_HDA_CFG_CMD_OFFSET 0x1004
332#define NVIDIA_TEGRA_HDA_CFG_BAR0_OFFSET 0x1010
333
334#define NVIDIA_TEGRA_HDA_ENABLE_IO_SPACE (1 << 0)
335#define NVIDIA_TEGRA_HDA_ENABLE_MEM_SPACE (1 << 1)
336#define NVIDIA_TEGRA_HDA_ENABLE_BUS_MASTER (1 << 2)
337#define NVIDIA_TEGRA_HDA_ENABLE_SERR (1 << 8)
338#define NVIDIA_TEGRA_HDA_DISABLE_INTR (1 << 10)
339#define NVIDIA_TEGRA_HDA_BAR0_INIT_PROGRAM 0xFFFFFFFF
340#define NVIDIA_TEGRA_HDA_BAR0_FINAL_PROGRAM (1 << 14)
341
342/* IPFS */
343#define NVIDIA_TEGRA_HDA_IPFS_CONFIG 0x180
344#define NVIDIA_TEGRA_HDA_IPFS_EN_FPCI 0x1
345
346#define NVIDIA_TEGRA_HDA_IPFS_FPCI_BAR0 0x80
347#define NVIDIA_TEGRA_HDA_FPCI_BAR0_START 0x40
348
349#define NVIDIA_TEGRA_HDA_IPFS_INTR_MASK 0x188
350#define NVIDIA_TEGRA_HDA_IPFS_EN_INTR (1 << 16)
351#endif /* CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA */
352
323/* Defines for Intel SCH HDA snoop control */ 353/* Defines for Intel SCH HDA snoop control */
324#define INTEL_SCH_HDA_DEVC 0x78 354#define INTEL_SCH_HDA_DEVC 0x78
325#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) 355#define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11)
@@ -387,6 +417,9 @@ struct azx_rb {
387struct azx { 417struct azx {
388 struct snd_card *card; 418 struct snd_card *card;
389 struct pci_dev *pci; 419 struct pci_dev *pci;
420 struct platform_device *pdev;
421 struct device *dev;
422 int irq_id;
390 int dev_index; 423 int dev_index;
391 424
392 /* chip type specific */ 425 /* chip type specific */
@@ -401,8 +434,18 @@ struct azx {
401 /* pci resources */ 434 /* pci resources */
402 unsigned long addr; 435 unsigned long addr;
403 void __iomem *remap_addr; 436 void __iomem *remap_addr;
437#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
438 void __iomem *remap_config_addr;
439#endif
404 int irq; 440 int irq;
405 441
442#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
443 /* platform driver clocks */
444 struct clk **platform_clks;
445 int platform_clk_count;
446 int platform_clk_enable;
447#endif
448
406 /* locks */ 449 /* locks */
407 spinlock_t reg_lock; 450 spinlock_t reg_lock;
408 struct mutex open_mutex; 451 struct mutex open_mutex;
@@ -459,6 +502,7 @@ enum {
459 AZX_DRIVER_SIS, 502 AZX_DRIVER_SIS,
460 AZX_DRIVER_ULI, 503 AZX_DRIVER_ULI,
461 AZX_DRIVER_NVIDIA, 504 AZX_DRIVER_NVIDIA,
505 AZX_DRIVER_NVIDIA_TEGRA,
462 AZX_DRIVER_TERA, 506 AZX_DRIVER_TERA,
463 AZX_DRIVER_CTX, 507 AZX_DRIVER_CTX,
464 AZX_DRIVER_GENERIC, 508 AZX_DRIVER_GENERIC,
@@ -479,6 +523,7 @@ enum {
479#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ 523#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */
480#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ 524#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
481#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ 525#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */
526#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
482 527
483/* quirks for ATI SB / AMD Hudson */ 528/* quirks for ATI SB / AMD Hudson */
484#define AZX_DCAPS_PRESET_ATI_SB \ 529#define AZX_DCAPS_PRESET_ATI_SB \
@@ -503,6 +548,7 @@ static char *driver_short_names[] __devinitdata = {
503 [AZX_DRIVER_SIS] = "HDA SIS966", 548 [AZX_DRIVER_SIS] = "HDA SIS966",
504 [AZX_DRIVER_ULI] = "HDA ULI M5461", 549 [AZX_DRIVER_ULI] = "HDA ULI M5461",
505 [AZX_DRIVER_NVIDIA] = "HDA NVidia", 550 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
551 [AZX_DRIVER_NVIDIA_TEGRA] = "HDA NVIDIA Tegra",
506 [AZX_DRIVER_TERA] = "HDA Teradici", 552 [AZX_DRIVER_TERA] = "HDA Teradici",
507 [AZX_DRIVER_CTX] = "HDA Creative", 553 [AZX_DRIVER_CTX] = "HDA Creative",
508 [AZX_DRIVER_GENERIC] = "HD-Audio Generic", 554 [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
@@ -511,6 +557,48 @@ static char *driver_short_names[] __devinitdata = {
511/* 557/*
512 * macros for easy use 558 * macros for easy use
513 */ 559 */
560#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
561#define MASK_LONG_ALIGN 0x3UL
562#define SHIFT_BYTE 3
563#define SHIFT_BITS(reg) ((reg & MASK_LONG_ALIGN) << SHIFT_BYTE)
564#define ADDR_ALIGN_L(base, reg) (base + (reg & ~MASK_LONG_ALIGN))
565#define MASK(bits) (BIT(bits) - 1)
566#define MASK_REG(reg, bits) (MASK(bits) << SHIFT_BITS(reg))
567
568#define tegra_write(base, reg, val, bits) \
569 writel((readl(ADDR_ALIGN_L(base, reg)) & ~MASK_REG(reg, bits)) | \
570 ((val) << SHIFT_BITS(reg)), ADDR_ALIGN_L(base, reg))
571
572#define tegra_read(base, reg, bits) \
573 ((readl(ADDR_ALIGN_L(base, reg)) >> SHIFT_BITS(reg)) & MASK(bits))
574
575#define azx_writel(chip, reg, value) \
576 writel(value, (chip)->remap_addr + ICH6_REG_##reg)
577#define azx_readl(chip, reg) \
578 readl((chip)->remap_addr + ICH6_REG_##reg)
579#define azx_writew(chip, reg, value) \
580 tegra_write((chip)->remap_addr, ICH6_REG_##reg, value, 16)
581#define azx_readw(chip, reg) \
582 tegra_read((chip)->remap_addr, ICH6_REG_##reg, 16)
583#define azx_writeb(chip, reg, value) \
584 tegra_write((chip)->remap_addr, ICH6_REG_##reg, value, 8)
585#define azx_readb(chip, reg) \
586 tegra_read((chip)->remap_addr, ICH6_REG_##reg, 8)
587
588#define azx_sd_writel(dev, reg, value) \
589 writel(value, (dev)->sd_addr + ICH6_REG_##reg)
590#define azx_sd_readl(dev, reg) \
591 readl((dev)->sd_addr + ICH6_REG_##reg)
592#define azx_sd_writew(dev, reg, value) \
593 tegra_write((dev)->sd_addr, ICH6_REG_##reg, value, 16)
594#define azx_sd_readw(dev, reg) \
595 tegra_read((dev)->sd_addr, ICH6_REG_##reg, 16)
596#define azx_sd_writeb(dev, reg, value) \
597 tegra_write((dev)->sd_addr, ICH6_REG_##reg, value, 8)
598#define azx_sd_readb(dev, reg) \
599 tegra_read((dev)->sd_addr, ICH6_REG_##reg, 8)
600
601#else /* CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA */
514#define azx_writel(chip,reg,value) \ 602#define azx_writel(chip,reg,value) \
515 writel(value, (chip)->remap_addr + ICH6_REG_##reg) 603 writel(value, (chip)->remap_addr + ICH6_REG_##reg)
516#define azx_readl(chip,reg) \ 604#define azx_readl(chip,reg) \
@@ -537,6 +625,8 @@ static char *driver_short_names[] __devinitdata = {
537#define azx_sd_readb(dev,reg) \ 625#define azx_sd_readb(dev,reg) \
538 readb((dev)->sd_addr + ICH6_REG_##reg) 626 readb((dev)->sd_addr + ICH6_REG_##reg)
539 627
628#endif /* CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA */
629
540/* for pcm support */ 630/* for pcm support */
541#define get_azx_dev(substream) (substream->runtime->private_data) 631#define get_azx_dev(substream) (substream->runtime->private_data)
542 632
@@ -555,7 +645,7 @@ static int azx_alloc_cmd_io(struct azx *chip)
555 645
556 /* single page (at least 4096 bytes) must suffice for both ringbuffes */ 646 /* single page (at least 4096 bytes) must suffice for both ringbuffes */
557 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 647 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
558 snd_dma_pci_data(chip->pci), 648 chip->dev,
559 PAGE_SIZE, &chip->rb); 649 PAGE_SIZE, &chip->rb);
560 if (err < 0) { 650 if (err < 0) {
561 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); 651 snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n");
@@ -892,6 +982,20 @@ static unsigned int azx_get_response(struct hda_bus *bus,
892static void azx_power_notify(struct hda_bus *bus); 982static void azx_power_notify(struct hda_bus *bus);
893#endif 983#endif
894 984
985static void hda_codec_reset_deassert(void)
986{
987 int rc = gpio_direction_output(HDA_RESET, 1);
988 if (rc)
989 pr_err("HDA_RESET gpio direction configuration output 1 failed:%d\n", rc);
990}
991
992static void hda_codec_reset_assert(void)
993{
994 int rc = gpio_direction_output(HDA_RESET, 0);
995 if (rc)
996 pr_err("HDA_RESET gpio direction configuration output 0 failed:%d\n", rc);
997}
998
895/* reset codec link */ 999/* reset codec link */
896static int azx_reset(struct azx *chip, int full_reset) 1000static int azx_reset(struct azx *chip, int full_reset)
897{ 1001{
@@ -908,22 +1012,26 @@ static int azx_reset(struct azx *chip, int full_reset)
908 1012
909 count = 50; 1013 count = 50;
910 while (azx_readb(chip, GCTL) && --count) 1014 while (azx_readb(chip, GCTL) && --count)
911 msleep(1); 1015 mdelay(1);
1016
1017 hda_codec_reset_assert();
912 1018
913 /* delay for >= 100us for codec PLL to settle per spec 1019 /* delay for >= 100us for codec PLL to settle per spec
914 * Rev 0.9 section 5.5.1 1020 * Rev 0.9 section 5.5.1
915 */ 1021 */
916 msleep(1); 1022 mdelay(1);
917 1023
918 /* Bring controller out of reset */ 1024 /* Bring controller out of reset */
919 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET); 1025 azx_writeb(chip, GCTL, azx_readb(chip, GCTL) | ICH6_GCTL_RESET);
920 1026
921 count = 50; 1027 count = 50;
922 while (!azx_readb(chip, GCTL) && --count) 1028 while (!azx_readb(chip, GCTL) && --count)
923 msleep(1); 1029 mdelay(1);
1030
1031 hda_codec_reset_deassert();
924 1032
925 /* Brent Chartrand said to wait >= 540us for codecs to initialize */ 1033 /* Brent Chartrand said to wait >= 540us for codecs to initialize */
926 msleep(1); 1034 mdelay(1);
927 1035
928 __skip: 1036 __skip:
929 /* check to see if controller is ready */ 1037 /* check to see if controller is ready */
@@ -1129,6 +1237,83 @@ static void azx_init_pci(struct azx *chip)
1129 } 1237 }
1130} 1238}
1131 1239
1240#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
1241/*
1242 * initialize the platform specific registers
1243 */
1244static void reg_update_bits(void __iomem *base, unsigned int reg,
1245 unsigned int mask, unsigned int val)
1246{
1247 unsigned int data;
1248
1249 data = readl(base + reg);
1250 data &= ~mask;
1251 data |= (val & mask);
1252 writel(data, base + reg);
1253}
1254
1255static void azx_init_platform(struct azx *chip)
1256{
1257 switch (chip->driver_type) {
1258#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
1259 case AZX_DRIVER_NVIDIA_TEGRA:
1260 /*Enable the PCI access */
1261 reg_update_bits(chip->remap_config_addr,
1262 NVIDIA_TEGRA_HDA_IPFS_CONFIG,
1263 NVIDIA_TEGRA_HDA_IPFS_EN_FPCI,
1264 NVIDIA_TEGRA_HDA_IPFS_EN_FPCI);
1265 /* Enable MEM/IO space and bus master */
1266 reg_update_bits(chip->remap_config_addr,
1267 NVIDIA_TEGRA_HDA_CFG_CMD_OFFSET, 0x507,
1268 NVIDIA_TEGRA_HDA_ENABLE_MEM_SPACE |
1269 NVIDIA_TEGRA_HDA_ENABLE_IO_SPACE |
1270 NVIDIA_TEGRA_HDA_ENABLE_BUS_MASTER |
1271 NVIDIA_TEGRA_HDA_ENABLE_SERR);
1272 reg_update_bits(chip->remap_config_addr,
1273 NVIDIA_TEGRA_HDA_CFG_BAR0_OFFSET, 0xFFFFFFFF,
1274 NVIDIA_TEGRA_HDA_BAR0_INIT_PROGRAM);
1275 reg_update_bits(chip->remap_config_addr,
1276 NVIDIA_TEGRA_HDA_CFG_BAR0_OFFSET, 0xFFFFFFFF,
1277 NVIDIA_TEGRA_HDA_BAR0_FINAL_PROGRAM);
1278 reg_update_bits(chip->remap_config_addr,
1279 NVIDIA_TEGRA_HDA_IPFS_FPCI_BAR0, 0xFFFFFFFF,
1280 NVIDIA_TEGRA_HDA_FPCI_BAR0_START);
1281 reg_update_bits(chip->remap_config_addr,
1282 NVIDIA_TEGRA_HDA_IPFS_INTR_MASK,
1283 NVIDIA_TEGRA_HDA_IPFS_EN_INTR,
1284 NVIDIA_TEGRA_HDA_IPFS_EN_INTR);
1285 break;
1286#endif
1287 default:
1288 break;
1289 }
1290
1291 return;
1292}
1293
1294static void azx_platform_enable_clocks(struct azx *chip)
1295{
1296 int i;
1297
1298 for (i = 0; i < chip->platform_clk_count; i++)
1299 clk_enable(chip->platform_clks[i]);
1300
1301 chip->platform_clk_enable++;
1302}
1303
1304static void azx_platform_disable_clocks(struct azx *chip)
1305{
1306 int i;
1307
1308 if (!chip->platform_clk_enable)
1309 return;
1310
1311 for (i = 0; i < chip->platform_clk_count; i++)
1312 clk_disable(chip->platform_clks[i]);
1313
1314 chip->platform_clk_enable--;
1315}
1316#endif /* CONFIG_SND_HDA_PLATFORM_DRIVER */
1132 1317
1133static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev); 1318static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
1134 1319
@@ -1435,6 +1620,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1435 bus_temp.private_data = chip; 1620 bus_temp.private_data = chip;
1436 bus_temp.modelname = model; 1621 bus_temp.modelname = model;
1437 bus_temp.pci = chip->pci; 1622 bus_temp.pci = chip->pci;
1623 bus_temp.pdev = chip->pdev;
1438 bus_temp.ops.command = azx_send_cmd; 1624 bus_temp.ops.command = azx_send_cmd;
1439 bus_temp.ops.get_response = azx_get_response; 1625 bus_temp.ops.get_response = azx_get_response;
1440 bus_temp.ops.attach_pcm = azx_attach_pcm_stream; 1626 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
@@ -1706,13 +1892,16 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream)
1706 struct snd_pcm_runtime *runtime = substream->runtime; 1892 struct snd_pcm_runtime *runtime = substream->runtime;
1707 unsigned int bufsize, period_bytes, format_val, stream_tag; 1893 unsigned int bufsize, period_bytes, format_val, stream_tag;
1708 int err; 1894 int err;
1895 struct hda_spdif_out *spdif =
1896 snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid);
1897 unsigned short ctls = spdif ? spdif->ctls : 0;
1709 1898
1710 azx_stream_reset(chip, azx_dev); 1899 azx_stream_reset(chip, azx_dev);
1711 format_val = snd_hda_calc_stream_format(runtime->rate, 1900 format_val = snd_hda_calc_stream_format(runtime->rate,
1712 runtime->channels, 1901 runtime->channels,
1713 runtime->format, 1902 runtime->format,
1714 hinfo->maxbps, 1903 hinfo->maxbps,
1715 apcm->codec->spdif_ctls); 1904 ctls);
1716 if (!format_val) { 1905 if (!format_val) {
1717 snd_printk(KERN_ERR SFX 1906 snd_printk(KERN_ERR SFX
1718 "invalid format_val, rate=%d, ch=%d, format=%d\n", 1907 "invalid format_val, rate=%d, ch=%d, format=%d\n",
@@ -1792,7 +1981,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1792 spin_lock(&chip->reg_lock); 1981 spin_lock(&chip->reg_lock);
1793 if (nsync > 1) { 1982 if (nsync > 1) {
1794 /* first, set SYNC bits of corresponding streams */ 1983 /* first, set SYNC bits of corresponding streams */
1795 azx_writel(chip, SYNC, azx_readl(chip, SYNC) | sbits); 1984 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
1985 azx_writel(chip, OLD_SSYNC,
1986 azx_readl(chip, OLD_SSYNC) | sbits);
1987 else
1988 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits);
1796 } 1989 }
1797 snd_pcm_group_for_each_entry(s, substream) { 1990 snd_pcm_group_for_each_entry(s, substream) {
1798 if (s->pcm->card != substream->pcm->card) 1991 if (s->pcm->card != substream->pcm->card)
@@ -1848,7 +2041,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1848 if (nsync > 1) { 2041 if (nsync > 1) {
1849 spin_lock(&chip->reg_lock); 2042 spin_lock(&chip->reg_lock);
1850 /* reset SYNC bits */ 2043 /* reset SYNC bits */
1851 azx_writel(chip, SYNC, azx_readl(chip, SYNC) & ~sbits); 2044 if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC)
2045 azx_writel(chip, OLD_SSYNC,
2046 azx_readl(chip, OLD_SSYNC) & ~sbits);
2047 else
2048 azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits);
1852 spin_unlock(&chip->reg_lock); 2049 spin_unlock(&chip->reg_lock);
1853 } 2050 }
1854 return 0; 2051 return 0;
@@ -1863,7 +2060,7 @@ static unsigned int azx_via_get_position(struct azx *chip,
1863 unsigned int fifo_size; 2060 unsigned int fifo_size;
1864 2061
1865 link_pos = azx_sd_readl(azx_dev, SD_LPIB); 2062 link_pos = azx_sd_readl(azx_dev, SD_LPIB);
1866 if (azx_dev->index >= 4) { 2063 if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1867 /* Playback, no problem using link position */ 2064 /* Playback, no problem using link position */
1868 return link_pos; 2065 return link_pos;
1869 } 2066 }
@@ -1911,7 +2108,8 @@ static unsigned int azx_via_get_position(struct azx *chip,
1911} 2108}
1912 2109
1913static unsigned int azx_get_position(struct azx *chip, 2110static unsigned int azx_get_position(struct azx *chip,
1914 struct azx_dev *azx_dev) 2111 struct azx_dev *azx_dev,
2112 bool with_check)
1915{ 2113{
1916 unsigned int pos; 2114 unsigned int pos;
1917 int stream = azx_dev->substream->stream; 2115 int stream = azx_dev->substream->stream;
@@ -1927,6 +2125,17 @@ static unsigned int azx_get_position(struct azx *chip,
1927 default: 2125 default:
1928 /* use the position buffer */ 2126 /* use the position buffer */
1929 pos = le32_to_cpu(*azx_dev->posbuf); 2127 pos = le32_to_cpu(*azx_dev->posbuf);
2128 if (with_check && chip->position_fix[stream] == POS_FIX_AUTO) {
2129 if (!pos || pos == (u32)-1) {
2130 printk(KERN_WARNING
2131 "hda-intel: Invalid position buffer, "
2132 "using LPIB read method instead.\n");
2133 chip->position_fix[stream] = POS_FIX_LPIB;
2134 pos = azx_sd_readl(azx_dev, SD_LPIB);
2135 } else
2136 chip->position_fix[stream] = POS_FIX_POSBUF;
2137 }
2138 break;
1930 } 2139 }
1931 2140
1932 if (pos >= azx_dev->bufsize) 2141 if (pos >= azx_dev->bufsize)
@@ -1940,7 +2149,7 @@ static snd_pcm_uframes_t azx_pcm_pointer(struct snd_pcm_substream *substream)
1940 struct azx *chip = apcm->chip; 2149 struct azx *chip = apcm->chip;
1941 struct azx_dev *azx_dev = get_azx_dev(substream); 2150 struct azx_dev *azx_dev = get_azx_dev(substream);
1942 return bytes_to_frames(substream->runtime, 2151 return bytes_to_frames(substream->runtime,
1943 azx_get_position(chip, azx_dev)); 2152 azx_get_position(chip, azx_dev, false));
1944} 2153}
1945 2154
1946/* 2155/*
@@ -1963,17 +2172,7 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
1963 return -1; /* bogus (too early) interrupt */ 2172 return -1; /* bogus (too early) interrupt */
1964 2173
1965 stream = azx_dev->substream->stream; 2174 stream = azx_dev->substream->stream;
1966 pos = azx_get_position(chip, azx_dev); 2175 pos = azx_get_position(chip, azx_dev, true);
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 2176
1978 if (WARN_ONCE(!azx_dev->period_bytes, 2177 if (WARN_ONCE(!azx_dev->period_bytes,
1979 "hda-intel: zero azx_dev->period_bytes")) 2178 "hda-intel: zero azx_dev->period_bytes"))
@@ -2061,6 +2260,8 @@ static void azx_pcm_free(struct snd_pcm *pcm)
2061 } 2260 }
2062} 2261}
2063 2262
2263#define MAX_PREALLOC_SIZE (32 * 1024 * 1024)
2264
2064static int 2265static int
2065azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, 2266azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2066 struct hda_pcm *cpcm) 2267 struct hda_pcm *cpcm)
@@ -2069,6 +2270,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2069 struct snd_pcm *pcm; 2270 struct snd_pcm *pcm;
2070 struct azx_pcm *apcm; 2271 struct azx_pcm *apcm;
2071 int pcm_dev = cpcm->device; 2272 int pcm_dev = cpcm->device;
2273 unsigned int size;
2072 int s, err; 2274 int s, err;
2073 2275
2074 if (pcm_dev >= HDA_MAX_PCMS) { 2276 if (pcm_dev >= HDA_MAX_PCMS) {
@@ -2104,9 +2306,12 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
2104 snd_pcm_set_ops(pcm, s, &azx_pcm_ops); 2306 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
2105 } 2307 }
2106 /* buffer pre-allocation */ 2308 /* buffer pre-allocation */
2309 size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
2310 if (size > MAX_PREALLOC_SIZE)
2311 size = MAX_PREALLOC_SIZE;
2107 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 2312 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
2108 snd_dma_pci_data(chip->pci), 2313 chip->dev,
2109 1024 * 64, 32 * 1024 * 1024); 2314 size, MAX_PREALLOC_SIZE);
2110 return 0; 2315 return 0;
2111} 2316}
2112 2317
@@ -2147,17 +2352,19 @@ static int __devinit azx_init_stream(struct azx *chip)
2147 2352
2148static int azx_acquire_irq(struct azx *chip, int do_disconnect) 2353static int azx_acquire_irq(struct azx *chip, int do_disconnect)
2149{ 2354{
2150 if (request_irq(chip->pci->irq, azx_interrupt, 2355 if (request_irq(chip->irq_id, azx_interrupt,
2151 chip->msi ? 0 : IRQF_SHARED, 2356 chip->msi ? 0 : IRQF_SHARED,
2152 "hda_intel", chip)) { 2357 KBUILD_MODNAME, chip)) {
2153 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, " 2358 printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
2154 "disabling device\n", chip->pci->irq); 2359 "disabling device\n", chip->irq_id);
2155 if (do_disconnect) 2360 if (do_disconnect)
2156 snd_card_disconnect(chip->card); 2361 snd_card_disconnect(chip->card);
2157 return -1; 2362 return -1;
2158 } 2363 }
2159 chip->irq = chip->pci->irq; 2364 chip->irq = chip->irq_id;
2160 pci_intx(chip->pci, !chip->msi); 2365 if (chip->pci)
2366 pci_intx(chip->pci, !chip->msi);
2367
2161 return 0; 2368 return 0;
2162} 2369}
2163 2370
@@ -2195,11 +2402,19 @@ static void azx_power_notify(struct hda_bus *bus)
2195 break; 2402 break;
2196 } 2403 }
2197 } 2404 }
2198 if (power_on) 2405 if (power_on) {
2406#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2407 azx_platform_enable_clocks(chip);
2408#endif
2199 azx_init_chip(chip, 1); 2409 azx_init_chip(chip, 1);
2410 }
2200 else if (chip->running && power_save_controller && 2411 else if (chip->running && power_save_controller &&
2201 !bus->power_keep_link_on) 2412 !bus->power_keep_link_on) {
2202 azx_stop_chip(chip); 2413 azx_stop_chip(chip);
2414#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2415 azx_platform_disable_clocks(chip);
2416#endif
2417 }
2203} 2418}
2204#endif /* CONFIG_SND_HDA_POWER_SAVE */ 2419#endif /* CONFIG_SND_HDA_POWER_SAVE */
2205 2420
@@ -2219,12 +2434,17 @@ static int snd_hda_codecs_inuse(struct hda_bus *bus)
2219 return 0; 2434 return 0;
2220} 2435}
2221 2436
2222static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2437static int azx_suspend(struct azx *chip, pm_message_t state)
2223{ 2438{
2224 struct snd_card *card = pci_get_drvdata(pci); 2439 struct snd_card *card = chip->card;
2225 struct azx *chip = card->private_data;
2226 int i; 2440 int i;
2227 2441
2442#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \
2443 defined(CONFIG_SND_HDA_POWER_SAVE)
2444 if (chip->pdev)
2445 azx_platform_enable_clocks(chip);
2446#endif
2447
2228 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2448 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2229 azx_clear_irq_pending(chip); 2449 azx_clear_irq_pending(chip);
2230 for (i = 0; i < HDA_MAX_PCMS; i++) 2450 for (i = 0; i < HDA_MAX_PCMS; i++)
@@ -2236,42 +2456,111 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2236 free_irq(chip->irq, chip); 2456 free_irq(chip->irq, chip);
2237 chip->irq = -1; 2457 chip->irq = -1;
2238 } 2458 }
2239 if (chip->msi) 2459
2240 pci_disable_msi(chip->pci); 2460 if (chip->pci) {
2241 pci_disable_device(pci); 2461 if (chip->msi)
2242 pci_save_state(pci); 2462 pci_disable_msi(chip->pci);
2243 pci_set_power_state(pci, pci_choose_state(pci, state)); 2463 pci_disable_device(chip->pci);
2464 pci_save_state(chip->pci);
2465 pci_set_power_state(chip->pci,
2466 pci_choose_state(chip->pci, state));
2467 }
2468
2469#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2470 if (chip->pdev) {
2471 /* Disable all clk references */
2472 while (chip->platform_clk_enable)
2473 azx_platform_disable_clocks(chip);
2474 }
2475#endif
2476
2244 return 0; 2477 return 0;
2245} 2478}
2246 2479
2247static int azx_resume(struct pci_dev *pci) 2480static int azx_resume(struct azx *chip)
2248{ 2481{
2249 struct snd_card *card = pci_get_drvdata(pci); 2482 struct snd_card *card = chip->card;
2250 struct azx *chip = card->private_data;
2251 2483
2252 pci_set_power_state(pci, PCI_D0); 2484#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2253 pci_restore_state(pci); 2485 if (chip->pdev)
2254 if (pci_enable_device(pci) < 0) { 2486 azx_platform_enable_clocks(chip);
2255 printk(KERN_ERR "hda-intel: pci_enable_device failed, " 2487#endif
2256 "disabling device\n"); 2488
2257 snd_card_disconnect(card); 2489 if (chip->pci) {
2258 return -EIO; 2490 pci_set_power_state(chip->pci, PCI_D0);
2491 pci_restore_state(chip->pci);
2492 if (pci_enable_device(chip->pci) < 0) {
2493 printk(KERN_ERR "hda-intel: pci_enable_device failed, "
2494 "disabling device\n");
2495 snd_card_disconnect(card);
2496 return -EIO;
2497 }
2498 pci_set_master(chip->pci);
2499 if (chip->msi)
2500 if (pci_enable_msi(chip->pci) < 0)
2501 chip->msi = 0;
2259 } 2502 }
2260 pci_set_master(pci); 2503
2261 if (chip->msi)
2262 if (pci_enable_msi(pci) < 0)
2263 chip->msi = 0;
2264 if (azx_acquire_irq(chip, 1) < 0) 2504 if (azx_acquire_irq(chip, 1) < 0)
2265 return -EIO; 2505 return -EIO;
2266 azx_init_pci(chip); 2506
2507 if (chip->pci)
2508 azx_init_pci(chip);
2509
2510#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2511 if (chip->pdev)
2512 azx_init_platform(chip);
2513#endif
2267 2514
2268 if (snd_hda_codecs_inuse(chip->bus)) 2515 if (snd_hda_codecs_inuse(chip->bus))
2269 azx_init_chip(chip, 1); 2516 azx_init_chip(chip, 1);
2270 2517
2271 snd_hda_resume(chip->bus); 2518 snd_hda_resume(chip->bus);
2272 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2519 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2520
2521#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \
2522 defined(CONFIG_SND_HDA_POWER_SAVE)
2523 if (chip->pdev)
2524 azx_platform_disable_clocks(chip);
2525#endif
2526
2273 return 0; 2527 return 0;
2274} 2528}
2529
2530static int azx_suspend_pci(struct pci_dev *pci, pm_message_t state)
2531{
2532 struct snd_card *card = pci_get_drvdata(pci);
2533 struct azx *chip = card->private_data;
2534
2535 return azx_suspend(chip, state);
2536}
2537
2538static int azx_resume_pci(struct pci_dev *pci)
2539{
2540 struct snd_card *card = pci_get_drvdata(pci);
2541 struct azx *chip = card->private_data;
2542
2543 return azx_resume(chip);
2544}
2545
2546#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2547static int azx_suspend_platform(struct platform_device *pdev,
2548 pm_message_t state)
2549{
2550 struct snd_card *card = dev_get_drvdata(&pdev->dev);
2551 struct azx *chip = card->private_data;
2552
2553 return azx_suspend(chip, state);
2554}
2555
2556static int azx_resume_platform(struct platform_device *pdev)
2557{
2558 struct snd_card *card = dev_get_drvdata(&pdev->dev);
2559 struct azx *chip = card->private_data;
2560
2561 return azx_resume(chip);
2562}
2563#endif /* CONFIG_SND_HDA_PLATFORM_DRIVER */
2275#endif /* CONFIG_PM */ 2564#endif /* CONFIG_PM */
2276 2565
2277 2566
@@ -2281,8 +2570,22 @@ static int azx_resume(struct pci_dev *pci)
2281static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) 2570static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
2282{ 2571{
2283 struct azx *chip = container_of(nb, struct azx, reboot_notifier); 2572 struct azx *chip = container_of(nb, struct azx, reboot_notifier);
2573
2574#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \
2575 defined(CONFIG_SND_HDA_POWER_SAVE)
2576 if (chip->pdev)
2577 azx_platform_enable_clocks(chip);
2578#endif
2579
2284 snd_hda_bus_reboot_notify(chip->bus); 2580 snd_hda_bus_reboot_notify(chip->bus);
2285 azx_stop_chip(chip); 2581 azx_stop_chip(chip);
2582
2583#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \
2584 defined(CONFIG_SND_HDA_POWER_SAVE)
2585 if (chip->pdev)
2586 azx_platform_disable_clocks(chip);
2587#endif
2588
2286 return NOTIFY_OK; 2589 return NOTIFY_OK;
2287} 2590}
2288 2591
@@ -2314,9 +2617,15 @@ static int azx_free(struct azx *chip)
2314 azx_stop_chip(chip); 2617 azx_stop_chip(chip);
2315 } 2618 }
2316 2619
2620#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2621 azx_platform_disable_clocks(chip);
2622 for (i = 0; i < chip->platform_clk_count; i++)
2623 clk_put(chip->platform_clks[i]);
2624#endif
2625
2317 if (chip->irq >= 0) 2626 if (chip->irq >= 0)
2318 free_irq(chip->irq, (void*)chip); 2627 free_irq(chip->irq, (void*)chip);
2319 if (chip->msi) 2628 if (chip->pci && chip->msi)
2320 pci_disable_msi(chip->pci); 2629 pci_disable_msi(chip->pci);
2321 if (chip->remap_addr) 2630 if (chip->remap_addr)
2322 iounmap(chip->remap_addr); 2631 iounmap(chip->remap_addr);
@@ -2330,8 +2639,10 @@ static int azx_free(struct azx *chip)
2330 snd_dma_free_pages(&chip->rb); 2639 snd_dma_free_pages(&chip->rb);
2331 if (chip->posbuf.area) 2640 if (chip->posbuf.area)
2332 snd_dma_free_pages(&chip->posbuf); 2641 snd_dma_free_pages(&chip->posbuf);
2333 pci_release_regions(chip->pci); 2642 if (chip->pci) {
2334 pci_disable_device(chip->pci); 2643 pci_release_regions(chip->pci);
2644 pci_disable_device(chip->pci);
2645 }
2335 kfree(chip->azx_dev); 2646 kfree(chip->azx_dev);
2336 kfree(chip); 2647 kfree(chip);
2337 2648
@@ -2347,28 +2658,22 @@ static int azx_dev_free(struct snd_device *device)
2347 * white/black-listing for position_fix 2658 * white/black-listing for position_fix
2348 */ 2659 */
2349static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2660static 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), 2661 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2353 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2662 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2354 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), 2663 SND_PCI_QUIRK(0x1028, 0x02c6, "Dell Inspiron 1010", 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), 2664 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2357 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2665 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2358 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2666 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
2359 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), 2667 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
2360 SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB), 2668 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB),
2361 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), 2669 SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
2362 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), 2670 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), 2671 SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
2365 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), 2672 SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
2366 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2673 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), 2674 SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
2369 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), 2675 SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
2370 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), 2676 SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
2371 SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB),
2372 {} 2677 {}
2373}; 2678};
2374 2679
@@ -2383,13 +2688,15 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2383 return fix; 2688 return fix;
2384 } 2689 }
2385 2690
2386 q = snd_pci_quirk_lookup(chip->pci, position_fix_list); 2691 if (chip->pci) {
2387 if (q) { 2692 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
2388 printk(KERN_INFO 2693 if (q) {
2389 "hda_intel: position_fix set to %d " 2694 printk(KERN_INFO
2390 "for device %04x:%04x\n", 2695 "hda_intel: position_fix set to %d "
2391 q->value, q->subvendor, q->subdevice); 2696 "for device %04x:%04x\n",
2392 return q->value; 2697 q->value, q->subvendor, q->subdevice);
2698 return q->value;
2699 }
2393 } 2700 }
2394 2701
2395 /* Check VIA/ATI HD Audio Controller exist */ 2702 /* Check VIA/ATI HD Audio Controller exist */
@@ -2431,7 +2738,7 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2431 const struct snd_pci_quirk *q; 2738 const struct snd_pci_quirk *q;
2432 2739
2433 chip->codec_probe_mask = probe_mask[dev]; 2740 chip->codec_probe_mask = probe_mask[dev];
2434 if (chip->codec_probe_mask == -1) { 2741 if (chip->pci && (chip->codec_probe_mask == -1)) {
2435 q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); 2742 q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
2436 if (q) { 2743 if (q) {
2437 printk(KERN_INFO 2744 printk(KERN_INFO
@@ -2467,6 +2774,12 @@ static void __devinit check_msi(struct azx *chip)
2467{ 2774{
2468 const struct snd_pci_quirk *q; 2775 const struct snd_pci_quirk *q;
2469 2776
2777 /* Disable MSI if chip is not a pci device */
2778 if (!chip->pci) {
2779 chip->msi = 0;
2780 return;
2781 }
2782
2470 if (enable_msi >= 0) { 2783 if (enable_msi >= 0) {
2471 chip->msi = !!enable_msi; 2784 chip->msi = !!enable_msi;
2472 return; 2785 return;
@@ -2488,16 +2801,25 @@ static void __devinit check_msi(struct azx *chip)
2488 } 2801 }
2489} 2802}
2490 2803
2804#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
2805static const char *tegra_clk_names[] __devinitdata = {
2806 "hda",
2807 "hda2codec",
2808 "hda2hdmi",
2809};
2810static struct clk *tegra_clks[ARRAY_SIZE(tegra_clk_names)];
2811#endif
2491 2812
2492/* 2813/*
2493 * constructor 2814 * constructor
2494 */ 2815 */
2495static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, 2816static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2817 struct platform_device *pdev,
2496 int dev, unsigned int driver_caps, 2818 int dev, unsigned int driver_caps,
2497 struct azx **rchip) 2819 struct azx **rchip)
2498{ 2820{
2499 struct azx *chip; 2821 struct azx *chip;
2500 int i, err; 2822 int i, err = 0;
2501 unsigned short gcap; 2823 unsigned short gcap;
2502 static struct snd_device_ops ops = { 2824 static struct snd_device_ops ops = {
2503 .dev_free = azx_dev_free, 2825 .dev_free = azx_dev_free,
@@ -2505,14 +2827,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2505 2827
2506 *rchip = NULL; 2828 *rchip = NULL;
2507 2829
2508 err = pci_enable_device(pci); 2830 if (pci) {
2509 if (err < 0) 2831 err = pci_enable_device(pci);
2510 return err; 2832 if (err < 0)
2833 return err;
2834 }
2511 2835
2512 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 2836 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
2513 if (!chip) { 2837 if (!chip) {
2514 snd_printk(KERN_ERR SFX "cannot allocate chip\n"); 2838 snd_printk(KERN_ERR SFX "cannot allocate chip\n");
2515 pci_disable_device(pci); 2839 if (pci)
2840 pci_disable_device(pci);
2516 return -ENOMEM; 2841 return -ENOMEM;
2517 } 2842 }
2518 2843
@@ -2520,6 +2845,9 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2520 mutex_init(&chip->open_mutex); 2845 mutex_init(&chip->open_mutex);
2521 chip->card = card; 2846 chip->card = card;
2522 chip->pci = pci; 2847 chip->pci = pci;
2848 chip->pdev = pdev;
2849 chip->dev = pci ? snd_dma_pci_data(pci) : &pdev->dev;
2850 chip->irq_id = pci ? pci->irq : platform_get_irq(pdev, 0);
2523 chip->irq = -1; 2851 chip->irq = -1;
2524 chip->driver_caps = driver_caps; 2852 chip->driver_caps = driver_caps;
2525 chip->driver_type = driver_caps & 0xff; 2853 chip->driver_type = driver_caps & 0xff;
@@ -2555,38 +2883,105 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2555 } 2883 }
2556#endif 2884#endif
2557 2885
2558 err = pci_request_regions(pci, "ICH HD audio"); 2886 if (chip->pci) {
2559 if (err < 0) { 2887 err = pci_request_regions(pci, "ICH HD audio");
2560 kfree(chip); 2888 if (err < 0) {
2561 pci_disable_device(pci); 2889 kfree(chip);
2562 return err; 2890 pci_disable_device(pci);
2563 } 2891 return err;
2892 }
2564 2893
2565 chip->addr = pci_resource_start(pci, 0); 2894 chip->addr = pci_resource_start(pci, 0);
2566 chip->remap_addr = pci_ioremap_bar(pci, 0); 2895 chip->remap_addr = pci_ioremap_bar(pci, 0);
2567 if (chip->remap_addr == NULL) { 2896 if (chip->remap_addr == NULL) {
2568 snd_printk(KERN_ERR SFX "ioremap error\n"); 2897 snd_printk(KERN_ERR SFX "ioremap error\n");
2569 err = -ENXIO; 2898 err = -ENXIO;
2570 goto errout; 2899 goto errout;
2900 }
2901
2902 if (chip->msi)
2903 if (pci_enable_msi(pci) < 0)
2904 chip->msi = 0;
2571 } 2905 }
2572 2906
2573 if (chip->msi) 2907#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
2574 if (pci_enable_msi(pci) < 0) 2908 if (chip->pdev) {
2575 chip->msi = 0; 2909 struct resource *res, *region;
2910
2911 /* Do platform specific initialization */
2912 switch (chip->driver_type) {
2913#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
2914 case AZX_DRIVER_NVIDIA_TEGRA:
2915 chip->platform_clk_count = ARRAY_SIZE(tegra_clk_names);
2916 for (i = 0; i < chip->platform_clk_count; i++) {
2917 tegra_clks[i] = clk_get(&pdev->dev,
2918 tegra_clk_names[i]);
2919 if (IS_ERR_OR_NULL(tegra_clks[i])) {
2920 err = PTR_ERR(tegra_clks[i]);
2921 goto errout;
2922 }
2923 }
2924 chip->platform_clks = tegra_clks;
2925 break;
2926#endif
2927 default:
2928 break;
2929 }
2930
2931 azx_platform_enable_clocks(chip);
2932
2933 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2934 if (res == NULL) {
2935 err = EINVAL;
2936 goto errout;
2937 }
2938
2939 region = devm_request_mem_region(chip->dev, res->start,
2940 resource_size(res),
2941 pdev->name);
2942 if (!region) {
2943 snd_printk(KERN_ERR SFX "Mem region already claimed\n");
2944 err = -EINVAL;
2945 goto errout;
2946 }
2947
2948 chip->addr = res->start;
2949 chip->remap_addr = devm_ioremap(chip->dev,
2950 res->start,
2951 resource_size(res));
2952 if (chip->remap_addr == NULL) {
2953 snd_printk(KERN_ERR SFX "ioremap error\n");
2954 err = -ENXIO;
2955 goto errout;
2956 }
2957
2958#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
2959 if (chip->driver_type == AZX_DRIVER_NVIDIA_TEGRA) {
2960 chip->remap_config_addr = chip->remap_addr;
2961 chip->remap_addr += NVIDIA_TEGRA_HDA_BAR0_OFFSET;
2962 chip->addr += NVIDIA_TEGRA_HDA_BAR0_OFFSET;
2963 }
2964#endif
2965
2966 azx_init_platform(chip);
2967 }
2968#endif /* CONFIG_SND_HDA_PLATFORM_DRIVER */
2576 2969
2577 if (azx_acquire_irq(chip, 0) < 0) { 2970 if (azx_acquire_irq(chip, 0) < 0) {
2578 err = -EBUSY; 2971 err = -EBUSY;
2579 goto errout; 2972 goto errout;
2580 } 2973 }
2581 2974
2582 pci_set_master(pci); 2975 if (chip->pci)
2976 pci_set_master(pci);
2977
2583 synchronize_irq(chip->irq); 2978 synchronize_irq(chip->irq);
2584 2979
2585 gcap = azx_readw(chip, GCAP); 2980 gcap = azx_readw(chip, GCAP);
2586 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); 2981 snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap);
2587 2982
2588 /* disable SB600 64bit support for safety */ 2983 /* disable SB600 64bit support for safety */
2589 if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { 2984 if (chip->pci && chip->pci->vendor == PCI_VENDOR_ID_ATI) {
2590 struct pci_dev *p_smbus; 2985 struct pci_dev *p_smbus;
2591 p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, 2986 p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
2592 PCI_DEVICE_ID_ATI_SBX00_SMBUS, 2987 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
@@ -2604,12 +2999,15 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2604 gcap &= ~ICH6_GCAP_64OK; 2999 gcap &= ~ICH6_GCAP_64OK;
2605 } 3000 }
2606 3001
2607 /* allow 64bit DMA address if supported by H/W */ 3002 if (chip->pci) {
2608 if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) 3003 /* allow 64bit DMA address if supported by H/W */
2609 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); 3004 if ((gcap & ICH6_GCAP_64OK) &&
2610 else { 3005 !pci_set_dma_mask(pci, DMA_BIT_MASK(64)))
2611 pci_set_dma_mask(pci, DMA_BIT_MASK(32)); 3006 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64));
2612 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); 3007 else {
3008 pci_set_dma_mask(pci, DMA_BIT_MASK(32));
3009 pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32));
3010 }
2613 } 3011 }
2614 3012
2615 /* read number of streams from GCAP register instead of using 3013 /* read number of streams from GCAP register instead of using
@@ -2649,7 +3047,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2649 for (i = 0; i < chip->num_streams; i++) { 3047 for (i = 0; i < chip->num_streams; i++) {
2650 /* allocate memory for the BDL for each stream */ 3048 /* allocate memory for the BDL for each stream */
2651 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 3049 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
2652 snd_dma_pci_data(chip->pci), 3050 chip->dev,
2653 BDL_SIZE, &chip->azx_dev[i].bdl); 3051 BDL_SIZE, &chip->azx_dev[i].bdl);
2654 if (err < 0) { 3052 if (err < 0) {
2655 snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); 3053 snd_printk(KERN_ERR SFX "cannot allocate BDL\n");
@@ -2658,7 +3056,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2658 } 3056 }
2659 /* allocate memory for the position buffer */ 3057 /* allocate memory for the position buffer */
2660 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, 3058 err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
2661 snd_dma_pci_data(chip->pci), 3059 chip->dev,
2662 chip->num_streams * 8, &chip->posbuf); 3060 chip->num_streams * 8, &chip->posbuf);
2663 if (err < 0) { 3061 if (err < 0) {
2664 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); 3062 snd_printk(KERN_ERR SFX "cannot allocate posbuf\n");
@@ -2673,7 +3071,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2673 azx_init_stream(chip); 3071 azx_init_stream(chip);
2674 3072
2675 /* initialize chip */ 3073 /* initialize chip */
2676 azx_init_pci(chip); 3074 if (chip->pci)
3075 azx_init_pci(chip);
2677 azx_init_chip(chip, (probe_only[dev] & 2) == 0); 3076 azx_init_chip(chip, (probe_only[dev] & 2) == 0);
2678 3077
2679 /* codec detection */ 3078 /* codec detection */
@@ -2718,11 +3117,13 @@ static void power_down_all_codecs(struct azx *chip)
2718} 3117}
2719 3118
2720static int __devinit azx_probe(struct pci_dev *pci, 3119static int __devinit azx_probe(struct pci_dev *pci,
2721 const struct pci_device_id *pci_id) 3120 struct platform_device *pdev,
3121 int driver_data)
2722{ 3122{
2723 static int dev; 3123 static int dev;
2724 struct snd_card *card; 3124 struct snd_card *card;
2725 struct azx *chip; 3125 struct azx *chip;
3126 struct device *azx_dev = pci ? &pci->dev : &pdev->dev;
2726 int err; 3127 int err;
2727 3128
2728 if (dev >= SNDRV_CARDS) 3129 if (dev >= SNDRV_CARDS)
@@ -2739,9 +3140,9 @@ static int __devinit azx_probe(struct pci_dev *pci,
2739 } 3140 }
2740 3141
2741 /* set this here since it's referred in snd_hda_load_patch() */ 3142 /* set this here since it's referred in snd_hda_load_patch() */
2742 snd_card_set_dev(card, &pci->dev); 3143 snd_card_set_dev(card, azx_dev);
2743 3144
2744 err = azx_create(card, pci, dev, pci_id->driver_data, &chip); 3145 err = azx_create(card, pci, pdev, dev, driver_data, &chip);
2745 if (err < 0) 3146 if (err < 0)
2746 goto out_free; 3147 goto out_free;
2747 card->private_data = chip; 3148 card->private_data = chip;
@@ -2783,7 +3184,11 @@ static int __devinit azx_probe(struct pci_dev *pci,
2783 if (err < 0) 3184 if (err < 0)
2784 goto out_free; 3185 goto out_free;
2785 3186
2786 pci_set_drvdata(pci, card); 3187 if (pci)
3188 pci_set_drvdata(pci, card);
3189 else
3190 dev_set_drvdata(&pdev->dev, card);
3191
2787 chip->running = 1; 3192 chip->running = 1;
2788 power_down_all_codecs(chip); 3193 power_down_all_codecs(chip);
2789 azx_notifier_register(chip); 3194 azx_notifier_register(chip);
@@ -2795,14 +3200,20 @@ out_free:
2795 return err; 3200 return err;
2796} 3201}
2797 3202
2798static void __devexit azx_remove(struct pci_dev *pci) 3203static int __devinit azx_probe_pci(struct pci_dev *pci,
3204 const struct pci_device_id *pci_id)
3205{
3206 return azx_probe(pci, NULL, pci_id->driver_data);
3207}
3208
3209static void __devexit azx_remove_pci(struct pci_dev *pci)
2799{ 3210{
2800 snd_card_free(pci_get_drvdata(pci)); 3211 snd_card_free(pci_get_drvdata(pci));
2801 pci_set_drvdata(pci, NULL); 3212 pci_set_drvdata(pci, NULL);
2802} 3213}
2803 3214
2804/* PCI IDs */ 3215/* PCI IDs */
2805static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { 3216static DEFINE_PCI_DEVICE_TABLE(azx_pci_ids) = {
2806 /* CPT */ 3217 /* CPT */
2807 { PCI_DEVICE(0x8086, 0x1c20), 3218 { PCI_DEVICE(0x8086, 0x1c20),
2808 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, 3219 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP },
@@ -2815,6 +3226,22 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2815 /* SCH */ 3226 /* SCH */
2816 { PCI_DEVICE(0x8086, 0x811b), 3227 { PCI_DEVICE(0x8086, 0x811b),
2817 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, 3228 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP },
3229 { PCI_DEVICE(0x8086, 0x2668),
3230 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */
3231 { PCI_DEVICE(0x8086, 0x27d8),
3232 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */
3233 { PCI_DEVICE(0x8086, 0x269a),
3234 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */
3235 { PCI_DEVICE(0x8086, 0x284b),
3236 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */
3237 { PCI_DEVICE(0x8086, 0x293e),
3238 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
3239 { PCI_DEVICE(0x8086, 0x293f),
3240 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */
3241 { PCI_DEVICE(0x8086, 0x3a3e),
3242 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
3243 { PCI_DEVICE(0x8086, 0x3a6e),
3244 .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */
2818 /* Generic Intel */ 3245 /* Generic Intel */
2819 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), 3246 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2820 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 3247 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
@@ -2882,12 +3309,12 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2882 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 3309 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2883 .class_mask = 0xffffff, 3310 .class_mask = 0xffffff,
2884 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 3311 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2885 AZX_DCAPS_RIRB_PRE_DELAY }, 3312 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2886#else 3313#else
2887 /* this entry seems still valid -- i.e. without emu20kx chip */ 3314 /* this entry seems still valid -- i.e. without emu20kx chip */
2888 { PCI_DEVICE(0x1102, 0x0009), 3315 { PCI_DEVICE(0x1102, 0x0009),
2889 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | 3316 .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2890 AZX_DCAPS_RIRB_PRE_DELAY }, 3317 AZX_DCAPS_RIRB_PRE_DELAY | AZX_DCAPS_POSFIX_LPIB },
2891#endif 3318#endif
2892 /* Vortex86MX */ 3319 /* Vortex86MX */
2893 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, 3320 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
@@ -2904,27 +3331,85 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2904 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, 3331 .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
2905 { 0, } 3332 { 0, }
2906}; 3333};
2907MODULE_DEVICE_TABLE(pci, azx_ids); 3334MODULE_DEVICE_TABLE(pci, azx_pci_ids);
2908 3335
2909/* pci_driver definition */ 3336/* pci_driver definition */
2910static struct pci_driver driver = { 3337static struct pci_driver driver = {
2911 .name = "HDA Intel", 3338 .name = KBUILD_MODNAME,
2912 .id_table = azx_ids, 3339 .id_table = azx_pci_ids,
2913 .probe = azx_probe, 3340 .probe = azx_probe_pci,
2914 .remove = __devexit_p(azx_remove), 3341 .remove = __devexit_p(azx_remove_pci),
2915#ifdef CONFIG_PM 3342#ifdef CONFIG_PM
2916 .suspend = azx_suspend, 3343 .suspend = azx_suspend_pci,
2917 .resume = azx_resume, 3344 .resume = azx_resume_pci,
2918#endif 3345#endif
2919}; 3346};
2920 3347
3348#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
3349static int __devinit azx_probe_platform(struct platform_device *pdev)
3350{
3351 const struct platform_device_id *pdev_id = platform_get_device_id(pdev);
3352
3353 return azx_probe(NULL, pdev, pdev_id->driver_data);
3354}
3355
3356static int __devexit azx_remove_platform(struct platform_device *pdev)
3357{
3358 return snd_card_free(dev_get_drvdata(&pdev->dev));
3359}
3360
3361static const struct platform_device_id azx_platform_ids[] = {
3362#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
3363 { "tegra30-hda",
3364 .driver_data = AZX_DRIVER_NVIDIA_TEGRA | AZX_DCAPS_RIRB_DELAY },
3365#endif
3366 { },
3367};
3368MODULE_DEVICE_TABLE(platform, azx_platform_ids);
3369
3370/* platform_driver definition */
3371static struct platform_driver hda_platform_driver = {
3372 .driver = {
3373 .name = "hda-platform"
3374 },
3375 .probe = azx_probe_platform,
3376 .remove = __devexit_p(azx_remove_platform),
3377 .id_table = azx_platform_ids,
3378#ifdef CONFIG_PM
3379 .suspend = azx_suspend_platform,
3380 .resume = azx_resume_platform,
3381#endif
3382};
3383#endif /* CONFIG_SND_HDA_PLATFORM_DRIVER */
3384
2921static int __init alsa_card_azx_init(void) 3385static int __init alsa_card_azx_init(void)
2922{ 3386{
2923 return pci_register_driver(&driver); 3387 int err = 0;
3388
3389 err = pci_register_driver(&driver);
3390 if (err < 0) {
3391 snd_printk(KERN_ERR SFX "Failed to register pci driver\n");
3392 return err;
3393 }
3394
3395#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
3396 err = platform_driver_register(&hda_platform_driver);
3397 if (err < 0) {
3398 snd_printk(KERN_ERR SFX "Failed to register platform driver\n");
3399 pci_unregister_driver(&driver);
3400 return err;
3401 }
3402#endif
3403
3404 return 0;
2924} 3405}
2925 3406
2926static void __exit alsa_card_azx_exit(void) 3407static void __exit alsa_card_azx_exit(void)
2927{ 3408{
3409#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER
3410 platform_driver_unregister(&hda_platform_driver);
3411#endif
3412
2928 pci_unregister_driver(&driver); 3413 pci_unregister_driver(&driver);
2929} 3414}
2930 3415
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 08ec073444e..d95a48491a3 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -131,7 +131,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
131 int direction, int idx, int mask, int val); 131 int direction, int idx, int mask, int val);
132int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, 132int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
133 int dir, int idx, int mask, int val); 133 int dir, int idx, int mask, int val);
134#ifdef SND_HDA_NEEDS_RESUME 134#ifdef CONFIG_PM
135void snd_hda_codec_resume_amp(struct hda_codec *codec); 135void snd_hda_codec_resume_amp(struct hda_codec *codec);
136#endif 136#endif
137 137
@@ -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/*
@@ -474,7 +476,12 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
474} 476}
475 477
476/* get the widget type from widget capability bits */ 478/* get the widget type from widget capability bits */
477#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT) 479static inline int get_wcaps_type(unsigned int wcaps)
480{
481 if (!wcaps)
482 return -1; /* invalid type */
483 return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
484}
478 485
479static inline unsigned int get_wcaps_channels(u32 wcaps) 486static inline unsigned int get_wcaps_channels(u32 wcaps)
480{ 487{
@@ -563,7 +570,6 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
563 * power-management 570 * power-management
564 */ 571 */
565 572
566#ifdef CONFIG_SND_HDA_POWER_SAVE
567void snd_hda_schedule_power_save(struct hda_codec *codec); 573void snd_hda_schedule_power_save(struct hda_codec *codec);
568 574
569struct hda_amp_list { 575struct hda_amp_list {
@@ -580,7 +586,6 @@ struct hda_loopback_check {
580int snd_hda_check_amp_list_power(struct hda_codec *codec, 586int snd_hda_check_amp_list_power(struct hda_codec *codec,
581 struct hda_loopback_check *check, 587 struct hda_loopback_check *check,
582 hda_nid_t nid); 588 hda_nid_t nid);
583#endif /* CONFIG_SND_HDA_POWER_SAVE */
584 589
585/* 590/*
586 * AMP control callbacks 591 * AMP control callbacks
@@ -616,6 +621,7 @@ struct cea_sad {
616struct hdmi_eld { 621struct hdmi_eld {
617 bool monitor_present; 622 bool monitor_present;
618 bool eld_valid; 623 bool eld_valid;
624 bool lpcm_sad_ready;
619 int eld_size; 625 int eld_size;
620 int baseline_len; 626 int baseline_len;
621 int eld_ver; 627 int eld_ver;
@@ -639,8 +645,8 @@ struct hdmi_eld {
639int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid); 645int 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); 646int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
641void snd_hdmi_show_eld(struct hdmi_eld *eld); 647void snd_hdmi_show_eld(struct hdmi_eld *eld);
642void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, 648void snd_hdmi_eld_update_pcm_info(struct hdmi_eld *eld,
643 struct hda_pcm_stream *codec_pars); 649 struct hda_pcm_stream *hinfo);
644 650
645#ifdef CONFIG_PROC_FS 651#ifdef CONFIG_PROC_FS
646int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld, 652int 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 bfe74c2fb07..6936c37b305 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -54,6 +54,8 @@ static const char *get_wid_type_name(unsigned int wid_value)
54 [AC_WID_BEEP] = "Beep Generator Widget", 54 [AC_WID_BEEP] = "Beep Generator Widget",
55 [AC_WID_VENDOR] = "Vendor Defined Widget", 55 [AC_WID_VENDOR] = "Vendor Defined Widget",
56 }; 56 };
57 if (wid_value == -1)
58 return "UNKNOWN Widget";
57 wid_value &= 0xf; 59 wid_value &= 0xf;
58 if (names[wid_value]) 60 if (names[wid_value])
59 return names[wid_value]; 61 return names[wid_value];
@@ -636,7 +638,7 @@ static void print_codec_info(struct snd_info_entry *entry,
636 wid_caps |= AC_WCAP_CONN_LIST; 638 wid_caps |= AC_WCAP_CONN_LIST;
637 639
638 if (wid_caps & AC_WCAP_CONN_LIST) 640 if (wid_caps & AC_WCAP_CONN_LIST)
639 conn_len = snd_hda_get_connections(codec, nid, conn, 641 conn_len = snd_hda_get_raw_connections(codec, nid, conn,
640 HDA_MAX_CONNECTIONS); 642 HDA_MAX_CONNECTIONS);
641 643
642 if (wid_caps & AC_WCAP_IN_AMP) { 644 if (wid_caps & AC_WCAP_IN_AMP) {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d694e9d4921..8648917acff 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,
@@ -561,7 +563,7 @@ static void ad198x_free(struct hda_codec *codec)
561 snd_hda_detach_beep_device(codec); 563 snd_hda_detach_beep_device(codec);
562} 564}
563 565
564#ifdef SND_HDA_NEEDS_RESUME 566#ifdef CONFIG_PM
565static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 567static int ad198x_suspend(struct hda_codec *codec, pm_message_t state)
566{ 568{
567 ad198x_shutup(codec); 569 ad198x_shutup(codec);
@@ -577,7 +579,7 @@ static const struct hda_codec_ops ad198x_patch_ops = {
577#ifdef CONFIG_SND_HDA_POWER_SAVE 579#ifdef CONFIG_SND_HDA_POWER_SAVE
578 .check_power_status = ad198x_check_power_status, 580 .check_power_status = ad198x_check_power_status,
579#endif 581#endif
580#ifdef SND_HDA_NEEDS_RESUME 582#ifdef CONFIG_PM
581 .suspend = ad198x_suspend, 583 .suspend = ad198x_suspend,
582#endif 584#endif
583 .reboot_notify = ad198x_shutup, 585 .reboot_notify = ad198x_shutup,
@@ -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 61b92634b16..6b406840846 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 00000000000..d9a2254ceef
--- /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 26a1521045b..3546d38db8a 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -25,6 +25,7 @@
25#include <sound/core.h> 25#include <sound/core.h>
26#include "hda_codec.h" 26#include "hda_codec.h"
27#include "hda_local.h" 27#include "hda_local.h"
28#include <sound/tlv.h>
28 29
29/* 30/*
30 */ 31 */
@@ -61,9 +62,15 @@ struct cs_spec {
61 62
62 unsigned int hp_detect:1; 63 unsigned int hp_detect:1;
63 unsigned int mic_detect:1; 64 unsigned int mic_detect:1;
65 /* CS421x */
66 unsigned int spdif_detect:1;
67 unsigned int sense_b:1;
68 hda_nid_t vendor_nid;
69 struct hda_input_mux input_mux;
70 unsigned int last_input;
64}; 71};
65 72
66/* available models */ 73/* available models with CS420x */
67enum { 74enum {
68 CS420X_MBP53, 75 CS420X_MBP53,
69 CS420X_MBP55, 76 CS420X_MBP55,
@@ -72,6 +79,12 @@ enum {
72 CS420X_MODELS 79 CS420X_MODELS
73}; 80};
74 81
82/* CS421x boards */
83enum {
84 CS421X_CDB4210,
85 CS421X_MODELS
86};
87
75/* Vendor-specific processing widget */ 88/* Vendor-specific processing widget */
76#define CS420X_VENDOR_NID 0x11 89#define CS420X_VENDOR_NID 0x11
77#define CS_DIG_OUT1_PIN_NID 0x10 90#define CS_DIG_OUT1_PIN_NID 0x10
@@ -111,21 +124,42 @@ enum {
111/* 0x0009 - 0x0014 -> 12 test regs */ 124/* 0x0009 - 0x0014 -> 12 test regs */
112/* 0x0015 - visibility reg */ 125/* 0x0015 - visibility reg */
113 126
127/*
128 * Cirrus Logic CS4210
129 *
130 * 1 DAC => HP(sense) / Speakers,
131 * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
132 * 1 SPDIF OUT => SPDIF Trasmitter(sense)
133*/
134#define CS4210_DAC_NID 0x02
135#define CS4210_ADC_NID 0x03
136#define CS421X_VENDOR_NID 0x0B
137#define CS421X_DMIC_PIN_NID 0x09 /* Port E */
138#define CS421X_SPDIF_PIN_NID 0x0A /* Port H */
139
140#define CS421X_IDX_DEV_CFG 0x01
141#define CS421X_IDX_ADC_CFG 0x02
142#define CS421X_IDX_DAC_CFG 0x03
143#define CS421X_IDX_SPK_CTL 0x04
144
145#define SPDIF_EVENT 0x04
114 146
115static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) 147static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
116{ 148{
117 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 149 struct cs_spec *spec = codec->spec;
150 snd_hda_codec_write(codec, spec->vendor_nid, 0,
118 AC_VERB_SET_COEF_INDEX, idx); 151 AC_VERB_SET_COEF_INDEX, idx);
119 return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0, 152 return snd_hda_codec_read(codec, spec->vendor_nid, 0,
120 AC_VERB_GET_PROC_COEF, 0); 153 AC_VERB_GET_PROC_COEF, 0);
121} 154}
122 155
123static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, 156static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
124 unsigned int coef) 157 unsigned int coef)
125{ 158{
126 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 159 struct cs_spec *spec = codec->spec;
160 snd_hda_codec_write(codec, spec->vendor_nid, 0,
127 AC_VERB_SET_COEF_INDEX, idx); 161 AC_VERB_SET_COEF_INDEX, idx);
128 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, 162 snd_hda_codec_write(codec, spec->vendor_nid, 0,
129 AC_VERB_SET_PROC_COEF, coef); 163 AC_VERB_SET_PROC_COEF, coef);
130} 164}
131 165
@@ -202,6 +236,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
202 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 236 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
203} 237}
204 238
239static void cs_update_input_select(struct hda_codec *codec)
240{
241 struct cs_spec *spec = codec->spec;
242 if (spec->cur_adc)
243 snd_hda_codec_write(codec, spec->cur_adc, 0,
244 AC_VERB_SET_CONNECT_SEL,
245 spec->adc_idx[spec->cur_input]);
246}
247
205/* 248/*
206 * Analog capture 249 * Analog capture
207 */ 250 */
@@ -215,6 +258,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
215 spec->cur_adc = spec->adc_nid[spec->cur_input]; 258 spec->cur_adc = spec->adc_nid[spec->cur_input];
216 spec->cur_adc_stream_tag = stream_tag; 259 spec->cur_adc_stream_tag = stream_tag;
217 spec->cur_adc_format = format; 260 spec->cur_adc_format = format;
261 cs_update_input_select(codec);
218 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 262 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
219 return 0; 263 return 0;
220} 264}
@@ -341,26 +385,19 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
341static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, 385static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
342 unsigned int *idxp) 386 unsigned int *idxp)
343{ 387{
344 int i; 388 int i, idx;
345 hda_nid_t nid; 389 hda_nid_t nid;
346 390
347 nid = codec->start_nid; 391 nid = codec->start_nid;
348 for (i = 0; i < codec->num_nodes; i++, nid++) { 392 for (i = 0; i < codec->num_nodes; i++, nid++) {
349 hda_nid_t pins[2];
350 unsigned int type; 393 unsigned int type;
351 int j, nums;
352 type = get_wcaps_type(get_wcaps(codec, nid)); 394 type = get_wcaps_type(get_wcaps(codec, nid));
353 if (type != AC_WID_AUD_IN) 395 if (type != AC_WID_AUD_IN)
354 continue; 396 continue;
355 nums = snd_hda_get_connections(codec, nid, pins, 397 idx = snd_hda_get_conn_index(codec, nid, pin, false);
356 ARRAY_SIZE(pins)); 398 if (idx >= 0) {
357 if (nums <= 0) 399 *idxp = idx;
358 continue; 400 return nid;
359 for (j = 0; j < nums; j++) {
360 if (pins[j] == pin) {
361 *idxp = j;
362 return nid;
363 }
364 } 401 }
365 } 402 }
366 return 0; 403 return 0;
@@ -508,7 +545,7 @@ static int add_volume(struct hda_codec *codec, const char *name,
508 int index, unsigned int pval, int dir, 545 int index, unsigned int pval, int dir,
509 struct snd_kcontrol **kctlp) 546 struct snd_kcontrol **kctlp)
510{ 547{
511 char tmp[32]; 548 char tmp[44];
512 struct snd_kcontrol_new knew = 549 struct snd_kcontrol_new knew =
513 HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT); 550 HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
514 knew.private_value = pval; 551 knew.private_value = pval;
@@ -661,10 +698,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx,
661 spec->cur_adc_stream_tag, 0, 698 spec->cur_adc_stream_tag, 0,
662 spec->cur_adc_format); 699 spec->cur_adc_format);
663 } 700 }
664 snd_hda_codec_write(codec, spec->cur_adc, 0,
665 AC_VERB_SET_CONNECT_SEL,
666 spec->adc_idx[idx]);
667 spec->cur_input = idx; 701 spec->cur_input = idx;
702 cs_update_input_select(codec);
668 return 1; 703 return 1;
669} 704}
670 705
@@ -821,7 +856,8 @@ static int build_digital_output(struct hda_codec *codec)
821 if (!spec->multiout.dig_out_nid) 856 if (!spec->multiout.dig_out_nid)
822 return 0; 857 return 0;
823 858
824 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 859 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid,
860 spec->multiout.dig_out_nid);
825 if (err < 0) 861 if (err < 0)
826 return err; 862 return err;
827 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); 863 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
@@ -840,6 +876,8 @@ static int build_digital_input(struct hda_codec *codec)
840 876
841/* 877/*
842 * auto-mute and auto-mic switching 878 * auto-mute and auto-mic switching
879 * CS421x auto-output redirecting
880 * HP/SPK/SPDIF
843 */ 881 */
844 882
845static void cs_automute(struct hda_codec *codec) 883static void cs_automute(struct hda_codec *codec)
@@ -847,9 +885,25 @@ static void cs_automute(struct hda_codec *codec)
847 struct cs_spec *spec = codec->spec; 885 struct cs_spec *spec = codec->spec;
848 struct auto_pin_cfg *cfg = &spec->autocfg; 886 struct auto_pin_cfg *cfg = &spec->autocfg;
849 unsigned int hp_present; 887 unsigned int hp_present;
888 unsigned int spdif_present;
850 hda_nid_t nid; 889 hda_nid_t nid;
851 int i; 890 int i;
852 891
892 spdif_present = 0;
893 if (cfg->dig_outs) {
894 nid = cfg->dig_out_pins[0];
895 if (is_jack_detectable(codec, nid)) {
896 /*
897 TODO: SPDIF output redirect when SENSE_B is enabled.
898 Shared (SENSE_A) jack (e.g HP/mini-TOSLINK)
899 assumed.
900 */
901 if (snd_hda_jack_detect(codec, nid)
902 /* && spec->sense_b */)
903 spdif_present = 1;
904 }
905 }
906
853 hp_present = 0; 907 hp_present = 0;
854 for (i = 0; i < cfg->hp_outs; i++) { 908 for (i = 0; i < cfg->hp_outs; i++) {
855 nid = cfg->hp_pins[i]; 909 nid = cfg->hp_pins[i];
@@ -859,11 +913,17 @@ static void cs_automute(struct hda_codec *codec)
859 if (hp_present) 913 if (hp_present)
860 break; 914 break;
861 } 915 }
916
917 /* mute speakers if spdif or hp jack is plugged in */
862 for (i = 0; i < cfg->speaker_outs; i++) { 918 for (i = 0; i < cfg->speaker_outs; i++) {
919 int pin_ctl = hp_present ? 0 : PIN_OUT;
920 /* detect on spdif is specific to CS421x */
921 if (spdif_present && (spec->vendor_nid == CS421X_VENDOR_NID))
922 pin_ctl = 0;
923
863 nid = cfg->speaker_pins[i]; 924 nid = cfg->speaker_pins[i];
864 snd_hda_codec_write(codec, nid, 0, 925 snd_hda_codec_write(codec, nid, 0,
865 AC_VERB_SET_PIN_WIDGET_CONTROL, 926 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl);
866 hp_present ? 0 : PIN_OUT);
867 } 927 }
868 if (spec->board_config == CS420X_MBP53 || 928 if (spec->board_config == CS420X_MBP53 ||
869 spec->board_config == CS420X_MBP55 || 929 spec->board_config == CS420X_MBP55 ||
@@ -872,21 +932,59 @@ static void cs_automute(struct hda_codec *codec)
872 snd_hda_codec_write(codec, 0x01, 0, 932 snd_hda_codec_write(codec, 0x01, 0,
873 AC_VERB_SET_GPIO_DATA, gpio); 933 AC_VERB_SET_GPIO_DATA, gpio);
874 } 934 }
935
936 /* specific to CS421x */
937 if (spec->vendor_nid == CS421X_VENDOR_NID) {
938 /* mute HPs if spdif jack (SENSE_B) is present */
939 for (i = 0; i < cfg->hp_outs; i++) {
940 nid = cfg->hp_pins[i];
941 snd_hda_codec_write(codec, nid, 0,
942 AC_VERB_SET_PIN_WIDGET_CONTROL,
943 (spdif_present && spec->sense_b) ? 0 : PIN_HP);
944 }
945
946 /* SPDIF TX on/off */
947 if (cfg->dig_outs) {
948 nid = cfg->dig_out_pins[0];
949 snd_hda_codec_write(codec, nid, 0,
950 AC_VERB_SET_PIN_WIDGET_CONTROL,
951 spdif_present ? PIN_OUT : 0);
952
953 }
954 /* Update board GPIOs if neccessary ... */
955 }
875} 956}
876 957
958/*
959 * Auto-input redirect for CS421x
960 * Switch max 3 inputs of a single ADC (nid 3)
961*/
962
877static void cs_automic(struct hda_codec *codec) 963static void cs_automic(struct hda_codec *codec)
878{ 964{
879 struct cs_spec *spec = codec->spec; 965 struct cs_spec *spec = codec->spec;
880 struct auto_pin_cfg *cfg = &spec->autocfg; 966 struct auto_pin_cfg *cfg = &spec->autocfg;
881 hda_nid_t nid; 967 hda_nid_t nid;
882 unsigned int present; 968 unsigned int present;
883 969
884 nid = cfg->inputs[spec->automic_idx].pin; 970 nid = cfg->inputs[spec->automic_idx].pin;
885 present = snd_hda_jack_detect(codec, nid); 971 present = snd_hda_jack_detect(codec, nid);
886 if (present) 972
887 change_cur_input(codec, spec->automic_idx, 0); 973 /* specific to CS421x, single ADC */
888 else 974 if (spec->vendor_nid == CS421X_VENDOR_NID) {
889 change_cur_input(codec, !spec->automic_idx, 0); 975 if (present) {
976 spec->last_input = spec->cur_input;
977 spec->cur_input = spec->automic_idx;
978 } else {
979 spec->cur_input = spec->last_input;
980 }
981 cs_update_input_select(codec);
982 } else {
983 if (present)
984 change_cur_input(codec, spec->automic_idx, 0);
985 else
986 change_cur_input(codec, !spec->automic_idx, 0);
987 }
890} 988}
891 989
892/* 990/*
@@ -916,23 +1014,28 @@ static void init_output(struct hda_codec *codec)
916 for (i = 0; i < cfg->line_outs; i++) 1014 for (i = 0; i < cfg->line_outs; i++)
917 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, 1015 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
918 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1016 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1017 /* HP */
919 for (i = 0; i < cfg->hp_outs; i++) { 1018 for (i = 0; i < cfg->hp_outs; i++) {
920 hda_nid_t nid = cfg->hp_pins[i]; 1019 hda_nid_t nid = cfg->hp_pins[i];
921 snd_hda_codec_write(codec, nid, 0, 1020 snd_hda_codec_write(codec, nid, 0,
922 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); 1021 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
923 if (!cfg->speaker_outs) 1022 if (!cfg->speaker_outs)
924 continue; 1023 continue;
925 if (is_jack_detectable(codec, nid)) { 1024 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
926 snd_hda_codec_write(codec, nid, 0, 1025 snd_hda_codec_write(codec, nid, 0,
927 AC_VERB_SET_UNSOLICITED_ENABLE, 1026 AC_VERB_SET_UNSOLICITED_ENABLE,
928 AC_USRSP_EN | HP_EVENT); 1027 AC_USRSP_EN | HP_EVENT);
929 spec->hp_detect = 1; 1028 spec->hp_detect = 1;
930 } 1029 }
931 } 1030 }
1031
1032 /* Speaker */
932 for (i = 0; i < cfg->speaker_outs; i++) 1033 for (i = 0; i < cfg->speaker_outs; i++)
933 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 1034 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
934 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1035 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
935 if (spec->hp_detect) 1036
1037 /* SPDIF is enabled on presence detect for CS421x */
1038 if (spec->hp_detect || spec->spdif_detect)
936 cs_automute(codec); 1039 cs_automute(codec);
937} 1040}
938 1041
@@ -966,19 +1069,29 @@ static void init_input(struct hda_codec *codec)
966 AC_VERB_SET_UNSOLICITED_ENABLE, 1069 AC_VERB_SET_UNSOLICITED_ENABLE,
967 AC_USRSP_EN | MIC_EVENT); 1070 AC_USRSP_EN | MIC_EVENT);
968 } 1071 }
969 change_cur_input(codec, spec->cur_input, 1); 1072 /* specific to CS421x */
970 if (spec->mic_detect) 1073 if (spec->vendor_nid == CS421X_VENDOR_NID) {
971 cs_automic(codec); 1074 if (spec->mic_detect)
972 1075 cs_automic(codec);
973 coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ 1076 else {
974 if (is_active_pin(codec, CS_DMIC2_PIN_NID)) 1077 spec->cur_adc = spec->adc_nid[spec->cur_input];
975 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ 1078 cs_update_input_select(codec);
976 if (is_active_pin(codec, CS_DMIC1_PIN_NID)) 1079 }
977 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 1080 } else {
978 * No effect if SPDIF_OUT2 is selected in 1081 change_cur_input(codec, spec->cur_input, 1);
979 * IDX_SPDIF_CTL. 1082 if (spec->mic_detect)
980 */ 1083 cs_automic(codec);
981 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 1084
1085 coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
1086 if (is_active_pin(codec, CS_DMIC2_PIN_NID))
1087 coef |= 0x0500; /* DMIC2 2 chan on, GPIO1 off */
1088 if (is_active_pin(codec, CS_DMIC1_PIN_NID))
1089 coef |= 0x1800; /* DMIC1 2 chan on, GPIO0 off
1090 * No effect if SPDIF_OUT2 is
1091 * selected in IDX_SPDIF_CTL.
1092 */
1093 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
1094 }
982} 1095}
983 1096
984static const struct hda_verb cs_coef_init_verbs[] = { 1097static const struct hda_verb cs_coef_init_verbs[] = {
@@ -1226,16 +1339,16 @@ static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1226 [CS420X_IMAC27] = imac27_pincfgs, 1339 [CS420X_IMAC27] = imac27_pincfgs,
1227}; 1340};
1228 1341
1229static void fix_pincfg(struct hda_codec *codec, int model) 1342static void fix_pincfg(struct hda_codec *codec, int model,
1343 const struct cs_pincfg **pin_configs)
1230{ 1344{
1231 const struct cs_pincfg *cfg = cs_pincfgs[model]; 1345 const struct cs_pincfg *cfg = pin_configs[model];
1232 if (!cfg) 1346 if (!cfg)
1233 return; 1347 return;
1234 for (; cfg->nid; cfg++) 1348 for (; cfg->nid; cfg++)
1235 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1349 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1236} 1350}
1237 1351
1238
1239static int patch_cs420x(struct hda_codec *codec) 1352static int patch_cs420x(struct hda_codec *codec)
1240{ 1353{
1241 struct cs_spec *spec; 1354 struct cs_spec *spec;
@@ -1246,11 +1359,13 @@ static int patch_cs420x(struct hda_codec *codec)
1246 return -ENOMEM; 1359 return -ENOMEM;
1247 codec->spec = spec; 1360 codec->spec = spec;
1248 1361
1362 spec->vendor_nid = CS420X_VENDOR_NID;
1363
1249 spec->board_config = 1364 spec->board_config =
1250 snd_hda_check_board_config(codec, CS420X_MODELS, 1365 snd_hda_check_board_config(codec, CS420X_MODELS,
1251 cs420x_models, cs420x_cfg_tbl); 1366 cs420x_models, cs420x_cfg_tbl);
1252 if (spec->board_config >= 0) 1367 if (spec->board_config >= 0)
1253 fix_pincfg(codec, spec->board_config); 1368 fix_pincfg(codec, spec->board_config, cs_pincfgs);
1254 1369
1255 switch (spec->board_config) { 1370 switch (spec->board_config) {
1256 case CS420X_IMAC27: 1371 case CS420X_IMAC27:
@@ -1277,6 +1392,551 @@ static int patch_cs420x(struct hda_codec *codec)
1277 return err; 1392 return err;
1278} 1393}
1279 1394
1395/*
1396 * Cirrus Logic CS4210
1397 *
1398 * 1 DAC => HP(sense) / Speakers,
1399 * 1 ADC <= LineIn(sense) / MicIn / DMicIn,
1400 * 1 SPDIF OUT => SPDIF Trasmitter(sense)
1401*/
1402
1403/* CS4210 board names */
1404static const char *cs421x_models[CS421X_MODELS] = {
1405 [CS421X_CDB4210] = "cdb4210",
1406};
1407
1408static const struct snd_pci_quirk cs421x_cfg_tbl[] = {
1409 /* Test Intel board + CDB2410 */
1410 SND_PCI_QUIRK(0x8086, 0x5001, "DP45SG/CDB4210", CS421X_CDB4210),
1411 {} /* terminator */
1412};
1413
1414/* CS4210 board pinconfigs */
1415/* Default CS4210 (CDB4210)*/
1416static const struct cs_pincfg cdb4210_pincfgs[] = {
1417 { 0x05, 0x0321401f },
1418 { 0x06, 0x90170010 },
1419 { 0x07, 0x03813031 },
1420 { 0x08, 0xb7a70037 },
1421 { 0x09, 0xb7a6003e },
1422 { 0x0a, 0x034510f0 },
1423 {} /* terminator */
1424};
1425
1426static const struct cs_pincfg *cs421x_pincfgs[CS421X_MODELS] = {
1427 [CS421X_CDB4210] = cdb4210_pincfgs,
1428};
1429
1430static const struct hda_verb cs421x_coef_init_verbs[] = {
1431 {0x0B, AC_VERB_SET_PROC_STATE, 1},
1432 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DEV_CFG},
1433 /*
1434 Disable Coefficient Index Auto-Increment(DAI)=1,
1435 PDREF=0
1436 */
1437 {0x0B, AC_VERB_SET_PROC_COEF, 0x0001 },
1438
1439 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_ADC_CFG},
1440 /* ADC SZCMode = Digital Soft Ramp */
1441 {0x0B, AC_VERB_SET_PROC_COEF, 0x0002 },
1442
1443 {0x0B, AC_VERB_SET_COEF_INDEX, CS421X_IDX_DAC_CFG},
1444 {0x0B, AC_VERB_SET_PROC_COEF,
1445 (0x0002 /* DAC SZCMode = Digital Soft Ramp */
1446 | 0x0004 /* Mute DAC on FIFO error */
1447 | 0x0008 /* Enable DAC High Pass Filter */
1448 )},
1449 {} /* terminator */
1450};
1451
1452/* Errata: CS4210 rev A1 Silicon
1453 *
1454 * http://www.cirrus.com/en/pubs/errata/
1455 *
1456 * Description:
1457 * 1. Performance degredation is present in the ADC.
1458 * 2. Speaker output is not completely muted upon HP detect.
1459 * 3. Noise is present when clipping occurs on the amplified
1460 * speaker outputs.
1461 *
1462 * Workaround:
1463 * The following verb sequence written to the registers during
1464 * initialization will correct the issues listed above.
1465 */
1466
1467static const struct hda_verb cs421x_coef_init_verbs_A1_silicon_fixes[] = {
1468 {0x0B, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */
1469
1470 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0006},
1471 {0x0B, AC_VERB_SET_PROC_COEF, 0x9999}, /* Test mode: on */
1472
1473 {0x0B, AC_VERB_SET_COEF_INDEX, 0x000A},
1474 {0x0B, AC_VERB_SET_PROC_COEF, 0x14CB}, /* Chop double */
1475
1476 {0x0B, AC_VERB_SET_COEF_INDEX, 0x0011},
1477 {0x0B, AC_VERB_SET_PROC_COEF, 0xA2D0}, /* Increase ADC current */
1478
1479 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001A},
1480 {0x0B, AC_VERB_SET_PROC_COEF, 0x02A9}, /* Mute speaker */
1481
1482 {0x0B, AC_VERB_SET_COEF_INDEX, 0x001B},
1483 {0x0B, AC_VERB_SET_PROC_COEF, 0X1006}, /* Remove noise */
1484
1485 {} /* terminator */
1486};
1487
1488/* Speaker Amp Gain is controlled by the vendor widget's coef 4 */
1489static const DECLARE_TLV_DB_SCALE(cs421x_speaker_boost_db_scale, 900, 300, 0);
1490
1491static int cs421x_boost_vol_info(struct snd_kcontrol *kcontrol,
1492 struct snd_ctl_elem_info *uinfo)
1493{
1494 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1495 uinfo->count = 1;
1496 uinfo->value.integer.min = 0;
1497 uinfo->value.integer.max = 3;
1498 return 0;
1499}
1500
1501static int cs421x_boost_vol_get(struct snd_kcontrol *kcontrol,
1502 struct snd_ctl_elem_value *ucontrol)
1503{
1504 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1505
1506 ucontrol->value.integer.value[0] =
1507 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL) & 0x0003;
1508 return 0;
1509}
1510
1511static int cs421x_boost_vol_put(struct snd_kcontrol *kcontrol,
1512 struct snd_ctl_elem_value *ucontrol)
1513{
1514 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1515
1516 unsigned int vol = ucontrol->value.integer.value[0];
1517 unsigned int coef =
1518 cs_vendor_coef_get(codec, CS421X_IDX_SPK_CTL);
1519 unsigned int original_coef = coef;
1520
1521 coef &= ~0x0003;
1522 coef |= (vol & 0x0003);
1523 if (original_coef == coef)
1524 return 0;
1525 else {
1526 cs_vendor_coef_set(codec, CS421X_IDX_SPK_CTL, coef);
1527 return 1;
1528 }
1529}
1530
1531static const struct snd_kcontrol_new cs421x_speaker_bost_ctl = {
1532
1533 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1534 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1535 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
1536 .name = "Speaker Boost Playback Volume",
1537 .info = cs421x_boost_vol_info,
1538 .get = cs421x_boost_vol_get,
1539 .put = cs421x_boost_vol_put,
1540 .tlv = { .p = cs421x_speaker_boost_db_scale },
1541};
1542
1543static void cs421x_pinmux_init(struct hda_codec *codec)
1544{
1545 struct cs_spec *spec = codec->spec;
1546 unsigned int def_conf, coef;
1547
1548 /* GPIO, DMIC_SCL, DMIC_SDA and SENSE_B are multiplexed */
1549 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
1550
1551 if (spec->gpio_mask)
1552 coef |= 0x0008; /* B1,B2 are GPIOs */
1553 else
1554 coef &= ~0x0008;
1555
1556 if (spec->sense_b)
1557 coef |= 0x0010; /* B2 is SENSE_B, not inverted */
1558 else
1559 coef &= ~0x0010;
1560
1561 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
1562
1563 if ((spec->gpio_mask || spec->sense_b) &&
1564 is_active_pin(codec, CS421X_DMIC_PIN_NID)) {
1565
1566 /*
1567 GPIO or SENSE_B forced - disconnect the DMIC pin.
1568 */
1569 def_conf = snd_hda_codec_get_pincfg(codec, CS421X_DMIC_PIN_NID);
1570 def_conf &= ~AC_DEFCFG_PORT_CONN;
1571 def_conf |= (AC_JACK_PORT_NONE << AC_DEFCFG_PORT_CONN_SHIFT);
1572 snd_hda_codec_set_pincfg(codec, CS421X_DMIC_PIN_NID, def_conf);
1573 }
1574}
1575
1576static void init_cs421x_digital(struct hda_codec *codec)
1577{
1578 struct cs_spec *spec = codec->spec;
1579 struct auto_pin_cfg *cfg = &spec->autocfg;
1580 int i;
1581
1582
1583 for (i = 0; i < cfg->dig_outs; i++) {
1584 hda_nid_t nid = cfg->dig_out_pins[i];
1585 if (!cfg->speaker_outs)
1586 continue;
1587 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
1588
1589 snd_hda_codec_write(codec, nid, 0,
1590 AC_VERB_SET_UNSOLICITED_ENABLE,
1591 AC_USRSP_EN | SPDIF_EVENT);
1592 spec->spdif_detect = 1;
1593 }
1594 }
1595}
1596
1597static int cs421x_init(struct hda_codec *codec)
1598{
1599 struct cs_spec *spec = codec->spec;
1600
1601 snd_hda_sequence_write(codec, cs421x_coef_init_verbs);
1602 snd_hda_sequence_write(codec, cs421x_coef_init_verbs_A1_silicon_fixes);
1603
1604 cs421x_pinmux_init(codec);
1605
1606 if (spec->gpio_mask) {
1607 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
1608 spec->gpio_mask);
1609 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
1610 spec->gpio_dir);
1611 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
1612 spec->gpio_data);
1613 }
1614
1615 init_output(codec);
1616 init_input(codec);
1617 init_cs421x_digital(codec);
1618
1619 return 0;
1620}
1621
1622/*
1623 * CS4210 Input MUX (1 ADC)
1624 */
1625static int cs421x_mux_enum_info(struct snd_kcontrol *kcontrol,
1626 struct snd_ctl_elem_info *uinfo)
1627{
1628 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1629 struct cs_spec *spec = codec->spec;
1630
1631 return snd_hda_input_mux_info(&spec->input_mux, uinfo);
1632}
1633
1634static int cs421x_mux_enum_get(struct snd_kcontrol *kcontrol,
1635 struct snd_ctl_elem_value *ucontrol)
1636{
1637 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1638 struct cs_spec *spec = codec->spec;
1639
1640 ucontrol->value.enumerated.item[0] = spec->cur_input;
1641 return 0;
1642}
1643
1644static int cs421x_mux_enum_put(struct snd_kcontrol *kcontrol,
1645 struct snd_ctl_elem_value *ucontrol)
1646{
1647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1648 struct cs_spec *spec = codec->spec;
1649
1650 return snd_hda_input_mux_put(codec, &spec->input_mux, ucontrol,
1651 spec->adc_nid[0], &spec->cur_input);
1652
1653}
1654
1655static struct snd_kcontrol_new cs421x_capture_source = {
1656
1657 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1658 .name = "Capture Source",
1659 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
1660 .info = cs421x_mux_enum_info,
1661 .get = cs421x_mux_enum_get,
1662 .put = cs421x_mux_enum_put,
1663};
1664
1665static int cs421x_add_input_volume_control(struct hda_codec *codec, int item)
1666{
1667 struct cs_spec *spec = codec->spec;
1668 struct auto_pin_cfg *cfg = &spec->autocfg;
1669 const struct hda_input_mux *imux = &spec->input_mux;
1670 hda_nid_t pin = cfg->inputs[item].pin;
1671 struct snd_kcontrol *kctl;
1672 u32 caps;
1673
1674 if (!(get_wcaps(codec, pin) & AC_WCAP_IN_AMP))
1675 return 0;
1676
1677 caps = query_amp_caps(codec, pin, HDA_INPUT);
1678 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1679 if (caps <= 1)
1680 return 0;
1681
1682 return add_volume(codec, imux->items[item].label, 0,
1683 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT), 1, &kctl);
1684}
1685
1686/* add a (input-boost) volume control to the given input pin */
1687static int build_cs421x_input(struct hda_codec *codec)
1688{
1689 struct cs_spec *spec = codec->spec;
1690 struct auto_pin_cfg *cfg = &spec->autocfg;
1691 struct hda_input_mux *imux = &spec->input_mux;
1692 int i, err, type_idx;
1693 const char *label;
1694
1695 if (!spec->num_inputs)
1696 return 0;
1697
1698 /* make bind-capture */
1699 spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
1700 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
1701 for (i = 0; i < 2; i++) {
1702 struct snd_kcontrol *kctl;
1703 int n;
1704 if (!spec->capture_bind[i])
1705 return -ENOMEM;
1706 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
1707 if (!kctl)
1708 return -ENOMEM;
1709 kctl->private_value = (long)spec->capture_bind[i];
1710 err = snd_hda_ctl_add(codec, 0, kctl);
1711 if (err < 0)
1712 return err;
1713 for (n = 0; n < AUTO_PIN_LAST; n++) {
1714 if (!spec->adc_nid[n])
1715 continue;
1716 err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]);
1717 if (err < 0)
1718 return err;
1719 }
1720 }
1721
1722 /* Add Input MUX Items + Capture Volume/Switch */
1723 for (i = 0; i < spec->num_inputs; i++) {
1724 label = hda_get_autocfg_input_label(codec, cfg, i);
1725 snd_hda_add_imux_item(imux, label, spec->adc_idx[i], &type_idx);
1726
1727 err = cs421x_add_input_volume_control(codec, i);
1728 if (err < 0)
1729 return err;
1730 }
1731
1732 /*
1733 Add 'Capture Source' Switch if
1734 * 2 inputs and no mic detec
1735 * 3 inputs
1736 */
1737 if ((spec->num_inputs == 2 && !spec->mic_detect) ||
1738 (spec->num_inputs == 3)) {
1739
1740 err = snd_hda_ctl_add(codec, spec->adc_nid[0],
1741 snd_ctl_new1(&cs421x_capture_source, codec));
1742 if (err < 0)
1743 return err;
1744 }
1745
1746 return 0;
1747}
1748
1749/* Single DAC (Mute/Gain) */
1750static int build_cs421x_output(struct hda_codec *codec)
1751{
1752 hda_nid_t dac = CS4210_DAC_NID;
1753 struct cs_spec *spec = codec->spec;
1754 struct auto_pin_cfg *cfg = &spec->autocfg;
1755 struct snd_kcontrol *kctl;
1756 int err;
1757 char *name = "Master";
1758
1759 fix_volume_caps(codec, dac);
1760
1761 err = add_mute(codec, name, 0,
1762 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
1763 if (err < 0)
1764 return err;
1765
1766 err = add_volume(codec, name, 0,
1767 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
1768 if (err < 0)
1769 return err;
1770
1771 if (cfg->speaker_outs) {
1772 err = snd_hda_ctl_add(codec, 0,
1773 snd_ctl_new1(&cs421x_speaker_bost_ctl, codec));
1774 if (err < 0)
1775 return err;
1776 }
1777 return err;
1778}
1779
1780static int cs421x_build_controls(struct hda_codec *codec)
1781{
1782 int err;
1783
1784 err = build_cs421x_output(codec);
1785 if (err < 0)
1786 return err;
1787 err = build_cs421x_input(codec);
1788 if (err < 0)
1789 return err;
1790 err = build_digital_output(codec);
1791 if (err < 0)
1792 return err;
1793 return cs421x_init(codec);
1794}
1795
1796static void cs421x_unsol_event(struct hda_codec *codec, unsigned int res)
1797{
1798 switch ((res >> 26) & 0x3f) {
1799 case HP_EVENT:
1800 case SPDIF_EVENT:
1801 cs_automute(codec);
1802 break;
1803
1804 case MIC_EVENT:
1805 cs_automic(codec);
1806 break;
1807 }
1808}
1809
1810static int parse_cs421x_input(struct hda_codec *codec)
1811{
1812 struct cs_spec *spec = codec->spec;
1813 struct auto_pin_cfg *cfg = &spec->autocfg;
1814 int i;
1815
1816 for (i = 0; i < cfg->num_inputs; i++) {
1817 hda_nid_t pin = cfg->inputs[i].pin;
1818 spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
1819 spec->cur_input = spec->last_input = i;
1820 spec->num_inputs++;
1821
1822 /* check whether the automatic mic switch is available */
1823 if (is_ext_mic(codec, i) && cfg->num_inputs >= 2) {
1824 spec->mic_detect = 1;
1825 spec->automic_idx = i;
1826 }
1827 }
1828 return 0;
1829}
1830
1831static int cs421x_parse_auto_config(struct hda_codec *codec)
1832{
1833 struct cs_spec *spec = codec->spec;
1834 int err;
1835
1836 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1837 if (err < 0)
1838 return err;
1839 err = parse_output(codec);
1840 if (err < 0)
1841 return err;
1842 err = parse_cs421x_input(codec);
1843 if (err < 0)
1844 return err;
1845 err = parse_digital_output(codec);
1846 if (err < 0)
1847 return err;
1848 return 0;
1849}
1850
1851#ifdef CONFIG_PM
1852/*
1853 Manage PDREF, when transitioning to D3hot
1854 (DAC,ADC) -> D3, PDREF=1, AFG->D3
1855*/
1856static int cs421x_suspend(struct hda_codec *codec, pm_message_t state)
1857{
1858 unsigned int coef;
1859
1860 snd_hda_shutup_pins(codec);
1861
1862 snd_hda_codec_write(codec, CS4210_DAC_NID, 0,
1863 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1864 snd_hda_codec_write(codec, CS4210_ADC_NID, 0,
1865 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
1866
1867 coef = cs_vendor_coef_get(codec, CS421X_IDX_DEV_CFG);
1868 coef |= 0x0004; /* PDREF */
1869 cs_vendor_coef_set(codec, CS421X_IDX_DEV_CFG, coef);
1870
1871 return 0;
1872}
1873#endif
1874
1875static struct hda_codec_ops cs4210_patch_ops = {
1876 .build_controls = cs421x_build_controls,
1877 .build_pcms = cs_build_pcms,
1878 .init = cs421x_init,
1879 .free = cs_free,
1880 .unsol_event = cs421x_unsol_event,
1881#ifdef CONFIG_PM
1882 .suspend = cs421x_suspend,
1883#endif
1884};
1885
1886static int patch_cs421x(struct hda_codec *codec)
1887{
1888 struct cs_spec *spec;
1889 int err;
1890
1891 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1892 if (!spec)
1893 return -ENOMEM;
1894 codec->spec = spec;
1895
1896 spec->vendor_nid = CS421X_VENDOR_NID;
1897
1898 spec->board_config =
1899 snd_hda_check_board_config(codec, CS421X_MODELS,
1900 cs421x_models, cs421x_cfg_tbl);
1901 if (spec->board_config >= 0)
1902 fix_pincfg(codec, spec->board_config, cs421x_pincfgs);
1903 /*
1904 Setup GPIO/SENSE for each board (if used)
1905 */
1906 switch (spec->board_config) {
1907 case CS421X_CDB4210:
1908 snd_printd("CS4210 board: %s\n",
1909 cs421x_models[spec->board_config]);
1910/* spec->gpio_mask = 3;
1911 spec->gpio_dir = 3;
1912 spec->gpio_data = 3;
1913*/
1914 spec->sense_b = 1;
1915
1916 break;
1917 }
1918
1919 /*
1920 Update the GPIO/DMIC/SENSE_B pinmux before the configuration
1921 is auto-parsed. If GPIO or SENSE_B is forced, DMIC input
1922 is disabled.
1923 */
1924 cs421x_pinmux_init(codec);
1925
1926 err = cs421x_parse_auto_config(codec);
1927 if (err < 0)
1928 goto error;
1929
1930 codec->patch_ops = cs4210_patch_ops;
1931
1932 return 0;
1933
1934 error:
1935 kfree(codec->spec);
1936 codec->spec = NULL;
1937 return err;
1938}
1939
1280 1940
1281/* 1941/*
1282 * patch entries 1942 * patch entries
@@ -1284,11 +1944,13 @@ static int patch_cs420x(struct hda_codec *codec)
1284static const struct hda_codec_preset snd_hda_preset_cirrus[] = { 1944static const struct hda_codec_preset snd_hda_preset_cirrus[] = {
1285 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, 1945 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1286 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, 1946 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1947 { .id = 0x10134210, .name = "CS4210", .patch = patch_cs421x },
1287 {} /* terminator */ 1948 {} /* terminator */
1288}; 1949};
1289 1950
1290MODULE_ALIAS("snd-hda-codec-id:10134206"); 1951MODULE_ALIAS("snd-hda-codec-id:10134206");
1291MODULE_ALIAS("snd-hda-codec-id:10134207"); 1952MODULE_ALIAS("snd-hda-codec-id:10134207");
1953MODULE_ALIAS("snd-hda-codec-id:10134210");
1292 1954
1293MODULE_LICENSE("GPL"); 1955MODULE_LICENSE("GPL");
1294MODULE_DESCRIPTION("Cirrus Logic HD-audio codec"); 1956MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index ab3308daa96..cd2cf5e94e8 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 7bbc5f237a5..85fe10d5858 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -136,6 +136,8 @@ struct conexant_spec {
136 unsigned int thinkpad:1; 136 unsigned int thinkpad:1;
137 unsigned int hp_laptop:1; 137 unsigned int hp_laptop:1;
138 unsigned int asus:1; 138 unsigned int asus:1;
139 unsigned int pin_eapd_ctrls:1;
140 unsigned int single_adc_amp:1;
139 141
140 unsigned int adc_switching:1; 142 unsigned int adc_switching:1;
141 143
@@ -155,6 +157,10 @@ struct conexant_spec {
155 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */ 157 unsigned int mic_boost; /* offset into cxt5066_analog_mic_boost */
156 158
157 unsigned int beep_amp; 159 unsigned int beep_amp;
160
161 /* extra EAPD pins */
162 unsigned int num_eapds;
163 hda_nid_t eapds[4];
158}; 164};
159 165
160static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 166static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -442,6 +448,19 @@ static int conexant_init_jacks(struct hda_codec *codec)
442 return 0; 448 return 0;
443} 449}
444 450
451static void conexant_set_power(struct hda_codec *codec, hda_nid_t fg,
452 unsigned int power_state)
453{
454 if (power_state == AC_PWRST_D3)
455 msleep(100);
456 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
457 power_state);
458 /* partial workaround for "azx_get_response timeout" */
459 if (power_state == AC_PWRST_D0)
460 msleep(10);
461 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
462}
463
445static int conexant_init(struct hda_codec *codec) 464static int conexant_init(struct hda_codec *codec)
446{ 465{
447 struct conexant_spec *spec = codec->spec; 466 struct conexant_spec *spec = codec->spec;
@@ -510,6 +529,7 @@ static int conexant_build_controls(struct hda_codec *codec)
510 } 529 }
511 if (spec->multiout.dig_out_nid) { 530 if (spec->multiout.dig_out_nid) {
512 err = snd_hda_create_spdif_out_ctls(codec, 531 err = snd_hda_create_spdif_out_ctls(codec,
532 spec->multiout.dig_out_nid,
513 spec->multiout.dig_out_nid); 533 spec->multiout.dig_out_nid);
514 if (err < 0) 534 if (err < 0)
515 return err; 535 return err;
@@ -583,6 +603,7 @@ static const struct hda_codec_ops conexant_patch_ops = {
583 .build_pcms = conexant_build_pcms, 603 .build_pcms = conexant_build_pcms,
584 .init = conexant_init, 604 .init = conexant_init,
585 .free = conexant_free, 605 .free = conexant_free,
606 .set_power_state = conexant_set_power,
586#ifdef CONFIG_SND_HDA_POWER_SAVE 607#ifdef CONFIG_SND_HDA_POWER_SAVE
587 .suspend = conexant_suspend, 608 .suspend = conexant_suspend,
588#endif 609#endif
@@ -1098,8 +1119,6 @@ static const char * const cxt5045_models[CXT5045_MODELS] = {
1098 1119
1099static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { 1120static const struct snd_pci_quirk cxt5045_cfg_tbl[] = {
1100 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), 1121 SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530),
1101 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series",
1102 CXT5045_LAPTOP_HPSENSE),
1103 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), 1122 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE),
1104 SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), 1123 SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ),
1105 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), 1124 SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE),
@@ -1123,10 +1142,8 @@ static int patch_cxt5045(struct hda_codec *codec)
1123 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, 1142 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
1124 cxt5045_models, 1143 cxt5045_models,
1125 cxt5045_cfg_tbl); 1144 cxt5045_cfg_tbl);
1126#if 0 /* use the old method just for safety */
1127 if (board_config < 0) 1145 if (board_config < 0)
1128 board_config = CXT5045_AUTO; 1146 board_config = CXT5045_AUTO; /* model=auto as default */
1129#endif
1130 if (board_config == CXT5045_AUTO) 1147 if (board_config == CXT5045_AUTO)
1131 return patch_conexant_auto(codec); 1148 return patch_conexant_auto(codec);
1132 1149
@@ -1564,10 +1581,8 @@ static int patch_cxt5047(struct hda_codec *codec)
1564 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, 1581 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1565 cxt5047_models, 1582 cxt5047_models,
1566 cxt5047_cfg_tbl); 1583 cxt5047_cfg_tbl);
1567#if 0 /* not enabled as default, as BIOS often broken for this codec */
1568 if (board_config < 0) 1584 if (board_config < 0)
1569 board_config = CXT5047_AUTO; 1585 board_config = CXT5047_AUTO; /* model=auto as default */
1570#endif
1571 if (board_config == CXT5047_AUTO) 1586 if (board_config == CXT5047_AUTO)
1572 return patch_conexant_auto(codec); 1587 return patch_conexant_auto(codec);
1573 1588
@@ -1993,10 +2008,8 @@ static int patch_cxt5051(struct hda_codec *codec)
1993 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 2008 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1994 cxt5051_models, 2009 cxt5051_models,
1995 cxt5051_cfg_tbl); 2010 cxt5051_cfg_tbl);
1996#if 0 /* use the old method just for safety */
1997 if (board_config < 0) 2011 if (board_config < 0)
1998 board_config = CXT5051_AUTO; 2012 board_config = CXT5051_AUTO; /* model=auto as default */
1999#endif
2000 if (board_config == CXT5051_AUTO) 2013 if (board_config == CXT5051_AUTO)
2001 return patch_conexant_auto(codec); 2014 return patch_conexant_auto(codec);
2002 2015
@@ -3097,6 +3110,7 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3097 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), 3110 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3098 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), 3111 SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS),
3099 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), 3112 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3113 SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO),
3100 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), 3114 SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD),
3101 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), 3115 SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD),
3102 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), 3116 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS),
@@ -3114,10 +3128,8 @@ static int patch_cxt5066(struct hda_codec *codec)
3114 3128
3115 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, 3129 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
3116 cxt5066_models, cxt5066_cfg_tbl); 3130 cxt5066_models, cxt5066_cfg_tbl);
3117#if 0 /* use the old method just for safety */
3118 if (board_config < 0) 3131 if (board_config < 0)
3119 board_config = CXT5066_AUTO; 3132 board_config = CXT5066_AUTO; /* model=auto as default */
3120#endif
3121 if (board_config == CXT5066_AUTO) 3133 if (board_config == CXT5066_AUTO)
3122 return patch_conexant_auto(codec); 3134 return patch_conexant_auto(codec);
3123 3135
@@ -3308,19 +3320,8 @@ static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3308 3320
3309static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3321static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3310 3322
3311/* get the connection index of @nid in the widget @mux */ 3323#define get_connection_index(codec, mux, nid)\
3312static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3324 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 3325
3325/* get an unassigned DAC from the given list. 3326/* get an unassigned DAC from the given list.
3326 * Return the nid if found and reduce the DAC list, or return zero if 3327 * Return the nid if found and reduce the DAC list, or return zero if
@@ -3348,6 +3349,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
3348 3349
3349#define MAX_AUTO_DACS 5 3350#define MAX_AUTO_DACS 5
3350 3351
3352#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
3353
3351/* fill analog DAC list from the widget tree */ 3354/* fill analog DAC list from the widget tree */
3352static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) 3355static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3353{ 3356{
@@ -3370,16 +3373,26 @@ static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
3370/* fill pin_dac_pair list from the pin and dac list */ 3373/* fill pin_dac_pair list from the pin and dac list */
3371static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, 3374static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
3372 int num_pins, hda_nid_t *dacs, int *rest, 3375 int num_pins, hda_nid_t *dacs, int *rest,
3373 struct pin_dac_pair *filled, int type) 3376 struct pin_dac_pair *filled, int nums,
3377 int type)
3374{ 3378{
3375 int i, nums; 3379 int i, start = nums;
3376 3380
3377 nums = 0; 3381 for (i = 0; i < num_pins; i++, nums++) {
3378 for (i = 0; i < num_pins; i++) {
3379 filled[nums].pin = pins[i]; 3382 filled[nums].pin = pins[i];
3380 filled[nums].type = type; 3383 filled[nums].type = type;
3381 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); 3384 filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
3382 nums++; 3385 if (filled[nums].dac)
3386 continue;
3387 if (filled[start].dac && get_connection_index(codec, pins[i], filled[start].dac) >= 0) {
3388 filled[nums].dac = filled[start].dac | DAC_SLAVE_FLAG;
3389 continue;
3390 }
3391 if (filled[0].dac && get_connection_index(codec, pins[i], filled[0].dac) >= 0) {
3392 filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
3393 continue;
3394 }
3395 snd_printdd("Failed to find a DAC for pin 0x%x", pins[i]);
3383 } 3396 }
3384 return nums; 3397 return nums;
3385} 3398}
@@ -3395,19 +3408,19 @@ static void cx_auto_parse_output(struct hda_codec *codec)
3395 rest = fill_cx_auto_dacs(codec, dacs); 3408 rest = fill_cx_auto_dacs(codec, dacs);
3396 /* parse all analog output pins */ 3409 /* parse all analog output pins */
3397 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs, 3410 nums = fill_dacs_for_pins(codec, cfg->line_out_pins, cfg->line_outs,
3398 dacs, &rest, spec->dac_info, 3411 dacs, &rest, spec->dac_info, 0,
3399 AUTO_PIN_LINE_OUT); 3412 AUTO_PIN_LINE_OUT);
3400 nums += fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs, 3413 nums = fill_dacs_for_pins(codec, cfg->hp_pins, cfg->hp_outs,
3401 dacs, &rest, spec->dac_info + nums, 3414 dacs, &rest, spec->dac_info, nums,
3402 AUTO_PIN_HP_OUT); 3415 AUTO_PIN_HP_OUT);
3403 nums += fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs, 3416 nums = fill_dacs_for_pins(codec, cfg->speaker_pins, cfg->speaker_outs,
3404 dacs, &rest, spec->dac_info + nums, 3417 dacs, &rest, spec->dac_info, nums,
3405 AUTO_PIN_SPEAKER_OUT); 3418 AUTO_PIN_SPEAKER_OUT);
3406 spec->dac_info_filled = nums; 3419 spec->dac_info_filled = nums;
3407 /* fill multiout struct */ 3420 /* fill multiout struct */
3408 for (i = 0; i < nums; i++) { 3421 for (i = 0; i < nums; i++) {
3409 hda_nid_t dac = spec->dac_info[i].dac; 3422 hda_nid_t dac = spec->dac_info[i].dac;
3410 if (!dac) 3423 if (!dac || (dac & DAC_SLAVE_FLAG))
3411 continue; 3424 continue;
3412 switch (spec->dac_info[i].type) { 3425 switch (spec->dac_info[i].type) {
3413 case AUTO_PIN_LINE_OUT: 3426 case AUTO_PIN_LINE_OUT:
@@ -3460,12 +3473,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins,
3460static void do_automute(struct hda_codec *codec, int num_pins, 3473static void do_automute(struct hda_codec *codec, int num_pins,
3461 hda_nid_t *pins, bool on) 3474 hda_nid_t *pins, bool on)
3462{ 3475{
3476 struct conexant_spec *spec = codec->spec;
3463 int i; 3477 int i;
3464 for (i = 0; i < num_pins; i++) 3478 for (i = 0; i < num_pins; i++)
3465 snd_hda_codec_write(codec, pins[i], 0, 3479 snd_hda_codec_write(codec, pins[i], 0,
3466 AC_VERB_SET_PIN_WIDGET_CONTROL, 3480 AC_VERB_SET_PIN_WIDGET_CONTROL,
3467 on ? PIN_OUT : 0); 3481 on ? PIN_OUT : 0);
3468 cx_auto_turn_eapd(codec, num_pins, pins, on); 3482 if (spec->pin_eapd_ctrls)
3483 cx_auto_turn_eapd(codec, num_pins, pins, on);
3469} 3484}
3470 3485
3471static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3486static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
@@ -3490,9 +3505,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec)
3490 int on = 1; 3505 int on = 1;
3491 3506
3492 /* turn on HP EAPD when HP jacks are present */ 3507 /* turn on HP EAPD when HP jacks are present */
3493 if (spec->auto_mute) 3508 if (spec->pin_eapd_ctrls) {
3494 on = spec->hp_present; 3509 if (spec->auto_mute)
3495 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); 3510 on = spec->hp_present;
3511 cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on);
3512 }
3513
3496 /* mute speakers in auto-mode if HP or LO jacks are plugged */ 3514 /* mute speakers in auto-mode if HP or LO jacks are plugged */
3497 if (spec->auto_mute) 3515 if (spec->auto_mute)
3498 on = !(spec->hp_present || 3516 on = !(spec->hp_present ||
@@ -3862,7 +3880,7 @@ static void cx_auto_parse_input(struct hda_codec *codec)
3862 } 3880 }
3863 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) 3881 if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items)
3864 cx_auto_check_auto_mic(codec); 3882 cx_auto_check_auto_mic(codec);
3865 if (imux->num_items > 1 && !spec->auto_mic) { 3883 if (imux->num_items > 1) {
3866 for (i = 1; i < imux->num_items; i++) { 3884 for (i = 1; i < imux->num_items; i++) {
3867 if (spec->imux_info[i].adc != spec->imux_info[0].adc) { 3885 if (spec->imux_info[i].adc != spec->imux_info[0].adc) {
3868 spec->adc_switching = 1; 3886 spec->adc_switching = 1;
@@ -3919,6 +3937,32 @@ static void cx_auto_parse_beep(struct hda_codec *codec)
3919#define cx_auto_parse_beep(codec) 3937#define cx_auto_parse_beep(codec)
3920#endif 3938#endif
3921 3939
3940/* parse EAPDs */
3941static void cx_auto_parse_eapd(struct hda_codec *codec)
3942{
3943 struct conexant_spec *spec = codec->spec;
3944 hda_nid_t nid, end_nid;
3945
3946 end_nid = codec->start_nid + codec->num_nodes;
3947 for (nid = codec->start_nid; nid < end_nid; nid++) {
3948 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3949 continue;
3950 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD))
3951 continue;
3952 spec->eapds[spec->num_eapds++] = nid;
3953 if (spec->num_eapds >= ARRAY_SIZE(spec->eapds))
3954 break;
3955 }
3956
3957 /* NOTE: below is a wild guess; if we have more than two EAPDs,
3958 * it's a new chip, where EAPDs are supposed to be associated to
3959 * pins, and we can control EAPD per pin.
3960 * OTOH, if only one or two EAPDs are found, it's an old chip,
3961 * thus it might control over all pins.
3962 */
3963 spec->pin_eapd_ctrls = spec->num_eapds > 2;
3964}
3965
3922static int cx_auto_parse_auto_config(struct hda_codec *codec) 3966static int cx_auto_parse_auto_config(struct hda_codec *codec)
3923{ 3967{
3924 struct conexant_spec *spec = codec->spec; 3968 struct conexant_spec *spec = codec->spec;
@@ -3932,6 +3976,7 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec)
3932 cx_auto_parse_input(codec); 3976 cx_auto_parse_input(codec);
3933 cx_auto_parse_digital(codec); 3977 cx_auto_parse_digital(codec);
3934 cx_auto_parse_beep(codec); 3978 cx_auto_parse_beep(codec);
3979 cx_auto_parse_eapd(codec);
3935 return 0; 3980 return 0;
3936} 3981}
3937 3982
@@ -4002,6 +4047,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
4002 nid = spec->dac_info[i].dac; 4047 nid = spec->dac_info[i].dac;
4003 if (!nid) 4048 if (!nid)
4004 nid = spec->multiout.dac_nids[0]; 4049 nid = spec->multiout.dac_nids[0];
4050 else if (nid & DAC_SLAVE_FLAG)
4051 nid &= ~DAC_SLAVE_FLAG;
4005 select_connection(codec, spec->dac_info[i].pin, nid); 4052 select_connection(codec, spec->dac_info[i].pin, nid);
4006 } 4053 }
4007 if (spec->auto_mute) { 4054 if (spec->auto_mute) {
@@ -4019,6 +4066,9 @@ static void cx_auto_init_output(struct hda_codec *codec)
4019 } 4066 }
4020 } 4067 }
4021 cx_auto_update_speakers(codec); 4068 cx_auto_update_speakers(codec);
4069 /* turn on all EAPDs if no individual EAPD control is available */
4070 if (!spec->pin_eapd_ctrls)
4071 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
4022} 4072}
4023 4073
4024static void cx_auto_init_input(struct hda_codec *codec) 4074static void cx_auto_init_input(struct hda_codec *codec)
@@ -4132,9 +4182,11 @@ static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac,
4132 hda_nid_t pin, const char *name, int idx) 4182 hda_nid_t pin, const char *name, int idx)
4133{ 4183{
4134 unsigned int caps; 4184 unsigned int caps;
4135 caps = query_amp_caps(codec, dac, HDA_OUTPUT); 4185 if (dac && !(dac & DAC_SLAVE_FLAG)) {
4136 if (caps & AC_AMPCAP_NUM_STEPS) 4186 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
4137 return cx_auto_add_pb_volume(codec, dac, name, idx); 4187 if (caps & AC_AMPCAP_NUM_STEPS)
4188 return cx_auto_add_pb_volume(codec, dac, name, idx);
4189 }
4138 caps = query_amp_caps(codec, pin, HDA_OUTPUT); 4190 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
4139 if (caps & AC_AMPCAP_NUM_STEPS) 4191 if (caps & AC_AMPCAP_NUM_STEPS)
4140 return cx_auto_add_pb_volume(codec, pin, name, idx); 4192 return cx_auto_add_pb_volume(codec, pin, name, idx);
@@ -4156,8 +4208,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
4156 for (i = 0; i < spec->dac_info_filled; i++) { 4208 for (i = 0; i < spec->dac_info_filled; i++) {
4157 const char *label; 4209 const char *label;
4158 int idx, type; 4210 int idx, type;
4159 if (!spec->dac_info[i].dac) 4211 hda_nid_t dac = spec->dac_info[i].dac;
4160 continue;
4161 type = spec->dac_info[i].type; 4212 type = spec->dac_info[i].type;
4162 if (type == AUTO_PIN_LINE_OUT) 4213 if (type == AUTO_PIN_LINE_OUT)
4163 type = spec->autocfg.line_out_type; 4214 type = spec->autocfg.line_out_type;
@@ -4176,7 +4227,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
4176 idx = num_spk++; 4227 idx = num_spk++;
4177 break; 4228 break;
4178 } 4229 }
4179 err = try_add_pb_volume(codec, spec->dac_info[i].dac, 4230 err = try_add_pb_volume(codec, dac,
4180 spec->dac_info[i].pin, 4231 spec->dac_info[i].pin,
4181 label, idx); 4232 label, idx);
4182 if (err < 0) 4233 if (err < 0)
@@ -4204,6 +4255,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
4204 int idx = get_input_connection(codec, adc_nid, nid); 4255 int idx = get_input_connection(codec, adc_nid, nid);
4205 if (idx < 0) 4256 if (idx < 0)
4206 continue; 4257 continue;
4258 if (spec->single_adc_amp)
4259 idx = 0;
4207 return cx_auto_add_volume_idx(codec, label, pfx, 4260 return cx_auto_add_volume_idx(codec, label, pfx,
4208 cidx, adc_nid, HDA_INPUT, idx); 4261 cidx, adc_nid, HDA_INPUT, idx);
4209 } 4262 }
@@ -4244,14 +4297,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4244 struct hda_input_mux *imux = &spec->private_imux; 4297 struct hda_input_mux *imux = &spec->private_imux;
4245 const char *prev_label; 4298 const char *prev_label;
4246 int input_conn[HDA_MAX_NUM_INPUTS]; 4299 int input_conn[HDA_MAX_NUM_INPUTS];
4247 int i, err, cidx; 4300 int i, j, err, cidx;
4248 int multi_connection; 4301 int multi_connection;
4249 4302
4303 if (!imux->num_items)
4304 return 0;
4305
4250 multi_connection = 0; 4306 multi_connection = 0;
4251 for (i = 0; i < imux->num_items; i++) { 4307 for (i = 0; i < imux->num_items; i++) {
4252 cidx = get_input_connection(codec, spec->imux_info[i].adc, 4308 cidx = get_input_connection(codec, spec->imux_info[i].adc,
4253 spec->imux_info[i].pin); 4309 spec->imux_info[i].pin);
4254 input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; 4310 if (cidx < 0)
4311 continue;
4312 input_conn[i] = spec->imux_info[i].adc;
4313 if (!spec->single_adc_amp)
4314 input_conn[i] |= cidx << 8;
4255 if (i > 0 && input_conn[i] != input_conn[0]) 4315 if (i > 0 && input_conn[i] != input_conn[0])
4256 multi_connection = 1; 4316 multi_connection = 1;
4257 } 4317 }
@@ -4280,6 +4340,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
4280 err = cx_auto_add_capture_volume(codec, nid, 4340 err = cx_auto_add_capture_volume(codec, nid,
4281 "Capture", "", cidx); 4341 "Capture", "", cidx);
4282 } else { 4342 } else {
4343 bool dup_found = false;
4344 for (j = 0; j < i; j++) {
4345 if (input_conn[j] == input_conn[i]) {
4346 dup_found = true;
4347 break;
4348 }
4349 }
4350 if (dup_found)
4351 continue;
4283 err = cx_auto_add_capture_volume(codec, nid, 4352 err = cx_auto_add_capture_volume(codec, nid,
4284 label, " Capture", cidx); 4353 label, " Capture", cidx);
4285 } 4354 }
@@ -4356,6 +4425,13 @@ static int patch_conexant_auto(struct hda_codec *codec)
4356 return -ENOMEM; 4425 return -ENOMEM;
4357 codec->spec = spec; 4426 codec->spec = spec;
4358 codec->pin_amp_workaround = 1; 4427 codec->pin_amp_workaround = 1;
4428
4429 switch (codec->vendor_id) {
4430 case 0x14f15045:
4431 spec->single_adc_amp = 1;
4432 break;
4433 }
4434
4359 err = cx_auto_search_adcs(codec); 4435 err = cx_auto_search_adcs(codec);
4360 if (err < 0) 4436 if (err < 0)
4361 return err; 4437 return err;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index bd0ae697f9c..fcc32f59087 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -34,6 +34,11 @@
34#include <linux/moduleparam.h> 34#include <linux/moduleparam.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/jack.h> 36#include <sound/jack.h>
37
38#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
39#include <mach/hdmi-audio.h>
40#endif
41
37#include "hda_codec.h" 42#include "hda_codec.h"
38#include "hda_local.h" 43#include "hda_local.h"
39 44
@@ -43,7 +48,7 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
43 48
44/* 49/*
45 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device 50 * 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 51 * could support N independent pipes, each of them can be connected to one or
47 * more ports (DVI, HDMI or DisplayPort). 52 * more ports (DVI, HDMI or DisplayPort).
48 * 53 *
49 * The HDA correspondence of pipes/ports are converter/pin nodes. 54 * The HDA correspondence of pipes/ports are converter/pin nodes.
@@ -51,30 +56,33 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
51#define MAX_HDMI_CVTS 4 56#define MAX_HDMI_CVTS 4
52#define MAX_HDMI_PINS 4 57#define MAX_HDMI_PINS 4
53 58
54struct hdmi_spec { 59struct hdmi_spec_per_cvt {
55 int num_cvts; 60 hda_nid_t cvt_nid;
56 int num_pins; 61 int assigned;
57 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */ 62 unsigned int channels_min;
58 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */ 63 unsigned int channels_max;
64 u32 rates;
65 u64 formats;
66 unsigned int maxbps;
67};
59 68
60 /* 69struct hdmi_spec_per_pin {
61 * source connection for each pin 70 hda_nid_t pin_nid;
62 */ 71 int num_mux_nids;
63 hda_nid_t pin_cvt[MAX_HDMI_PINS+1]; 72 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
73 struct hdmi_eld sink_eld;
74};
64 75
65 /* 76struct hdmi_spec {
66 * HDMI sink attached to each pin 77 int num_cvts;
67 */ 78 struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS];
68 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
69 79
70 /* 80 int num_pins;
71 * export one pcm per pipe 81 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS];
72 */ 82 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 83
76 /* 84 /*
77 * ati/nvhdmi specific 85 * Non-generic ATI/NVIDIA specific
78 */ 86 */
79 struct hda_multi_out multiout; 87 struct hda_multi_out multiout;
80 const struct hda_pcm_stream *pcm_playback; 88 const struct hda_pcm_stream *pcm_playback;
@@ -284,15 +292,40 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
284 * HDMI routines 292 * HDMI routines
285 */ 293 */
286 294
287static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) 295static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid)
288{ 296{
289 int i; 297 int pin_idx;
298
299 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
300 if (spec->pins[pin_idx].pin_nid == pin_nid)
301 return pin_idx;
302
303 snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid);
304 return -EINVAL;
305}
306
307static int hinfo_to_pin_index(struct hdmi_spec *spec,
308 struct hda_pcm_stream *hinfo)
309{
310 int pin_idx;
311
312 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
313 if (&spec->pcm_rec[pin_idx].stream[0] == hinfo)
314 return pin_idx;
315
316 snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo);
317 return -EINVAL;
318}
290 319
291 for (i = 0; nids[i]; i++) 320static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
292 if (nids[i] == nid) 321{
293 return i; 322 int cvt_idx;
323
324 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
325 if (spec->cvts[cvt_idx].cvt_nid == cvt_nid)
326 return cvt_idx;
294 327
295 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid); 328 snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid);
296 return -EINVAL; 329 return -EINVAL;
297} 330}
298 331
@@ -326,28 +359,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); 359 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
327} 360}
328 361
329static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid) 362static void hdmi_init_pin(struct hda_codec *codec, hda_nid_t pin_nid)
330{ 363{
331 /* Unmute */ 364 /* Unmute */
332 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP) 365 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
333 snd_hda_codec_write(codec, pin_nid, 0, 366 snd_hda_codec_write(codec, pin_nid, 0,
334 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 367 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
335 /* Enable pin out */ 368 /* Disable pin out until stream is active*/
336 snd_hda_codec_write(codec, pin_nid, 0, 369 snd_hda_codec_write(codec, pin_nid, 0,
337 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 370 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
338} 371}
339 372
340static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid) 373static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t cvt_nid)
341{ 374{
342 return 1 + snd_hda_codec_read(codec, nid, 0, 375 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
343 AC_VERB_GET_CVT_CHAN_COUNT, 0); 376 AC_VERB_GET_CVT_CHAN_COUNT, 0);
344} 377}
345 378
346static void hdmi_set_channel_count(struct hda_codec *codec, 379static void hdmi_set_channel_count(struct hda_codec *codec,
347 hda_nid_t nid, int chs) 380 hda_nid_t cvt_nid, int chs)
348{ 381{
349 if (chs != hdmi_get_channel_count(codec, nid)) 382 if (chs != hdmi_get_channel_count(codec, cvt_nid))
350 snd_hda_codec_write(codec, nid, 0, 383 snd_hda_codec_write(codec, cvt_nid, 0,
351 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 384 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
352} 385}
353 386
@@ -384,11 +417,8 @@ static void init_channel_allocations(void)
384 * 417 *
385 * TODO: it could select the wrong CA from multiple candidates. 418 * TODO: it could select the wrong CA from multiple candidates.
386*/ 419*/
387static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid, 420static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
388 int channels)
389{ 421{
390 struct hdmi_spec *spec = codec->spec;
391 struct hdmi_eld *eld;
392 int i; 422 int i;
393 int ca = 0; 423 int ca = 0;
394 int spk_mask = 0; 424 int spk_mask = 0;
@@ -400,19 +430,6 @@ static int hdmi_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
400 if (channels <= 2) 430 if (channels <= 2)
401 return 0; 431 return 0;
402 432
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 /* 433 /*
417 * expand ELD's speaker allocation mask 434 * expand ELD's speaker allocation mask
418 * 435 *
@@ -608,67 +625,63 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
608 return true; 625 return true;
609} 626}
610 627
611static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid, 628static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
612 struct snd_pcm_substream *substream) 629 struct snd_pcm_substream *substream)
613{ 630{
614 struct hdmi_spec *spec = codec->spec; 631 struct hdmi_spec *spec = codec->spec;
615 hda_nid_t pin_nid; 632 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
633 hda_nid_t pin_nid = per_pin->pin_nid;
616 int channels = substream->runtime->channels; 634 int channels = substream->runtime->channels;
635 struct hdmi_eld *eld;
617 int ca; 636 int ca;
618 int i;
619 union audio_infoframe ai; 637 union audio_infoframe ai;
620 638
621 ca = hdmi_channel_allocation(codec, nid, channels); 639 eld = &spec->pins[pin_idx].sink_eld;
622 640 if (!eld->monitor_present)
623 for (i = 0; i < spec->num_pins; i++) { 641 return;
624 if (spec->pin_cvt[i] != nid)
625 continue;
626 if (!spec->sink_eld[i].monitor_present)
627 continue;
628 642
629 pin_nid = spec->pin[i]; 643 ca = hdmi_channel_allocation(eld, channels);
630 644
631 memset(&ai, 0, sizeof(ai)); 645 memset(&ai, 0, sizeof(ai));
632 if (spec->sink_eld[i].conn_type == 0) { /* HDMI */ 646 if (eld->conn_type == 0) { /* HDMI */
633 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi; 647 struct hdmi_audio_infoframe *hdmi_ai = &ai.hdmi;
634 648
635 hdmi_ai->type = 0x84; 649 hdmi_ai->type = 0x84;
636 hdmi_ai->ver = 0x01; 650 hdmi_ai->ver = 0x01;
637 hdmi_ai->len = 0x0a; 651 hdmi_ai->len = 0x0a;
638 hdmi_ai->CC02_CT47 = channels - 1; 652 hdmi_ai->CC02_CT47 = channels - 1;
639 hdmi_ai->CA = ca; 653 hdmi_ai->CA = ca;
640 hdmi_checksum_audio_infoframe(hdmi_ai); 654 hdmi_checksum_audio_infoframe(hdmi_ai);
641 } else if (spec->sink_eld[i].conn_type == 1) { /* DisplayPort */ 655 } else if (eld->conn_type == 1) { /* DisplayPort */
642 struct dp_audio_infoframe *dp_ai = &ai.dp; 656 struct dp_audio_infoframe *dp_ai = &ai.dp;
643 657
644 dp_ai->type = 0x84; 658 dp_ai->type = 0x84;
645 dp_ai->len = 0x1b; 659 dp_ai->len = 0x1b;
646 dp_ai->ver = 0x11 << 2; 660 dp_ai->ver = 0x11 << 2;
647 dp_ai->CC02_CT47 = channels - 1; 661 dp_ai->CC02_CT47 = channels - 1;
648 dp_ai->CA = ca; 662 dp_ai->CA = ca;
649 } else { 663 } else {
650 snd_printd("HDMI: unknown connection type at pin %d\n", 664 snd_printd("HDMI: unknown connection type at pin %d\n",
651 pin_nid); 665 pin_nid);
652 continue; 666 return;
653 } 667 }
654 668
655 /* 669 /*
656 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or 670 * sizeof(ai) is used instead of sizeof(*hdmi_ai) or
657 * sizeof(*dp_ai) to avoid partial match/update problems when 671 * sizeof(*dp_ai) to avoid partial match/update problems when
658 * the user switches between HDMI/DP monitors. 672 * the user switches between HDMI/DP monitors.
659 */ 673 */
660 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes, 674 if (!hdmi_infoframe_uptodate(codec, pin_nid, ai.bytes,
661 sizeof(ai))) { 675 sizeof(ai))) {
662 snd_printdd("hdmi_setup_audio_infoframe: " 676 snd_printdd("hdmi_setup_audio_infoframe: "
663 "cvt=%d pin=%d channels=%d\n", 677 "pin=%d channels=%d\n",
664 nid, pin_nid, 678 pin_nid,
665 channels); 679 channels);
666 hdmi_setup_channel_mapping(codec, pin_nid, ca); 680 hdmi_setup_channel_mapping(codec, pin_nid, ca);
667 hdmi_stop_infoframe_trans(codec, pin_nid); 681 hdmi_stop_infoframe_trans(codec, pin_nid);
668 hdmi_fill_audio_infoframe(codec, pin_nid, 682 hdmi_fill_audio_infoframe(codec, pin_nid,
669 ai.bytes, sizeof(ai)); 683 ai.bytes, sizeof(ai));
670 hdmi_start_infoframe_trans(codec, pin_nid); 684 hdmi_start_infoframe_trans(codec, pin_nid);
671 }
672 } 685 }
673} 686}
674 687
@@ -686,17 +699,27 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
686 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; 699 int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT;
687 int pd = !!(res & AC_UNSOL_RES_PD); 700 int pd = !!(res & AC_UNSOL_RES_PD);
688 int eldv = !!(res & AC_UNSOL_RES_ELDV); 701 int eldv = !!(res & AC_UNSOL_RES_ELDV);
689 int index; 702 int pin_idx;
703 struct hdmi_eld *eld;
690 704
691 printk(KERN_INFO 705 printk(KERN_INFO
692 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 706 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
693 pin_nid, pd, eldv); 707 codec->addr, pin_nid, pd, eldv);
694 708
695 index = hda_node_index(spec->pin, pin_nid); 709 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
696 if (index < 0) 710 if (pin_idx < 0)
697 return; 711 return;
712 eld = &spec->pins[pin_idx].sink_eld;
698 713
699 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); 714 hdmi_present_sense(codec, pin_nid, eld);
715
716 /*
717 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
718 * in console or for audio devices. Assume the highest speakers
719 * configuration, to _not_ prohibit multi-channel audio playback.
720 */
721 if (!eld->spk_alloc)
722 eld->spk_alloc = 0xffff;
700} 723}
701 724
702static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) 725static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
@@ -707,7 +730,8 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
707 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); 730 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
708 731
709 printk(KERN_INFO 732 printk(KERN_INFO
710 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", 733 "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
734 codec->addr,
711 tag, 735 tag,
712 subtag, 736 subtag,
713 cp_state, 737 cp_state,
@@ -727,7 +751,7 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
727 int tag = res >> AC_UNSOL_RES_TAG_SHIFT; 751 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
728 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; 752 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
729 753
730 if (hda_node_index(spec->pin, tag) < 0) { 754 if (pin_nid_to_pin_index(spec, tag) < 0) {
731 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); 755 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
732 return; 756 return;
733 } 757 }
@@ -746,21 +770,14 @@ static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
746#define is_hbr_format(format) \ 770#define is_hbr_format(format) \
747 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7) 771 ((format & AC_FMT_TYPE_NON_PCM) && (format & AC_FMT_CHAN_MASK) == 7)
748 772
749static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid, 773static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t cvt_nid,
750 u32 stream_tag, int format) 774 hda_nid_t pin_nid, u32 stream_tag, int format)
751{ 775{
752 struct hdmi_spec *spec = codec->spec;
753 int pinctl; 776 int pinctl;
754 int new_pinctl = 0; 777 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 778
763 pinctl = snd_hda_codec_read(codec, spec->pin[i], 0, 779 if (snd_hda_query_pin_caps(codec, pin_nid) & AC_PINCAP_HBR) {
780 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
764 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 781 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
765 782
766 new_pinctl = pinctl & ~AC_PINCTL_EPT; 783 new_pinctl = pinctl & ~AC_PINCTL_EPT;
@@ -771,22 +788,22 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
771 788
772 snd_printdd("hdmi_setup_stream: " 789 snd_printdd("hdmi_setup_stream: "
773 "NID=0x%x, %spinctl=0x%x\n", 790 "NID=0x%x, %spinctl=0x%x\n",
774 spec->pin[i], 791 pin_nid,
775 pinctl == new_pinctl ? "" : "new-", 792 pinctl == new_pinctl ? "" : "new-",
776 new_pinctl); 793 new_pinctl);
777 794
778 if (pinctl != new_pinctl) 795 if (pinctl != new_pinctl)
779 snd_hda_codec_write(codec, spec->pin[i], 0, 796 snd_hda_codec_write(codec, pin_nid, 0,
780 AC_VERB_SET_PIN_WIDGET_CONTROL, 797 AC_VERB_SET_PIN_WIDGET_CONTROL,
781 new_pinctl); 798 new_pinctl);
782 }
783 799
800 }
784 if (is_hbr_format(format) && !new_pinctl) { 801 if (is_hbr_format(format) && !new_pinctl) {
785 snd_printdd("hdmi_setup_stream: HBR is not supported\n"); 802 snd_printdd("hdmi_setup_stream: HBR is not supported\n");
786 return -EINVAL; 803 return -EINVAL;
787 } 804 }
788 805
789 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 806 snd_hda_codec_setup_stream(codec, cvt_nid, stream_tag, 0, format);
790 return 0; 807 return 0;
791} 808}
792 809
@@ -798,37 +815,85 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
798 struct snd_pcm_substream *substream) 815 struct snd_pcm_substream *substream)
799{ 816{
800 struct hdmi_spec *spec = codec->spec; 817 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; 818 struct snd_pcm_runtime *runtime = substream->runtime;
804 unsigned int idx; 819 int pin_idx, cvt_idx, mux_idx = 0;
820 struct hdmi_spec_per_pin *per_pin;
821 struct hdmi_eld *eld;
822 struct hdmi_spec_per_cvt *per_cvt = NULL;
823 int pinctl;
805 824
806 for (idx = 0; idx < spec->num_cvts; idx++) 825 /* Validate hinfo */
807 if (hinfo->nid == spec->cvt[idx]) 826 pin_idx = hinfo_to_pin_index(spec, hinfo);
808 break; 827 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; 828 return -EINVAL;
829 per_pin = &spec->pins[pin_idx];
830 eld = &per_pin->sink_eld;
831
832#ifdef CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA
833 if ((codec->preset->id == 0x10de0020) &&
834 (!eld->monitor_present || !eld->lpcm_sad_ready)) {
835 if (!eld->monitor_present) {
836 if (tegra_hdmi_setup_hda_presence() < 0) {
837 snd_printk(KERN_WARNING
838 "HDMI: No HDMI device connected\n");
839 return -ENODEV;
840 }
841 }
842 if (!eld->lpcm_sad_ready)
843 return -ENODEV;
844 }
845#endif
812 846
813 /* save the PCM info the codec provides */ 847 /* Dynamically assign converter to stream */
814 codec_pars = &spec->codec_pcm_pars[idx]; 848 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
815 if (!codec_pars->rates) 849 per_cvt = &spec->cvts[cvt_idx];
816 *codec_pars = *hinfo;
817 850
818 eld = &spec->sink_eld[idx]; 851 /* Must not already be assigned */
819 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) { 852 if (per_cvt->assigned)
820 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 853 continue;
854 /* Must be in pin's mux's list of converters */
855 for (mux_idx = 0; mux_idx < per_pin->num_mux_nids; mux_idx++)
856 if (per_pin->mux_nids[mux_idx] == per_cvt->cvt_nid)
857 break;
858 /* Not in mux list */
859 if (mux_idx == per_pin->num_mux_nids)
860 continue;
861 break;
862 }
863 /* No free converters */
864 if (cvt_idx == spec->num_cvts)
865 return -ENODEV;
866
867 /* Claim converter */
868 per_cvt->assigned = 1;
869 hinfo->nid = per_cvt->cvt_nid;
870
871 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
872 AC_VERB_SET_CONNECT_SEL,
873 mux_idx);
874 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
875 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
876 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
877 AC_VERB_SET_PIN_WIDGET_CONTROL,
878 pinctl | PIN_OUT);
879 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
880
881 /* Initially set the converter's capabilities */
882 hinfo->channels_min = per_cvt->channels_min;
883 hinfo->channels_max = per_cvt->channels_max;
884 hinfo->rates = per_cvt->rates;
885 hinfo->formats = per_cvt->formats;
886 hinfo->maxbps = per_cvt->maxbps;
887
888 /* Restrict capabilities by ELD if this isn't disabled */
889 if (!static_hdmi_pcm && (eld->eld_valid || eld->lpcm_sad_ready)) {
890 snd_hdmi_eld_update_pcm_info(eld, hinfo);
821 if (hinfo->channels_min > hinfo->channels_max || 891 if (hinfo->channels_min > hinfo->channels_max ||
822 !hinfo->rates || !hinfo->formats) 892 !hinfo->rates || !hinfo->formats)
823 return -ENODEV; 893 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 } 894 }
831 /* store the updated parameters */ 895
896 /* Store the updated parameters */
832 runtime->hw.channels_min = hinfo->channels_min; 897 runtime->hw.channels_min = hinfo->channels_min;
833 runtime->hw.channels_max = hinfo->channels_max; 898 runtime->hw.channels_max = hinfo->channels_max;
834 runtime->hw.formats = hinfo->formats; 899 runtime->hw.formats = hinfo->formats;
@@ -842,12 +907,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
842/* 907/*
843 * HDA/HDMI auto parsing 908 * HDA/HDMI auto parsing
844 */ 909 */
845static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) 910static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
846{ 911{
847 struct hdmi_spec *spec = codec->spec; 912 struct hdmi_spec *spec = codec->spec;
848 hda_nid_t conn_list[HDA_MAX_CONNECTIONS]; 913 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
849 int conn_len, curr; 914 hda_nid_t pin_nid = per_pin->pin_nid;
850 int index;
851 915
852 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { 916 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
853 snd_printk(KERN_WARNING 917 snd_printk(KERN_WARNING
@@ -857,19 +921,9 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
857 return -EINVAL; 921 return -EINVAL;
858 } 922 }
859 923
860 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list, 924 per_pin->num_mux_nids = snd_hda_get_connections(codec, pin_nid,
861 HDA_MAX_CONNECTIONS); 925 per_pin->mux_nids,
862 if (conn_len > 1) 926 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 927
874 return 0; 928 return 0;
875} 929}
@@ -886,20 +940,23 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
886 * the unsolicited response to avoid custom WARs. 940 * the unsolicited response to avoid custom WARs.
887 */ 941 */
888 int present = snd_hda_pin_sense(codec, pin_nid); 942 int present = snd_hda_pin_sense(codec, pin_nid);
943 bool eld_valid = false;
889 944
890 memset(eld, 0, sizeof(*eld)); 945#ifdef CONFIG_PROC_FS
946 memset(eld, 0, offsetof(struct hdmi_eld, proc_entry));
947#else
948 memset(eld, 0, sizeof(struct hdmi_eld));
949#endif
891 950
892 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); 951 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
893 if (eld->monitor_present) 952 if (eld->monitor_present)
894 eld->eld_valid = !!(present & AC_PINSENSE_ELDV); 953 eld_valid = !!(present & AC_PINSENSE_ELDV);
895 else
896 eld->eld_valid = 0;
897 954
898 printk(KERN_INFO 955 printk(KERN_INFO
899 "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 956 "HDMI status: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
900 pin_nid, eld->monitor_present, eld->eld_valid); 957 codec->addr, pin_nid, eld->monitor_present, eld_valid);
901 958
902 if (eld->eld_valid) 959 if (eld_valid)
903 if (!snd_hdmi_get_eld(eld, codec, pin_nid)) 960 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
904 snd_hdmi_show_eld(eld); 961 snd_hdmi_show_eld(eld);
905 962
@@ -909,47 +966,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) 966static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
910{ 967{
911 struct hdmi_spec *spec = codec->spec; 968 struct hdmi_spec *spec = codec->spec;
969 unsigned int caps, config;
970 int pin_idx;
971 struct hdmi_spec_per_pin *per_pin;
972 struct hdmi_eld *eld;
912 int err; 973 int err;
913 974
914 if (spec->num_pins >= MAX_HDMI_PINS) { 975 caps = snd_hda_param_read(codec, pin_nid, AC_PAR_PIN_CAP);
915 snd_printk(KERN_WARNING 976 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
916 "HDMI: no space for pin %d\n", pin_nid); 977 return 0;
978
979 config = snd_hda_codec_read(codec, pin_nid, 0,
980 AC_VERB_GET_CONFIG_DEFAULT, 0);
981 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
982 return 0;
983
984 if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS))
917 return -E2BIG; 985 return -E2BIG;
918 } 986
987 pin_idx = spec->num_pins;
988 per_pin = &spec->pins[pin_idx];
989 eld = &per_pin->sink_eld;
990
991 per_pin->pin_nid = pin_nid;
919 992
920 err = snd_hda_input_jack_add(codec, pin_nid, 993 err = snd_hda_input_jack_add(codec, pin_nid,
921 SND_JACK_VIDEOOUT, NULL); 994 SND_JACK_VIDEOOUT, NULL);
922 if (err < 0) 995 if (err < 0)
923 return err; 996 return err;
924 997
925 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); 998 err = hdmi_read_pin_conn(codec, pin_idx);
999 if (err < 0)
1000 return err;
926 1001
927 spec->pin[spec->num_pins] = pin_nid;
928 spec->num_pins++; 1002 spec->num_pins++;
929 1003
930 return hdmi_read_pin_conn(codec, pin_nid); 1004 hdmi_present_sense(codec, pin_nid, eld);
1005
1006 return 0;
931} 1007}
932 1008
933static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 1009static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
934{ 1010{
935 int i, found_pin = 0;
936 struct hdmi_spec *spec = codec->spec; 1011 struct hdmi_spec *spec = codec->spec;
937 1012 int cvt_idx;
938 for (i = 0; i < spec->num_pins; i++) 1013 struct hdmi_spec_per_cvt *per_cvt;
939 if (nid == spec->pin_cvt[i]) { 1014 unsigned int chans;
940 found_pin = 1; 1015 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 1016
949 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) 1017 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
950 return -E2BIG; 1018 return -E2BIG;
951 1019
952 spec->cvt[spec->num_cvts] = nid; 1020 chans = get_wcaps(codec, cvt_nid);
1021 chans = get_wcaps_channels(chans);
1022
1023 cvt_idx = spec->num_cvts;
1024 per_cvt = &spec->cvts[cvt_idx];
1025
1026 per_cvt->cvt_nid = cvt_nid;
1027 per_cvt->channels_min = 2;
1028 if (chans <= 16)
1029 per_cvt->channels_max = chans;
1030
1031 err = snd_hda_query_supported_pcm(codec, cvt_nid,
1032 &per_cvt->rates,
1033 &per_cvt->formats,
1034 &per_cvt->maxbps);
1035 if (err < 0)
1036 return err;
1037
953 spec->num_cvts++; 1038 spec->num_cvts++;
954 1039
955 return 0; 1040 return 0;
@@ -959,8 +1044,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
959{ 1044{
960 hda_nid_t nid; 1045 hda_nid_t nid;
961 int i, nodes; 1046 int i, nodes;
962 int num_tmp_cvts = 0;
963 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
964 1047
965 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 1048 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
966 if (!nid || nodes < 0) { 1049 if (!nid || nodes < 0) {
@@ -971,7 +1054,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
971 for (i = 0; i < nodes; i++, nid++) { 1054 for (i = 0; i < nodes; i++, nid++) {
972 unsigned int caps; 1055 unsigned int caps;
973 unsigned int type; 1056 unsigned int type;
974 unsigned int config;
975 1057
976 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 1058 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
977 type = get_wcaps_type(caps); 1059 type = get_wcaps_type(caps);
@@ -981,40 +1063,22 @@ static int hdmi_parse_codec(struct hda_codec *codec)
981 1063
982 switch (type) { 1064 switch (type) {
983 case AC_WID_AUD_OUT: 1065 case AC_WID_AUD_OUT:
984 if (num_tmp_cvts >= MAX_HDMI_CVTS) { 1066 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; 1067 break;
992 case AC_WID_PIN: 1068 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); 1069 hdmi_add_pin(codec, nid);
1003 break; 1070 break;
1004 } 1071 }
1005 } 1072 }
1006 1073
1007 for (i = 0; i < num_tmp_cvts; i++)
1008 hdmi_add_cvt(codec, tmp_cvt[i]);
1009
1010 /* 1074 /*
1011 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 1075 * 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 1076 * can be lost and presence sense verb will become inaccurate if the
1013 * HDA link is powered off at hot plug or hw initialization time. 1077 * HDA link is powered off at hot plug or hw initialization time.
1014 */ 1078 */
1015#ifdef CONFIG_SND_HDA_POWER_SAVE 1079#ifdef CONFIG_SND_HDA_POWER_SAVE
1016 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) & 1080 if ((!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
1017 AC_PWRST_EPSS)) 1081 AC_PWRST_EPSS)) && (codec->preset->id != 0x10de0020))
1018 codec->bus->power_keep_link_on = 1; 1082 codec->bus->power_keep_link_on = 1;
1019#endif 1083#endif
1020 1084
@@ -1023,7 +1087,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
1023 1087
1024/* 1088/*
1025 */ 1089 */
1026static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { 1090static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = {
1027 "HDMI 0", 1091 "HDMI 0",
1028 "HDMI 1", 1092 "HDMI 1",
1029 "HDMI 2", 1093 "HDMI 2",
@@ -1040,51 +1104,99 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1040 unsigned int format, 1104 unsigned int format,
1041 struct snd_pcm_substream *substream) 1105 struct snd_pcm_substream *substream)
1042{ 1106{
1043 hdmi_set_channel_count(codec, hinfo->nid, 1107 hda_nid_t cvt_nid = hinfo->nid;
1044 substream->runtime->channels); 1108 struct hdmi_spec *spec = codec->spec;
1109 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1110 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1111
1112#if defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA) && defined(CONFIG_TEGRA_DC)
1113 if (codec->preset->id == 0x10de0020) {
1114 int err = 0;
1115 /* Set hdmi:audio freq and source selection*/
1116 err = tegra_hdmi_setup_audio_freq_source(
1117 substream->runtime->rate, HDA);
1118 if ( err < 0 ) {
1119 snd_printk(KERN_ERR
1120 "Unable to set hdmi audio freq to %d \n",
1121 substream->runtime->rate);
1122 return err;
1123 }
1124 }
1125#endif
1045 1126
1046 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream); 1127 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1047 1128
1048 return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); 1129 hdmi_setup_audio_infoframe(codec, pin_idx, substream);
1130
1131 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1049} 1132}
1050 1133
1051static const struct hda_pcm_stream generic_hdmi_pcm_playback = { 1134static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1052 .substreams = 1, 1135 struct hda_codec *codec,
1053 .channels_min = 2, 1136 struct snd_pcm_substream *substream)
1054 .ops = { 1137{
1055 .open = hdmi_pcm_open, 1138 struct hdmi_spec *spec = codec->spec;
1056 .prepare = generic_hdmi_playback_pcm_prepare, 1139 int cvt_idx, pin_idx;
1057 }, 1140 struct hdmi_spec_per_cvt *per_cvt;
1141 struct hdmi_spec_per_pin *per_pin;
1142 int pinctl;
1143
1144 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
1145
1146 if (hinfo->nid) {
1147 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
1148 if (snd_BUG_ON(cvt_idx < 0))
1149 return -EINVAL;
1150 per_cvt = &spec->cvts[cvt_idx];
1151
1152 snd_BUG_ON(!per_cvt->assigned);
1153 per_cvt->assigned = 0;
1154 hinfo->nid = 0;
1155
1156 pin_idx = hinfo_to_pin_index(spec, hinfo);
1157 if (snd_BUG_ON(pin_idx < 0))
1158 return -EINVAL;
1159 per_pin = &spec->pins[pin_idx];
1160
1161 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
1162 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1163 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
1164 AC_VERB_SET_PIN_WIDGET_CONTROL,
1165 pinctl & ~PIN_OUT);
1166 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1167 }
1168
1169 return 0;
1170}
1171
1172static const struct hda_pcm_ops generic_ops = {
1173 .open = hdmi_pcm_open,
1174 .prepare = generic_hdmi_playback_pcm_prepare,
1175 .cleanup = generic_hdmi_playback_pcm_cleanup,
1058}; 1176};
1059 1177
1060static int generic_hdmi_build_pcms(struct hda_codec *codec) 1178static int generic_hdmi_build_pcms(struct hda_codec *codec)
1061{ 1179{
1062 struct hdmi_spec *spec = codec->spec; 1180 struct hdmi_spec *spec = codec->spec;
1063 struct hda_pcm *info = spec->pcm_rec; 1181 int pin_idx;
1064 int i;
1065 1182
1066 codec->num_pcms = spec->num_cvts; 1183 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1067 codec->pcm_info = info; 1184 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; 1185 struct hda_pcm_stream *pstr;
1072 1186
1073 chans = get_wcaps(codec, spec->cvt[i]); 1187 info = &spec->pcm_rec[pin_idx];
1074 chans = get_wcaps_channels(chans); 1188 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; 1189 info->pcm_type = HDA_PCM_TYPE_HDMI;
1190
1078 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1191 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1079 if (spec->pcm_playback) 1192 pstr->substreams = 1;
1080 *pstr = *spec->pcm_playback; 1193 pstr->ops = generic_ops;
1081 else 1194 /* 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 } 1195 }
1087 1196
1197 codec->num_pcms = spec->num_pins;
1198 codec->pcm_info = spec->pcm_rec;
1199
1088 return 0; 1200 return 0;
1089} 1201}
1090 1202
@@ -1092,12 +1204,16 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1092{ 1204{
1093 struct hdmi_spec *spec = codec->spec; 1205 struct hdmi_spec *spec = codec->spec;
1094 int err; 1206 int err;
1095 int i; 1207 int pin_idx;
1096 1208
1097 for (i = 0; i < codec->num_pcms; i++) { 1209 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1098 err = snd_hda_create_spdif_out_ctls(codec, spec->cvt[i]); 1210 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1211 err = snd_hda_create_spdif_out_ctls(codec,
1212 per_pin->pin_nid,
1213 per_pin->mux_nids[0]);
1099 if (err < 0) 1214 if (err < 0)
1100 return err; 1215 return err;
1216 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1101 } 1217 }
1102 1218
1103 return 0; 1219 return 0;
@@ -1106,13 +1222,27 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1106static int generic_hdmi_init(struct hda_codec *codec) 1222static int generic_hdmi_init(struct hda_codec *codec)
1107{ 1223{
1108 struct hdmi_spec *spec = codec->spec; 1224 struct hdmi_spec *spec = codec->spec;
1109 int i; 1225 int pin_idx;
1226
1227 switch (codec->preset->id) {
1228 case 0x10de0020:
1229 snd_hda_codec_write(codec, 4, 0,
1230 AC_VERB_SET_DIGI_CONVERT_1, 0x11);
1231 default:
1232 break;
1233 }
1234
1235 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1236 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1237 hda_nid_t pin_nid = per_pin->pin_nid;
1238 struct hdmi_eld *eld = &per_pin->sink_eld;
1110 1239
1111 for (i = 0; spec->pin[i]; i++) { 1240 hdmi_init_pin(codec, pin_nid);
1112 hdmi_enable_output(codec, spec->pin[i]); 1241 snd_hda_codec_write(codec, pin_nid, 0,
1113 snd_hda_codec_write(codec, spec->pin[i], 0,
1114 AC_VERB_SET_UNSOLICITED_ENABLE, 1242 AC_VERB_SET_UNSOLICITED_ENABLE,
1115 AC_USRSP_EN | spec->pin[i]); 1243 AC_USRSP_EN | pin_nid);
1244
1245 snd_hda_eld_proc_new(codec, eld, pin_idx);
1116 } 1246 }
1117 return 0; 1247 return 0;
1118} 1248}
@@ -1120,10 +1250,14 @@ static int generic_hdmi_init(struct hda_codec *codec)
1120static void generic_hdmi_free(struct hda_codec *codec) 1250static void generic_hdmi_free(struct hda_codec *codec)
1121{ 1251{
1122 struct hdmi_spec *spec = codec->spec; 1252 struct hdmi_spec *spec = codec->spec;
1123 int i; 1253 int pin_idx;
1254
1255 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1256 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1257 struct hdmi_eld *eld = &per_pin->sink_eld;
1124 1258
1125 for (i = 0; i < spec->num_pins; i++) 1259 snd_hda_eld_proc_free(codec, eld);
1126 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); 1260 }
1127 snd_hda_input_jack_free(codec); 1261 snd_hda_input_jack_free(codec);
1128 1262
1129 kfree(spec); 1263 kfree(spec);
@@ -1140,7 +1274,6 @@ static const struct hda_codec_ops generic_hdmi_patch_ops = {
1140static int patch_generic_hdmi(struct hda_codec *codec) 1274static int patch_generic_hdmi(struct hda_codec *codec)
1141{ 1275{
1142 struct hdmi_spec *spec; 1276 struct hdmi_spec *spec;
1143 int i;
1144 1277
1145 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1278 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1146 if (spec == NULL) 1279 if (spec == NULL)
@@ -1154,15 +1287,69 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1154 } 1287 }
1155 codec->patch_ops = generic_hdmi_patch_ops; 1288 codec->patch_ops = generic_hdmi_patch_ops;
1156 1289
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(); 1290 init_channel_allocations();
1161 1291
1162 return 0; 1292 return 0;
1163} 1293}
1164 1294
1165/* 1295/*
1296 * Shared non-generic implementations
1297 */
1298
1299static int simple_playback_build_pcms(struct hda_codec *codec)
1300{
1301 struct hdmi_spec *spec = codec->spec;
1302 struct hda_pcm *info = spec->pcm_rec;
1303 int i;
1304
1305 codec->num_pcms = spec->num_cvts;
1306 codec->pcm_info = info;
1307
1308 for (i = 0; i < codec->num_pcms; i++, info++) {
1309 unsigned int chans;
1310 struct hda_pcm_stream *pstr;
1311
1312 chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
1313 chans = get_wcaps_channels(chans);
1314
1315 info->name = generic_hdmi_pcm_names[i];
1316 info->pcm_type = HDA_PCM_TYPE_HDMI;
1317 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1318 snd_BUG_ON(!spec->pcm_playback);
1319 *pstr = *spec->pcm_playback;
1320 pstr->nid = spec->cvts[i].cvt_nid;
1321 if (pstr->channels_max <= 2 && chans && chans <= 16)
1322 pstr->channels_max = chans;
1323 }
1324
1325 return 0;
1326}
1327
1328static int simple_playback_build_controls(struct hda_codec *codec)
1329{
1330 struct hdmi_spec *spec = codec->spec;
1331 int err;
1332 int i;
1333
1334 for (i = 0; i < codec->num_pcms; i++) {
1335 err = snd_hda_create_spdif_out_ctls(codec,
1336 spec->cvts[i].cvt_nid,
1337 spec->cvts[i].cvt_nid);
1338 if (err < 0)
1339 return err;
1340 }
1341
1342 return 0;
1343}
1344
1345static void simple_playback_free(struct hda_codec *codec)
1346{
1347 struct hdmi_spec *spec = codec->spec;
1348
1349 kfree(spec);
1350}
1351
1352/*
1166 * Nvidia specific implementations 1353 * Nvidia specific implementations
1167 */ 1354 */
1168 1355
@@ -1352,6 +1539,9 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1352 int chs; 1539 int chs;
1353 unsigned int dataDCC1, dataDCC2, channel_id; 1540 unsigned int dataDCC1, dataDCC2, channel_id;
1354 int i; 1541 int i;
1542 struct hdmi_spec *spec = codec->spec;
1543 struct hda_spdif_out *spdif =
1544 snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid);
1355 1545
1356 mutex_lock(&codec->spdif_mutex); 1546 mutex_lock(&codec->spdif_mutex);
1357 1547
@@ -1361,12 +1551,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1361 dataDCC2 = 0x2; 1551 dataDCC2 = 0x2;
1362 1552
1363 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 1553 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
1364 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 1554 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE))
1365 snd_hda_codec_write(codec, 1555 snd_hda_codec_write(codec,
1366 nvhdmi_master_con_nid_7x, 1556 nvhdmi_master_con_nid_7x,
1367 0, 1557 0,
1368 AC_VERB_SET_DIGI_CONVERT_1, 1558 AC_VERB_SET_DIGI_CONVERT_1,
1369 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1559 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1370 1560
1371 /* set the stream id */ 1561 /* set the stream id */
1372 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0, 1562 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
@@ -1378,12 +1568,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1378 1568
1379 /* turn on again (if needed) */ 1569 /* turn on again (if needed) */
1380 /* enable and set the channel status audio/data flag */ 1570 /* enable and set the channel status audio/data flag */
1381 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1571 if (codec->spdif_status_reset && (spdif->ctls & AC_DIG1_ENABLE)) {
1382 snd_hda_codec_write(codec, 1572 snd_hda_codec_write(codec,
1383 nvhdmi_master_con_nid_7x, 1573 nvhdmi_master_con_nid_7x,
1384 0, 1574 0,
1385 AC_VERB_SET_DIGI_CONVERT_1, 1575 AC_VERB_SET_DIGI_CONVERT_1,
1386 codec->spdif_ctls & 0xff); 1576 spdif->ctls & 0xff);
1387 snd_hda_codec_write(codec, 1577 snd_hda_codec_write(codec,
1388 nvhdmi_master_con_nid_7x, 1578 nvhdmi_master_con_nid_7x,
1389 0, 1579 0,
@@ -1400,12 +1590,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1400 *otherwise the IEC958 bits won't be updated 1590 *otherwise the IEC958 bits won't be updated
1401 */ 1591 */
1402 if (codec->spdif_status_reset && 1592 if (codec->spdif_status_reset &&
1403 (codec->spdif_ctls & AC_DIG1_ENABLE)) 1593 (spdif->ctls & AC_DIG1_ENABLE))
1404 snd_hda_codec_write(codec, 1594 snd_hda_codec_write(codec,
1405 nvhdmi_con_nids_7x[i], 1595 nvhdmi_con_nids_7x[i],
1406 0, 1596 0,
1407 AC_VERB_SET_DIGI_CONVERT_1, 1597 AC_VERB_SET_DIGI_CONVERT_1,
1408 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 1598 spdif->ctls & ~AC_DIG1_ENABLE & 0xff);
1409 /* set the stream id */ 1599 /* set the stream id */
1410 snd_hda_codec_write(codec, 1600 snd_hda_codec_write(codec,
1411 nvhdmi_con_nids_7x[i], 1601 nvhdmi_con_nids_7x[i],
@@ -1421,12 +1611,12 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
1421 /* turn on again (if needed) */ 1611 /* turn on again (if needed) */
1422 /* enable and set the channel status audio/data flag */ 1612 /* enable and set the channel status audio/data flag */
1423 if (codec->spdif_status_reset && 1613 if (codec->spdif_status_reset &&
1424 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 1614 (spdif->ctls & AC_DIG1_ENABLE)) {
1425 snd_hda_codec_write(codec, 1615 snd_hda_codec_write(codec,
1426 nvhdmi_con_nids_7x[i], 1616 nvhdmi_con_nids_7x[i],
1427 0, 1617 0,
1428 AC_VERB_SET_DIGI_CONVERT_1, 1618 AC_VERB_SET_DIGI_CONVERT_1,
1429 codec->spdif_ctls & 0xff); 1619 spdif->ctls & 0xff);
1430 snd_hda_codec_write(codec, 1620 snd_hda_codec_write(codec,
1431 nvhdmi_con_nids_7x[i], 1621 nvhdmi_con_nids_7x[i],
1432 0, 1622 0,
@@ -1471,17 +1661,17 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1471}; 1661};
1472 1662
1473static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { 1663static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1474 .build_controls = generic_hdmi_build_controls, 1664 .build_controls = simple_playback_build_controls,
1475 .build_pcms = generic_hdmi_build_pcms, 1665 .build_pcms = simple_playback_build_pcms,
1476 .init = nvhdmi_7x_init, 1666 .init = nvhdmi_7x_init,
1477 .free = generic_hdmi_free, 1667 .free = simple_playback_free,
1478}; 1668};
1479 1669
1480static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { 1670static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1481 .build_controls = generic_hdmi_build_controls, 1671 .build_controls = simple_playback_build_controls,
1482 .build_pcms = generic_hdmi_build_pcms, 1672 .build_pcms = simple_playback_build_pcms,
1483 .init = nvhdmi_7x_init, 1673 .init = nvhdmi_7x_init,
1484 .free = generic_hdmi_free, 1674 .free = simple_playback_free,
1485}; 1675};
1486 1676
1487static int patch_nvhdmi_2ch(struct hda_codec *codec) 1677static int patch_nvhdmi_2ch(struct hda_codec *codec)
@@ -1498,7 +1688,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
1498 spec->multiout.max_channels = 2; 1688 spec->multiout.max_channels = 2;
1499 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; 1689 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1500 spec->num_cvts = 1; 1690 spec->num_cvts = 1;
1501 spec->cvt[0] = nvhdmi_master_con_nid_7x; 1691 spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
1502 spec->pcm_playback = &nvhdmi_pcm_playback_2ch; 1692 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1503 1693
1504 codec->patch_ops = nvhdmi_patch_ops_2ch; 1694 codec->patch_ops = nvhdmi_patch_ops_2ch;
@@ -1549,11 +1739,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1549 substream); 1739 substream);
1550 if (err < 0) 1740 if (err < 0)
1551 return err; 1741 return err;
1552 snd_hda_codec_write(codec, spec->cvt[0], 0, AC_VERB_SET_CVT_CHAN_COUNT, 1742 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1553 chans - 1); 1743 AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
1554 /* FIXME: XXX */ 1744 /* FIXME: XXX */
1555 for (i = 0; i < chans; i++) { 1745 for (i = 0; i < chans; i++) {
1556 snd_hda_codec_write(codec, spec->cvt[0], 0, 1746 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0,
1557 AC_VERB_SET_HDMI_CHAN_SLOT, 1747 AC_VERB_SET_HDMI_CHAN_SLOT,
1558 (i << 4) | i); 1748 (i << 4) | i);
1559 } 1749 }
@@ -1584,18 +1774,18 @@ static int atihdmi_init(struct hda_codec *codec)
1584 1774
1585 snd_hda_sequence_write(codec, atihdmi_basic_init); 1775 snd_hda_sequence_write(codec, atihdmi_basic_init);
1586 /* SI codec requires to unmute the pin */ 1776 /* SI codec requires to unmute the pin */
1587 if (get_wcaps(codec, spec->pin[0]) & AC_WCAP_OUT_AMP) 1777 if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP)
1588 snd_hda_codec_write(codec, spec->pin[0], 0, 1778 snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0,
1589 AC_VERB_SET_AMP_GAIN_MUTE, 1779 AC_VERB_SET_AMP_GAIN_MUTE,
1590 AMP_OUT_UNMUTE); 1780 AMP_OUT_UNMUTE);
1591 return 0; 1781 return 0;
1592} 1782}
1593 1783
1594static const struct hda_codec_ops atihdmi_patch_ops = { 1784static const struct hda_codec_ops atihdmi_patch_ops = {
1595 .build_controls = generic_hdmi_build_controls, 1785 .build_controls = simple_playback_build_controls,
1596 .build_pcms = generic_hdmi_build_pcms, 1786 .build_pcms = simple_playback_build_pcms,
1597 .init = atihdmi_init, 1787 .init = atihdmi_init,
1598 .free = generic_hdmi_free, 1788 .free = simple_playback_free,
1599}; 1789};
1600 1790
1601 1791
@@ -1613,8 +1803,8 @@ static int patch_atihdmi(struct hda_codec *codec)
1613 spec->multiout.max_channels = 2; 1803 spec->multiout.max_channels = 2;
1614 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; 1804 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1615 spec->num_cvts = 1; 1805 spec->num_cvts = 1;
1616 spec->cvt[0] = ATIHDMI_CVT_NID; 1806 spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
1617 spec->pin[0] = ATIHDMI_PIN_NID; 1807 spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
1618 spec->pcm_playback = &atihdmi_pcm_digital_playback; 1808 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1619 1809
1620 codec->patch_ops = atihdmi_patch_ops; 1810 codec->patch_ops = atihdmi_patch_ops;
@@ -1656,6 +1846,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1656{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, 1846{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi },
1657{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, 1847{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi },
1658{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, 1848{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi },
1849{ .id = 0x10de0020, .name = "Tegra30 HDMI", .patch = patch_generic_hdmi },
1659{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, 1850{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi },
1660{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, 1851{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi },
1661{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, 1852{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
@@ -1701,6 +1892,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0019");
1701MODULE_ALIAS("snd-hda-codec-id:10de001a"); 1892MODULE_ALIAS("snd-hda-codec-id:10de001a");
1702MODULE_ALIAS("snd-hda-codec-id:10de001b"); 1893MODULE_ALIAS("snd-hda-codec-id:10de001b");
1703MODULE_ALIAS("snd-hda-codec-id:10de001c"); 1894MODULE_ALIAS("snd-hda-codec-id:10de001c");
1895MODULE_ALIAS("snd-hda-codec-id:10de0020");
1704MODULE_ALIAS("snd-hda-codec-id:10de0040"); 1896MODULE_ALIAS("snd-hda-codec-id:10de0040");
1705MODULE_ALIAS("snd-hda-codec-id:10de0041"); 1897MODULE_ALIAS("snd-hda-codec-id:10de0041");
1706MODULE_ALIAS("snd-hda-codec-id:10de0042"); 1898MODULE_ALIAS("snd-hda-codec-id:10de0042");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b48fb43b544..4cd3bc8f1c7 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,15 +165,17 @@ 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; NOP when automute_hp_lo isn't set */
401 unsigned int automute_hp_lo:1; /* both HP and LO available */ 172 unsigned int automute_hp_lo:1; /* both HP and LO available */
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,85 @@ 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];
283 if (!imux->num_items)
284 return 0;
285
286 if (idx >= imux->num_items)
287 idx = imux->num_items - 1;
288 if (spec->cur_mux[adc_idx] == idx && !force)
289 return 0;
290 spec->cur_mux[adc_idx] = idx;
291
292 if (spec->dyn_adc_switch) {
293 alc_dyn_adc_pcm_resetup(codec, idx);
294 adc_idx = spec->dyn_adc_idx[idx];
295 }
296
297 nid = spec->capsrc_nids ?
298 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
299
300 /* no selection? */
301 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
302 return 1;
512 303
513 type = get_wcaps_type(get_wcaps(codec, nid)); 304 type = get_wcaps_type(get_wcaps(codec, nid));
514 if (type == AC_WID_AUD_MIX) { 305 if (type == AC_WID_AUD_MIX) {
515 /* Matrix-mixer style (e.g. ALC882) */ 306 /* 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++) { 307 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE; 308 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 309 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index, 310 imux->items[i].index,
528 HDA_AMP_MUTE, v); 311 HDA_AMP_MUTE, v);
529 } 312 }
530 *cur_val = idx;
531 return 1;
532 } else { 313 } else {
533 /* MUX style (e.g. ALC880) */ 314 /* 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, 315 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL, 316 AC_VERB_SET_CONNECT_SEL,
681 alc_pin_mode_values[val]); 317 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 } 318 }
705 return change; 319 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} 320}
844 321
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol, 322static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol) 323 struct snd_ctl_elem_value *ucontrol)
847{ 324{
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 325 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff; 326 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff; 327 return alc_mux_select(codec, adc_idx,
852 long val = *ucontrol->value.integer.value; 328 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} 329}
868 330
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/* 331/*
879 * set up the input pin config (depending on the given auto-pin type) 332 * set up the input pin config (depending on the given auto-pin type)
880 */ 333 */
@@ -903,29 +356,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); 356 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904} 357}
905 358
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/* 359/*
360 * Append the given mixer and verb elements for the later use
361 * The mixer array is referred in build_controls(), and init_verbs are
362 * called in init().
929 */ 363 */
930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 364static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931{ 365{
@@ -942,61 +376,8 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
942} 376}
943 377
944/* 378/*
945 * set up from the preset table 379 * GPIO setup tables, used in initialization
946 */ 380 */
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 */ 381/* Enable GPIO mask and set output */
1001static const struct hda_verb alc_gpio1_init_verbs[] = { 382static const struct hda_verb alc_gpio1_init_verbs[] = {
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 383 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
@@ -1051,14 +432,19 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1051 alc_fix_pll(codec); 432 alc_fix_pll(codec);
1052} 433}
1053 434
435/*
436 * Jack-reporting via input-jack layer
437 */
438
439/* initialization of jacks; currently checks only a few known pins */
1054static int alc_init_jacks(struct hda_codec *codec) 440static int alc_init_jacks(struct hda_codec *codec)
1055{ 441{
1056#ifdef CONFIG_SND_HDA_INPUT_JACK 442#ifdef CONFIG_SND_HDA_INPUT_JACK
1057 struct alc_spec *spec = codec->spec; 443 struct alc_spec *spec = codec->spec;
1058 int err; 444 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0]; 445 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin; 446 unsigned int mic_nid = spec->ext_mic_pin;
1061 unsigned int dock_nid = spec->dock_mic.pin; 447 unsigned int dock_nid = spec->dock_mic_pin;
1062 448
1063 if (hp_nid) { 449 if (hp_nid) {
1064 err = snd_hda_input_jack_add(codec, hp_nid, 450 err = snd_hda_input_jack_add(codec, hp_nid,
@@ -1086,7 +472,12 @@ static int alc_init_jacks(struct hda_codec *codec)
1086 return 0; 472 return 0;
1087} 473}
1088 474
1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 475/*
476 * Jack detections for HP auto-mute and mic-switch
477 */
478
479/* check each pin in the given array; returns true if any of them is plugged */
480static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090{ 481{
1091 int i, present = 0; 482 int i, present = 0;
1092 483
@@ -1100,6 +491,7 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1100 return present; 491 return present;
1101} 492}
1102 493
494/* standard HP/line-out auto-mute helper */
1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 495static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out) 496 bool mute, bool hp_out)
1105{ 497{
@@ -1161,7 +553,7 @@ static void update_speakers(struct hda_codec *codec)
1161 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || 553 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) 554 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1163 return; 555 return;
1164 if (!spec->automute_lines || !spec->automute) 556 if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines))
1165 on = 0; 557 on = 0;
1166 else 558 else
1167 on = spec->jack_present; 559 on = spec->jack_present;
@@ -1170,130 +562,63 @@ static void update_speakers(struct hda_codec *codec)
1170 spec->autocfg.line_out_pins, on, false); 562 spec->autocfg.line_out_pins, on, false);
1171} 563}
1172 564
565/* standard HP-automute helper */
1173static void alc_hp_automute(struct hda_codec *codec) 566static void alc_hp_automute(struct hda_codec *codec)
1174{ 567{
1175 struct alc_spec *spec = codec->spec; 568 struct alc_spec *spec = codec->spec;
1176 569
1177 if (!spec->automute)
1178 return;
1179 spec->jack_present = 570 spec->jack_present =
1180 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 571 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181 spec->autocfg.hp_pins); 572 spec->autocfg.hp_pins);
573 if (!spec->automute)
574 return;
1182 update_speakers(codec); 575 update_speakers(codec);
1183} 576}
1184 577
578/* standard line-out-automute helper */
1185static void alc_line_automute(struct hda_codec *codec) 579static void alc_line_automute(struct hda_codec *codec)
1186{ 580{
1187 struct alc_spec *spec = codec->spec; 581 struct alc_spec *spec = codec->spec;
1188 582
1189 if (!spec->automute || !spec->detect_line) 583 /* check LO jack only when it's different from HP */
584 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
1190 return; 585 return;
586
1191 spec->line_jack_present = 587 spec->line_jack_present =
1192 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 588 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193 spec->autocfg.line_out_pins); 589 spec->autocfg.line_out_pins);
590 if (!spec->automute || !spec->detect_line)
591 return;
1194 update_speakers(codec); 592 update_speakers(codec);
1195} 593}
1196 594
1197static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 595#define get_connection_index(codec, mux, nid) \
1198 hda_nid_t nid) 596 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 597
598/* standard mic auto-switch helper */
1233static void alc_mic_automute(struct hda_codec *codec) 599static void alc_mic_automute(struct hda_codec *codec)
1234{ 600{
1235 struct alc_spec *spec = codec->spec; 601 struct alc_spec *spec = codec->spec;
1236 struct alc_mic_route *dead1, *dead2, *alive; 602 hda_nid_t *pins = spec->imux_pins;
1237 unsigned int present, type;
1238 hda_nid_t cap_nid;
1239 603
1240 if (!spec->auto_mic) 604 if (!spec->auto_mic || !spec->auto_mic_valid_imux)
1241 return;
1242 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243 return; 605 return;
1244 if (snd_BUG_ON(!spec->adc_nids)) 606 if (snd_BUG_ON(!spec->adc_nids))
1245 return; 607 return;
1246 608 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; 609 return;
1250 }
1251 610
1252 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; 611 if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
1253 612 alc_mux_select(codec, 0, spec->ext_mic_idx, false);
1254 alive = &spec->int_mic; 613 else if (spec->dock_mic_idx >= 0 &&
1255 dead1 = &spec->ext_mic; 614 snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
1256 dead2 = &spec->dock_mic; 615 alc_mux_select(codec, 0, spec->dock_mic_idx, false);
1257 616 else
1258 present = snd_hda_jack_detect(codec, spec->ext_mic.pin); 617 alc_mux_select(codec, 0, spec->int_mic_idx, false);
1259 if (present) {
1260 alive = &spec->ext_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->dock_mic;
1263 }
1264 if (!present && spec->dock_mic.pin > 0) {
1265 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266 if (present) {
1267 alive = &spec->dock_mic;
1268 dead1 = &spec->int_mic;
1269 dead2 = &spec->ext_mic;
1270 }
1271 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1272 }
1273
1274 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1275 if (type == AC_WID_AUD_MIX) {
1276 /* Matrix-mixer style (e.g. ALC882) */
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1278 alive->mux_idx,
1279 HDA_AMP_MUTE, 0);
1280 if (dead1->pin > 0)
1281 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282 dead1->mux_idx,
1283 HDA_AMP_MUTE, HDA_AMP_MUTE);
1284 if (dead2->pin > 0)
1285 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286 dead2->mux_idx,
1287 HDA_AMP_MUTE, HDA_AMP_MUTE);
1288 } else {
1289 /* MUX style (e.g. ALC880) */
1290 snd_hda_codec_write_cache(codec, cap_nid, 0,
1291 AC_VERB_SET_CONNECT_SEL,
1292 alive->mux_idx);
1293 }
1294 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1295 618
1296 /* FIXME: analog mixer */ 619 snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]);
620 if (spec->dock_mic_idx >= 0)
621 snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]);
1297} 622}
1298 623
1299/* unsolicited event for HP jack sensing */ 624/* unsolicited event for HP jack sensing */
@@ -1304,18 +629,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1304 else 629 else
1305 res >>= 26; 630 res >>= 26;
1306 switch (res) { 631 switch (res) {
1307 case ALC880_HP_EVENT: 632 case ALC_HP_EVENT:
1308 alc_hp_automute(codec); 633 alc_hp_automute(codec);
1309 break; 634 break;
1310 case ALC880_FRONT_EVENT: 635 case ALC_FRONT_EVENT:
1311 alc_line_automute(codec); 636 alc_line_automute(codec);
1312 break; 637 break;
1313 case ALC880_MIC_EVENT: 638 case ALC_MIC_EVENT:
1314 alc_mic_automute(codec); 639 alc_mic_automute(codec);
1315 break; 640 break;
1316 } 641 }
1317} 642}
1318 643
644/* call init functions of standard auto-mute helpers */
1319static void alc_inithook(struct hda_codec *codec) 645static void alc_inithook(struct hda_codec *codec)
1320{ 646{
1321 alc_hp_automute(codec); 647 alc_hp_automute(codec);
@@ -1341,6 +667,7 @@ static void alc888_coef_init(struct hda_codec *codec)
1341 AC_VERB_SET_PROC_COEF, 0x3030); 667 AC_VERB_SET_PROC_COEF, 0x3030);
1342} 668}
1343 669
670/* additional initialization for ALC889 variants */
1344static void alc889_coef_init(struct hda_codec *codec) 671static void alc889_coef_init(struct hda_codec *codec)
1345{ 672{
1346 unsigned int tmp; 673 unsigned int tmp;
@@ -1365,28 +692,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) 692static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366{ 693{
1367 /* We currently only handle front, HP */ 694 /* We currently only handle front, HP */
1368 switch (codec->vendor_id) { 695 static hda_nid_t pins[] = {
1369 case 0x10ec0260: 696 0x0f, 0x10, 0x14, 0x15, 0
1370 set_eapd(codec, 0x0f, on); 697 };
1371 set_eapd(codec, 0x10, on); 698 hda_nid_t *p;
1372 break; 699 for (p = pins; *p; p++)
1373 case 0x10ec0262: 700 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} 701}
1391 702
1392/* generic shutup callback; 703/* generic shutup callback;
@@ -1398,10 +709,12 @@ static void alc_eapd_shutup(struct hda_codec *codec)
1398 msleep(200); 709 msleep(200);
1399} 710}
1400 711
712/* generic EAPD initialization */
1401static void alc_auto_init_amp(struct hda_codec *codec, int type) 713static void alc_auto_init_amp(struct hda_codec *codec, int type)
1402{ 714{
1403 unsigned int tmp; 715 unsigned int tmp;
1404 716
717 alc_auto_setup_eapd(codec, true);
1405 switch (type) { 718 switch (type) {
1406 case ALC_INIT_GPIO1: 719 case ALC_INIT_GPIO1:
1407 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 720 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
@@ -1413,7 +726,6 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1413 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 726 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414 break; 727 break;
1415 case ALC_INIT_DEFAULT: 728 case ALC_INIT_DEFAULT:
1416 alc_auto_setup_eapd(codec, true);
1417 switch (codec->vendor_id) { 729 switch (codec->vendor_id) {
1418 case 0x10ec0260: 730 case 0x10ec0260:
1419 snd_hda_codec_write(codec, 0x1a, 0, 731 snd_hda_codec_write(codec, 0x1a, 0,
@@ -1457,6 +769,9 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1457 } 769 }
1458} 770}
1459 771
772/*
773 * Auto-Mute mode mixer enum support
774 */
1460static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 775static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_info *uinfo) 776 struct snd_ctl_elem_info *uinfo)
1462{ 777{
@@ -1494,7 +809,7 @@ static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1494 unsigned int val; 809 unsigned int val;
1495 if (!spec->automute) 810 if (!spec->automute)
1496 val = 0; 811 val = 0;
1497 else if (!spec->automute_lines) 812 else if (!spec->automute_hp_lo || !spec->automute_lines)
1498 val = 1; 813 val = 1;
1499 else 814 else
1500 val = 2; 815 val = 2;
@@ -1515,7 +830,8 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1515 spec->automute = 0; 830 spec->automute = 0;
1516 break; 831 break;
1517 case 1: 832 case 1:
1518 if (spec->automute && !spec->automute_lines) 833 if (spec->automute &&
834 (!spec->automute_hp_lo || !spec->automute_lines))
1519 return 0; 835 return 0;
1520 spec->automute = 1; 836 spec->automute = 1;
1521 spec->automute_lines = 0; 837 spec->automute_lines = 0;
@@ -1543,7 +859,11 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {
1543 .put = alc_automute_mode_put, 859 .put = alc_automute_mode_put,
1544}; 860};
1545 861
1546static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 862static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
863{
864 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
865 return snd_array_new(&spec->kctls);
866}
1547 867
1548static int alc_add_automute_mode_enum(struct hda_codec *codec) 868static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549{ 869{
@@ -1560,6 +880,10 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
1560 return 0; 880 return 0;
1561} 881}
1562 882
883/*
884 * Check the availability of HP/line-out auto-mute;
885 * Set up appropriately if really supported
886 */
1563static void alc_init_auto_hp(struct hda_codec *codec) 887static void alc_init_auto_hp(struct hda_codec *codec)
1564{ 888{
1565 struct alc_spec *spec = codec->spec; 889 struct alc_spec *spec = codec->spec;
@@ -1578,13 +902,15 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1578 if (present == 3) 902 if (present == 3)
1579 spec->automute_hp_lo = 1; /* both HP and LO automute */ 903 spec->automute_hp_lo = 1; /* both HP and LO automute */
1580 904
1581 if (!cfg->speaker_pins[0]) { 905 if (!cfg->speaker_pins[0] &&
906 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
1582 memcpy(cfg->speaker_pins, cfg->line_out_pins, 907 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1583 sizeof(cfg->speaker_pins)); 908 sizeof(cfg->speaker_pins));
1584 cfg->speaker_outs = cfg->line_outs; 909 cfg->speaker_outs = cfg->line_outs;
1585 } 910 }
1586 911
1587 if (!cfg->hp_pins[0]) { 912 if (!cfg->hp_pins[0] &&
913 cfg->line_out_type == AUTO_PIN_HP_OUT) {
1588 memcpy(cfg->hp_pins, cfg->line_out_pins, 914 memcpy(cfg->hp_pins, cfg->line_out_pins,
1589 sizeof(cfg->hp_pins)); 915 sizeof(cfg->hp_pins));
1590 cfg->hp_outs = cfg->line_outs; 916 cfg->hp_outs = cfg->line_outs;
@@ -1598,11 +924,12 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1598 nid); 924 nid);
1599 snd_hda_codec_write_cache(codec, nid, 0, 925 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE, 926 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_HP_EVENT); 927 AC_USRSP_EN | ALC_HP_EVENT);
1602 spec->automute = 1; 928 spec->automute = 1;
1603 spec->automute_mode = ALC_AUTOMUTE_PIN; 929 spec->automute_mode = ALC_AUTOMUTE_PIN;
1604 } 930 }
1605 if (spec->automute && cfg->line_out_pins[0] && 931 if (spec->automute && cfg->line_out_pins[0] &&
932 cfg->speaker_pins[0] &&
1606 cfg->line_out_pins[0] != cfg->hp_pins[0] && 933 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1607 cfg->line_out_pins[0] != cfg->speaker_pins[0]) { 934 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1608 for (i = 0; i < cfg->line_outs; i++) { 935 for (i = 0; i < cfg->line_outs; i++) {
@@ -1613,7 +940,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1613 "on NID 0x%x\n", nid); 940 "on NID 0x%x\n", nid);
1614 snd_hda_codec_write_cache(codec, nid, 0, 941 snd_hda_codec_write_cache(codec, nid, 0,
1615 AC_VERB_SET_UNSOLICITED_ENABLE, 942 AC_VERB_SET_UNSOLICITED_ENABLE,
1616 AC_USRSP_EN | ALC880_FRONT_EVENT); 943 AC_USRSP_EN | ALC_FRONT_EVENT);
1617 spec->detect_line = 1; 944 spec->detect_line = 1;
1618 } 945 }
1619 spec->automute_lines = spec->detect_line; 946 spec->automute_lines = spec->detect_line;
@@ -1626,6 +953,144 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1626 } 953 }
1627} 954}
1628 955
956/* return the position of NID in the list, or -1 if not found */
957static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
958{
959 int i;
960 for (i = 0; i < nums; i++)
961 if (list[i] == nid)
962 return i;
963 return -1;
964}
965
966/* check whether dynamic ADC-switching is available */
967static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
968{
969 struct alc_spec *spec = codec->spec;
970 struct hda_input_mux *imux = &spec->private_imux[0];
971 int i, n, idx;
972 hda_nid_t cap, pin;
973
974 if (imux != spec->input_mux) /* no dynamic imux? */
975 return false;
976
977 for (n = 0; n < spec->num_adc_nids; n++) {
978 cap = spec->private_capsrc_nids[n];
979 for (i = 0; i < imux->num_items; i++) {
980 pin = spec->imux_pins[i];
981 if (!pin)
982 return false;
983 if (get_connection_index(codec, cap, pin) < 0)
984 break;
985 }
986 if (i >= imux->num_items)
987 return true; /* no ADC-switch is needed */
988 }
989
990 for (i = 0; i < imux->num_items; i++) {
991 pin = spec->imux_pins[i];
992 for (n = 0; n < spec->num_adc_nids; n++) {
993 cap = spec->private_capsrc_nids[n];
994 idx = get_connection_index(codec, cap, pin);
995 if (idx >= 0) {
996 imux->items[i].index = idx;
997 spec->dyn_adc_idx[i] = n;
998 break;
999 }
1000 }
1001 }
1002
1003 snd_printdd("realtek: enabling ADC switching\n");
1004 spec->dyn_adc_switch = 1;
1005 return true;
1006}
1007
1008/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1009static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1010{
1011 struct alc_spec *spec = codec->spec;
1012 struct hda_input_mux *imux;
1013 static char * const texts[3] = {
1014 "Mic", "Internal Mic", "Dock Mic"
1015 };
1016 int i;
1017
1018 if (!spec->auto_mic)
1019 return false;
1020 imux = &spec->private_imux[0];
1021 if (spec->input_mux == imux)
1022 return true;
1023 spec->imux_pins[0] = spec->ext_mic_pin;
1024 spec->imux_pins[1] = spec->int_mic_pin;
1025 spec->imux_pins[2] = spec->dock_mic_pin;
1026 for (i = 0; i < 3; i++) {
1027 strcpy(imux->items[i].label, texts[i]);
1028 if (spec->imux_pins[i]) {
1029 hda_nid_t pin = spec->imux_pins[i];
1030 int c;
1031 for (c = 0; c < spec->num_adc_nids; c++) {
1032 hda_nid_t cap = spec->capsrc_nids ?
1033 spec->capsrc_nids[c] : spec->adc_nids[c];
1034 int idx = get_connection_index(codec, cap, pin);
1035 if (idx >= 0) {
1036 imux->items[i].index = idx;
1037 break;
1038 }
1039 }
1040 imux->num_items = i + 1;
1041 }
1042 }
1043 spec->num_mux_defs = 1;
1044 spec->input_mux = imux;
1045 return true;
1046}
1047
1048/* check whether all auto-mic pins are valid; setup indices if OK */
1049static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1050{
1051 struct alc_spec *spec = codec->spec;
1052 const struct hda_input_mux *imux;
1053
1054 if (!spec->auto_mic)
1055 return false;
1056 if (spec->auto_mic_valid_imux)
1057 return true; /* already checked */
1058
1059 /* fill up imux indices */
1060 if (!alc_check_dyn_adc_switch(codec)) {
1061 spec->auto_mic = 0;
1062 return false;
1063 }
1064
1065 imux = spec->input_mux;
1066 spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
1067 spec->imux_pins, imux->num_items);
1068 spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
1069 spec->imux_pins, imux->num_items);
1070 spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
1071 spec->imux_pins, imux->num_items);
1072 if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
1073 spec->auto_mic = 0;
1074 return false; /* no corresponding imux */
1075 }
1076
1077 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1078 AC_VERB_SET_UNSOLICITED_ENABLE,
1079 AC_USRSP_EN | ALC_MIC_EVENT);
1080 if (spec->dock_mic_pin)
1081 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1082 AC_VERB_SET_UNSOLICITED_ENABLE,
1083 AC_USRSP_EN | ALC_MIC_EVENT);
1084
1085 spec->auto_mic_valid_imux = 1;
1086 spec->auto_mic = 1;
1087 return true;
1088}
1089
1090/*
1091 * Check the availability of auto-mic switch;
1092 * Set up if really supported
1093 */
1629static void alc_init_auto_mic(struct hda_codec *codec) 1094static void alc_init_auto_mic(struct hda_codec *codec)
1630{ 1095{
1631 struct alc_spec *spec = codec->spec; 1096 struct alc_spec *spec = codec->spec;
@@ -1633,6 +1098,8 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1633 hda_nid_t fixed, ext, dock; 1098 hda_nid_t fixed, ext, dock;
1634 int i; 1099 int i;
1635 1100
1101 spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
1102
1636 fixed = ext = dock = 0; 1103 fixed = ext = dock = 0;
1637 for (i = 0; i < cfg->num_inputs; i++) { 1104 for (i = 0; i < cfg->num_inputs; i++) {
1638 hda_nid_t nid = cfg->inputs[i].pin; 1105 hda_nid_t nid = cfg->inputs[i].pin;
@@ -1674,21 +1141,32 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1674 return; /* no unsol support */ 1141 return; /* no unsol support */
1675 if (dock && !is_jack_detectable(codec, dock)) 1142 if (dock && !is_jack_detectable(codec, dock))
1676 return; /* no unsol support */ 1143 return; /* no unsol support */
1144
1145 /* check imux indices */
1146 spec->ext_mic_pin = ext;
1147 spec->int_mic_pin = fixed;
1148 spec->dock_mic_pin = dock;
1149
1150 spec->auto_mic = 1;
1151 if (!alc_auto_mic_check_imux(codec))
1152 return;
1153
1677 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1154 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1678 ext, fixed, dock); 1155 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; 1156 spec->unsol_event = alc_sku_unsol_event;
1690} 1157}
1691 1158
1159/* check the availabilities of auto-mute and auto-mic switches */
1160static void alc_auto_check_switches(struct hda_codec *codec)
1161{
1162 alc_init_auto_hp(codec);
1163 alc_init_auto_mic(codec);
1164}
1165
1166/*
1167 * Realtek SSID verification
1168 */
1169
1692/* Could be any non-zero and even value. When used as fixup, tells 1170/* Could be any non-zero and even value. When used as fixup, tells
1693 * the driver to ignore any present sku defines. 1171 * the driver to ignore any present sku defines.
1694 */ 1172 */
@@ -1710,8 +1188,10 @@ static int alc_auto_parse_customize_define(struct hda_codec *codec)
1710 } 1188 }
1711 1189
1712 ass = codec->subsystem_id & 0xffff; 1190 ass = codec->subsystem_id & 0xffff;
1191#if !defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA)
1713 if (ass != codec->bus->pci->subsystem_device && (ass & 1)) 1192 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1714 goto do_sku; 1193 goto do_sku;
1194#endif
1715 1195
1716 nid = 0x1d; 1196 nid = 0x1d;
1717 if (codec->vendor_id == 0x10ec0260) 1197 if (codec->vendor_id == 0x10ec0260)
@@ -1759,6 +1239,12 @@ do_sku:
1759 return 0; 1239 return 0;
1760} 1240}
1761 1241
1242/* return true if the given NID is found in the list */
1243static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1244{
1245 return find_idx_in_nid_list(nid, list, nums) >= 0;
1246}
1247
1762/* check subsystem ID and set up device-specific initialization; 1248/* check subsystem ID and set up device-specific initialization;
1763 * return 1 if initialized, 0 if invalid SSID 1249 * return 1 if initialized, 0 if invalid SSID
1764 */ 1250 */
@@ -1784,8 +1270,10 @@ static int alc_subsystem_id(struct hda_codec *codec,
1784 } 1270 }
1785 1271
1786 ass = codec->subsystem_id & 0xffff; 1272 ass = codec->subsystem_id & 0xffff;
1273#if !defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA)
1787 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) 1274 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1788 goto do_sku; 1275 goto do_sku;
1276#endif
1789 1277
1790 /* invalid SSID, check the special NID pin defcfg instead */ 1278 /* invalid SSID, check the special NID pin defcfg instead */
1791 /* 1279 /*
@@ -1855,7 +1343,9 @@ do_sku:
1855 * 15 : 1 --> enable the function "Mute internal speaker 1343 * 15 : 1 --> enable the function "Mute internal speaker
1856 * when the external headphone out jack is plugged" 1344 * when the external headphone out jack is plugged"
1857 */ 1345 */
1858 if (!spec->autocfg.hp_pins[0]) { 1346 if (!spec->autocfg.hp_pins[0] &&
1347 !(spec->autocfg.line_out_pins[0] &&
1348 spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)) {
1859 hda_nid_t nid; 1349 hda_nid_t nid;
1860 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1350 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1861 if (tmp == 0) 1351 if (tmp == 0)
@@ -1868,27 +1358,24 @@ do_sku:
1868 nid = porti; 1358 nid = porti;
1869 else 1359 else
1870 return 1; 1360 return 1;
1871 for (i = 0; i < spec->autocfg.line_outs; i++) 1361 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1872 if (spec->autocfg.line_out_pins[i] == nid) 1362 spec->autocfg.line_outs))
1873 return 1; 1363 return 1;
1874 spec->autocfg.hp_pins[0] = nid; 1364 spec->autocfg.hp_pins[0] = nid;
1875 } 1365 }
1876 return 1; 1366 return 1;
1877} 1367}
1878 1368
1879static void alc_ssid_check(struct hda_codec *codec, 1369/* Check the validity of ALC subsystem-id
1880 hda_nid_t porta, hda_nid_t porte, 1370 * ports contains an array of 4 pin NIDs for port-A, E, D and I */
1881 hda_nid_t portd, hda_nid_t porti) 1371static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports)
1882{ 1372{
1883 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) { 1373 if (!alc_subsystem_id(codec, ports[0], ports[1], ports[2], ports[3])) {
1884 struct alc_spec *spec = codec->spec; 1374 struct alc_spec *spec = codec->spec;
1885 snd_printd("realtek: " 1375 snd_printd("realtek: "
1886 "Enable default setup for auto mode as fallback\n"); 1376 "Enable default setup for auto mode as fallback\n");
1887 spec->init_amp = ALC_INIT_DEFAULT; 1377 spec->init_amp = ALC_INIT_DEFAULT;
1888 } 1378 }
1889
1890 alc_init_auto_hp(codec);
1891 alc_init_auto_mic(codec);
1892} 1379}
1893 1380
1894/* 1381/*
@@ -1935,6 +1422,7 @@ enum {
1935 1422
1936static void alc_apply_fixup(struct hda_codec *codec, int action) 1423static void alc_apply_fixup(struct hda_codec *codec, int action)
1937{ 1424{
1425#if !defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA)
1938 struct alc_spec *spec = codec->spec; 1426 struct alc_spec *spec = codec->spec;
1939 int id = spec->fixup_id; 1427 int id = spec->fixup_id;
1940#ifdef CONFIG_SND_DEBUG_VERBOSE 1428#ifdef CONFIG_SND_DEBUG_VERBOSE
@@ -1998,6 +1486,7 @@ static void alc_apply_fixup(struct hda_codec *codec, int action)
1998 break; 1486 break;
1999 id = fix->chain_id; 1487 id = fix->chain_id;
2000 } 1488 }
1489#endif
2001} 1490}
2002 1491
2003static void alc_pick_fixup(struct hda_codec *codec, 1492static void alc_pick_fixup(struct hda_codec *codec,
@@ -2005,6 +1494,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
2005 const struct snd_pci_quirk *quirk, 1494 const struct snd_pci_quirk *quirk,
2006 const struct alc_fixup *fixlist) 1495 const struct alc_fixup *fixlist)
2007{ 1496{
1497#if !defined(CONFIG_SND_HDA_PLATFORM_NVIDIA_TEGRA)
2008 struct alc_spec *spec = codec->spec; 1498 struct alc_spec *spec = codec->spec;
2009 int id = -1; 1499 int id = -1;
2010 const char *name = NULL; 1500 const char *name = NULL;
@@ -2034,8 +1524,12 @@ static void alc_pick_fixup(struct hda_codec *codec,
2034 spec->fixup_list = fixlist; 1524 spec->fixup_list = fixlist;
2035 spec->fixup_name = name; 1525 spec->fixup_name = name;
2036 } 1526 }
1527#endif
2037} 1528}
2038 1529
1530/*
1531 * COEF access helper functions
1532 */
2039static int alc_read_coef_idx(struct hda_codec *codec, 1533static int alc_read_coef_idx(struct hda_codec *codec,
2040 unsigned int coef_idx) 1534 unsigned int coef_idx)
2041{ 1535{
@@ -2056,20 +1550,32 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2056 coef_val); 1550 coef_val);
2057} 1551}
2058 1552
1553/*
1554 * Digital I/O handling
1555 */
1556
2059/* set right pin controls for digital I/O */ 1557/* set right pin controls for digital I/O */
2060static void alc_auto_init_digital(struct hda_codec *codec) 1558static void alc_auto_init_digital(struct hda_codec *codec)
2061{ 1559{
2062 struct alc_spec *spec = codec->spec; 1560 struct alc_spec *spec = codec->spec;
2063 int i; 1561 int i;
2064 hda_nid_t pin; 1562 hda_nid_t pin, dac;
2065 1563
2066 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1564 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2067 pin = spec->autocfg.dig_out_pins[i]; 1565 pin = spec->autocfg.dig_out_pins[i];
2068 if (pin) { 1566 if (!pin)
2069 snd_hda_codec_write(codec, pin, 0, 1567 continue;
2070 AC_VERB_SET_PIN_WIDGET_CONTROL, 1568 snd_hda_codec_write(codec, pin, 0,
2071 PIN_OUT); 1569 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2072 } 1570 if (!i)
1571 dac = spec->multiout.dig_out_nid;
1572 else
1573 dac = spec->slave_dig_outs[i - 1];
1574 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
1575 continue;
1576 snd_hda_codec_write(codec, dac, 0,
1577 AC_VERB_SET_AMP_GAIN_MUTE,
1578 AMP_OUT_UNMUTE);
2073 } 1579 }
2074 pin = spec->autocfg.dig_in_pin; 1580 pin = spec->autocfg.dig_in_pin;
2075 if (pin) 1581 if (pin)
@@ -2082,25 +1588,29 @@ static void alc_auto_init_digital(struct hda_codec *codec)
2082static void alc_auto_parse_digital(struct hda_codec *codec) 1588static void alc_auto_parse_digital(struct hda_codec *codec)
2083{ 1589{
2084 struct alc_spec *spec = codec->spec; 1590 struct alc_spec *spec = codec->spec;
2085 int i, err; 1591 int i, err, nums;
2086 hda_nid_t dig_nid; 1592 hda_nid_t dig_nid;
2087 1593
2088 /* support multiple SPDIFs; the secondary is set up as a slave */ 1594 /* support multiple SPDIFs; the secondary is set up as a slave */
1595 nums = 0;
2089 for (i = 0; i < spec->autocfg.dig_outs; i++) { 1596 for (i = 0; i < spec->autocfg.dig_outs; i++) {
1597 hda_nid_t conn[4];
2090 err = snd_hda_get_connections(codec, 1598 err = snd_hda_get_connections(codec,
2091 spec->autocfg.dig_out_pins[i], 1599 spec->autocfg.dig_out_pins[i],
2092 &dig_nid, 1); 1600 conn, ARRAY_SIZE(conn));
2093 if (err < 0) 1601 if (err <= 0)
2094 continue; 1602 continue;
2095 if (!i) { 1603 dig_nid = conn[0]; /* assume the first element is audio-out */
1604 if (!nums) {
2096 spec->multiout.dig_out_nid = dig_nid; 1605 spec->multiout.dig_out_nid = dig_nid;
2097 spec->dig_out_type = spec->autocfg.dig_out_type[0]; 1606 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2098 } else { 1607 } else {
2099 spec->multiout.slave_dig_outs = spec->slave_dig_outs; 1608 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2100 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) 1609 if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2101 break; 1610 break;
2102 spec->slave_dig_outs[i - 1] = dig_nid; 1611 spec->slave_dig_outs[nums - 1] = dig_nid;
2103 } 1612 }
1613 nums++;
2104 } 1614 }
2105 1615
2106 if (spec->autocfg.dig_in_pin) { 1616 if (spec->autocfg.dig_in_pin) {
@@ -2124,572 +1634,22 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2124} 1634}
2125 1635
2126/* 1636/*
2127 * ALC888 1637 * capture mixer elements
2128 */
2129
2130/*
2131 * 2ch mode
2132 */
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 */ 1638 */
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, 1639static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_info *uinfo) 1640 struct snd_ctl_elem_info *uinfo)
2685{ 1641{
2686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2687 struct alc_spec *spec = codec->spec; 1643 struct alc_spec *spec = codec->spec;
1644 unsigned long val;
2688 int err; 1645 int err;
2689 1646
2690 mutex_lock(&codec->control_mutex); 1647 mutex_lock(&codec->control_mutex);
2691 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1648 if (spec->vol_in_capsrc)
2692 HDA_INPUT); 1649 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1650 else
1651 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1652 kcontrol->private_value = val;
2693 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1653 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2694 mutex_unlock(&codec->control_mutex); 1654 mutex_unlock(&codec->control_mutex);
2695 return err; 1655 return err;
@@ -2700,11 +1660,15 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2700{ 1660{
2701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1661 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2702 struct alc_spec *spec = codec->spec; 1662 struct alc_spec *spec = codec->spec;
1663 unsigned long val;
2703 int err; 1664 int err;
2704 1665
2705 mutex_lock(&codec->control_mutex); 1666 mutex_lock(&codec->control_mutex);
2706 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1667 if (spec->vol_in_capsrc)
2707 HDA_INPUT); 1668 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
1669 else
1670 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
1671 kcontrol->private_value = val;
2708 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1672 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2709 mutex_unlock(&codec->control_mutex); 1673 mutex_unlock(&codec->control_mutex);
2710 return err; 1674 return err;
@@ -2722,7 +1686,7 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2722 int i, err = 0; 1686 int i, err = 0;
2723 1687
2724 mutex_lock(&codec->control_mutex); 1688 mutex_lock(&codec->control_mutex);
2725 if (check_adc_switch && spec->dual_adc_switch) { 1689 if (check_adc_switch && spec->dyn_adc_switch) {
2726 for (i = 0; i < spec->num_adc_nids; i++) { 1690 for (i = 0; i < spec->num_adc_nids; i++) {
2727 kcontrol->private_value = 1691 kcontrol->private_value =
2728 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1692 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
@@ -2733,9 +1697,14 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2733 } 1697 }
2734 } else { 1698 } else {
2735 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1699 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2736 kcontrol->private_value = 1700 if (spec->vol_in_capsrc)
2737 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1701 kcontrol->private_value =
2738 3, 0, HDA_INPUT); 1702 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
1703 3, 0, HDA_OUTPUT);
1704 else
1705 kcontrol->private_value =
1706 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
1707 3, 0, HDA_INPUT);
2739 err = func(kcontrol, ucontrol); 1708 err = func(kcontrol, ucontrol);
2740 } 1709 }
2741 error: 1710 error:
@@ -2830,335 +1799,6 @@ DEFINE_CAPMIX_NOSRC(2);
2830DEFINE_CAPMIX_NOSRC(3); 1799DEFINE_CAPMIX_NOSRC(3);
2831 1800
2832/* 1801/*
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 1802 * virtual master controls
3163 */ 1803 */
3164 1804
@@ -3175,6 +1815,7 @@ static const char * const alc_slave_vols[] = {
3175 "Speaker Playback Volume", 1815 "Speaker Playback Volume",
3176 "Mono Playback Volume", 1816 "Mono Playback Volume",
3177 "Line-Out Playback Volume", 1817 "Line-Out Playback Volume",
1818 "PCM Playback Volume",
3178 NULL, 1819 NULL,
3179}; 1820};
3180 1821
@@ -3189,6 +1830,7 @@ static const char * const alc_slave_sws[] = {
3189 "Mono Playback Switch", 1830 "Mono Playback Switch",
3190 "IEC958 Playback Switch", 1831 "IEC958 Playback Switch",
3191 "Line-Out Playback Switch", 1832 "Line-Out Playback Switch",
1833 "PCM Playback Switch",
3192 NULL, 1834 NULL,
3193}; 1835};
3194 1836
@@ -3237,6 +1879,7 @@ static int alc_build_controls(struct hda_codec *codec)
3237 } 1879 }
3238 if (spec->multiout.dig_out_nid) { 1880 if (spec->multiout.dig_out_nid) {
3239 err = snd_hda_create_spdif_out_ctls(codec, 1881 err = snd_hda_create_spdif_out_ctls(codec,
1882 spec->multiout.dig_out_nid,
3240 spec->multiout.dig_out_nid); 1883 spec->multiout.dig_out_nid);
3241 if (err < 0) 1884 if (err < 0)
3242 return err; 1885 return err;
@@ -3304,7 +1947,7 @@ static int alc_build_controls(struct hda_codec *codec)
3304 return err; 1947 return err;
3305 } 1948 }
3306 } 1949 }
3307 if (spec->cap_mixer) { 1950 if (spec->cap_mixer && spec->adc_nids) {
3308 const char *kname = kctl ? kctl->id.name : NULL; 1951 const char *kname = kctl ? kctl->id.name : NULL;
3309 for (knew = spec->cap_mixer; knew->name; knew++) { 1952 for (knew = spec->cap_mixer; knew->name; knew++) {
3310 if (kname && strcmp(knew->name, kname) == 0) 1953 if (kname && strcmp(knew->name, kname) == 0)
@@ -3368,789 +2011,6 @@ static int alc_build_controls(struct hda_codec *codec)
3368 2011
3369 2012
3370/* 2013/*
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 2014 * Common callbacks
4155 */ 2015 */
4156 2016
@@ -4196,7 +2056,7 @@ static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4196/* 2056/*
4197 * Analog playback callbacks 2057 * Analog playback callbacks
4198 */ 2058 */
4199static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo, 2059static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
4200 struct hda_codec *codec, 2060 struct hda_codec *codec,
4201 struct snd_pcm_substream *substream) 2061 struct snd_pcm_substream *substream)
4202{ 2062{
@@ -4205,7 +2065,7 @@ static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4205 hinfo); 2065 hinfo);
4206} 2066}
4207 2067
4208static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2068static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4209 struct hda_codec *codec, 2069 struct hda_codec *codec,
4210 unsigned int stream_tag, 2070 unsigned int stream_tag,
4211 unsigned int format, 2071 unsigned int format,
@@ -4216,7 +2076,7 @@ static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4216 stream_tag, format, substream); 2076 stream_tag, format, substream);
4217} 2077}
4218 2078
4219static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2079static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4220 struct hda_codec *codec, 2080 struct hda_codec *codec,
4221 struct snd_pcm_substream *substream) 2081 struct snd_pcm_substream *substream)
4222{ 2082{
@@ -4227,7 +2087,7 @@ static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4227/* 2087/*
4228 * Digital out 2088 * Digital out
4229 */ 2089 */
4230static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 2090static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4231 struct hda_codec *codec, 2091 struct hda_codec *codec,
4232 struct snd_pcm_substream *substream) 2092 struct snd_pcm_substream *substream)
4233{ 2093{
@@ -4235,7 +2095,7 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4235 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 2095 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4236} 2096}
4237 2097
4238static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 2098static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4239 struct hda_codec *codec, 2099 struct hda_codec *codec,
4240 unsigned int stream_tag, 2100 unsigned int stream_tag,
4241 unsigned int format, 2101 unsigned int format,
@@ -4246,7 +2106,7 @@ static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4246 stream_tag, format, substream); 2106 stream_tag, format, substream);
4247} 2107}
4248 2108
4249static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 2109static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4250 struct hda_codec *codec, 2110 struct hda_codec *codec,
4251 struct snd_pcm_substream *substream) 2111 struct snd_pcm_substream *substream)
4252{ 2112{
@@ -4254,7 +2114,7 @@ static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4254 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 2114 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4255} 2115}
4256 2116
4257static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 2117static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4258 struct hda_codec *codec, 2118 struct hda_codec *codec,
4259 struct snd_pcm_substream *substream) 2119 struct snd_pcm_substream *substream)
4260{ 2120{
@@ -4265,7 +2125,7 @@ static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4265/* 2125/*
4266 * Analog capture 2126 * Analog capture
4267 */ 2127 */
4268static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2128static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4269 struct hda_codec *codec, 2129 struct hda_codec *codec,
4270 unsigned int stream_tag, 2130 unsigned int stream_tag,
4271 unsigned int format, 2131 unsigned int format,
@@ -4278,7 +2138,7 @@ static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4278 return 0; 2138 return 0;
4279} 2139}
4280 2140
4281static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2141static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4282 struct hda_codec *codec, 2142 struct hda_codec *codec,
4283 struct snd_pcm_substream *substream) 2143 struct snd_pcm_substream *substream)
4284{ 2144{
@@ -4290,21 +2150,21 @@ static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4290} 2150}
4291 2151
4292/* analog capture with dynamic dual-adc changes */ 2152/* analog capture with dynamic dual-adc changes */
4293static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 2153static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4294 struct hda_codec *codec, 2154 struct hda_codec *codec,
4295 unsigned int stream_tag, 2155 unsigned int stream_tag,
4296 unsigned int format, 2156 unsigned int format,
4297 struct snd_pcm_substream *substream) 2157 struct snd_pcm_substream *substream)
4298{ 2158{
4299 struct alc_spec *spec = codec->spec; 2159 struct alc_spec *spec = codec->spec;
4300 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx]; 2160 spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
4301 spec->cur_adc_stream_tag = stream_tag; 2161 spec->cur_adc_stream_tag = stream_tag;
4302 spec->cur_adc_format = format; 2162 spec->cur_adc_format = format;
4303 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); 2163 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4304 return 0; 2164 return 0;
4305} 2165}
4306 2166
4307static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 2167static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4308 struct hda_codec *codec, 2168 struct hda_codec *codec,
4309 struct snd_pcm_substream *substream) 2169 struct snd_pcm_substream *substream)
4310{ 2170{
@@ -4314,70 +2174,70 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4314 return 0; 2174 return 0;
4315} 2175}
4316 2176
4317static const struct hda_pcm_stream dualmic_pcm_analog_capture = { 2177static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
4318 .substreams = 1, 2178 .substreams = 1,
4319 .channels_min = 2, 2179 .channels_min = 2,
4320 .channels_max = 2, 2180 .channels_max = 2,
4321 .nid = 0, /* fill later */ 2181 .nid = 0, /* fill later */
4322 .ops = { 2182 .ops = {
4323 .prepare = dualmic_capture_pcm_prepare, 2183 .prepare = dyn_adc_capture_pcm_prepare,
4324 .cleanup = dualmic_capture_pcm_cleanup 2184 .cleanup = dyn_adc_capture_pcm_cleanup
4325 }, 2185 },
4326}; 2186};
4327 2187
4328/* 2188/*
4329 */ 2189 */
4330static const struct hda_pcm_stream alc880_pcm_analog_playback = { 2190static const struct hda_pcm_stream alc_pcm_analog_playback = {
4331 .substreams = 1, 2191 .substreams = 1,
4332 .channels_min = 2, 2192 .channels_min = 2,
4333 .channels_max = 8, 2193 .channels_max = 8,
4334 /* NID is set in alc_build_pcms */ 2194 /* NID is set in alc_build_pcms */
4335 .ops = { 2195 .ops = {
4336 .open = alc880_playback_pcm_open, 2196 .open = alc_playback_pcm_open,
4337 .prepare = alc880_playback_pcm_prepare, 2197 .prepare = alc_playback_pcm_prepare,
4338 .cleanup = alc880_playback_pcm_cleanup 2198 .cleanup = alc_playback_pcm_cleanup
4339 }, 2199 },
4340}; 2200};
4341 2201
4342static const struct hda_pcm_stream alc880_pcm_analog_capture = { 2202static const struct hda_pcm_stream alc_pcm_analog_capture = {
4343 .substreams = 1, 2203 .substreams = 1,
4344 .channels_min = 2, 2204 .channels_min = 2,
4345 .channels_max = 2, 2205 .channels_max = 2,
4346 /* NID is set in alc_build_pcms */ 2206 /* NID is set in alc_build_pcms */
4347}; 2207};
4348 2208
4349static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { 2209static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
4350 .substreams = 1, 2210 .substreams = 1,
4351 .channels_min = 2, 2211 .channels_min = 2,
4352 .channels_max = 2, 2212 .channels_max = 2,
4353 /* NID is set in alc_build_pcms */ 2213 /* NID is set in alc_build_pcms */
4354}; 2214};
4355 2215
4356static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { 2216static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
4357 .substreams = 2, /* can be overridden */ 2217 .substreams = 2, /* can be overridden */
4358 .channels_min = 2, 2218 .channels_min = 2,
4359 .channels_max = 2, 2219 .channels_max = 2,
4360 /* NID is set in alc_build_pcms */ 2220 /* NID is set in alc_build_pcms */
4361 .ops = { 2221 .ops = {
4362 .prepare = alc880_alt_capture_pcm_prepare, 2222 .prepare = alc_alt_capture_pcm_prepare,
4363 .cleanup = alc880_alt_capture_pcm_cleanup 2223 .cleanup = alc_alt_capture_pcm_cleanup
4364 }, 2224 },
4365}; 2225};
4366 2226
4367static const struct hda_pcm_stream alc880_pcm_digital_playback = { 2227static const struct hda_pcm_stream alc_pcm_digital_playback = {
4368 .substreams = 1, 2228 .substreams = 1,
4369 .channels_min = 2, 2229 .channels_min = 2,
4370 .channels_max = 2, 2230 .channels_max = 2,
4371 /* NID is set in alc_build_pcms */ 2231 /* NID is set in alc_build_pcms */
4372 .ops = { 2232 .ops = {
4373 .open = alc880_dig_playback_pcm_open, 2233 .open = alc_dig_playback_pcm_open,
4374 .close = alc880_dig_playback_pcm_close, 2234 .close = alc_dig_playback_pcm_close,
4375 .prepare = alc880_dig_playback_pcm_prepare, 2235 .prepare = alc_dig_playback_pcm_prepare,
4376 .cleanup = alc880_dig_playback_pcm_cleanup 2236 .cleanup = alc_dig_playback_pcm_cleanup
4377 }, 2237 },
4378}; 2238};
4379 2239
4380static const struct hda_pcm_stream alc880_pcm_digital_capture = { 2240static const struct hda_pcm_stream alc_pcm_digital_capture = {
4381 .substreams = 1, 2241 .substreams = 1,
4382 .channels_min = 2, 2242 .channels_min = 2,
4383 .channels_max = 2, 2243 .channels_max = 2,
@@ -4395,6 +2255,8 @@ static int alc_build_pcms(struct hda_codec *codec)
4395{ 2255{
4396 struct alc_spec *spec = codec->spec; 2256 struct alc_spec *spec = codec->spec;
4397 struct hda_pcm *info = spec->pcm_rec; 2257 struct hda_pcm *info = spec->pcm_rec;
2258 const struct hda_pcm_stream *p;
2259 bool have_multi_adcs;
4398 int i; 2260 int i;
4399 2261
4400 codec->num_pcms = 1; 2262 codec->num_pcms = 1;
@@ -4407,16 +2269,22 @@ static int alc_build_pcms(struct hda_codec *codec)
4407 "%s Analog", codec->chip_name); 2269 "%s Analog", codec->chip_name);
4408 info->name = spec->stream_name_analog; 2270 info->name = spec->stream_name_analog;
4409 2271
4410 if (spec->stream_analog_playback) { 2272 if (spec->multiout.dac_nids > 0) {
4411 if (snd_BUG_ON(!spec->multiout.dac_nids)) 2273 p = spec->stream_analog_playback;
4412 return -EINVAL; 2274 if (!p)
4413 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); 2275 p = &alc_pcm_analog_playback;
2276 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 2277 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4415 } 2278 }
4416 if (spec->stream_analog_capture) { 2279 if (spec->adc_nids) {
4417 if (snd_BUG_ON(!spec->adc_nids)) 2280 p = spec->stream_analog_capture;
4418 return -EINVAL; 2281 if (!p) {
4419 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); 2282 if (spec->dyn_adc_switch)
2283 p = &dyn_adc_pcm_analog_capture;
2284 else
2285 p = &alc_pcm_analog_capture;
2286 }
2287 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4420 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 2288 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4421 } 2289 }
4422 2290
@@ -4443,14 +2311,18 @@ static int alc_build_pcms(struct hda_codec *codec)
4443 info->pcm_type = spec->dig_out_type; 2311 info->pcm_type = spec->dig_out_type;
4444 else 2312 else
4445 info->pcm_type = HDA_PCM_TYPE_SPDIF; 2313 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4446 if (spec->multiout.dig_out_nid && 2314 if (spec->multiout.dig_out_nid) {
4447 spec->stream_digital_playback) { 2315 p = spec->stream_digital_playback;
4448 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback); 2316 if (!p)
2317 p = &alc_pcm_digital_playback;
2318 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4449 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 2319 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4450 } 2320 }
4451 if (spec->dig_in_nid && 2321 if (spec->dig_in_nid) {
4452 spec->stream_digital_capture) { 2322 p = spec->stream_digital_capture;
4453 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); 2323 if (!p)
2324 p = &alc_pcm_digital_capture;
2325 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4454 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 2326 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4455 } 2327 }
4456 /* FIXME: do we need this for all Realtek codec models? */ 2328 /* FIXME: do we need this for all Realtek codec models? */
@@ -4463,15 +2335,19 @@ static int alc_build_pcms(struct hda_codec *codec)
4463 /* If the use of more than one ADC is requested for the current 2335 /* If the use of more than one ADC is requested for the current
4464 * model, configure a second analog capture-only PCM. 2336 * model, configure a second analog capture-only PCM.
4465 */ 2337 */
2338 have_multi_adcs = (spec->num_adc_nids > 1) &&
2339 !spec->dyn_adc_switch && !spec->auto_mic &&
2340 (!spec->input_mux || spec->input_mux->num_items > 1);
4466 /* Additional Analaog capture for index #2 */ 2341 /* Additional Analaog capture for index #2 */
4467 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) || 2342 if (spec->alt_dac_nid || have_multi_adcs) {
4468 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4469 codec->num_pcms = 3; 2343 codec->num_pcms = 3;
4470 info = spec->pcm_rec + 2; 2344 info = spec->pcm_rec + 2;
4471 info->name = spec->stream_name_analog; 2345 info->name = spec->stream_name_analog;
4472 if (spec->alt_dac_nid) { 2346 if (spec->alt_dac_nid) {
4473 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 2347 p = spec->stream_analog_alt_playback;
4474 *spec->stream_analog_alt_playback; 2348 if (!p)
2349 p = &alc_pcm_analog_alt_playback;
2350 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4475 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 2351 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4476 spec->alt_dac_nid; 2352 spec->alt_dac_nid;
4477 } else { 2353 } else {
@@ -4479,9 +2355,11 @@ static int alc_build_pcms(struct hda_codec *codec)
4479 alc_pcm_null_stream; 2355 alc_pcm_null_stream;
4480 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; 2356 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4481 } 2357 }
4482 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { 2358 if (have_multi_adcs) {
4483 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 2359 p = spec->stream_analog_alt_capture;
4484 *spec->stream_analog_alt_capture; 2360 if (!p)
2361 p = &alc_pcm_analog_alt_capture;
2362 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 2363 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4486 spec->adc_nids[1]; 2364 spec->adc_nids[1];
4487 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 2365 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
@@ -4548,7 +2426,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4548} 2426}
4549#endif 2427#endif
4550 2428
4551#ifdef SND_HDA_NEEDS_RESUME 2429#ifdef CONFIG_PM
4552static int alc_resume(struct hda_codec *codec) 2430static int alc_resume(struct hda_codec *codec)
4553{ 2431{
4554 msleep(150); /* to avoid pop noise */ 2432 msleep(150); /* to avoid pop noise */
@@ -4568,7 +2446,7 @@ static const struct hda_codec_ops alc_patch_ops = {
4568 .init = alc_init, 2446 .init = alc_init,
4569 .free = alc_free, 2447 .free = alc_free,
4570 .unsol_event = alc_unsol_event, 2448 .unsol_event = alc_unsol_event,
4571#ifdef SND_HDA_NEEDS_RESUME 2449#ifdef CONFIG_PM
4572 .resume = alc_resume, 2450 .resume = alc_resume,
4573#endif 2451#endif
4574#ifdef CONFIG_SND_HDA_POWER_SAVE 2452#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -4591,679 +2469,6 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4591} 2469}
4592 2470
4593/* 2471/*
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 2472 * Automatic parse of I/O pins from the BIOS configuration
5268 */ 2473 */
5269 2474
@@ -5272,18 +2477,12 @@ enum {
5272 ALC_CTL_WIDGET_MUTE, 2477 ALC_CTL_WIDGET_MUTE,
5273 ALC_CTL_BIND_MUTE, 2478 ALC_CTL_BIND_MUTE,
5274}; 2479};
5275static const struct snd_kcontrol_new alc880_control_templates[] = { 2480static const struct snd_kcontrol_new alc_control_templates[] = {
5276 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2481 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5277 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2482 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5278 HDA_BIND_MUTE(NULL, 0, 0, 0), 2483 HDA_BIND_MUTE(NULL, 0, 0, 0),
5279}; 2484};
5280 2485
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 */ 2486/* add dynamic controls */
5288static int add_control(struct alc_spec *spec, int type, const char *name, 2487static int add_control(struct alc_spec *spec, int type, const char *name,
5289 int cidx, unsigned long val) 2488 int cidx, unsigned long val)
@@ -5293,7 +2492,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
5293 knew = alc_kcontrol_new(spec); 2492 knew = alc_kcontrol_new(spec);
5294 if (!knew) 2493 if (!knew)
5295 return -ENOMEM; 2494 return -ENOMEM;
5296 *knew = alc880_control_templates[type]; 2495 *knew = alc_control_templates[type];
5297 knew->name = kstrdup(name, GFP_KERNEL); 2496 knew->name = kstrdup(name, GFP_KERNEL);
5298 if (!knew->name) 2497 if (!knew->name)
5299 return -ENOMEM; 2498 return -ENOMEM;
@@ -5322,60 +2521,15 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
5322#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2521#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5323 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2522 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5324 2523
5325#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17) 2524static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5326#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 2525 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{ 2526{
5377 struct auto_pin_cfg *cfg = &spec->autocfg; 2527 struct auto_pin_cfg *cfg = &spec->autocfg;
2528 static const char * const chname[4] = {
2529 "Front", "Surround", NULL /*CLFE*/, "Side"
2530 };
5378 2531
2532 *index = 0;
5379 if (cfg->line_outs == 1 && !spec->multi_ios && 2533 if (cfg->line_outs == 1 && !spec->multi_ios &&
5380 !cfg->hp_outs && !cfg->speaker_outs && can_be_master) 2534 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5381 return "Master"; 2535 return "Master";
@@ -5386,120 +2540,17 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5386 return "Speaker"; 2540 return "Speaker";
5387 break; 2541 break;
5388 case AUTO_PIN_HP_OUT: 2542 case AUTO_PIN_HP_OUT:
2543 /* for multi-io case, only the primary out */
2544 if (ch && spec->multi_ios)
2545 break;
2546 *index = ch;
5389 return "Headphone"; 2547 return "Headphone";
5390 default: 2548 default:
5391 if (cfg->line_outs == 1 && !spec->multi_ios) 2549 if (cfg->line_outs == 1 && !spec->multi_ios)
5392 return "PCM"; 2550 return "PCM";
5393 break; 2551 break;
5394 } 2552 }
5395 return NULL; 2553 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} 2554}
5504 2555
5505/* create input playback/capture controls for the given pin */ 2556/* create input playback/capture controls for the given pin */
@@ -5526,17 +2577,72 @@ static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5526 return (pincap & AC_PINCAP_IN) != 0; 2577 return (pincap & AC_PINCAP_IN) != 0;
5527} 2578}
5528 2579
2580/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
2581static int alc_auto_fill_adc_caps(struct hda_codec *codec)
2582{
2583 struct alc_spec *spec = codec->spec;
2584 hda_nid_t nid;
2585 hda_nid_t *adc_nids = spec->private_adc_nids;
2586 hda_nid_t *cap_nids = spec->private_capsrc_nids;
2587 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
2588 bool indep_capsrc = false;
2589 int i, nums = 0;
2590
2591 nid = codec->start_nid;
2592 for (i = 0; i < codec->num_nodes; i++, nid++) {
2593 hda_nid_t src;
2594 const hda_nid_t *list;
2595 unsigned int caps = get_wcaps(codec, nid);
2596 int type = get_wcaps_type(caps);
2597
2598 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
2599 continue;
2600 adc_nids[nums] = nid;
2601 cap_nids[nums] = nid;
2602 src = nid;
2603 for (;;) {
2604 int n;
2605 type = get_wcaps_type(get_wcaps(codec, src));
2606 if (type == AC_WID_PIN)
2607 break;
2608 if (type == AC_WID_AUD_SEL) {
2609 cap_nids[nums] = src;
2610 indep_capsrc = true;
2611 break;
2612 }
2613 n = snd_hda_get_conn_list(codec, src, &list);
2614 if (n > 1) {
2615 cap_nids[nums] = src;
2616 indep_capsrc = true;
2617 break;
2618 } else if (n != 1)
2619 break;
2620 src = *list;
2621 }
2622 if (++nums >= max_nums)
2623 break;
2624 }
2625 spec->adc_nids = spec->private_adc_nids;
2626 spec->capsrc_nids = spec->private_capsrc_nids;
2627 spec->num_adc_nids = nums;
2628 return nums;
2629}
2630
5529/* create playback/capture controls for input pins */ 2631/* create playback/capture controls for input pins */
5530static int alc_auto_create_input_ctls(struct hda_codec *codec, 2632static 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{ 2633{
5535 struct alc_spec *spec = codec->spec; 2634 struct alc_spec *spec = codec->spec;
2635 const struct auto_pin_cfg *cfg = &spec->autocfg;
2636 hda_nid_t mixer = spec->mixer_nid;
5536 struct hda_input_mux *imux = &spec->private_imux[0]; 2637 struct hda_input_mux *imux = &spec->private_imux[0];
5537 int i, err, idx, type_idx = 0; 2638 int num_adcs;
2639 int i, c, err, idx, type_idx = 0;
5538 const char *prev_label = NULL; 2640 const char *prev_label = NULL;
5539 2641
2642 num_adcs = alc_auto_fill_adc_caps(codec);
2643 if (num_adcs < 0)
2644 return 0;
2645
5540 for (i = 0; i < cfg->num_inputs; i++) { 2646 for (i = 0; i < cfg->num_inputs; i++) {
5541 hda_nid_t pin; 2647 hda_nid_t pin;
5542 const char *label; 2648 const char *label;
@@ -5563,21 +2669,22 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5563 } 2669 }
5564 } 2670 }
5565 2671
5566 if (!cap1) 2672 for (c = 0; c < num_adcs; c++) {
5567 continue; 2673 hda_nid_t cap = spec->capsrc_nids ?
5568 idx = get_connection_index(codec, cap1, pin); 2674 spec->capsrc_nids[c] : spec->adc_nids[c];
5569 if (idx < 0 && cap2) 2675 idx = get_connection_index(codec, cap, pin);
5570 idx = get_connection_index(codec, cap2, pin); 2676 if (idx >= 0) {
5571 if (idx >= 0) 2677 spec->imux_pins[imux->num_items] = pin;
5572 snd_hda_add_imux_item(imux, label, idx, NULL); 2678 snd_hda_add_imux_item(imux, label, idx, NULL);
2679 break;
2680 }
2681 }
5573 } 2682 }
5574 return 0;
5575}
5576 2683
5577static int alc880_auto_create_input_ctls(struct hda_codec *codec, 2684 spec->num_mux_defs = 1;
5578 const struct auto_pin_cfg *cfg) 2685 spec->input_mux = imux;
5579{ 2686
5580 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09); 2687 return 0;
5581} 2688}
5582 2689
5583static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2690static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
@@ -5586,25 +2693,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, 2693 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5587 pin_type); 2694 pin_type);
5588 /* unmute pin */ 2695 /* unmute pin */
5589 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 2696 if (nid_has_mute(codec, nid, HDA_OUTPUT))
2697 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5590 AMP_OUT_UNMUTE); 2698 AMP_OUT_UNMUTE);
5591} 2699}
5592 2700
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) 2701static int get_pin_type(int line_out_type)
5609{ 2702{
5610 if (line_out_type == AUTO_PIN_HP_OUT) 2703 if (line_out_type == AUTO_PIN_HP_OUT)
@@ -5613,177 +2706,744 @@ static int get_pin_type(int line_out_type)
5613 return PIN_OUT; 2706 return PIN_OUT;
5614} 2707}
5615 2708
5616static void alc880_auto_init_multi_out(struct hda_codec *codec) 2709static void alc_auto_init_analog_input(struct hda_codec *codec)
5617{ 2710{
5618 struct alc_spec *spec = codec->spec; 2711 struct alc_spec *spec = codec->spec;
2712 struct auto_pin_cfg *cfg = &spec->autocfg;
5619 int i; 2713 int i;
5620 2714
5621 for (i = 0; i < spec->autocfg.line_outs; i++) { 2715 for (i = 0; i < cfg->num_inputs; i++) {
5622 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 2716 hda_nid_t nid = cfg->inputs[i].pin;
5623 int pin_type = get_pin_type(spec->autocfg.line_out_type); 2717 if (alc_is_input_pin(codec, nid)) {
5624 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); 2718 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
2719 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
2720 snd_hda_codec_write(codec, nid, 0,
2721 AC_VERB_SET_AMP_GAIN_MUTE,
2722 AMP_OUT_MUTE);
2723 }
2724 }
2725
2726 /* mute all loopback inputs */
2727 if (spec->mixer_nid) {
2728 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
2729 for (i = 0; i < nums; i++)
2730 snd_hda_codec_write(codec, spec->mixer_nid, 0,
2731 AC_VERB_SET_AMP_GAIN_MUTE,
2732 AMP_IN_MUTE(i));
2733 }
2734}
2735
2736/* convert from MIX nid to DAC */
2737static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
2738{
2739 hda_nid_t list[5];
2740 int i, num;
2741
2742 if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_AUD_OUT)
2743 return nid;
2744 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
2745 for (i = 0; i < num; i++) {
2746 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2747 return list[i];
2748 }
2749 return 0;
2750}
2751
2752/* go down to the selector widget before the mixer */
2753static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2754{
2755 hda_nid_t srcs[5];
2756 int num = snd_hda_get_connections(codec, pin, srcs,
2757 ARRAY_SIZE(srcs));
2758 if (num != 1 ||
2759 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2760 return pin;
2761 return srcs[0];
2762}
2763
2764/* get MIX nid connected to the given pin targeted to DAC */
2765static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2766 hda_nid_t dac)
2767{
2768 hda_nid_t mix[5];
2769 int i, num;
2770
2771 pin = alc_go_down_to_selector(codec, pin);
2772 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2773 for (i = 0; i < num; i++) {
2774 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2775 return mix[i];
5625 } 2776 }
2777 return 0;
5626} 2778}
5627 2779
5628static void alc880_auto_init_extra_out(struct hda_codec *codec) 2780/* select the connection from pin to DAC if needed */
2781static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2782 hda_nid_t dac)
2783{
2784 hda_nid_t mix[5];
2785 int i, num;
2786
2787 pin = alc_go_down_to_selector(codec, pin);
2788 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2789 if (num < 2)
2790 return 0;
2791 for (i = 0; i < num; i++) {
2792 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2793 snd_hda_codec_update_cache(codec, pin, 0,
2794 AC_VERB_SET_CONNECT_SEL, i);
2795 return 0;
2796 }
2797 }
2798 return 0;
2799}
2800
2801/* look for an empty DAC slot */
2802static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
5629{ 2803{
5630 struct alc_spec *spec = codec->spec; 2804 struct alc_spec *spec = codec->spec;
5631 hda_nid_t pin; 2805 hda_nid_t srcs[5];
2806 int i, num;
5632 2807
5633 pin = spec->autocfg.speaker_pins[0]; 2808 pin = alc_go_down_to_selector(codec, pin);
5634 if (pin) /* connect to front */ 2809 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
5635 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 2810 for (i = 0; i < num; i++) {
5636 pin = spec->autocfg.hp_pins[0]; 2811 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
5637 if (pin) /* connect to front */ 2812 if (!nid)
5638 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 2813 continue;
2814 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2815 spec->multiout.num_dacs))
2816 continue;
2817 if (spec->multiout.hp_nid == nid)
2818 continue;
2819 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2820 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2821 continue;
2822 return nid;
2823 }
2824 return 0;
2825}
2826
2827static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2828{
2829 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2830 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
2831 return alc_auto_look_for_dac(codec, pin);
2832 return 0;
5639} 2833}
5640 2834
5641static void alc880_auto_init_analog_input(struct hda_codec *codec) 2835/* fill in the dac_nids table from the parsed pin configuration */
2836static int alc_auto_fill_dac_nids(struct hda_codec *codec)
5642{ 2837{
5643 struct alc_spec *spec = codec->spec; 2838 struct alc_spec *spec = codec->spec;
5644 struct auto_pin_cfg *cfg = &spec->autocfg; 2839 const struct auto_pin_cfg *cfg = &spec->autocfg;
2840 bool redone = false;
5645 int i; 2841 int i;
5646 2842
5647 for (i = 0; i < cfg->num_inputs; i++) { 2843 again:
5648 hda_nid_t nid = cfg->inputs[i].pin; 2844 /* set num_dacs once to full for alc_auto_look_for_dac() */
5649 if (alc_is_input_pin(codec, nid)) { 2845 spec->multiout.num_dacs = cfg->line_outs;
5650 alc_set_input_pin(codec, nid, cfg->inputs[i].type); 2846 spec->multiout.hp_nid = 0;
5651 if (nid != ALC880_PIN_CD_NID && 2847 spec->multiout.extra_out_nid[0] = 0;
5652 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 2848 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
5653 snd_hda_codec_write(codec, nid, 0, 2849 spec->multiout.dac_nids = spec->private_dac_nids;
5654 AC_VERB_SET_AMP_GAIN_MUTE, 2850
5655 AMP_OUT_MUTE); 2851 /* fill hard-wired DACs first */
2852 if (!redone) {
2853 for (i = 0; i < cfg->line_outs; i++)
2854 spec->private_dac_nids[i] =
2855 get_dac_if_single(codec, cfg->line_out_pins[i]);
2856 if (cfg->hp_outs)
2857 spec->multiout.hp_nid =
2858 get_dac_if_single(codec, cfg->hp_pins[0]);
2859 if (cfg->speaker_outs)
2860 spec->multiout.extra_out_nid[0] =
2861 get_dac_if_single(codec, cfg->speaker_pins[0]);
2862 }
2863
2864 for (i = 0; i < cfg->line_outs; i++) {
2865 hda_nid_t pin = cfg->line_out_pins[i];
2866 if (spec->private_dac_nids[i])
2867 continue;
2868 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
2869 if (!spec->private_dac_nids[i] && !redone) {
2870 /* if we can't find primary DACs, re-probe without
2871 * checking the hard-wired DACs
2872 */
2873 redone = true;
2874 goto again;
5656 } 2875 }
5657 } 2876 }
2877
2878 /* re-count num_dacs and squash invalid entries */
2879 spec->multiout.num_dacs = 0;
2880 for (i = 0; i < cfg->line_outs; i++) {
2881 if (spec->private_dac_nids[i])
2882 spec->multiout.num_dacs++;
2883 else
2884 memmove(spec->private_dac_nids + i,
2885 spec->private_dac_nids + i + 1,
2886 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2887 }
2888
2889 if (cfg->hp_outs && !spec->multiout.hp_nid)
2890 spec->multiout.hp_nid =
2891 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
2892 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
2893 spec->multiout.extra_out_nid[0] =
2894 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
2895
2896 return 0;
5658} 2897}
5659 2898
5660static void alc880_auto_init_input_src(struct hda_codec *codec) 2899static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2900 const char *pfx, int cidx,
2901 hda_nid_t nid, unsigned int chs)
5661{ 2902{
5662 struct alc_spec *spec = codec->spec; 2903 if (!nid)
5663 int c; 2904 return 0;
5664 2905 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
5665 for (c = 0; c < spec->num_adc_nids; c++) { 2906 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} 2907}
5678 2908
5679static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); 2909#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
2910 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
5680 2911
5681/* parse the BIOS configuration and set up the alc_spec */ 2912/* create a mute-switch for the given mixer widget;
5682/* return 1 if successful, 0 if the proper config is not found, 2913 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
5683 * or a negative error code
5684 */ 2914 */
5685static int alc880_parse_auto_config(struct hda_codec *codec) 2915static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2916 const char *pfx, int cidx,
2917 hda_nid_t nid, unsigned int chs)
2918{
2919 int wid_type;
2920 int type;
2921 unsigned long val;
2922 if (!nid)
2923 return 0;
2924 wid_type = get_wcaps_type(get_wcaps(codec, nid));
2925 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT) {
2926 type = ALC_CTL_WIDGET_MUTE;
2927 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
2928 } else if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2929 type = ALC_CTL_WIDGET_MUTE;
2930 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2931 } else {
2932 type = ALC_CTL_BIND_MUTE;
2933 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2934 }
2935 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2936}
2937
2938#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2939 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2940
2941static hda_nid_t alc_look_for_out_mute_nid(struct hda_codec *codec,
2942 hda_nid_t pin, hda_nid_t dac)
2943{
2944 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2945 if (nid_has_mute(codec, pin, HDA_OUTPUT))
2946 return pin;
2947 else if (mix && nid_has_mute(codec, mix, HDA_INPUT))
2948 return mix;
2949 else if (nid_has_mute(codec, dac, HDA_OUTPUT))
2950 return dac;
2951 return 0;
2952}
2953
2954static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec,
2955 hda_nid_t pin, hda_nid_t dac)
2956{
2957 hda_nid_t mix = alc_auto_dac_to_mix(codec, pin, dac);
2958 if (nid_has_volume(codec, dac, HDA_OUTPUT))
2959 return dac;
2960 else if (nid_has_volume(codec, mix, HDA_OUTPUT))
2961 return mix;
2962 else if (nid_has_volume(codec, pin, HDA_OUTPUT))
2963 return pin;
2964 return 0;
2965}
2966
2967/* add playback controls from the parsed DAC table */
2968static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2969 const struct auto_pin_cfg *cfg)
5686{ 2970{
5687 struct alc_spec *spec = codec->spec; 2971 struct alc_spec *spec = codec->spec;
2972 int i, err, noutputs;
2973
2974 noutputs = cfg->line_outs;
2975 if (spec->multi_ios > 0)
2976 noutputs += spec->multi_ios;
2977
2978 for (i = 0; i < noutputs; i++) {
2979 const char *name;
2980 int index;
2981 hda_nid_t dac, pin;
2982 hda_nid_t sw, vol;
2983
2984 dac = spec->multiout.dac_nids[i];
2985 if (!dac)
2986 continue;
2987 if (i >= cfg->line_outs)
2988 pin = spec->multi_io[i - 1].pin;
2989 else
2990 pin = cfg->line_out_pins[i];
2991
2992 sw = alc_look_for_out_mute_nid(codec, pin, dac);
2993 vol = alc_look_for_out_vol_nid(codec, pin, dac);
2994 name = alc_get_line_out_pfx(spec, i, true, &index);
2995 if (!name) {
2996 /* Center/LFE */
2997 err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1);
2998 if (err < 0)
2999 return err;
3000 err = alc_auto_add_vol_ctl(codec, "LFE", 0, vol, 2);
3001 if (err < 0)
3002 return err;
3003 err = alc_auto_add_sw_ctl(codec, "Center", 0, sw, 1);
3004 if (err < 0)
3005 return err;
3006 err = alc_auto_add_sw_ctl(codec, "LFE", 0, sw, 2);
3007 if (err < 0)
3008 return err;
3009 } else {
3010 err = alc_auto_add_stereo_vol(codec, name, index, vol);
3011 if (err < 0)
3012 return err;
3013 err = alc_auto_add_stereo_sw(codec, name, index, sw);
3014 if (err < 0)
3015 return err;
3016 }
3017 }
3018 return 0;
3019}
3020
3021/* add playback controls for speaker and HP outputs */
3022static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3023 hda_nid_t dac, const char *pfx)
3024{
3025 struct alc_spec *spec = codec->spec;
3026 hda_nid_t sw, vol;
5688 int err; 3027 int err;
5689 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5690 3028
5691 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3029 if (!pin)
5692 alc880_ignore); 3030 return 0;
5693 if (err < 0) 3031 if (!dac) {
5694 return err; 3032 /* the corresponding DAC is already occupied */
5695 if (!spec->autocfg.line_outs) 3033 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
5696 return 0; /* can't find valid BIOS pin config */ 3034 return 0; /* no way */
3035 /* create a switch only */
3036 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
3037 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
3038 }
5697 3039
5698 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 3040 sw = alc_look_for_out_mute_nid(codec, pin, dac);
5699 if (err < 0) 3041 vol = alc_look_for_out_vol_nid(codec, pin, dac);
5700 return err; 3042 err = alc_auto_add_stereo_vol(codec, pfx, 0, vol);
5701 err = alc_auto_add_multi_channel_mode(codec);
5702 if (err < 0) 3043 if (err < 0)
5703 return err; 3044 return err;
5704 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 3045 err = alc_auto_add_stereo_sw(codec, pfx, 0, sw);
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)
5715 return err;
5716 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5717 if (err < 0) 3046 if (err < 0)
5718 return err; 3047 return err;
3048 return 0;
3049}
5719 3050
5720 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 3051static int alc_auto_create_hp_out(struct hda_codec *codec)
3052{
3053 struct alc_spec *spec = codec->spec;
3054 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3055 spec->multiout.hp_nid,
3056 "Headphone");
3057}
5721 3058
5722 alc_auto_parse_digital(codec); 3059static int alc_auto_create_speaker_out(struct hda_codec *codec)
3060{
3061 struct alc_spec *spec = codec->spec;
3062 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
3063 spec->multiout.extra_out_nid[0],
3064 "Speaker");
3065}
5723 3066
5724 if (spec->kctls.list) 3067static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
5725 add_mixer(spec, spec->kctls.list); 3068 hda_nid_t pin, int pin_type,
3069 hda_nid_t dac)
3070{
3071 int i, num;
3072 hda_nid_t nid, mix = 0;
3073 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
5726 3074
5727 add_verb(spec, alc880_volume_init_verbs); 3075 alc_set_pin_output(codec, pin, pin_type);
3076 nid = alc_go_down_to_selector(codec, pin);
3077 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
3078 for (i = 0; i < num; i++) {
3079 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
3080 continue;
3081 mix = srcs[i];
3082 break;
3083 }
3084 if (!mix)
3085 return;
5728 3086
5729 spec->num_mux_defs = 1; 3087 /* need the manual connection? */
5730 spec->input_mux = &spec->private_imux[0]; 3088 if (num > 1)
3089 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
3090 /* unmute mixer widget inputs */
3091 if (nid_has_mute(codec, mix, HDA_INPUT)) {
3092 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3093 AMP_IN_UNMUTE(0));
3094 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3095 AMP_IN_UNMUTE(1));
3096 }
3097 /* initialize volume */
3098 nid = alc_look_for_out_vol_nid(codec, pin, dac);
3099 if (nid)
3100 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3101 AMP_OUT_ZERO);
3102
3103 /* unmute DAC if it's not assigned to a mixer */
3104 nid = alc_look_for_out_mute_nid(codec, pin, dac);
3105 if (nid == mix && nid_has_mute(codec, dac, HDA_OUTPUT))
3106 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3107 AMP_OUT_ZERO);
3108}
3109
3110static void alc_auto_init_multi_out(struct hda_codec *codec)
3111{
3112 struct alc_spec *spec = codec->spec;
3113 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3114 int i;
3115
3116 for (i = 0; i <= HDA_SIDE; i++) {
3117 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3118 if (nid)
3119 alc_auto_set_output_and_unmute(codec, nid, pin_type,
3120 spec->multiout.dac_nids[i]);
3121 }
3122}
3123
3124static void alc_auto_init_extra_out(struct hda_codec *codec)
3125{
3126 struct alc_spec *spec = codec->spec;
3127 hda_nid_t pin, dac;
3128
3129 pin = spec->autocfg.hp_pins[0];
3130 if (pin) {
3131 dac = spec->multiout.hp_nid;
3132 if (!dac)
3133 dac = spec->multiout.dac_nids[0];
3134 alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
3135 }
3136 pin = spec->autocfg.speaker_pins[0];
3137 if (pin) {
3138 dac = spec->multiout.extra_out_nid[0];
3139 if (!dac)
3140 dac = spec->multiout.dac_nids[0];
3141 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
3142 }
3143}
3144
3145/*
3146 * multi-io helper
3147 */
3148static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3149 unsigned int location)
3150{
3151 struct alc_spec *spec = codec->spec;
3152 struct auto_pin_cfg *cfg = &spec->autocfg;
3153 int type, i, num_pins = 0;
3154
3155 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3156 for (i = 0; i < cfg->num_inputs; i++) {
3157 hda_nid_t nid = cfg->inputs[i].pin;
3158 hda_nid_t dac;
3159 unsigned int defcfg, caps;
3160 if (cfg->inputs[i].type != type)
3161 continue;
3162 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3163 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3164 continue;
3165 if (location && get_defcfg_location(defcfg) != location)
3166 continue;
3167 caps = snd_hda_query_pin_caps(codec, nid);
3168 if (!(caps & AC_PINCAP_OUT))
3169 continue;
3170 dac = alc_auto_look_for_dac(codec, nid);
3171 if (!dac)
3172 continue;
3173 spec->multi_io[num_pins].pin = nid;
3174 spec->multi_io[num_pins].dac = dac;
3175 num_pins++;
3176 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3177 }
3178 }
3179 spec->multiout.num_dacs = 1;
3180 if (num_pins < 2)
3181 return 0;
3182 return num_pins;
3183}
5731 3184
5732 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 3185static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3186 struct snd_ctl_elem_info *uinfo)
3187{
3188 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3189 struct alc_spec *spec = codec->spec;
5733 3190
3191 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3192 uinfo->count = 1;
3193 uinfo->value.enumerated.items = spec->multi_ios + 1;
3194 if (uinfo->value.enumerated.item > spec->multi_ios)
3195 uinfo->value.enumerated.item = spec->multi_ios;
3196 sprintf(uinfo->value.enumerated.name, "%dch",
3197 (uinfo->value.enumerated.item + 1) * 2);
3198 return 0;
3199}
3200
3201static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3202 struct snd_ctl_elem_value *ucontrol)
3203{
3204 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3205 struct alc_spec *spec = codec->spec;
3206 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3207 return 0;
3208}
3209
3210static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3211{
3212 struct alc_spec *spec = codec->spec;
3213 hda_nid_t nid = spec->multi_io[idx].pin;
3214
3215 if (!spec->multi_io[idx].ctl_in)
3216 spec->multi_io[idx].ctl_in =
3217 snd_hda_codec_read(codec, nid, 0,
3218 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3219 if (output) {
3220 snd_hda_codec_update_cache(codec, nid, 0,
3221 AC_VERB_SET_PIN_WIDGET_CONTROL,
3222 PIN_OUT);
3223 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3224 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3225 HDA_AMP_MUTE, 0);
3226 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3227 } else {
3228 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3229 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3230 HDA_AMP_MUTE, HDA_AMP_MUTE);
3231 snd_hda_codec_update_cache(codec, nid, 0,
3232 AC_VERB_SET_PIN_WIDGET_CONTROL,
3233 spec->multi_io[idx].ctl_in);
3234 }
3235 return 0;
3236}
3237
3238static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3239 struct snd_ctl_elem_value *ucontrol)
3240{
3241 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3242 struct alc_spec *spec = codec->spec;
3243 int i, ch;
3244
3245 ch = ucontrol->value.enumerated.item[0];
3246 if (ch < 0 || ch > spec->multi_ios)
3247 return -EINVAL;
3248 if (ch == (spec->ext_channel_count - 1) / 2)
3249 return 0;
3250 spec->ext_channel_count = (ch + 1) * 2;
3251 for (i = 0; i < spec->multi_ios; i++)
3252 alc_set_multi_io(codec, i, i < ch);
3253 spec->multiout.max_channels = spec->ext_channel_count;
3254 if (spec->need_dac_fix && !spec->const_channel_count)
3255 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
5734 return 1; 3256 return 1;
5735} 3257}
5736 3258
5737/* additional initialization for auto-configuration model */ 3259static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
5738static void alc880_auto_init(struct hda_codec *codec) 3260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3261 .name = "Channel Mode",
3262 .info = alc_auto_ch_mode_info,
3263 .get = alc_auto_ch_mode_get,
3264 .put = alc_auto_ch_mode_put,
3265};
3266
3267static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3268 int (*fill_dac)(struct hda_codec *))
5739{ 3269{
5740 struct alc_spec *spec = codec->spec; 3270 struct alc_spec *spec = codec->spec;
5741 alc880_auto_init_multi_out(codec); 3271 struct auto_pin_cfg *cfg = &spec->autocfg;
5742 alc880_auto_init_extra_out(codec); 3272 unsigned int location, defcfg;
5743 alc880_auto_init_analog_input(codec); 3273 int num_pins;
5744 alc880_auto_init_input_src(codec); 3274
5745 alc_auto_init_digital(codec); 3275 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
5746 if (spec->unsol_event) 3276 /* use HP as primary out */
5747 alc_inithook(codec); 3277 cfg->speaker_outs = cfg->line_outs;
3278 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3279 sizeof(cfg->speaker_pins));
3280 cfg->line_outs = cfg->hp_outs;
3281 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3282 cfg->hp_outs = 0;
3283 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3284 cfg->line_out_type = AUTO_PIN_HP_OUT;
3285 if (fill_dac)
3286 fill_dac(codec);
3287 }
3288 if (cfg->line_outs != 1 ||
3289 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3290 return 0;
3291
3292 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
3293 location = get_defcfg_location(defcfg);
3294
3295 num_pins = alc_auto_fill_multi_ios(codec, location);
3296 if (num_pins > 0) {
3297 struct snd_kcontrol_new *knew;
3298
3299 knew = alc_kcontrol_new(spec);
3300 if (!knew)
3301 return -ENOMEM;
3302 *knew = alc_auto_channel_mode_enum;
3303 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3304 if (!knew->name)
3305 return -ENOMEM;
3306
3307 spec->multi_ios = num_pins;
3308 spec->ext_channel_count = 2;
3309 spec->multiout.num_dacs = num_pins + 1;
3310 }
3311 return 0;
5748} 3312}
5749 3313
5750/* check the ADC/MUX contains all input pins; some ADC/MUX contains only 3314/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5751 * one of two digital mic pins, e.g. on ALC272 3315 * active input pins
5752 */ 3316 */
5753static void fixup_automic_adc(struct hda_codec *codec) 3317static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5754{ 3318{
5755 struct alc_spec *spec = codec->spec; 3319 struct alc_spec *spec = codec->spec;
5756 int i; 3320 const struct hda_input_mux *imux;
3321 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3322 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3323 int i, n, nums;
5757 3324
5758 for (i = 0; i < spec->num_adc_nids; i++) { 3325 imux = spec->input_mux;
5759 hda_nid_t cap = spec->capsrc_nids ? 3326 if (!imux)
5760 spec->capsrc_nids[i] : spec->adc_nids[i]; 3327 return;
5761 int iidx, eidx; 3328 if (spec->dyn_adc_switch)
3329 return;
5762 3330
5763 iidx = get_connection_index(codec, cap, spec->int_mic.pin); 3331 nums = 0;
5764 if (iidx < 0) 3332 for (n = 0; n < spec->num_adc_nids; n++) {
5765 continue; 3333 hda_nid_t cap = spec->private_capsrc_nids[n];
5766 eidx = get_connection_index(codec, cap, spec->ext_mic.pin); 3334 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5767 if (eidx < 0) 3335 for (i = 0; i < imux->num_items; i++) {
5768 continue; 3336 hda_nid_t pin = spec->imux_pins[i];
5769 spec->int_mic.mux_idx = iidx; 3337 if (pin) {
5770 spec->ext_mic.mux_idx = eidx; 3338 if (get_connection_index(codec, cap, pin) < 0)
5771 if (spec->capsrc_nids) 3339 break;
5772 spec->capsrc_nids += i; 3340 } else if (num_conns <= imux->items[i].index)
5773 spec->adc_nids += i; 3341 break;
5774 spec->num_adc_nids = 1; 3342 }
5775 /* optional dock-mic */ 3343 if (i >= imux->num_items) {
5776 eidx = get_connection_index(codec, cap, spec->dock_mic.pin); 3344 adc_nids[nums] = spec->private_adc_nids[n];
5777 if (eidx < 0) 3345 capsrc_nids[nums++] = cap;
5778 spec->dock_mic.pin = 0; 3346 }
5779 else 3347 }
5780 spec->dock_mic.mux_idx = eidx; 3348 if (!nums) {
3349 /* check whether ADC-switch is possible */
3350 if (!alc_check_dyn_adc_switch(codec)) {
3351 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3352 " using fallback 0x%x\n",
3353 codec->chip_name, spec->private_adc_nids[0]);
3354 spec->num_adc_nids = 1;
3355 spec->auto_mic = 0;
3356 return;
3357 }
3358 } else if (nums != spec->num_adc_nids) {
3359 memcpy(spec->private_adc_nids, adc_nids,
3360 nums * sizeof(hda_nid_t));
3361 memcpy(spec->private_capsrc_nids, capsrc_nids,
3362 nums * sizeof(hda_nid_t));
3363 spec->num_adc_nids = nums;
3364 }
3365
3366 if (spec->auto_mic)
3367 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3368 else if (spec->input_mux->num_items == 1)
3369 spec->num_adc_nids = 1; /* reduce to a single ADC */
3370}
3371
3372/*
3373 * initialize ADC paths
3374 */
3375static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3376{
3377 struct alc_spec *spec = codec->spec;
3378 hda_nid_t nid;
3379
3380 nid = spec->adc_nids[adc_idx];
3381 /* mute ADC */
3382 if (nid_has_mute(codec, nid, HDA_INPUT)) {
3383 snd_hda_codec_write(codec, nid, 0,
3384 AC_VERB_SET_AMP_GAIN_MUTE,
3385 AMP_IN_MUTE(0));
5781 return; 3386 return;
5782 } 3387 }
5783 snd_printd(KERN_INFO "hda_codec: %s: " 3388 if (!spec->capsrc_nids)
5784 "No ADC/MUX containing both 0x%x and 0x%x pins\n", 3389 return;
5785 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin); 3390 nid = spec->capsrc_nids[adc_idx];
5786 spec->auto_mic = 0; /* disable auto-mic to be sure */ 3391 if (nid_has_mute(codec, nid, HDA_OUTPUT))
3392 snd_hda_codec_write(codec, nid, 0,
3393 AC_VERB_SET_AMP_GAIN_MUTE,
3394 AMP_OUT_MUTE);
3395}
3396
3397static void alc_auto_init_input_src(struct hda_codec *codec)
3398{
3399 struct alc_spec *spec = codec->spec;
3400 int c, nums;
3401
3402 for (c = 0; c < spec->num_adc_nids; c++)
3403 alc_auto_init_adc(codec, c);
3404 if (spec->dyn_adc_switch)
3405 nums = 1;
3406 else
3407 nums = spec->num_adc_nids;
3408 for (c = 0; c < nums; c++)
3409 alc_mux_select(codec, 0, spec->cur_mux[c], true);
3410}
3411
3412/* add mic boosts if needed */
3413static int alc_auto_add_mic_boost(struct hda_codec *codec)
3414{
3415 struct alc_spec *spec = codec->spec;
3416 struct auto_pin_cfg *cfg = &spec->autocfg;
3417 int i, err;
3418 int type_idx = 0;
3419 hda_nid_t nid;
3420 const char *prev_label = NULL;
3421
3422 for (i = 0; i < cfg->num_inputs; i++) {
3423 if (cfg->inputs[i].type > AUTO_PIN_MIC)
3424 break;
3425 nid = cfg->inputs[i].pin;
3426 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
3427 const char *label;
3428 char boost_label[32];
3429
3430 label = hda_get_autocfg_input_label(codec, cfg, i);
3431 if (prev_label && !strcmp(label, prev_label))
3432 type_idx++;
3433 else
3434 type_idx = 0;
3435 prev_label = label;
3436
3437 snprintf(boost_label, sizeof(boost_label),
3438 "%s Boost Volume", label);
3439 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3440 boost_label, type_idx,
3441 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
3442 if (err < 0)
3443 return err;
3444 }
3445 }
3446 return 0;
5787} 3447}
5788 3448
5789/* select or unmute the given capsrc route */ 3449/* select or unmute the given capsrc route */
@@ -5793,7 +3453,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) { 3453 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5794 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, 3454 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5795 HDA_AMP_MUTE, 0); 3455 HDA_AMP_MUTE, 0);
5796 } else { 3456 } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
5797 snd_hda_codec_write_cache(codec, cap, 0, 3457 snd_hda_codec_write_cache(codec, cap, 0,
5798 AC_VERB_SET_CONNECT_SEL, idx); 3458 AC_VERB_SET_CONNECT_SEL, idx);
5799 } 3459 }
@@ -5821,46 +3481,17 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5821 return -1; /* not found */ 3481 return -1; /* not found */
5822} 3482}
5823 3483
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 */ 3484/* initialize some special cases for input sources */
5855static void alc_init_special_input_src(struct hda_codec *codec) 3485static void alc_init_special_input_src(struct hda_codec *codec)
5856{ 3486{
5857 struct alc_spec *spec = codec->spec; 3487 struct alc_spec *spec = codec->spec;
5858 if (spec->dual_adc_switch) 3488 int i;
5859 fixup_dual_adc_switch(codec); 3489
5860 else if (spec->single_input_src) 3490 for (i = 0; i < spec->autocfg.num_inputs; i++)
5861 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin); 3491 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
5862} 3492}
5863 3493
3494/* assign appropriate capture mixers */
5864static void set_capture_mixer(struct hda_codec *codec) 3495static void set_capture_mixer(struct hda_codec *codec)
5865{ 3496{
5866 struct alc_spec *spec = codec->spec; 3497 struct alc_spec *spec = codec->spec;
@@ -5872,86 +3503,56 @@ static void set_capture_mixer(struct hda_codec *codec)
5872 alc_capture_mixer2, 3503 alc_capture_mixer2,
5873 alc_capture_mixer3 }, 3504 alc_capture_mixer3 },
5874 }; 3505 };
5875 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 3506
3507 /* check whether either of ADC or MUX has a volume control */
3508 if (!nid_has_volume(codec, spec->adc_nids[0], HDA_INPUT)) {
3509 if (!spec->capsrc_nids)
3510 return; /* no volume */
3511 if (!nid_has_volume(codec, spec->capsrc_nids[0], HDA_OUTPUT))
3512 return; /* no volume in capsrc, too */
3513 spec->vol_in_capsrc = 1;
3514 }
3515
3516 if (spec->num_adc_nids > 0) {
5876 int mux = 0; 3517 int mux = 0;
5877 int num_adcs = spec->num_adc_nids; 3518 int num_adcs = 0;
5878 if (spec->dual_adc_switch) 3519
3520 if (spec->input_mux && spec->input_mux->num_items > 1)
3521 mux = 1;
3522 if (spec->auto_mic) {
3523 num_adcs = 1;
3524 mux = 0;
3525 } else if (spec->dyn_adc_switch)
5879 num_adcs = 1; 3526 num_adcs = 1;
5880 else if (spec->auto_mic) 3527 if (!num_adcs) {
5881 fixup_automic_adc(codec); 3528 if (spec->num_adc_nids > 3)
5882 else if (spec->input_mux) { 3529 spec->num_adc_nids = 3;
5883 if (spec->input_mux->num_items > 1) 3530 else if (!spec->num_adc_nids)
5884 mux = 1; 3531 return;
5885 else if (spec->input_mux->num_items == 1) 3532 num_adcs = spec->num_adc_nids;
5886 fixup_single_adc(codec);
5887 } 3533 }
5888 spec->cap_mixer = caps[mux][num_adcs - 1]; 3534 spec->cap_mixer = caps[mux][num_adcs - 1];
5889 } 3535 }
5890} 3536}
5891 3537
5892/* fill adc_nids (and capsrc_nids) containing all active input pins */ 3538/*
5893static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, 3539 * standard auto-parser initializations
5894 int num_nids) 3540 */
3541static void alc_auto_init_std(struct hda_codec *codec)
5895{ 3542{
5896 struct alc_spec *spec = codec->spec; 3543 struct alc_spec *spec = codec->spec;
5897 struct auto_pin_cfg *cfg = &spec->autocfg; 3544 alc_auto_init_multi_out(codec);
5898 int n; 3545 alc_auto_init_extra_out(codec);
5899 hda_nid_t fallback_adc = 0, fallback_cap = 0; 3546 alc_auto_init_analog_input(codec);
5900 3547 alc_auto_init_input_src(codec);
5901 for (n = 0; n < num_nids; n++) { 3548 alc_auto_init_digital(codec);
5902 hda_nid_t adc, cap; 3549 if (spec->unsol_event)
5903 hda_nid_t conn[HDA_MAX_NUM_INPUTS]; 3550 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} 3551}
5954 3552
3553/*
3554 * Digital-beep handlers
3555 */
5955#ifdef CONFIG_SND_HDA_INPUT_BEEP 3556#ifdef CONFIG_SND_HDA_INPUT_BEEP
5956#define set_beep_amp(spec, nid, idx, dir) \ 3557#define set_beep_amp(spec, nid, idx, dir) \
5957 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 3558 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -5979,1402 +3580,195 @@ static inline int has_cdefine_beep(struct hda_codec *codec)
5979#define has_cdefine_beep(codec) 0 3580#define has_cdefine_beep(codec) 0
5980#endif 3581#endif
5981 3582
5982/* 3583/* parse the BIOS configuration and set up the alc_spec */
5983 * OK, here we have finally the patch for ALC880 3584/* return 1 if successful, 0 if the proper config is not found,
3585 * or a negative error code
5984 */ 3586 */
5985 3587static int alc_parse_auto_config(struct hda_codec *codec,
5986static int patch_alc880(struct hda_codec *codec) 3588 const hda_nid_t *ignore_nids,
3589 const hda_nid_t *ssid_nids)
5987{ 3590{
5988 struct alc_spec *spec; 3591 struct alc_spec *spec = codec->spec;
5989 int board_config;
5990 int err; 3592 int err;
5991 3593
5992 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 3594 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5993 if (spec == NULL) 3595 ignore_nids);
5994 return -ENOMEM; 3596 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; 3597 return err;
6025 } 3598 if (!spec->autocfg.line_outs) {
6026 3599 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
6027 if (board_config != ALC880_AUTO) 3600 spec->multiout.max_channels = 2;
6028 setup_preset(codec, &alc880_presets[board_config]); 3601 spec->no_analog = 1;
6029 3602 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 } 3603 }
3604 return 0; /* can't find valid BIOS pin config */
6049 } 3605 }
6050 set_capture_mixer(codec); 3606 err = alc_auto_fill_dac_nids(codec);
6051 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 3607 if (err < 0)
6052 3608 return err;
6053 spec->vmaster_nid = 0x0c; 3609 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
6054 3610 if (err < 0)
6055 codec->patch_ops = alc_patch_ops; 3611 return err;
6056 if (board_config == ALC880_AUTO) 3612 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
6057 spec->init_hook = alc880_auto_init; 3613 if (err < 0)
6058#ifdef CONFIG_SND_HDA_POWER_SAVE 3614 return err;
6059 if (!spec->loopback.amplist) 3615 err = alc_auto_create_hp_out(codec);
6060 spec->loopback.amplist = alc880_loopbacks; 3616 if (err < 0)
6061#endif 3617 return err;
6062 3618 err = alc_auto_create_speaker_out(codec);
6063 return 0; 3619 if (err < 0)
6064} 3620 return err;
6065 3621 err = alc_auto_create_input_ctls(codec);
6066 3622 if (err < 0)
6067/* 3623 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 3624
6189/* Mixer combinations 3625 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 3626
6198static const struct snd_kcontrol_new alc260_base_output_mixer[] = { 3627 dig_only:
6199 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3628 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 3629
6208static const struct snd_kcontrol_new alc260_input_mixer[] = { 3630 if (!spec->no_analog)
6209 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3631 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 3632
6220/* update HP, line and mono out pins according to the master switch */ 3633 if (ssid_nids)
6221static void alc260_hp_master_update(struct hda_codec *codec) 3634 alc_ssid_check(codec, ssid_nids);
6222{
6223 update_speakers(codec);
6224}
6225 3635
6226static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, 3636 if (!spec->no_analog) {
6227 struct snd_ctl_elem_value *ucontrol) 3637 alc_auto_check_switches(codec);
6228{ 3638 err = alc_auto_add_mic_boost(codec);
6229 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 3639 if (err < 0)
6230 struct alc_spec *spec = codec->spec; 3640 return err;
6231 *ucontrol->value.integer.value = !spec->master_mute; 3641 }
6232 return 0;
6233}
6234 3642
6235static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, 3643 if (spec->kctls.list)
6236 struct snd_ctl_elem_value *ucontrol) 3644 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 3645
6242 if (val == spec->master_mute)
6243 return 0;
6244 spec->master_mute = val;
6245 alc260_hp_master_update(codec);
6246 return 1; 3646 return 1;
6247} 3647}
6248 3648
6249static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { 3649static 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{ 3650{
6349 struct alc_spec *spec = codec->spec; 3651 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
6350 3652 static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 };
6351 spec->autocfg.hp_pins[0] = 0x10; 3653 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} 3654}
6358 3655
6359/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, 3656#ifdef CONFIG_SND_HDA_POWER_SAVE
6360 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. 3657static const struct hda_amp_list alc880_loopbacks[] = {
6361 */ 3658 { 0x0b, HDA_INPUT, 0 },
6362static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { 3659 { 0x0b, HDA_INPUT, 1 },
6363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3660 { 0x0b, HDA_INPUT, 2 },
6364 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), 3661 { 0x0b, HDA_INPUT, 3 },
6365 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), 3662 { 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 */ 3663 { } /* end */
6462}; 3664};
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 3665#endif
6580 3666
6581static const struct hda_verb alc260_hp_3013_init_verbs[] = { 3667/*
6582 /* Line out and output */ 3668 * 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 */ 3669 */
6964static const struct hda_input_mux alc260_test_capture_sources[2] = { 3670#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6965 { 3671#define alc_board_config \
6966 .num_items = 7, 3672 snd_hda_check_board_config
6967 .items = { 3673#define alc_board_codec_sid_config \
6968 { "MIC1 pin", 0x0 }, 3674 snd_hda_check_board_codec_sid_config
6969 { "MIC2 pin", 0x1 }, 3675#include "alc_quirks.c"
6970 { "LINE1 pin", 0x2 }, 3676#else
6971 { "LINE2 pin", 0x3 }, 3677#define alc_board_config(codec, nums, models, tbl) -1
6972 { "CD pin", 0x4 }, 3678#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
6973 { "LINE-OUT pin", 0x5 }, 3679#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 3680#endif
7137 3681
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/* 3682/*
7145 * for BIOS auto-configuration 3683 * OK, here we have finally the patch for ALC880
7146 */ 3684 */
3685#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3686#include "alc880_quirks.c"
3687#endif
7147 3688
7148static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, 3689static int patch_alc880(struct hda_codec *codec)
7149 const char *pfx, int *vol_bits)
7150{ 3690{
7151 hda_nid_t nid_vol; 3691 struct alc_spec *spec;
7152 unsigned long vol_val, sw_val; 3692 int board_config;
7153 int err; 3693 int err;
7154 3694
7155 if (nid >= 0x0f && nid < 0x11) { 3695 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7156 nid_vol = nid - 0x7; 3696 if (spec == NULL)
7157 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT); 3697 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 3698
7183/* add playback controls from the parsed DAC table */ 3699 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 3700
7191 spec->multiout.num_dacs = 1; 3701 spec->mixer_nid = 0x0b;
7192 spec->multiout.dac_nids = spec->private_dac_nids; 3702 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 3703
7209 nid = cfg->speaker_pins[0]; 3704 board_config = alc_board_config(codec, ALC880_MODEL_LAST,
7210 if (nid) { 3705 alc880_models, alc880_cfg_tbl);
7211 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols); 3706 if (board_config < 0) {
7212 if (err < 0) 3707 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7213 return err; 3708 codec->chip_name);
3709 board_config = ALC_MODEL_AUTO;
7214 } 3710 }
7215 3711
7216 nid = cfg->hp_pins[0]; 3712 if (board_config == ALC_MODEL_AUTO) {
7217 if (nid) { 3713 /* automatic parse from the BIOS config */
7218 err = alc260_add_playback_controls(spec, nid, "Headphone", 3714 err = alc880_parse_auto_config(codec);
7219 &vols); 3715 if (err < 0) {
7220 if (err < 0) 3716 alc_free(codec);
7221 return err; 3717 return err;
3718 }
3719#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3720 else if (!err) {
3721 printk(KERN_INFO
3722 "hda_codec: Cannot set up configuration "
3723 "from BIOS. Using 3-stack mode...\n");
3724 board_config = ALC880_3ST;
3725 }
3726#endif
7222 } 3727 }
7223 return 0;
7224}
7225 3728
7226/* create playback/capture controls for input pins */ 3729 if (board_config != ALC_MODEL_AUTO)
7227static int alc260_auto_create_input_ctls(struct hda_codec *codec, 3730 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 3731
7233static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 3732 if (!spec->no_analog && !spec->adc_nids) {
7234 hda_nid_t nid, int pin_type, 3733 alc_auto_fill_adc_caps(codec);
7235 int sel_idx) 3734 alc_rebuild_imux_for_auto_mic(codec);
7236{ 3735 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 } 3736 }
7244}
7245 3737
7246static void alc260_auto_init_multi_out(struct hda_codec *codec) 3738 if (!spec->no_analog && !spec->cap_mixer)
7247{ 3739 set_capture_mixer(codec);
7248 struct alc_spec *spec = codec->spec;
7249 hda_nid_t nid;
7250 3740
7251 nid = spec->autocfg.line_out_pins[0]; 3741 if (!spec->no_analog) {
7252 if (nid) { 3742 err = snd_hda_attach_beep_device(codec, 0x1);
7253 int pin_type = get_pin_type(spec->autocfg.line_out_type); 3743 if (err < 0) {
7254 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); 3744 alc_free(codec);
3745 return err;
3746 }
3747 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7255 } 3748 }
7256 3749
7257 nid = spec->autocfg.speaker_pins[0]; 3750 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 3751
7266#define ALC260_PIN_CD_NID 0x16 3752 codec->patch_ops = alc_patch_ops;
7267static void alc260_auto_init_analog_input(struct hda_codec *codec) 3753 if (board_config == ALC_MODEL_AUTO)
7268{ 3754 spec->init_hook = alc_auto_init_std;
7269 struct alc_spec *spec = codec->spec; 3755#ifdef CONFIG_SND_HDA_POWER_SAVE
7270 struct auto_pin_cfg *cfg = &spec->autocfg; 3756 if (!spec->loopback.amplist)
7271 int i; 3757 spec->loopback.amplist = alc880_loopbacks;
3758#endif
7272 3759
7273 for (i = 0; i < cfg->num_inputs; i++) { 3760 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} 3761}
7285 3762
7286#define alc260_auto_init_input_src alc880_auto_init_input_src
7287 3763
7288/* 3764/*
7289 * generic initialization of ADC, input mixers and output mixers 3765 * ALC260 support
7290 */ 3766 */
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) 3767static int alc260_parse_auto_config(struct hda_codec *codec)
7333{ 3768{
7334 struct alc_spec *spec = codec->spec;
7335 int err;
7336 static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; 3769 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7337 3770 static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 };
7338 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 3771 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} 3772}
7379 3773
7380#ifdef CONFIG_SND_HDA_POWER_SAVE 3774#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -7411,186 +3805,10 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7411}; 3805};
7412 3806
7413/* 3807/*
7414 * ALC260 configurations
7415 */ 3808 */
7416static const char * const alc260_models[ALC260_MODEL_LAST] = { 3809#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
7417 [ALC260_BASIC] = "basic", 3810#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 3811#endif
7593};
7594 3812
7595static int patch_alc260(struct hda_codec *codec) 3813static int patch_alc260(struct hda_codec *codec)
7596{ 3814{
@@ -7603,73 +3821,66 @@ static int patch_alc260(struct hda_codec *codec)
7603 3821
7604 codec->spec = spec; 3822 codec->spec = spec;
7605 3823
7606 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 3824 spec->mixer_nid = 0x07;
7607 alc260_models, 3825
7608 alc260_cfg_tbl); 3826 board_config = alc_board_config(codec, ALC260_MODEL_LAST,
3827 alc260_models, alc260_cfg_tbl);
7609 if (board_config < 0) { 3828 if (board_config < 0) {
7610 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3829 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7611 codec->chip_name); 3830 codec->chip_name);
7612 board_config = ALC260_AUTO; 3831 board_config = ALC_MODEL_AUTO;
7613 } 3832 }
7614 3833
7615 if (board_config == ALC260_AUTO) { 3834 if (board_config == ALC_MODEL_AUTO) {
7616 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 3835 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7617 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3836 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7618 } 3837 }
7619 3838
7620 if (board_config == ALC260_AUTO) { 3839 if (board_config == ALC_MODEL_AUTO) {
7621 /* automatic parse from the BIOS config */ 3840 /* automatic parse from the BIOS config */
7622 err = alc260_parse_auto_config(codec); 3841 err = alc260_parse_auto_config(codec);
7623 if (err < 0) { 3842 if (err < 0) {
7624 alc_free(codec); 3843 alc_free(codec);
7625 return err; 3844 return err;
7626 } else if (!err) { 3845 }
3846#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3847 else if (!err) {
7627 printk(KERN_INFO 3848 printk(KERN_INFO
7628 "hda_codec: Cannot set up configuration " 3849 "hda_codec: Cannot set up configuration "
7629 "from BIOS. Using base mode...\n"); 3850 "from BIOS. Using base mode...\n");
7630 board_config = ALC260_BASIC; 3851 board_config = ALC260_BASIC;
7631 } 3852 }
3853#endif
7632 } 3854 }
7633 3855
7634 err = snd_hda_attach_beep_device(codec, 0x1); 3856 if (board_config != ALC_MODEL_AUTO)
7635 if (err < 0) { 3857 setup_preset(codec, &alc260_presets[board_config]);
7636 alc_free(codec); 3858
7637 return err; 3859 if (!spec->no_analog && !spec->adc_nids) {
3860 alc_auto_fill_adc_caps(codec);
3861 alc_rebuild_imux_for_auto_mic(codec);
3862 alc_remove_invalid_adc_nids(codec);
7638 } 3863 }
7639 3864
7640 if (board_config != ALC260_AUTO) 3865 if (!spec->no_analog && !spec->cap_mixer)
7641 setup_preset(codec, &alc260_presets[board_config]); 3866 set_capture_mixer(codec);
7642 3867
7643 spec->stream_analog_playback = &alc260_pcm_analog_playback; 3868 if (!spec->no_analog) {
7644 spec->stream_analog_capture = &alc260_pcm_analog_capture; 3869 err = snd_hda_attach_beep_device(codec, 0x1);
7645 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture; 3870 if (err < 0) {
7646 3871 alc_free(codec);
7647 spec->stream_digital_playback = &alc260_pcm_digital_playback; 3872 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 } 3873 }
3874 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7662 } 3875 }
7663 set_capture_mixer(codec);
7664 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7665 3876
7666 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 3877 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7667 3878
7668 spec->vmaster_nid = 0x08; 3879 spec->vmaster_nid = 0x08;
7669 3880
7670 codec->patch_ops = alc_patch_ops; 3881 codec->patch_ops = alc_patch_ops;
7671 if (board_config == ALC260_AUTO) 3882 if (board_config == ALC_MODEL_AUTO)
7672 spec->init_hook = alc260_auto_init; 3883 spec->init_hook = alc_auto_init_std;
7673 spec->shutup = alc_eapd_shutup; 3884 spec->shutup = alc_eapd_shutup;
7674#ifdef CONFIG_SND_HDA_POWER_SAVE 3885#ifdef CONFIG_SND_HDA_POWER_SAVE
7675 if (!spec->loopback.amplist) 3886 if (!spec->loopback.amplist)
@@ -7691,3299 +3902,10 @@ static int patch_alc260(struct hda_codec *codec)
7691 * In addition, an independent DAC for the multi-playback (not used in this 3902 * In addition, an independent DAC for the multi-playback (not used in this
7692 * driver yet). 3903 * driver yet).
7693 */ 3904 */
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 3905#ifdef CONFIG_SND_HDA_POWER_SAVE
10025#define alc882_loopbacks alc880_loopbacks 3906#define alc882_loopbacks alc880_loopbacks
10026#endif 3907#endif
10027 3908
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/* 3909/*
10988 * Pin config fixes 3910 * Pin config fixes
10989 */ 3911 */
@@ -11036,255 +3958,19 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11036/* 3958/*
11037 * BIOS auto configuration 3959 * BIOS auto configuration
11038 */ 3960 */
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... */ 3961/* almost identical with ALC880 parser... */
11217static int alc882_parse_auto_config(struct hda_codec *codec) 3962static int alc882_parse_auto_config(struct hda_codec *codec)
11218{ 3963{
11219 struct alc_spec *spec = codec->spec;
11220 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; 3964 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11221 int err; 3965 static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 };
11222 3966 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} 3967}
11275 3968
11276/* additional initialization for auto-configuration model */ 3969/*
11277static void alc882_auto_init(struct hda_codec *codec) 3970 */
11278{ 3971#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
11279 struct alc_spec *spec = codec->spec; 3972#include "alc882_quirks.c"
11280 alc882_auto_init_multi_out(codec); 3973#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 3974
11289static int patch_alc882(struct hda_codec *codec) 3975static int patch_alc882(struct hda_codec *codec)
11290{ 3976{
@@ -11297,6 +3983,8 @@ static int patch_alc882(struct hda_codec *codec)
11297 3983
11298 codec->spec = spec; 3984 codec->spec = spec;
11299 3985
3986 spec->mixer_nid = 0x0b;
3987
11300 switch (codec->vendor_id) { 3988 switch (codec->vendor_id) {
11301 case 0x10ec0882: 3989 case 0x10ec0882:
11302 case 0x10ec0885: 3990 case 0x10ec0885:
@@ -11307,106 +3995,71 @@ static int patch_alc882(struct hda_codec *codec)
11307 break; 3995 break;
11308 } 3996 }
11309 3997
11310 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 3998 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
11311 alc882_models, 3999 alc882_models, alc882_cfg_tbl);
11312 alc882_cfg_tbl);
11313 4000
11314 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 4001 if (board_config < 0)
11315 board_config = snd_hda_check_board_codec_sid_config(codec, 4002 board_config = alc_board_codec_sid_config(codec,
11316 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 4003 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11317 4004
11318 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4005 if (board_config < 0) {
11319 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4006 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11320 codec->chip_name); 4007 codec->chip_name);
11321 board_config = ALC882_AUTO; 4008 board_config = ALC_MODEL_AUTO;
11322 } 4009 }
11323 4010
11324 if (board_config == ALC882_AUTO) { 4011 if (board_config == ALC_MODEL_AUTO) {
11325 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 4012 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11326 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4013 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11327 } 4014 }
11328 4015
11329 alc_auto_parse_customize_define(codec); 4016 alc_auto_parse_customize_define(codec);
11330 4017
11331 if (board_config == ALC882_AUTO) { 4018 if (board_config == ALC_MODEL_AUTO) {
11332 /* automatic parse from the BIOS config */ 4019 /* automatic parse from the BIOS config */
11333 err = alc882_parse_auto_config(codec); 4020 err = alc882_parse_auto_config(codec);
11334 if (err < 0) { 4021 if (err < 0) {
11335 alc_free(codec); 4022 alc_free(codec);
11336 return err; 4023 return err;
11337 } else if (!err) { 4024 }
4025#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4026 else if (!err) {
11338 printk(KERN_INFO 4027 printk(KERN_INFO
11339 "hda_codec: Cannot set up configuration " 4028 "hda_codec: Cannot set up configuration "
11340 "from BIOS. Using base mode...\n"); 4029 "from BIOS. Using base mode...\n");
11341 board_config = ALC882_3ST_DIG; 4030 board_config = ALC882_3ST_DIG;
11342 } 4031 }
4032#endif
11343 } 4033 }
11344 4034
11345 if (has_cdefine_beep(codec)) { 4035 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]); 4036 setup_preset(codec, &alc882_presets[board_config]);
11355 4037
11356 spec->stream_analog_playback = &alc882_pcm_analog_playback; 4038 if (!spec->no_analog && !spec->adc_nids) {
11357 spec->stream_analog_capture = &alc882_pcm_analog_capture; 4039 alc_auto_fill_adc_caps(codec);
11358 /* FIXME: setup DAC5 */ 4040 alc_rebuild_imux_for_auto_mic(codec);
11359 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/ 4041 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 } 4042 }
11397 4043
11398 set_capture_mixer(codec); 4044 if (!spec->no_analog && !spec->cap_mixer)
4045 set_capture_mixer(codec);
11399 4046
11400 if (has_cdefine_beep(codec)) 4047 if (!spec->no_analog && has_cdefine_beep(codec)) {
4048 err = snd_hda_attach_beep_device(codec, 0x1);
4049 if (err < 0) {
4050 alc_free(codec);
4051 return err;
4052 }
11401 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4053 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4054 }
11402 4055
11403 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4056 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11404 4057
11405 spec->vmaster_nid = 0x0c; 4058 spec->vmaster_nid = 0x0c;
11406 4059
11407 codec->patch_ops = alc_patch_ops; 4060 codec->patch_ops = alc_patch_ops;
11408 if (board_config == ALC882_AUTO) 4061 if (board_config == ALC_MODEL_AUTO)
11409 spec->init_hook = alc882_auto_init; 4062 spec->init_hook = alc_auto_init_std;
11410 4063
11411 alc_init_jacks(codec); 4064 alc_init_jacks(codec);
11412#ifdef CONFIG_SND_HDA_POWER_SAVE 4065#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -11421,1192 +4074,13 @@ static int patch_alc882(struct hda_codec *codec)
11421/* 4074/*
11422 * ALC262 support 4075 * ALC262 support
11423 */ 4076 */
11424 4077static 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{ 4078{
12270 const char *pfx; 4079 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12271 int vbits; 4080 static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 };
12272 int i, err; 4081 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} 4082}
12325 4083
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/* 4084/*
12611 * Pin config fixes 4085 * Pin config fixes
12612 */ 4086 */
@@ -12645,396 +4119,11 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12645#define alc262_loopbacks alc880_loopbacks 4119#define alc262_loopbacks alc880_loopbacks
12646#endif 4120#endif
12647 4121
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/* 4122/*
12655 * BIOS auto configuration
12656 */ 4123 */
12657static int alc262_parse_auto_config(struct hda_codec *codec) 4124#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
12658{ 4125#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 4126#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 4127
13039static int patch_alc262(struct hda_codec *codec) 4128static int patch_alc262(struct hda_codec *codec)
13040{ 4129{
@@ -13047,6 +4136,9 @@ static int patch_alc262(struct hda_codec *codec)
13047 return -ENOMEM; 4136 return -ENOMEM;
13048 4137
13049 codec->spec = spec; 4138 codec->spec = spec;
4139
4140 spec->mixer_nid = 0x0b;
4141
13050#if 0 4142#if 0
13051 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is 4143 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13052 * under-run 4144 * under-run
@@ -13063,96 +4155,65 @@ static int patch_alc262(struct hda_codec *codec)
13063 4155
13064 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 4156 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13065 4157
13066 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 4158 board_config = alc_board_config(codec, ALC262_MODEL_LAST,
13067 alc262_models, 4159 alc262_models, alc262_cfg_tbl);
13068 alc262_cfg_tbl);
13069 4160
13070 if (board_config < 0) { 4161 if (board_config < 0) {
13071 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4162 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13072 codec->chip_name); 4163 codec->chip_name);
13073 board_config = ALC262_AUTO; 4164 board_config = ALC_MODEL_AUTO;
13074 } 4165 }
13075 4166
13076 if (board_config == ALC262_AUTO) { 4167 if (board_config == ALC_MODEL_AUTO) {
13077 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 4168 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13078 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4169 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13079 } 4170 }
13080 4171
13081 if (board_config == ALC262_AUTO) { 4172 if (board_config == ALC_MODEL_AUTO) {
13082 /* automatic parse from the BIOS config */ 4173 /* automatic parse from the BIOS config */
13083 err = alc262_parse_auto_config(codec); 4174 err = alc262_parse_auto_config(codec);
13084 if (err < 0) { 4175 if (err < 0) {
13085 alc_free(codec); 4176 alc_free(codec);
13086 return err; 4177 return err;
13087 } else if (!err) { 4178 }
4179#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4180 else if (!err) {
13088 printk(KERN_INFO 4181 printk(KERN_INFO
13089 "hda_codec: Cannot set up configuration " 4182 "hda_codec: Cannot set up configuration "
13090 "from BIOS. Using base mode...\n"); 4183 "from BIOS. Using base mode...\n");
13091 board_config = ALC262_BASIC; 4184 board_config = ALC262_BASIC;
13092 } 4185 }
4186#endif
13093 } 4187 }
13094 4188
4189 if (board_config != ALC_MODEL_AUTO)
4190 setup_preset(codec, &alc262_presets[board_config]);
4191
4192 if (!spec->no_analog && !spec->adc_nids) {
4193 alc_auto_fill_adc_caps(codec);
4194 alc_rebuild_imux_for_auto_mic(codec);
4195 alc_remove_invalid_adc_nids(codec);
4196 }
4197
4198 if (!spec->no_analog && !spec->cap_mixer)
4199 set_capture_mixer(codec);
4200
13095 if (!spec->no_analog && has_cdefine_beep(codec)) { 4201 if (!spec->no_analog && has_cdefine_beep(codec)) {
13096 err = snd_hda_attach_beep_device(codec, 0x1); 4202 err = snd_hda_attach_beep_device(codec, 0x1);
13097 if (err < 0) { 4203 if (err < 0) {
13098 alc_free(codec); 4204 alc_free(codec);
13099 return err; 4205 return err;
13100 } 4206 }
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); 4207 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4208 }
13148 4209
13149 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4210 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13150 4211
13151 spec->vmaster_nid = 0x0c; 4212 spec->vmaster_nid = 0x0c;
13152 4213
13153 codec->patch_ops = alc_patch_ops; 4214 codec->patch_ops = alc_patch_ops;
13154 if (board_config == ALC262_AUTO) 4215 if (board_config == ALC_MODEL_AUTO)
13155 spec->init_hook = alc262_auto_init; 4216 spec->init_hook = alc_auto_init_std;
13156 spec->shutup = alc_eapd_shutup; 4217 spec->shutup = alc_eapd_shutup;
13157 4218
13158 alc_init_jacks(codec); 4219 alc_init_jacks(codec);
@@ -13165,51 +4226,8 @@ static int patch_alc262(struct hda_codec *codec)
13165} 4226}
13166 4227
13167/* 4228/*
13168 * ALC268 channel source setting (2 channel) 4229 * ALC268
13169 */ 4230 */
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 */ 4231/* bind Beep switches of both NID 0x0f and 0x10 */
13214static const struct hda_bind_ctls alc268_bind_beep_sw = { 4232static const struct hda_bind_ctls alc268_bind_beep_sw = {
13215 .ops = &snd_hda_bind_sw, 4233 .ops = &snd_hda_bind_sw,
@@ -13226,846 +4244,36 @@ static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13226 { } 4244 { }
13227}; 4245};
13228 4246
13229static const struct hda_verb alc268_eapd_verbs[] = { 4247/* set PCBEEP vol = 0, mute connections */
13230 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 4248static 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)}, 4249 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13453 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4250 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13454 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 4251 {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 { } 4252 { }
13464}; 4253};
13465 4254
13466/* 4255/*
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 4256 * BIOS auto configuration
13793 */ 4257 */
13794static int alc268_parse_auto_config(struct hda_codec *codec) 4258static int alc268_parse_auto_config(struct hda_codec *codec)
13795{ 4259{
4260 static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 };
13796 struct alc_spec *spec = codec->spec; 4261 struct alc_spec *spec = codec->spec;
13797 int err; 4262 int err = alc_parse_auto_config(codec, NULL, alc268_ssids);
13798 static const hda_nid_t alc268_ignore[] = { 0 }; 4263 if (err > 0) {
13799 4264 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
13800 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4265 add_mixer(spec, alc268_beep_mixer);
13801 alc268_ignore); 4266 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 } 4267 }
13810 return 0; /* can't find valid BIOS pin config */
13811 } 4268 }
13812 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 4269 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} 4270}
13859 4271
13860/* 4272/*
13861 * configuration and preset
13862 */ 4273 */
13863static const char * const alc268_models[ALC268_MODEL_LAST] = { 4274#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
13864 [ALC267_QUANTA_IL1] = "quanta-il1", 4275#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 4276#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 4277
14070static int patch_alc268(struct hda_codec *codec) 4278static int patch_alc268(struct hda_codec *codec)
14071{ 4279{
@@ -14079,43 +4287,41 @@ static int patch_alc268(struct hda_codec *codec)
14079 4287
14080 codec->spec = spec; 4288 codec->spec = spec;
14081 4289
14082 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 4290 /* ALC268 has no aa-loopback mixer */
14083 alc268_models,
14084 alc268_cfg_tbl);
14085 4291
14086 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 4292 board_config = alc_board_config(codec, ALC268_MODEL_LAST,
14087 board_config = snd_hda_check_board_codec_sid_config(codec, 4293 alc268_models, alc268_cfg_tbl);
4294
4295 if (board_config < 0)
4296 board_config = alc_board_codec_sid_config(codec,
14088 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 4297 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14089 4298
14090 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 4299 if (board_config < 0) {
14091 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4300 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14092 codec->chip_name); 4301 codec->chip_name);
14093 board_config = ALC268_AUTO; 4302 board_config = ALC_MODEL_AUTO;
14094 } 4303 }
14095 4304
14096 if (board_config == ALC268_AUTO) { 4305 if (board_config == ALC_MODEL_AUTO) {
14097 /* automatic parse from the BIOS config */ 4306 /* automatic parse from the BIOS config */
14098 err = alc268_parse_auto_config(codec); 4307 err = alc268_parse_auto_config(codec);
14099 if (err < 0) { 4308 if (err < 0) {
14100 alc_free(codec); 4309 alc_free(codec);
14101 return err; 4310 return err;
14102 } else if (!err) { 4311 }
4312#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4313 else if (!err) {
14103 printk(KERN_INFO 4314 printk(KERN_INFO
14104 "hda_codec: Cannot set up configuration " 4315 "hda_codec: Cannot set up configuration "
14105 "from BIOS. Using base mode...\n"); 4316 "from BIOS. Using base mode...\n");
14106 board_config = ALC268_3ST; 4317 board_config = ALC268_3ST;
14107 } 4318 }
4319#endif
14108 } 4320 }
14109 4321
14110 if (board_config != ALC268_AUTO) 4322 if (board_config != ALC_MODEL_AUTO)
14111 setup_preset(codec, &alc268_presets[board_config]); 4323 setup_preset(codec, &alc268_presets[board_config]);
14112 4324
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; 4325 has_beep = 0;
14120 for (i = 0; i < spec->num_mixers; i++) { 4326 for (i = 0; i < spec->num_mixers; i++) {
14121 if (spec->mixers[i] == alc268_beep_mixer) { 4327 if (spec->mixers[i] == alc268_beep_mixer) {
@@ -14139,35 +4345,20 @@ static int patch_alc268(struct hda_codec *codec)
14139 (0 << AC_AMPCAP_MUTE_SHIFT)); 4345 (0 << AC_AMPCAP_MUTE_SHIFT));
14140 } 4346 }
14141 4347
14142 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) { 4348 if (!spec->no_analog && !spec->adc_nids) {
14143 /* check whether NID 0x07 is valid */ 4349 alc_auto_fill_adc_caps(codec);
14144 unsigned int wcap = get_wcaps(codec, 0x07); 4350 alc_rebuild_imux_for_auto_mic(codec);
14145 4351 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 } 4352 }
14165 4353
4354 if (!spec->no_analog && !spec->cap_mixer)
4355 set_capture_mixer(codec);
4356
14166 spec->vmaster_nid = 0x02; 4357 spec->vmaster_nid = 0x02;
14167 4358
14168 codec->patch_ops = alc_patch_ops; 4359 codec->patch_ops = alc_patch_ops;
14169 if (board_config == ALC268_AUTO) 4360 if (board_config == ALC_MODEL_AUTO)
14170 spec->init_hook = alc268_auto_init; 4361 spec->init_hook = alc_auto_init_std;
14171 spec->shutup = alc_eapd_shutup; 4362 spec->shutup = alc_eapd_shutup;
14172 4363
14173 alc_init_jacks(codec); 4364 alc_init_jacks(codec);
@@ -14176,498 +4367,12 @@ static int patch_alc268(struct hda_codec *codec)
14176} 4367}
14177 4368
14178/* 4369/*
14179 * ALC269 channel source setting (2 channel) 4370 * ALC269
14180 */ 4371 */
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 4372#ifdef CONFIG_SND_HDA_POWER_SAVE
14662#define alc269_loopbacks alc880_loopbacks 4373#define alc269_loopbacks alc880_loopbacks
14663#endif 4374#endif
14664 4375
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 = { 4376static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14672 .substreams = 1, 4377 .substreams = 1,
14673 .channels_min = 2, 4378 .channels_min = 2,
@@ -14675,9 +4380,9 @@ static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14675 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ 4380 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14676 /* NID is set in alc_build_pcms */ 4381 /* NID is set in alc_build_pcms */
14677 .ops = { 4382 .ops = {
14678 .open = alc880_playback_pcm_open, 4383 .open = alc_playback_pcm_open,
14679 .prepare = alc880_playback_pcm_prepare, 4384 .prepare = alc_playback_pcm_prepare,
14680 .cleanup = alc880_playback_pcm_cleanup 4385 .cleanup = alc_playback_pcm_cleanup
14681 }, 4386 },
14682}; 4387};
14683 4388
@@ -14718,44 +4423,11 @@ static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14718} 4423}
14719#endif /* CONFIG_SND_HDA_POWER_SAVE */ 4424#endif /* CONFIG_SND_HDA_POWER_SAVE */
14720 4425
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 */ 4426/* different alc269-variants */
14752enum { 4427enum {
14753 ALC269_TYPE_NORMAL, 4428 ALC269_TYPE_ALC269VA,
14754 ALC269_TYPE_ALC258,
14755 ALC269_TYPE_ALC259,
14756 ALC269_TYPE_ALC269VB, 4429 ALC269_TYPE_ALC269VB,
14757 ALC269_TYPE_ALC270, 4430 ALC269_TYPE_ALC269VC,
14758 ALC269_TYPE_ALC271X,
14759}; 4431};
14760 4432
14761/* 4433/*
@@ -14763,76 +4435,14 @@ enum {
14763 */ 4435 */
14764static int alc269_parse_auto_config(struct hda_codec *codec) 4436static int alc269_parse_auto_config(struct hda_codec *codec)
14765{ 4437{
14766 struct alc_spec *spec = codec->spec;
14767 int err;
14768 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 4438 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14769 4439 static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 };
14770 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4440 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; 4441 struct alc_spec *spec = codec->spec;
14828 alc269_auto_init_multi_out(codec); 4442 const hda_nid_t *ssids = spec->codec_variant == ALC269_TYPE_ALC269VA ?
14829 alc269_auto_init_hp_out(codec); 4443 alc269va_ssids : alc269_ssids;
14830 alc269_auto_init_analog_input(codec); 4444
14831 if (!spec->dual_adc_switch) 4445 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} 4446}
14837 4447
14838static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) 4448static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
@@ -14855,7 +4465,7 @@ static void alc269_shutup(struct hda_codec *codec)
14855 } 4465 }
14856} 4466}
14857 4467
14858#ifdef SND_HDA_NEEDS_RESUME 4468#ifdef CONFIG_PM
14859static int alc269_resume(struct hda_codec *codec) 4469static int alc269_resume(struct hda_codec *codec)
14860{ 4470{
14861 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { 4471 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
@@ -14878,7 +4488,7 @@ static int alc269_resume(struct hda_codec *codec)
14878 hda_call_check_power_status(codec, 0x01); 4488 hda_call_check_power_status(codec, 0x01);
14879 return 0; 4489 return 0;
14880} 4490}
14881#endif /* SND_HDA_NEEDS_RESUME */ 4491#endif /* CONFIG_PM */
14882 4492
14883static void alc269_fixup_hweq(struct hda_codec *codec, 4493static void alc269_fixup_hweq(struct hda_codec *codec,
14884 const struct alc_fixup *fix, int action) 4494 const struct alc_fixup *fix, int action)
@@ -14908,6 +4518,37 @@ static void alc271_fixup_dmic(struct hda_codec *codec,
14908 snd_hda_sequence_write(codec, verbs); 4518 snd_hda_sequence_write(codec, verbs);
14909} 4519}
14910 4520
4521static void alc269_fixup_pcm_44k(struct hda_codec *codec,
4522 const struct alc_fixup *fix, int action)
4523{
4524 struct alc_spec *spec = codec->spec;
4525
4526 if (action != ALC_FIXUP_ACT_PROBE)
4527 return;
4528
4529 /* Due to a hardware problem on Lenovo Ideadpad, we need to
4530 * fix the sample rate of analog I/O to 44.1kHz
4531 */
4532 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
4533 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
4534}
4535
4536static void alc269_fixup_stereo_dmic(struct hda_codec *codec,
4537 const struct alc_fixup *fix, int action)
4538{
4539 int coef;
4540
4541 if (action != ALC_FIXUP_ACT_INIT)
4542 return;
4543 /* The digital-mic unit sends PDM (differential signal) instead of
4544 * the standard PCM, thus you can't record a valid mono stream as is.
4545 * Below is a workaround specific to ALC269 to control the dmic
4546 * signal source as mono.
4547 */
4548 coef = alc_read_coef_idx(codec, 0x07);
4549 alc_write_coef_idx(codec, 0x07, coef | 0x80);
4550}
4551
14911enum { 4552enum {
14912 ALC269_FIXUP_SONY_VAIO, 4553 ALC269_FIXUP_SONY_VAIO,
14913 ALC275_FIXUP_SONY_VAIO_GPIO2, 4554 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -14917,6 +4558,8 @@ enum {
14917 ALC269_FIXUP_LENOVO_EAPD, 4558 ALC269_FIXUP_LENOVO_EAPD,
14918 ALC275_FIXUP_SONY_HWEQ, 4559 ALC275_FIXUP_SONY_HWEQ,
14919 ALC271_FIXUP_DMIC, 4560 ALC271_FIXUP_DMIC,
4561 ALC269_FIXUP_PCM_44K,
4562 ALC269_FIXUP_STEREO_DMIC,
14920}; 4563};
14921 4564
14922static const struct alc_fixup alc269_fixups[] = { 4565static const struct alc_fixup alc269_fixups[] = {
@@ -14975,9 +4618,23 @@ static const struct alc_fixup alc269_fixups[] = {
14975 .type = ALC_FIXUP_FUNC, 4618 .type = ALC_FIXUP_FUNC,
14976 .v.func = alc271_fixup_dmic, 4619 .v.func = alc271_fixup_dmic,
14977 }, 4620 },
4621 [ALC269_FIXUP_PCM_44K] = {
4622 .type = ALC_FIXUP_FUNC,
4623 .v.func = alc269_fixup_pcm_44k,
4624 },
4625 [ALC269_FIXUP_STEREO_DMIC] = {
4626 .type = ALC_FIXUP_FUNC,
4627 .v.func = alc269_fixup_stereo_dmic,
4628 },
14978}; 4629};
14979 4630
14980static const struct snd_pci_quirk alc269_fixup_tbl[] = { 4631static const struct snd_pci_quirk alc269_fixup_tbl[] = {
4632 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
4633 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
4634 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
4635 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
4636 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
4637 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC),
14981 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), 4638 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14982 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4639 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14983 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 4640 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
@@ -14989,209 +4646,12 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14989 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 4646 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14990 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 4647 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14991 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 4648 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14992 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 4649 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
14993 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 4650 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14994 {} 4651 {}
14995}; 4652};
14996 4653
14997 4654
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) 4655static int alc269_fill_coef(struct hda_codec *codec)
15196{ 4656{
15197 int val; 4657 int val;
@@ -15234,6 +4694,12 @@ static int alc269_fill_coef(struct hda_codec *codec)
15234 return 0; 4694 return 0;
15235} 4695}
15236 4696
4697/*
4698 */
4699#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4700#include "alc269_quirks.c"
4701#endif
4702
15237static int patch_alc269(struct hda_codec *codec) 4703static int patch_alc269(struct hda_codec *codec)
15238{ 4704{
15239 struct alc_spec *spec; 4705 struct alc_spec *spec;
@@ -15246,116 +4712,105 @@ static int patch_alc269(struct hda_codec *codec)
15246 4712
15247 codec->spec = spec; 4713 codec->spec = spec;
15248 4714
4715 spec->mixer_nid = 0x0b;
4716
15249 alc_auto_parse_customize_define(codec); 4717 alc_auto_parse_customize_define(codec);
15250 4718
15251 if (codec->vendor_id == 0x10ec0269) { 4719 if (codec->vendor_id == 0x10ec0269) {
4720 spec->codec_variant = ALC269_TYPE_ALC269VA;
15252 coef = alc_read_coef_idx(codec, 0); 4721 coef = alc_read_coef_idx(codec, 0);
15253 if ((coef & 0x00f0) == 0x0010) { 4722 if ((coef & 0x00f0) == 0x0010) {
15254 if (codec->bus->pci->subsystem_vendor == 0x1025 && 4723 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15255 spec->cdefine.platform_type == 1) { 4724 spec->cdefine.platform_type == 1) {
15256 alc_codec_rename(codec, "ALC271X"); 4725 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) { 4726 } else if ((coef & 0xf000) == 0x2000) {
15261 alc_codec_rename(codec, "ALC259"); 4727 alc_codec_rename(codec, "ALC259");
15262 spec->codec_variant = ALC269_TYPE_ALC259;
15263 } else if ((coef & 0xf000) == 0x3000) { 4728 } else if ((coef & 0xf000) == 0x3000) {
15264 alc_codec_rename(codec, "ALC258"); 4729 alc_codec_rename(codec, "ALC258");
15265 spec->codec_variant = ALC269_TYPE_ALC258; 4730 } else if ((coef & 0xfff0) == 0x3010) {
4731 alc_codec_rename(codec, "ALC277");
15266 } else { 4732 } else {
15267 alc_codec_rename(codec, "ALC269VB"); 4733 alc_codec_rename(codec, "ALC269VB");
15268 spec->codec_variant = ALC269_TYPE_ALC269VB;
15269 } 4734 }
4735 spec->codec_variant = ALC269_TYPE_ALC269VB;
4736 } else if ((coef & 0x00f0) == 0x0020) {
4737 if (coef == 0xa023)
4738 alc_codec_rename(codec, "ALC259");
4739 else if (coef == 0x6023)
4740 alc_codec_rename(codec, "ALC281X");
4741 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
4742 codec->bus->pci->subsystem_device == 0x21f3)
4743 alc_codec_rename(codec, "ALC3202");
4744 else
4745 alc_codec_rename(codec, "ALC269VC");
4746 spec->codec_variant = ALC269_TYPE_ALC269VC;
15270 } else 4747 } else
15271 alc_fix_pll_init(codec, 0x20, 0x04, 15); 4748 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15272 alc269_fill_coef(codec); 4749 alc269_fill_coef(codec);
15273 } 4750 }
15274 4751
15275 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 4752 board_config = alc_board_config(codec, ALC269_MODEL_LAST,
15276 alc269_models, 4753 alc269_models, alc269_cfg_tbl);
15277 alc269_cfg_tbl);
15278 4754
15279 if (board_config < 0) { 4755 if (board_config < 0) {
15280 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4756 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15281 codec->chip_name); 4757 codec->chip_name);
15282 board_config = ALC269_AUTO; 4758 board_config = ALC_MODEL_AUTO;
15283 } 4759 }
15284 4760
15285 if (board_config == ALC269_AUTO) { 4761 if (board_config == ALC_MODEL_AUTO) {
15286 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 4762 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15287 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4763 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15288 } 4764 }
15289 4765
15290 if (board_config == ALC269_AUTO) { 4766 if (board_config == ALC_MODEL_AUTO) {
15291 /* automatic parse from the BIOS config */ 4767 /* automatic parse from the BIOS config */
15292 err = alc269_parse_auto_config(codec); 4768 err = alc269_parse_auto_config(codec);
15293 if (err < 0) { 4769 if (err < 0) {
15294 alc_free(codec); 4770 alc_free(codec);
15295 return err; 4771 return err;
15296 } else if (!err) { 4772 }
4773#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4774 else if (!err) {
15297 printk(KERN_INFO 4775 printk(KERN_INFO
15298 "hda_codec: Cannot set up configuration " 4776 "hda_codec: Cannot set up configuration "
15299 "from BIOS. Using base mode...\n"); 4777 "from BIOS. Using base mode...\n");
15300 board_config = ALC269_BASIC; 4778 board_config = ALC269_BASIC;
15301 } 4779 }
4780#endif
15302 } 4781 }
15303 4782
15304 if (has_cdefine_beep(codec)) { 4783 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]); 4784 setup_preset(codec, &alc269_presets[board_config]);
15314 4785
15315 if (board_config == ALC269_QUANTA_FL1) { 4786 if (!spec->no_analog && !spec->adc_nids) {
15316 /* Due to a hardware problem on Lenovo Ideadpad, we need to 4787 alc_auto_fill_adc_caps(codec);
15317 * fix the sample rate of analog I/O to 44.1kHz 4788 alc_rebuild_imux_for_auto_mic(codec);
15318 */ 4789 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 } 4790 }
15343 4791
15344 if (!spec->cap_mixer) 4792 if (!spec->no_analog && !spec->cap_mixer)
15345 set_capture_mixer(codec); 4793 set_capture_mixer(codec);
15346 if (has_cdefine_beep(codec)) 4794
4795 if (!spec->no_analog && has_cdefine_beep(codec)) {
4796 err = snd_hda_attach_beep_device(codec, 0x1);
4797 if (err < 0) {
4798 alc_free(codec);
4799 return err;
4800 }
15347 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 4801 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
4802 }
15348 4803
15349 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4804 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15350 4805
15351 spec->vmaster_nid = 0x02; 4806 spec->vmaster_nid = 0x02;
15352 4807
15353 codec->patch_ops = alc_patch_ops; 4808 codec->patch_ops = alc_patch_ops;
15354#ifdef SND_HDA_NEEDS_RESUME 4809#ifdef CONFIG_PM
15355 codec->patch_ops.resume = alc269_resume; 4810 codec->patch_ops.resume = alc269_resume;
15356#endif 4811#endif
15357 if (board_config == ALC269_AUTO) 4812 if (board_config == ALC_MODEL_AUTO)
15358 spec->init_hook = alc269_auto_init; 4813 spec->init_hook = alc_auto_init_std;
15359 spec->shutup = alc269_shutup; 4814 spec->shutup = alc269_shutup;
15360 4815
15361 alc_init_jacks(codec); 4816 alc_init_jacks(codec);
@@ -15370,883 +4825,14 @@ static int patch_alc269(struct hda_codec *codec)
15370} 4825}
15371 4826
15372/* 4827/*
15373 * ALC861 channel source setting (2/6 channel selection for 3-stack) 4828 * ALC861
15374 */ 4829 */
15375 4830
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 */
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
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) 4831static int alc861_parse_auto_config(struct hda_codec *codec)
16191{ 4832{
16192 struct alc_spec *spec = codec->spec;
16193 int err;
16194 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; 4833 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16195 4834 static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 };
16196 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4835 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} 4836}
16251 4837
16252#ifdef CONFIG_SND_HDA_POWER_SAVE 4838#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16260,155 +4846,10 @@ static const struct hda_amp_list alc861_loopbacks[] = {
16260#endif 4846#endif
16261 4847
16262 4848
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 */ 4849/* Pin config fixes */
16410enum { 4850enum {
16411 PINFIX_FSC_AMILO_PI1505, 4851 PINFIX_FSC_AMILO_PI1505,
4852 PINFIX_ASUS_A6RP,
16412}; 4853};
16413 4854
16414static const struct alc_fixup alc861_fixups[] = { 4855static const struct alc_fixup alc861_fixups[] = {
@@ -16420,13 +4861,29 @@ static const struct alc_fixup alc861_fixups[] = {
16420 { } 4861 { }
16421 } 4862 }
16422 }, 4863 },
4864 [PINFIX_ASUS_A6RP] = {
4865 .type = ALC_FIXUP_VERBS,
4866 .v.verbs = (const struct hda_verb[]) {
4867 /* node 0x0f VREF seems controlling the master output */
4868 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
4869 { }
4870 },
4871 },
16423}; 4872};
16424 4873
16425static const struct snd_pci_quirk alc861_fixup_tbl[] = { 4874static const struct snd_pci_quirk alc861_fixup_tbl[] = {
4875 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", PINFIX_ASUS_A6RP),
4876 SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", PINFIX_ASUS_A6RP),
16426 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), 4877 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16427 {} 4878 {}
16428}; 4879};
16429 4880
4881/*
4882 */
4883#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4884#include "alc861_quirks.c"
4885#endif
4886
16430static int patch_alc861(struct hda_codec *codec) 4887static int patch_alc861(struct hda_codec *codec)
16431{ 4888{
16432 struct alc_spec *spec; 4889 struct alc_spec *spec;
@@ -16439,61 +4896,67 @@ static int patch_alc861(struct hda_codec *codec)
16439 4896
16440 codec->spec = spec; 4897 codec->spec = spec;
16441 4898
16442 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 4899 spec->mixer_nid = 0x15;
16443 alc861_models, 4900
16444 alc861_cfg_tbl); 4901 board_config = alc_board_config(codec, ALC861_MODEL_LAST,
4902 alc861_models, alc861_cfg_tbl);
16445 4903
16446 if (board_config < 0) { 4904 if (board_config < 0) {
16447 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4905 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16448 codec->chip_name); 4906 codec->chip_name);
16449 board_config = ALC861_AUTO; 4907 board_config = ALC_MODEL_AUTO;
16450 } 4908 }
16451 4909
16452 if (board_config == ALC861_AUTO) { 4910 if (board_config == ALC_MODEL_AUTO) {
16453 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 4911 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16454 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4912 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16455 } 4913 }
16456 4914
16457 if (board_config == ALC861_AUTO) { 4915 if (board_config == ALC_MODEL_AUTO) {
16458 /* automatic parse from the BIOS config */ 4916 /* automatic parse from the BIOS config */
16459 err = alc861_parse_auto_config(codec); 4917 err = alc861_parse_auto_config(codec);
16460 if (err < 0) { 4918 if (err < 0) {
16461 alc_free(codec); 4919 alc_free(codec);
16462 return err; 4920 return err;
16463 } else if (!err) { 4921 }
4922#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4923 else if (!err) {
16464 printk(KERN_INFO 4924 printk(KERN_INFO
16465 "hda_codec: Cannot set up configuration " 4925 "hda_codec: Cannot set up configuration "
16466 "from BIOS. Using base mode...\n"); 4926 "from BIOS. Using base mode...\n");
16467 board_config = ALC861_3ST_DIG; 4927 board_config = ALC861_3ST_DIG;
16468 } 4928 }
4929#endif
16469 } 4930 }
16470 4931
16471 err = snd_hda_attach_beep_device(codec, 0x23); 4932 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]); 4933 setup_preset(codec, &alc861_presets[board_config]);
16479 4934
16480 spec->stream_analog_playback = &alc861_pcm_analog_playback; 4935 if (!spec->no_analog && !spec->adc_nids) {
16481 spec->stream_analog_capture = &alc861_pcm_analog_capture; 4936 alc_auto_fill_adc_caps(codec);
16482 4937 alc_rebuild_imux_for_auto_mic(codec);
16483 spec->stream_digital_playback = &alc861_pcm_digital_playback; 4938 alc_remove_invalid_adc_nids(codec);
16484 spec->stream_digital_capture = &alc861_pcm_digital_capture; 4939 }
16485 4940
16486 if (!spec->cap_mixer) 4941 if (!spec->no_analog && !spec->cap_mixer)
16487 set_capture_mixer(codec); 4942 set_capture_mixer(codec);
16488 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); 4943
4944 if (!spec->no_analog) {
4945 err = snd_hda_attach_beep_device(codec, 0x23);
4946 if (err < 0) {
4947 alc_free(codec);
4948 return err;
4949 }
4950 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
4951 }
16489 4952
16490 spec->vmaster_nid = 0x03; 4953 spec->vmaster_nid = 0x03;
16491 4954
16492 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 4955 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16493 4956
16494 codec->patch_ops = alc_patch_ops; 4957 codec->patch_ops = alc_patch_ops;
16495 if (board_config == ALC861_AUTO) { 4958 if (board_config == ALC_MODEL_AUTO) {
16496 spec->init_hook = alc861_auto_init; 4959 spec->init_hook = alc_auto_init_std;
16497#ifdef CONFIG_SND_HDA_POWER_SAVE 4960#ifdef CONFIG_SND_HDA_POWER_SAVE
16498 spec->power_hook = alc_power_eapd; 4961 spec->power_hook = alc_power_eapd;
16499#endif 4962#endif
@@ -16513,871 +4976,15 @@ static int patch_alc861(struct hda_codec *codec)
16513 * 4976 *
16514 * In addition, an independent DAC 4977 * In addition, an independent DAC
16515 */ 4978 */
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 4979#ifdef CONFIG_SND_HDA_POWER_SAVE
16961#define alc861vd_loopbacks alc880_loopbacks 4980#define alc861vd_loopbacks alc880_loopbacks
16962#endif 4981#endif
16963 4982
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) 4983static int alc861vd_parse_auto_config(struct hda_codec *codec)
17314{ 4984{
17315 struct alc_spec *spec = codec->spec;
17316 int err;
17317 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; 4985 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17318 4986 static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 };
17319 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 4987 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} 4988}
17382 4989
17383enum { 4990enum {
@@ -17402,6 +5009,18 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17402 {} 5009 {}
17403}; 5010};
17404 5011
5012static const struct hda_verb alc660vd_eapd_verbs[] = {
5013 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
5014 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5015 { }
5016};
5017
5018/*
5019 */
5020#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5021#include "alc861vd_quirks.c"
5022#endif
5023
17405static int patch_alc861vd(struct hda_codec *codec) 5024static int patch_alc861vd(struct hda_codec *codec)
17406{ 5025{
17407 struct alc_spec *spec; 5026 struct alc_spec *spec;
@@ -17413,42 +5032,40 @@ static int patch_alc861vd(struct hda_codec *codec)
17413 5032
17414 codec->spec = spec; 5033 codec->spec = spec;
17415 5034
17416 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 5035 spec->mixer_nid = 0x0b;
17417 alc861vd_models, 5036
17418 alc861vd_cfg_tbl); 5037 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
5038 alc861vd_models, alc861vd_cfg_tbl);
17419 5039
17420 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 5040 if (board_config < 0) {
17421 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5041 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17422 codec->chip_name); 5042 codec->chip_name);
17423 board_config = ALC861VD_AUTO; 5043 board_config = ALC_MODEL_AUTO;
17424 } 5044 }
17425 5045
17426 if (board_config == ALC861VD_AUTO) { 5046 if (board_config == ALC_MODEL_AUTO) {
17427 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 5047 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17428 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5048 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17429 } 5049 }
17430 5050
17431 if (board_config == ALC861VD_AUTO) { 5051 if (board_config == ALC_MODEL_AUTO) {
17432 /* automatic parse from the BIOS config */ 5052 /* automatic parse from the BIOS config */
17433 err = alc861vd_parse_auto_config(codec); 5053 err = alc861vd_parse_auto_config(codec);
17434 if (err < 0) { 5054 if (err < 0) {
17435 alc_free(codec); 5055 alc_free(codec);
17436 return err; 5056 return err;
17437 } else if (!err) { 5057 }
5058#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5059 else if (!err) {
17438 printk(KERN_INFO 5060 printk(KERN_INFO
17439 "hda_codec: Cannot set up configuration " 5061 "hda_codec: Cannot set up configuration "
17440 "from BIOS. Using base mode...\n"); 5062 "from BIOS. Using base mode...\n");
17441 board_config = ALC861VD_3ST; 5063 board_config = ALC861VD_3ST;
17442 } 5064 }
5065#endif
17443 } 5066 }
17444 5067
17445 err = snd_hda_attach_beep_device(codec, 0x23); 5068 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]); 5069 setup_preset(codec, &alc861vd_presets[board_config]);
17453 5070
17454 if (codec->vendor_id == 0x10ec0660) { 5071 if (codec->vendor_id == 0x10ec0660) {
@@ -17456,21 +5073,23 @@ static int patch_alc861vd(struct hda_codec *codec)
17456 add_verb(spec, alc660vd_eapd_verbs); 5073 add_verb(spec, alc660vd_eapd_verbs);
17457 } 5074 }
17458 5075
17459 spec->stream_analog_playback = &alc861vd_pcm_analog_playback; 5076 if (!spec->no_analog && !spec->adc_nids) {
17460 spec->stream_analog_capture = &alc861vd_pcm_analog_capture; 5077 alc_auto_fill_adc_caps(codec);
5078 alc_rebuild_imux_for_auto_mic(codec);
5079 alc_remove_invalid_adc_nids(codec);
5080 }
17461 5081
17462 spec->stream_digital_playback = &alc861vd_pcm_digital_playback; 5082 if (!spec->no_analog && !spec->cap_mixer)
17463 spec->stream_digital_capture = &alc861vd_pcm_digital_capture; 5083 set_capture_mixer(codec);
17464 5084
17465 if (!spec->adc_nids) { 5085 if (!spec->no_analog) {
17466 spec->adc_nids = alc861vd_adc_nids; 5086 err = snd_hda_attach_beep_device(codec, 0x23);
17467 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 5087 if (err < 0) {
5088 alc_free(codec);
5089 return err;
5090 }
5091 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17468 } 5092 }
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 5093
17475 spec->vmaster_nid = 0x02; 5094 spec->vmaster_nid = 0x02;
17476 5095
@@ -17478,8 +5097,8 @@ static int patch_alc861vd(struct hda_codec *codec)
17478 5097
17479 codec->patch_ops = alc_patch_ops; 5098 codec->patch_ops = alc_patch_ops;
17480 5099
17481 if (board_config == ALC861VD_AUTO) 5100 if (board_config == ALC_MODEL_AUTO)
17482 spec->init_hook = alc861vd_auto_init; 5101 spec->init_hook = alc_auto_init_std;
17483 spec->shutup = alc_eapd_shutup; 5102 spec->shutup = alc_eapd_shutup;
17484#ifdef CONFIG_SND_HDA_POWER_SAVE 5103#ifdef CONFIG_SND_HDA_POWER_SAVE
17485 if (!spec->loopback.amplist) 5104 if (!spec->loopback.amplist)
@@ -17500,1943 +5119,27 @@ static int patch_alc861vd(struct hda_codec *codec)
17500 * In addition, an independent DAC for the multi-playback (not used in this 5119 * In addition, an independent DAC for the multi-playback (not used in this
17501 * driver yet). 5120 * driver yet).
17502 */ 5121 */
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 5122#ifdef CONFIG_SND_HDA_POWER_SAVE
18453#define alc662_loopbacks alc880_loopbacks 5123#define alc662_loopbacks alc880_loopbacks
18454#endif 5124#endif
18455 5125
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/* 5126/*
18910 * BIOS auto configuration 5127 * BIOS auto configuration
18911 */ 5128 */
18912 5129
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) 5130static int alc662_parse_auto_config(struct hda_codec *codec)
19368{ 5131{
19369 struct alc_spec *spec = codec->spec;
19370 int err;
19371 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; 5132 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19372 5133 static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 };
19373 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 5134 static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 };
19374 alc662_ignore); 5135 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 5136
19420 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || 5137 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19421 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) 5138 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19422 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21); 5139 ssids = alc663_ssids;
19423 else 5140 else
19424 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 5141 ssids = alc662_ssids;
19425 5142 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} 5143}
19441 5144
19442static void alc272_fixup_mario(struct hda_codec *codec, 5145static void alc272_fixup_mario(struct hda_codec *codec,
@@ -19459,6 +5162,7 @@ enum {
19459 ALC272_FIXUP_MARIO, 5162 ALC272_FIXUP_MARIO,
19460 ALC662_FIXUP_CZC_P10T, 5163 ALC662_FIXUP_CZC_P10T,
19461 ALC662_FIXUP_SKU_IGNORE, 5164 ALC662_FIXUP_SKU_IGNORE,
5165 ALC662_FIXUP_HP_RP5800,
19462}; 5166};
19463 5167
19464static const struct alc_fixup alc662_fixups[] = { 5168static const struct alc_fixup alc662_fixups[] = {
@@ -19491,12 +5195,22 @@ static const struct alc_fixup alc662_fixups[] = {
19491 .type = ALC_FIXUP_SKU, 5195 .type = ALC_FIXUP_SKU,
19492 .v.sku = ALC_FIXUP_SKU_IGNORE, 5196 .v.sku = ALC_FIXUP_SKU_IGNORE,
19493 }, 5197 },
5198 [ALC662_FIXUP_HP_RP5800] = {
5199 .type = ALC_FIXUP_PINS,
5200 .v.pins = (const struct alc_pincfg[]) {
5201 { 0x14, 0x0221201f }, /* HP out */
5202 { }
5203 },
5204 .chained = true,
5205 .chain_id = ALC662_FIXUP_SKU_IGNORE
5206 },
19494}; 5207};
19495 5208
19496static const struct snd_pci_quirk alc662_fixup_tbl[] = { 5209static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19497 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 5210 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19498 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 5211 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19499 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 5212 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
5213 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
19500 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 5214 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19501 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 5215 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19502 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 5216 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
@@ -19510,6 +5224,12 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
19510}; 5224};
19511 5225
19512 5226
5227/*
5228 */
5229#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5230#include "alc662_quirks.c"
5231#endif
5232
19513static int patch_alc662(struct hda_codec *codec) 5233static int patch_alc662(struct hda_codec *codec)
19514{ 5234{
19515 struct alc_spec *spec; 5235 struct alc_spec *spec;
@@ -19522,6 +5242,8 @@ static int patch_alc662(struct hda_codec *codec)
19522 5242
19523 codec->spec = spec; 5243 codec->spec = spec;
19524 5244
5245 spec->mixer_nid = 0x0b;
5246
19525 alc_auto_parse_customize_define(codec); 5247 alc_auto_parse_customize_define(codec);
19526 5248
19527 alc_fix_pll_init(codec, 0x20, 0x04, 15); 5249 alc_fix_pll_init(codec, 0x20, 0x04, 15);
@@ -19536,16 +5258,15 @@ static int patch_alc662(struct hda_codec *codec)
19536 else if (coef == 0x4011) 5258 else if (coef == 0x4011)
19537 alc_codec_rename(codec, "ALC656"); 5259 alc_codec_rename(codec, "ALC656");
19538 5260
19539 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 5261 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
19540 alc662_models, 5262 alc662_models, alc662_cfg_tbl);
19541 alc662_cfg_tbl);
19542 if (board_config < 0) { 5263 if (board_config < 0) {
19543 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5264 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19544 codec->chip_name); 5265 codec->chip_name);
19545 board_config = ALC662_AUTO; 5266 board_config = ALC_MODEL_AUTO;
19546 } 5267 }
19547 5268
19548 if (board_config == ALC662_AUTO) { 5269 if (board_config == ALC_MODEL_AUTO) {
19549 alc_pick_fixup(codec, alc662_fixup_models, 5270 alc_pick_fixup(codec, alc662_fixup_models,
19550 alc662_fixup_tbl, alc662_fixups); 5271 alc662_fixup_tbl, alc662_fixups);
19551 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5272 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
@@ -19554,42 +5275,35 @@ static int patch_alc662(struct hda_codec *codec)
19554 if (err < 0) { 5275 if (err < 0) {
19555 alc_free(codec); 5276 alc_free(codec);
19556 return err; 5277 return err;
19557 } else if (!err) { 5278 }
5279#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5280 else if (!err) {
19558 printk(KERN_INFO 5281 printk(KERN_INFO
19559 "hda_codec: Cannot set up configuration " 5282 "hda_codec: Cannot set up configuration "
19560 "from BIOS. Using base mode...\n"); 5283 "from BIOS. Using base mode...\n");
19561 board_config = ALC662_3ST_2ch_DIG; 5284 board_config = ALC662_3ST_2ch_DIG;
19562 } 5285 }
5286#endif
19563 } 5287 }
19564 5288
19565 if (has_cdefine_beep(codec)) { 5289 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]); 5290 setup_preset(codec, &alc662_presets[board_config]);
19575 5291
19576 spec->stream_analog_playback = &alc662_pcm_analog_playback; 5292 if (!spec->no_analog && !spec->adc_nids) {
19577 spec->stream_analog_capture = &alc662_pcm_analog_capture; 5293 alc_auto_fill_adc_caps(codec);
19578 5294 alc_rebuild_imux_for_auto_mic(codec);
19579 spec->stream_digital_playback = &alc662_pcm_digital_playback; 5295 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 } 5296 }
19586 if (!spec->capsrc_nids)
19587 spec->capsrc_nids = alc662_capsrc_nids;
19588 5297
19589 if (!spec->cap_mixer) 5298 if (!spec->no_analog && !spec->cap_mixer)
19590 set_capture_mixer(codec); 5299 set_capture_mixer(codec);
19591 5300
19592 if (has_cdefine_beep(codec)) { 5301 if (!spec->no_analog && has_cdefine_beep(codec)) {
5302 err = snd_hda_attach_beep_device(codec, 0x1);
5303 if (err < 0) {
5304 alc_free(codec);
5305 return err;
5306 }
19593 switch (codec->vendor_id) { 5307 switch (codec->vendor_id) {
19594 case 0x10ec0662: 5308 case 0x10ec0662:
19595 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 5309 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
@@ -19609,8 +5323,8 @@ static int patch_alc662(struct hda_codec *codec)
19609 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5323 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19610 5324
19611 codec->patch_ops = alc_patch_ops; 5325 codec->patch_ops = alc_patch_ops;
19612 if (board_config == ALC662_AUTO) 5326 if (board_config == ALC_MODEL_AUTO)
19613 spec->init_hook = alc662_auto_init; 5327 spec->init_hook = alc_auto_init_std;
19614 spec->shutup = alc_eapd_shutup; 5328 spec->shutup = alc_eapd_shutup;
19615 5329
19616 alc_init_jacks(codec); 5330 alc_init_jacks(codec);
@@ -19652,389 +5366,17 @@ static int patch_alc899(struct hda_codec *codec)
19652/* 5366/*
19653 * ALC680 support 5367 * ALC680 support
19654 */ 5368 */
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
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 5369
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) 5370static int alc680_parse_auto_config(struct hda_codec *codec)
19956{ 5371{
19957 struct alc_spec *spec = codec->spec; 5372 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} 5373}
20008 5374
20009/* 5375/*
20010 * configuration and preset
20011 */ 5376 */
20012static const char * const alc680_models[ALC680_MODEL_LAST] = { 5377#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
20013 [ALC680_BASE] = "base", 5378#include "alc680_quirks.c"
20014 [ALC680_AUTO] = "auto", 5379#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 5380
20039static int patch_alc680(struct hda_codec *codec) 5381static int patch_alc680(struct hda_codec *codec)
20040{ 5382{
@@ -20048,51 +5390,55 @@ static int patch_alc680(struct hda_codec *codec)
20048 5390
20049 codec->spec = spec; 5391 codec->spec = spec;
20050 5392
20051 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 5393 /* ALC680 has no aa-loopback mixer */
20052 alc680_models,
20053 alc680_cfg_tbl);
20054 5394
20055 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 5395 board_config = alc_board_config(codec, ALC680_MODEL_LAST,
5396 alc680_models, alc680_cfg_tbl);
5397
5398 if (board_config < 0) {
20056 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5399 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20057 codec->chip_name); 5400 codec->chip_name);
20058 board_config = ALC680_AUTO; 5401 board_config = ALC_MODEL_AUTO;
20059 } 5402 }
20060 5403
20061 if (board_config == ALC680_AUTO) { 5404 if (board_config == ALC_MODEL_AUTO) {
20062 /* automatic parse from the BIOS config */ 5405 /* automatic parse from the BIOS config */
20063 err = alc680_parse_auto_config(codec); 5406 err = alc680_parse_auto_config(codec);
20064 if (err < 0) { 5407 if (err < 0) {
20065 alc_free(codec); 5408 alc_free(codec);
20066 return err; 5409 return err;
20067 } else if (!err) { 5410 }
5411#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5412 else if (!err) {
20068 printk(KERN_INFO 5413 printk(KERN_INFO
20069 "hda_codec: Cannot set up configuration " 5414 "hda_codec: Cannot set up configuration "
20070 "from BIOS. Using base mode...\n"); 5415 "from BIOS. Using base mode...\n");
20071 board_config = ALC680_BASE; 5416 board_config = ALC680_BASE;
20072 } 5417 }
5418#endif
20073 } 5419 }
20074 5420
20075 if (board_config != ALC680_AUTO) 5421 if (board_config != ALC_MODEL_AUTO) {
20076 setup_preset(codec, &alc680_presets[board_config]); 5422 setup_preset(codec, &alc680_presets[board_config]);
5423#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5424 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
5425#endif
5426 }
20077 5427
20078 spec->stream_analog_playback = &alc680_pcm_analog_playback; 5428 if (!spec->no_analog && !spec->adc_nids) {
20079 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 5429 alc_auto_fill_adc_caps(codec);
20080 spec->stream_digital_playback = &alc680_pcm_digital_playback; 5430 alc_rebuild_imux_for_auto_mic(codec);
20081 spec->stream_digital_capture = &alc680_pcm_digital_capture; 5431 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 } 5432 }
20087 5433
20088 if (!spec->cap_mixer) 5434 if (!spec->no_analog && !spec->cap_mixer)
20089 set_capture_mixer(codec); 5435 set_capture_mixer(codec);
20090 5436
20091 spec->vmaster_nid = 0x02; 5437 spec->vmaster_nid = 0x02;
20092 5438
20093 codec->patch_ops = alc_patch_ops; 5439 codec->patch_ops = alc_patch_ops;
20094 if (board_config == ALC680_AUTO) 5440 if (board_config == ALC_MODEL_AUTO)
20095 spec->init_hook = alc680_auto_init; 5441 spec->init_hook = alc_auto_init_std;
20096 5442
20097 return 0; 5443 return 0;
20098} 5444}
@@ -20120,6 +5466,8 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20120 .patch = patch_alc882 }, 5466 .patch = patch_alc882 },
20121 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 5467 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20122 .patch = patch_alc662 }, 5468 .patch = patch_alc662 },
5469 { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3",
5470 .patch = patch_alc662 },
20123 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 5471 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20124 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, 5472 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20125 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, 5473 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7f81cc2274f..d23379ef9e5 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -94,7 +94,9 @@ enum {
94 STAC_92HD83XXX_REF, 94 STAC_92HD83XXX_REF,
95 STAC_92HD83XXX_PWR_REF, 95 STAC_92HD83XXX_PWR_REF,
96 STAC_DELL_S14, 96 STAC_DELL_S14,
97 STAC_DELL_VOSTRO_3500,
97 STAC_92HD83XXX_HP, 98 STAC_92HD83XXX_HP,
99 STAC_92HD83XXX_HP_cNB11_INTQUAD,
98 STAC_HP_DV7_4000, 100 STAC_HP_DV7_4000,
99 STAC_92HD83XXX_MODELS 101 STAC_92HD83XXX_MODELS
100}; 102};
@@ -212,6 +214,8 @@ struct sigmatel_spec {
212 unsigned int gpio_mute; 214 unsigned int gpio_mute;
213 unsigned int gpio_led; 215 unsigned int gpio_led;
214 unsigned int gpio_led_polarity; 216 unsigned int gpio_led_polarity;
217 unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */
218 unsigned int vref_led;
215 219
216 /* stream */ 220 /* stream */
217 unsigned int stream_delay; 221 unsigned int stream_delay;
@@ -671,6 +675,32 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
671 return 0; 675 return 0;
672} 676}
673 677
678#ifdef CONFIG_SND_HDA_POWER_SAVE
679static int stac_vrefout_set(struct hda_codec *codec,
680 hda_nid_t nid, unsigned int new_vref)
681{
682 int error, pinctl;
683
684 snd_printdd("%s, nid %x ctl %x\n", __func__, nid, new_vref);
685 pinctl = snd_hda_codec_read(codec, nid, 0,
686 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
687
688 if (pinctl < 0)
689 return pinctl;
690
691 pinctl &= 0xff;
692 pinctl &= ~AC_PINCTL_VREFEN;
693 pinctl |= (new_vref & AC_PINCTL_VREFEN);
694
695 error = snd_hda_codec_write_cache(codec, nid, 0,
696 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
697 if (error < 0)
698 return error;
699
700 return 1;
701}
702#endif
703
674static unsigned int stac92xx_vref_set(struct hda_codec *codec, 704static unsigned int stac92xx_vref_set(struct hda_codec *codec,
675 hda_nid_t nid, unsigned int new_vref) 705 hda_nid_t nid, unsigned int new_vref)
676{ 706{
@@ -1112,7 +1142,9 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1112 } 1142 }
1113 1143
1114 if (spec->multiout.dig_out_nid) { 1144 if (spec->multiout.dig_out_nid) {
1115 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 1145 err = snd_hda_create_spdif_out_ctls(codec,
1146 spec->multiout.dig_out_nid,
1147 spec->multiout.dig_out_nid);
1116 if (err < 0) 1148 if (err < 0)
1117 return err; 1149 return err;
1118 err = snd_hda_create_spdif_share_sw(codec, 1150 err = snd_hda_create_spdif_share_sw(codec,
@@ -1628,16 +1660,30 @@ static const unsigned int dell_s14_pin_configs[10] = {
1628 0x40f000f0, 0x40f000f0, 1660 0x40f000f0, 0x40f000f0,
1629}; 1661};
1630 1662
1663static const unsigned int dell_vostro_3500_pin_configs[10] = {
1664 0x02a11020, 0x0221101f, 0x400000f0, 0x90170110,
1665 0x400000f1, 0x400000f2, 0x400000f3, 0x90a60160,
1666 0x400000f4, 0x400000f5,
1667};
1668
1631static const unsigned int hp_dv7_4000_pin_configs[10] = { 1669static const unsigned int hp_dv7_4000_pin_configs[10] = {
1632 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 1670 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110,
1633 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 1671 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140,
1634 0x40f000f0, 0x40f000f0, 1672 0x40f000f0, 0x40f000f0,
1635}; 1673};
1636 1674
1675static const unsigned int hp_cNB11_intquad_pin_configs[10] = {
1676 0x40f000f0, 0x0221101f, 0x02a11020, 0x92170110,
1677 0x40f000f0, 0x92170110, 0x40f000f0, 0xd5a30130,
1678 0x40f000f0, 0x40f000f0,
1679};
1680
1637static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { 1681static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1638 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, 1682 [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs,
1639 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, 1683 [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs,
1640 [STAC_DELL_S14] = dell_s14_pin_configs, 1684 [STAC_DELL_S14] = dell_s14_pin_configs,
1685 [STAC_DELL_VOSTRO_3500] = dell_vostro_3500_pin_configs,
1686 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = hp_cNB11_intquad_pin_configs,
1641 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1687 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1642}; 1688};
1643 1689
@@ -1646,7 +1692,9 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1646 [STAC_92HD83XXX_REF] = "ref", 1692 [STAC_92HD83XXX_REF] = "ref",
1647 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1693 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
1648 [STAC_DELL_S14] = "dell-s14", 1694 [STAC_DELL_S14] = "dell-s14",
1695 [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500",
1649 [STAC_92HD83XXX_HP] = "hp", 1696 [STAC_92HD83XXX_HP] = "hp",
1697 [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad",
1650 [STAC_HP_DV7_4000] = "hp-dv7-4000", 1698 [STAC_HP_DV7_4000] = "hp-dv7-4000",
1651}; 1699};
1652 1700
@@ -1658,8 +1706,50 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1658 "DFI LanParty", STAC_92HD83XXX_REF), 1706 "DFI LanParty", STAC_92HD83XXX_REF),
1659 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, 1707 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba,
1660 "unknown Dell", STAC_DELL_S14), 1708 "unknown Dell", STAC_DELL_S14),
1709 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028,
1710 "Dell Vostro 3500", STAC_DELL_VOSTRO_3500),
1661 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, 1711 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600,
1662 "HP", STAC_92HD83XXX_HP), 1712 "HP", STAC_92HD83XXX_HP),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656,
1714 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657,
1716 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1658,
1718 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1719 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1659,
1720 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1721 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165A,
1722 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1723 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x165B,
1724 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1725 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3388,
1726 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1727 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3389,
1728 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1729 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355B,
1730 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1731 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355C,
1732 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1733 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355D,
1734 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355E,
1736 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x355F,
1738 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1739 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3560,
1740 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1741 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358B,
1742 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1743 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358C,
1744 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1745 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x358D,
1746 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1747 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3591,
1748 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1749 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3592,
1750 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1751 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3593,
1752 "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD),
1663 {} /* terminator */ 1753 {} /* terminator */
1664}; 1754};
1665 1755
@@ -3406,30 +3496,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3406 return 0; 3496 return 0;
3407} 3497}
3408 3498
3409static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3499/* look for NID recursively */
3410 hda_nid_t nid) 3500#define get_connection_index(codec, mux, nid) \
3411{ 3501 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 3502
3434/* create a volume assigned to the given pin (only if supported) */ 3503/* create a volume assigned to the given pin (only if supported) */
3435/* return 1 if the volume control is created */ 3504/* return 1 if the volume control is created */
@@ -4039,6 +4108,8 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
4039{ 4108{
4040 unsigned int gpiostate, gpiomask, gpiodir; 4109 unsigned int gpiostate, gpiomask, gpiodir;
4041 4110
4111 snd_printdd("%s msk %x dir %x gpio %x\n", __func__, mask, dir_mask, data);
4112
4042 gpiostate = snd_hda_codec_read(codec, codec->afg, 0, 4113 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
4043 AC_VERB_GET_GPIO_DATA, 0); 4114 AC_VERB_GET_GPIO_DATA, 0);
4044 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask); 4115 gpiostate = (gpiostate & ~dir_mask) | (data & dir_mask);
@@ -4162,13 +4233,15 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4162 return 1; 4233 return 1;
4163} 4234}
4164 4235
4165static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 4236static int is_nid_out_jack_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
4166{ 4237{
4167 int i; 4238 int i;
4168 for (i = 0; i < cfg->hp_outs; i++) 4239 for (i = 0; i < cfg->hp_outs; i++)
4169 if (cfg->hp_pins[i] == nid) 4240 if (cfg->hp_pins[i] == nid)
4170 return 1; /* nid is a HP-Out */ 4241 return 1; /* nid is a HP-Out */
4171 4242 for (i = 0; i < cfg->line_outs; i++)
4243 if (cfg->line_out_pins[i] == nid)
4244 return 1; /* nid is a line-Out */
4172 return 0; /* nid is not a HP-Out */ 4245 return 0; /* nid is not a HP-Out */
4173}; 4246};
4174 4247
@@ -4235,6 +4308,27 @@ static void stac_store_hints(struct hda_codec *codec)
4235 } 4308 }
4236} 4309}
4237 4310
4311static void stac_issue_unsol_events(struct hda_codec *codec, int num_pins,
4312 const hda_nid_t *pins)
4313{
4314 while (num_pins--)
4315 stac_issue_unsol_event(codec, *pins++);
4316}
4317
4318/* fake event to set up pins */
4319static void stac_fake_hp_events(struct hda_codec *codec)
4320{
4321 struct sigmatel_spec *spec = codec->spec;
4322
4323 if (spec->autocfg.hp_outs)
4324 stac_issue_unsol_events(codec, spec->autocfg.hp_outs,
4325 spec->autocfg.hp_pins);
4326 if (spec->autocfg.line_outs &&
4327 spec->autocfg.line_out_pins[0] != spec->autocfg.hp_pins[0])
4328 stac_issue_unsol_events(codec, spec->autocfg.line_outs,
4329 spec->autocfg.line_out_pins);
4330}
4331
4238static int stac92xx_init(struct hda_codec *codec) 4332static int stac92xx_init(struct hda_codec *codec)
4239{ 4333{
4240 struct sigmatel_spec *spec = codec->spec; 4334 struct sigmatel_spec *spec = codec->spec;
@@ -4285,10 +4379,7 @@ static int stac92xx_init(struct hda_codec *codec)
4285 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 4379 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
4286 AC_PINCTL_OUT_EN); 4380 AC_PINCTL_OUT_EN);
4287 /* fake event to set up pins */ 4381 /* fake event to set up pins */
4288 if (cfg->hp_pins[0]) 4382 stac_fake_hp_events(codec);
4289 stac_issue_unsol_event(codec, cfg->hp_pins[0]);
4290 else if (cfg->line_out_pins[0])
4291 stac_issue_unsol_event(codec, cfg->line_out_pins[0]);
4292 } else { 4383 } else {
4293 stac92xx_auto_init_multi_out(codec); 4384 stac92xx_auto_init_multi_out(codec);
4294 stac92xx_auto_init_hp_out(codec); 4385 stac92xx_auto_init_hp_out(codec);
@@ -4354,7 +4445,7 @@ static int stac92xx_init(struct hda_codec *codec)
4354 continue; 4445 continue;
4355 } 4446 }
4356 4447
4357 if (is_nid_hp_pin(cfg, nid)) 4448 if (is_nid_out_jack_pin(cfg, nid))
4358 continue; /* already has an unsol event */ 4449 continue; /* already has an unsol event */
4359 4450
4360 pinctl = snd_hda_codec_read(codec, nid, 0, 4451 pinctl = snd_hda_codec_read(codec, nid, 0,
@@ -4401,11 +4492,26 @@ static void stac92xx_free_kctls(struct hda_codec *codec)
4401 snd_array_free(&spec->kctls); 4492 snd_array_free(&spec->kctls);
4402} 4493}
4403 4494
4495static void stac92xx_shutup_pins(struct hda_codec *codec)
4496{
4497 unsigned int i, def_conf;
4498
4499 if (codec->bus->shutdown)
4500 return;
4501 for (i = 0; i < codec->init_pins.used; i++) {
4502 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
4503 def_conf = snd_hda_codec_get_pincfg(codec, pin->nid);
4504 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
4505 snd_hda_codec_write(codec, pin->nid, 0,
4506 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4507 }
4508}
4509
4404static void stac92xx_shutup(struct hda_codec *codec) 4510static void stac92xx_shutup(struct hda_codec *codec)
4405{ 4511{
4406 struct sigmatel_spec *spec = codec->spec; 4512 struct sigmatel_spec *spec = codec->spec;
4407 4513
4408 snd_hda_shutup_pins(codec); 4514 stac92xx_shutup_pins(codec);
4409 4515
4410 if (spec->eapd_mask) 4516 if (spec->eapd_mask)
4411 stac_gpio_set(codec, spec->gpio_mask, 4517 stac_gpio_set(codec, spec->gpio_mask,
@@ -4803,10 +4909,17 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4803 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) { 4909 if ((codec->subsystem_id >> 16) == PCI_VENDOR_ID_HP) {
4804 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, 4910 while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING,
4805 NULL, dev))) { 4911 NULL, dev))) {
4806 if (sscanf(dev->name, "HP_Mute_LED_%d_%d", 4912 if (sscanf(dev->name, "HP_Mute_LED_%d_%x",
4807 &spec->gpio_led_polarity, 4913 &spec->gpio_led_polarity,
4808 &spec->gpio_led) == 2) { 4914 &spec->gpio_led) == 2) {
4809 spec->gpio_led = 1 << spec->gpio_led; 4915 unsigned int max_gpio;
4916 max_gpio = snd_hda_param_read(codec, codec->afg,
4917 AC_PAR_GPIO_CAP);
4918 max_gpio &= AC_GPIO_IO_COUNT;
4919 if (spec->gpio_led < max_gpio)
4920 spec->gpio_led = 1 << spec->gpio_led;
4921 else
4922 spec->vref_mute_led_nid = spec->gpio_led;
4810 return 1; 4923 return 1;
4811 } 4924 }
4812 if (sscanf(dev->name, "HP_Mute_LED_%d", 4925 if (sscanf(dev->name, "HP_Mute_LED_%d",
@@ -4904,45 +5017,72 @@ static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4904#define stac927x_proc_hook NULL 5017#define stac927x_proc_hook NULL
4905#endif 5018#endif
4906 5019
4907#ifdef SND_HDA_NEEDS_RESUME 5020#ifdef CONFIG_PM
4908static int stac92xx_resume(struct hda_codec *codec) 5021static int stac92xx_resume(struct hda_codec *codec)
4909{ 5022{
4910 struct sigmatel_spec *spec = codec->spec;
4911
4912 stac92xx_init(codec); 5023 stac92xx_init(codec);
4913 snd_hda_codec_resume_amp(codec); 5024 snd_hda_codec_resume_amp(codec);
4914 snd_hda_codec_resume_cache(codec); 5025 snd_hda_codec_resume_cache(codec);
4915 /* fake event to set up pins again to override cached values */ 5026 /* fake event to set up pins again to override cached values */
4916 if (spec->hp_detect) { 5027 stac_fake_hp_events(codec);
4917 if (spec->autocfg.hp_pins[0]) 5028 return 0;
4918 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]); 5029}
4919 else if (spec->autocfg.line_out_pins[0]) 5030
4920 stac_issue_unsol_event(codec, 5031static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4921 spec->autocfg.line_out_pins[0]); 5032{
4922 } 5033 stac92xx_shutup(codec);
5034 return 0;
5035}
5036
5037#ifdef CONFIG_SND_HDA_POWER_SAVE
5038static int stac92xx_pre_resume(struct hda_codec *codec)
5039{
5040 struct sigmatel_spec *spec = codec->spec;
5041
4923 /* sync mute LED */ 5042 /* sync mute LED */
4924 if (spec->gpio_led) 5043 if (spec->vref_mute_led_nid)
4925 hda_call_check_power_status(codec, 0x01); 5044 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5045 spec->vref_led);
5046 else if (spec->gpio_led)
5047 stac_gpio_set(codec, spec->gpio_mask,
5048 spec->gpio_dir, spec->gpio_data);
4926 return 0; 5049 return 0;
4927} 5050}
4928 5051
5052static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg,
5053 unsigned int power_state)
5054{
5055 unsigned int afg_power_state = power_state;
5056 struct sigmatel_spec *spec = codec->spec;
5057
5058 if (power_state == AC_PWRST_D3) {
5059 if (spec->vref_mute_led_nid) {
5060 /* with vref-out pin used for mute led control
5061 * codec AFG is prevented from D3 state
5062 */
5063 afg_power_state = AC_PWRST_D1;
5064 }
5065 /* this delay seems necessary to avoid click noise at power-down */
5066 msleep(100);
5067 }
5068 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
5069 afg_power_state);
5070 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
5071}
5072
4929/* 5073/*
4930 * using power check for controlling mute led of HP notebooks 5074 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed
4931 * check for mute state only on Speakers (nid = 0x10) 5075 * as mute LED state is updated in check_power_status hook
4932 *
4933 * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise
4934 * the LED is NOT working properly !
4935 *
4936 * Changed name to reflect that it now works for any designated
4937 * model, not just HP HDX.
4938 */ 5076 */
4939 5077static int stac92xx_update_led_status(struct hda_codec *codec)
4940#ifdef CONFIG_SND_HDA_POWER_SAVE
4941static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4942 hda_nid_t nid)
4943{ 5078{
4944 struct sigmatel_spec *spec = codec->spec; 5079 struct sigmatel_spec *spec = codec->spec;
4945 int i, muted = 1; 5080 int i, num_ext_dacs, muted = 1;
5081 unsigned int muted_lvl, notmtd_lvl;
5082 hda_nid_t nid;
5083
5084 if (!spec->gpio_led)
5085 return 0;
4946 5086
4947 for (i = 0; i < spec->multiout.num_dacs; i++) { 5087 for (i = 0; i < spec->multiout.num_dacs; i++) {
4948 nid = spec->multiout.dac_nids[i]; 5088 nid = spec->multiout.dac_nids[i];
@@ -4952,27 +5092,59 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4952 break; 5092 break;
4953 } 5093 }
4954 } 5094 }
4955 if (muted) 5095 if (muted && spec->multiout.hp_nid)
4956 spec->gpio_data &= ~spec->gpio_led; /* orange */ 5096 if (!(snd_hda_codec_amp_read(codec,
4957 else 5097 spec->multiout.hp_nid, 0, HDA_OUTPUT, 0) &
4958 spec->gpio_data |= spec->gpio_led; /* white */ 5098 HDA_AMP_MUTE)) {
4959 5099 muted = 0; /* HP is not muted */
4960 if (!spec->gpio_led_polarity) { 5100 }
4961 /* LED state is inverted on these systems */ 5101 num_ext_dacs = ARRAY_SIZE(spec->multiout.extra_out_nid);
4962 spec->gpio_data ^= spec->gpio_led; 5102 for (i = 0; muted && i < num_ext_dacs; i++) {
5103 nid = spec->multiout.extra_out_nid[i];
5104 if (nid == 0)
5105 break;
5106 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
5107 HDA_AMP_MUTE)) {
5108 muted = 0; /* extra output is not muted */
5109 }
4963 } 5110 }
5111 /*polarity defines *not* muted state level*/
5112 if (!spec->vref_mute_led_nid) {
5113 if (muted)
5114 spec->gpio_data &= ~spec->gpio_led; /* orange */
5115 else
5116 spec->gpio_data |= spec->gpio_led; /* white */
4964 5117
4965 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 5118 if (!spec->gpio_led_polarity) {
5119 /* LED state is inverted on these systems */
5120 spec->gpio_data ^= spec->gpio_led;
5121 }
5122 stac_gpio_set(codec, spec->gpio_mask,
5123 spec->gpio_dir, spec->gpio_data);
5124 } else {
5125 notmtd_lvl = spec->gpio_led_polarity ?
5126 AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_GRD;
5127 muted_lvl = spec->gpio_led_polarity ?
5128 AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ;
5129 spec->vref_led = muted ? muted_lvl : notmtd_lvl;
5130 stac_vrefout_set(codec, spec->vref_mute_led_nid,
5131 spec->vref_led);
5132 }
4966 return 0; 5133 return 0;
4967} 5134}
4968#endif
4969 5135
4970static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 5136/*
5137 * use power check for controlling mute led of HP notebooks
5138 */
5139static int stac92xx_check_power_status(struct hda_codec *codec,
5140 hda_nid_t nid)
4971{ 5141{
4972 stac92xx_shutup(codec); 5142 stac92xx_update_led_status(codec);
5143
4973 return 0; 5144 return 0;
4974} 5145}
4975#endif 5146#endif /* CONFIG_SND_HDA_POWER_SAVE */
5147#endif /* CONFIG_PM */
4976 5148
4977static const struct hda_codec_ops stac92xx_patch_ops = { 5149static const struct hda_codec_ops stac92xx_patch_ops = {
4978 .build_controls = stac92xx_build_controls, 5150 .build_controls = stac92xx_build_controls,
@@ -4980,7 +5152,7 @@ static const struct hda_codec_ops stac92xx_patch_ops = {
4980 .init = stac92xx_init, 5152 .init = stac92xx_init,
4981 .free = stac92xx_free, 5153 .free = stac92xx_free,
4982 .unsol_event = stac92xx_unsol_event, 5154 .unsol_event = stac92xx_unsol_event,
4983#ifdef SND_HDA_NEEDS_RESUME 5155#ifdef CONFIG_PM
4984 .suspend = stac92xx_suspend, 5156 .suspend = stac92xx_suspend,
4985 .resume = stac92xx_resume, 5157 .resume = stac92xx_resume,
4986#endif 5158#endif
@@ -5425,9 +5597,7 @@ static void stac92hd8x_fill_auto_spec(struct hda_codec *codec)
5425static int patch_stac92hd83xxx(struct hda_codec *codec) 5597static int patch_stac92hd83xxx(struct hda_codec *codec)
5426{ 5598{
5427 struct sigmatel_spec *spec; 5599 struct sigmatel_spec *spec;
5428 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5429 int err; 5600 int err;
5430 int num_dacs;
5431 5601
5432 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5602 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5433 if (spec == NULL) 5603 if (spec == NULL)
@@ -5467,25 +5637,8 @@ again:
5467 stac92xx_set_config_regs(codec, 5637 stac92xx_set_config_regs(codec,
5468 stac92hd83xxx_brd_tbl[spec->board_config]); 5638 stac92hd83xxx_brd_tbl[spec->board_config]);
5469 5639
5470 switch (codec->vendor_id) { 5640 if (spec->board_config != STAC_92HD83XXX_PWR_REF)
5471 case 0x111d76d1:
5472 case 0x111d76d9:
5473 case 0x111d76e5:
5474 case 0x111d7666:
5475 case 0x111d7667:
5476 case 0x111d7668:
5477 case 0x111d7669:
5478 case 0x111d76e3:
5479 case 0x111d7604:
5480 case 0x111d76d4:
5481 case 0x111d7605:
5482 case 0x111d76d5:
5483 case 0x111d76e7:
5484 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
5485 break;
5486 spec->num_pwrs = 0; 5641 spec->num_pwrs = 0;
5487 break;
5488 }
5489 5642
5490 codec->patch_ops = stac92xx_patch_ops; 5643 codec->patch_ops = stac92xx_patch_ops;
5491 5644
@@ -5496,16 +5649,25 @@ again:
5496 5649
5497#ifdef CONFIG_SND_HDA_POWER_SAVE 5650#ifdef CONFIG_SND_HDA_POWER_SAVE
5498 if (spec->gpio_led) { 5651 if (spec->gpio_led) {
5499 spec->gpio_mask |= spec->gpio_led; 5652 if (!spec->vref_mute_led_nid) {
5500 spec->gpio_dir |= spec->gpio_led; 5653 spec->gpio_mask |= spec->gpio_led;
5501 spec->gpio_data |= spec->gpio_led; 5654 spec->gpio_dir |= spec->gpio_led;
5502 /* register check_power_status callback. */ 5655 spec->gpio_data |= spec->gpio_led;
5656 } else {
5657 codec->patch_ops.set_power_state =
5658 stac92xx_set_power_state;
5659 }
5660 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5503 codec->patch_ops.check_power_status = 5661 codec->patch_ops.check_power_status =
5504 stac92xx_hp_check_power_status; 5662 stac92xx_check_power_status;
5505 } 5663 }
5506#endif 5664#endif
5507 5665
5508 err = stac92xx_parse_auto_config(codec, 0x1d, 0); 5666 /* 92HD65/66 series has S/PDIF-IN */
5667 if (codec->vendor_id >= 0x111d76e8 && codec->vendor_id <= 0x111d76f3)
5668 err = stac92xx_parse_auto_config(codec, 0x1d, 0x22);
5669 else
5670 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
5509 if (!err) { 5671 if (!err) {
5510 if (spec->board_config < 0) { 5672 if (spec->board_config < 0) {
5511 printk(KERN_WARNING "hda_codec: No auto-config is " 5673 printk(KERN_WARNING "hda_codec: No auto-config is "
@@ -5521,22 +5683,6 @@ again:
5521 return err; 5683 return err;
5522 } 5684 }
5523 5685
5524 /* docking output support */
5525 num_dacs = snd_hda_get_connections(codec, 0xF,
5526 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5527 /* skip non-DAC connections */
5528 while (num_dacs >= 0 &&
5529 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5530 != AC_WID_AUD_OUT))
5531 num_dacs--;
5532 /* set port E and F to select the last DAC */
5533 if (num_dacs >= 0) {
5534 snd_hda_codec_write_cache(codec, 0xE, 0,
5535 AC_VERB_SET_CONNECT_SEL, num_dacs);
5536 snd_hda_codec_write_cache(codec, 0xF, 0,
5537 AC_VERB_SET_CONNECT_SEL, num_dacs);
5538 }
5539
5540 codec->proc_widget_hook = stac92hd_proc_hook; 5686 codec->proc_widget_hook = stac92hd_proc_hook;
5541 5687
5542 return 0; 5688 return 0;
@@ -5824,12 +5970,17 @@ again:
5824 5970
5825#ifdef CONFIG_SND_HDA_POWER_SAVE 5971#ifdef CONFIG_SND_HDA_POWER_SAVE
5826 if (spec->gpio_led) { 5972 if (spec->gpio_led) {
5827 spec->gpio_mask |= spec->gpio_led; 5973 if (!spec->vref_mute_led_nid) {
5828 spec->gpio_dir |= spec->gpio_led; 5974 spec->gpio_mask |= spec->gpio_led;
5829 spec->gpio_data |= spec->gpio_led; 5975 spec->gpio_dir |= spec->gpio_led;
5830 /* register check_power_status callback. */ 5976 spec->gpio_data |= spec->gpio_led;
5977 } else {
5978 codec->patch_ops.set_power_state =
5979 stac92xx_set_power_state;
5980 }
5981 codec->patch_ops.pre_resume = stac92xx_pre_resume;
5831 codec->patch_ops.check_power_status = 5982 codec->patch_ops.check_power_status =
5832 stac92xx_hp_check_power_status; 5983 stac92xx_check_power_status;
5833 } 5984 }
5834#endif 5985#endif
5835 5986
@@ -6399,10 +6550,23 @@ static const struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6399 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx }, 6550 { .id = 0x111d76cc, .name = "92HD89F3", .patch = patch_stac92hd73xx },
6400 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx }, 6551 { .id = 0x111d76cd, .name = "92HD89F2", .patch = patch_stac92hd73xx },
6401 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx }, 6552 { .id = 0x111d76ce, .name = "92HD89F1", .patch = patch_stac92hd73xx },
6553 { .id = 0x111d76df, .name = "92HD93BXX", .patch = patch_stac92hd83xxx},
6402 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx}, 6554 { .id = 0x111d76e0, .name = "92HD91BXX", .patch = patch_stac92hd83xxx},
6403 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx}, 6555 { .id = 0x111d76e3, .name = "92HD98BXX", .patch = patch_stac92hd83xxx},
6404 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx}, 6556 { .id = 0x111d76e5, .name = "92HD99BXX", .patch = patch_stac92hd83xxx},
6405 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx}, 6557 { .id = 0x111d76e7, .name = "92HD90BXX", .patch = patch_stac92hd83xxx},
6558 { .id = 0x111d76e8, .name = "92HD66B1X5", .patch = patch_stac92hd83xxx},
6559 { .id = 0x111d76e9, .name = "92HD66B2X5", .patch = patch_stac92hd83xxx},
6560 { .id = 0x111d76ea, .name = "92HD66B3X5", .patch = patch_stac92hd83xxx},
6561 { .id = 0x111d76eb, .name = "92HD66C1X5", .patch = patch_stac92hd83xxx},
6562 { .id = 0x111d76ec, .name = "92HD66C2X5", .patch = patch_stac92hd83xxx},
6563 { .id = 0x111d76ed, .name = "92HD66C3X5", .patch = patch_stac92hd83xxx},
6564 { .id = 0x111d76ee, .name = "92HD66B1X3", .patch = patch_stac92hd83xxx},
6565 { .id = 0x111d76ef, .name = "92HD66B2X3", .patch = patch_stac92hd83xxx},
6566 { .id = 0x111d76f0, .name = "92HD66B3X3", .patch = patch_stac92hd83xxx},
6567 { .id = 0x111d76f1, .name = "92HD66C1X3", .patch = patch_stac92hd83xxx},
6568 { .id = 0x111d76f2, .name = "92HD66C2X3", .patch = patch_stac92hd83xxx},
6569 { .id = 0x111d76f3, .name = "92HD66C3/65", .patch = patch_stac92hd83xxx},
6406 {} /* terminator */ 6570 {} /* terminator */
6407}; 6571};
6408 6572
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index f43bb0eaed8..c3babe3c239 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,39 @@ 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 hp_work_active;
211 int vt1708_jack_detect;
162 int vt1708_hp_present; 212 int vt1708_hp_present;
163 213
164 void (*set_widgets_power_state)(struct hda_codec *codec); 214 void (*set_widgets_power_state)(struct hda_codec *codec);
165 215
166#ifdef CONFIG_SND_HDA_POWER_SAVE
167 struct hda_loopback_check loopback; 216 struct hda_loopback_check loopback;
168#endif 217 int num_loopbacks;
218 struct hda_amp_list loopback_list[8];
219
220 /* bind capture-volume */
221 struct hda_bind_ctls *bind_cap_vol;
222 struct hda_bind_ctls *bind_cap_sw;
223
224 struct mutex config_mutex;
169}; 225};
170 226
171static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec); 227static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
@@ -177,6 +233,7 @@ static struct via_spec * via_new_spec(struct hda_codec *codec)
177 if (spec == NULL) 233 if (spec == NULL)
178 return NULL; 234 return NULL;
179 235
236 mutex_init(&spec->config_mutex);
180 codec->spec = spec; 237 codec->spec = spec;
181 spec->codec = codec; 238 spec->codec = codec;
182 spec->codec_type = get_codec_type(codec); 239 spec->codec_type = get_codec_type(codec);
@@ -237,48 +294,46 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec)
237#define VIA_JACK_EVENT 0x20 294#define VIA_JACK_EVENT 0x20
238#define VIA_HP_EVENT 0x01 295#define VIA_HP_EVENT 0x01
239#define VIA_GPIO_EVENT 0x02 296#define VIA_GPIO_EVENT 0x02
240#define VIA_MONO_EVENT 0x03 297#define VIA_LINE_EVENT 0x03
241#define VIA_SPEAKER_EVENT 0x04
242#define VIA_BIND_HP_EVENT 0x05
243 298
244enum { 299enum {
245 VIA_CTL_WIDGET_VOL, 300 VIA_CTL_WIDGET_VOL,
246 VIA_CTL_WIDGET_MUTE, 301 VIA_CTL_WIDGET_MUTE,
247 VIA_CTL_WIDGET_ANALOG_MUTE, 302 VIA_CTL_WIDGET_ANALOG_MUTE,
248 VIA_CTL_WIDGET_BIND_PIN_MUTE,
249}; 303};
250 304
251enum { 305static void analog_low_current_mode(struct hda_codec *codec);
252 AUTO_SEQ_FRONT = 0, 306static bool is_aa_path_mute(struct hda_codec *codec);
253 AUTO_SEQ_SURROUND,
254 AUTO_SEQ_CENLFE,
255 AUTO_SEQ_SIDE
256};
257 307
258static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); 308#define hp_detect_with_aa(codec) \
259static int is_aa_path_mute(struct hda_codec *codec); 309 (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \
310 !is_aa_path_mute(codec))
260 311
261static void vt1708_start_hp_work(struct via_spec *spec) 312static void vt1708_stop_hp_work(struct via_spec *spec)
262{ 313{
263 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 314 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
264 return; 315 return;
265 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 316 if (spec->hp_work_active) {
266 !spec->vt1708_jack_detectect); 317 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1);
267 if (!delayed_work_pending(&spec->vt1708_hp_work)) 318 cancel_delayed_work_sync(&spec->vt1708_hp_work);
268 schedule_delayed_work(&spec->vt1708_hp_work, 319 spec->hp_work_active = 0;
269 msecs_to_jiffies(100)); 320 }
270} 321}
271 322
272static void vt1708_stop_hp_work(struct via_spec *spec) 323static void vt1708_update_hp_work(struct via_spec *spec)
273{ 324{
274 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) 325 if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0)
275 return; 326 return;
276 if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 327 if (spec->vt1708_jack_detect &&
277 && !is_aa_path_mute(spec->codec)) 328 (spec->active_streams || hp_detect_with_aa(spec->codec))) {
278 return; 329 if (!spec->hp_work_active) {
279 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 330 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0);
280 !spec->vt1708_jack_detectect); 331 schedule_delayed_work(&spec->vt1708_hp_work,
281 cancel_delayed_work_sync(&spec->vt1708_hp_work); 332 msecs_to_jiffies(100));
333 spec->hp_work_active = 1;
334 }
335 } else if (!hp_detect_with_aa(spec->codec))
336 vt1708_stop_hp_work(spec);
282} 337}
283 338
284static void set_widgets_power_state(struct hda_codec *codec) 339static void set_widgets_power_state(struct hda_codec *codec)
@@ -295,13 +350,8 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
295 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 350 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
296 351
297 set_widgets_power_state(codec); 352 set_widgets_power_state(codec);
298 analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); 353 analog_low_current_mode(snd_kcontrol_chip(kcontrol));
299 if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { 354 vt1708_update_hp_work(codec->spec);
300 if (is_aa_path_mute(codec))
301 vt1708_start_hp_work(codec->spec);
302 else
303 vt1708_stop_hp_work(codec->spec);
304 }
305 return change; 355 return change;
306} 356}
307 357
@@ -315,168 +365,44 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol,
315 .put = analog_input_switch_put, \ 365 .put = analog_input_switch_put, \
316 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } 366 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) }
317 367
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[] = { 368static const struct snd_kcontrol_new via_control_templates[] = {
414 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 369 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
415 HDA_CODEC_MUTE(NULL, 0, 0, 0), 370 HDA_CODEC_MUTE(NULL, 0, 0, 0),
416 ANALOG_INPUT_MUTE, 371 ANALOG_INPUT_MUTE,
417 BIND_PIN_MUTE,
418};
419
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
430static const hda_nid_t vt1708B_adc_nids[2] = {
431 /* ADC1-2 */
432 0x13, 0x14
433};
434
435static const hda_nid_t vt1708S_adc_nids[2] = {
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}; 372};
454 373
455static const hda_nid_t vt2002P_adc_nids[2] = {
456 /* ADC1-2 */
457 0x10, 0x11
458};
459 374
460static const hda_nid_t vt1812_adc_nids[2] = { 375/* add dynamic controls */
461 /* ADC1-2 */ 376static struct snd_kcontrol_new *__via_clone_ctl(struct via_spec *spec,
462 0x10, 0x11 377 const struct snd_kcontrol_new *tmpl,
463}; 378 const char *name)
379{
380 struct snd_kcontrol_new *knew;
464 381
382 snd_array_init(&spec->kctls, sizeof(*knew), 32);
383 knew = snd_array_new(&spec->kctls);
384 if (!knew)
385 return NULL;
386 *knew = *tmpl;
387 if (!name)
388 name = tmpl->name;
389 if (name) {
390 knew->name = kstrdup(name, GFP_KERNEL);
391 if (!knew->name)
392 return NULL;
393 }
394 return knew;
395}
465 396
466/* add dynamic controls */
467static int __via_add_control(struct via_spec *spec, int type, const char *name, 397static int __via_add_control(struct via_spec *spec, int type, const char *name,
468 int idx, unsigned long val) 398 int idx, unsigned long val)
469{ 399{
470 struct snd_kcontrol_new *knew; 400 struct snd_kcontrol_new *knew;
471 401
472 snd_array_init(&spec->kctls, sizeof(*knew), 32); 402 knew = __via_clone_ctl(spec, &via_control_templates[type], name);
473 knew = snd_array_new(&spec->kctls);
474 if (!knew) 403 if (!knew)
475 return -ENOMEM; 404 return -ENOMEM;
476 *knew = via_control_templates[type]; 405 knew->index = idx;
477 knew->name = kstrdup(name, GFP_KERNEL);
478 if (!knew->name)
479 return -ENOMEM;
480 if (get_amp_nid_(val)) 406 if (get_amp_nid_(val))
481 knew->subdevice = HDA_SUBDEV_AMP_FLAG; 407 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
482 knew->private_value = val; 408 knew->private_value = val;
@@ -486,21 +412,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name,
486#define via_add_control(spec, type, name, val) \ 412#define via_add_control(spec, type, name, val) \
487 __via_add_control(spec, type, name, 0, val) 413 __via_add_control(spec, type, name, 0, val)
488 414
489static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, 415#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 416
505static void via_free_kctls(struct hda_codec *codec) 417static void via_free_kctls(struct hda_codec *codec)
506{ 418{
@@ -535,58 +447,208 @@ static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
535 return 0; 447 return 0;
536} 448}
537 449
538static void via_auto_set_output_and_unmute(struct hda_codec *codec, 450#define get_connection_index(codec, mux, nid) \
539 hda_nid_t nid, int pin_type, 451 snd_hda_get_conn_index(codec, mux, nid, 0)
540 int dac_idx) 452
453static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
454 unsigned int mask)
541{ 455{
542 /* set as output */ 456 unsigned int caps;
543 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 457 if (!nid)
458 return false;
459 caps = get_wcaps(codec, nid);
460 if (dir == HDA_INPUT)
461 caps &= AC_WCAP_IN_AMP;
462 else
463 caps &= AC_WCAP_OUT_AMP;
464 if (!caps)
465 return false;
466 if (query_amp_caps(codec, nid, dir) & mask)
467 return true;
468 return false;
469}
470
471#define have_mute(codec, nid, dir) \
472 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
473
474/* enable/disable the output-route mixers */
475static void activate_output_mix(struct hda_codec *codec, struct nid_path *path,
476 hda_nid_t mix_nid, int idx, bool enable)
477{
478 int i, num, val;
479
480 if (!path)
481 return;
482 num = snd_hda_get_conn_list(codec, mix_nid, NULL);
483 for (i = 0; i < num; i++) {
484 if (i == idx)
485 val = AMP_IN_UNMUTE(i);
486 else
487 val = AMP_IN_MUTE(i);
488 snd_hda_codec_write(codec, mix_nid, 0,
489 AC_VERB_SET_AMP_GAIN_MUTE, val);
490 }
491}
492
493/* enable/disable the output-route */
494static void activate_output_path(struct hda_codec *codec, struct nid_path *path,
495 bool enable, bool force)
496{
497 struct via_spec *spec = codec->spec;
498 int i;
499 for (i = 0; i < path->depth; i++) {
500 hda_nid_t src, dst;
501 int idx = path->idx[i];
502 src = path->path[i];
503 if (i < path->depth - 1)
504 dst = path->path[i + 1];
505 else
506 dst = 0;
507 if (enable && path->multi[i])
508 snd_hda_codec_write(codec, dst, 0,
509 AC_VERB_SET_CONNECT_SEL, idx);
510 if (!force && (dst == spec->aa_mix_nid))
511 continue;
512 if (have_mute(codec, dst, HDA_INPUT))
513 activate_output_mix(codec, path, dst, idx, enable);
514 if (!force && (src == path->vol_ctl || src == path->mute_ctl))
515 continue;
516 if (have_mute(codec, src, HDA_OUTPUT)) {
517 int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE;
518 snd_hda_codec_write(codec, src, 0,
519 AC_VERB_SET_AMP_GAIN_MUTE, val);
520 }
521 }
522}
523
524/* set the given pin as output */
525static void init_output_pin(struct hda_codec *codec, hda_nid_t pin,
526 int pin_type)
527{
528 if (!pin)
529 return;
530 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
544 pin_type); 531 pin_type);
545 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 532 if (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD)
546 AMP_OUT_UNMUTE); 533 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); 534 AC_VERB_SET_EAPD_BTLENABLE, 0x02);
550} 535}
551 536
537static void via_auto_init_output(struct hda_codec *codec,
538 struct nid_path *path, int pin_type)
539{
540 unsigned int caps;
541 hda_nid_t pin;
542
543 if (!path->depth)
544 return;
545 pin = path->path[path->depth - 1];
546
547 init_output_pin(codec, pin, pin_type);
548 caps = query_amp_caps(codec, pin, HDA_OUTPUT);
549 if (caps & AC_AMPCAP_MUTE) {
550 unsigned int val;
551 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
552 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
553 AMP_OUT_MUTE | val);
554 }
555 activate_output_path(codec, path, true, true); /* force on */
556}
552 557
553static void via_auto_init_multi_out(struct hda_codec *codec) 558static void via_auto_init_multi_out(struct hda_codec *codec)
554{ 559{
555 struct via_spec *spec = codec->spec; 560 struct via_spec *spec = codec->spec;
561 struct nid_path *path;
556 int i; 562 int i;
557 563
558 for (i = 0; i <= AUTO_SEQ_SIDE; i++) { 564 for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) {
559 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 565 path = &spec->out_path[i];
560 if (nid) 566 if (!i && spec->aamix_mode && spec->out_mix_path.depth)
561 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); 567 path = &spec->out_mix_path;
568 via_auto_init_output(codec, path, PIN_OUT);
569 }
570}
571
572/* deactivate the inactive headphone-paths */
573static void deactivate_hp_paths(struct hda_codec *codec)
574{
575 struct via_spec *spec = codec->spec;
576 int shared = spec->hp_indep_shared;
577
578 if (spec->hp_independent_mode) {
579 activate_output_path(codec, &spec->hp_path, false, false);
580 activate_output_path(codec, &spec->hp_mix_path, false, false);
581 if (shared)
582 activate_output_path(codec, &spec->out_path[shared],
583 false, false);
584 } else if (spec->aamix_mode || !spec->hp_path.depth) {
585 activate_output_path(codec, &spec->hp_indep_path, false, false);
586 activate_output_path(codec, &spec->hp_path, false, false);
587 } else {
588 activate_output_path(codec, &spec->hp_indep_path, false, false);
589 activate_output_path(codec, &spec->hp_mix_path, false, false);
562 } 590 }
563} 591}
564 592
565static void via_auto_init_hp_out(struct hda_codec *codec) 593static void via_auto_init_hp_out(struct hda_codec *codec)
566{ 594{
567 struct via_spec *spec = codec->spec; 595 struct via_spec *spec = codec->spec;
568 hda_nid_t pin;
569 int i;
570 596
571 for (i = 0; i < spec->autocfg.hp_outs; i++) { 597 if (!spec->hp_path.depth) {
572 pin = spec->autocfg.hp_pins[i]; 598 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
573 if (pin) /* connect to front */ 599 return;
574 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
575 } 600 }
601 deactivate_hp_paths(codec);
602 if (spec->hp_independent_mode)
603 via_auto_init_output(codec, &spec->hp_indep_path, PIN_HP);
604 else if (spec->aamix_mode)
605 via_auto_init_output(codec, &spec->hp_mix_path, PIN_HP);
606 else
607 via_auto_init_output(codec, &spec->hp_path, PIN_HP);
576} 608}
577 609
578static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin); 610static void via_auto_init_speaker_out(struct hda_codec *codec)
611{
612 struct via_spec *spec = codec->spec;
613
614 if (!spec->autocfg.speaker_outs)
615 return;
616 if (!spec->speaker_path.depth) {
617 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
618 return;
619 }
620 if (!spec->aamix_mode) {
621 activate_output_path(codec, &spec->speaker_mix_path,
622 false, false);
623 via_auto_init_output(codec, &spec->speaker_path, PIN_OUT);
624 } else {
625 activate_output_path(codec, &spec->speaker_path, false, false);
626 via_auto_init_output(codec, &spec->speaker_mix_path, PIN_OUT);
627 }
628}
629
630static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin);
631static void via_hp_automute(struct hda_codec *codec);
579 632
580static void via_auto_init_analog_input(struct hda_codec *codec) 633static void via_auto_init_analog_input(struct hda_codec *codec)
581{ 634{
582 struct via_spec *spec = codec->spec; 635 struct via_spec *spec = codec->spec;
583 const struct auto_pin_cfg *cfg = &spec->autocfg; 636 const struct auto_pin_cfg *cfg = &spec->autocfg;
637 hda_nid_t conn[HDA_MAX_CONNECTIONS];
584 unsigned int ctl; 638 unsigned int ctl;
585 int i; 639 int i, num_conns;
586 640
641 /* init ADCs */
642 for (i = 0; i < spec->num_adc_nids; i++) {
643 snd_hda_codec_write(codec, spec->adc_nids[i], 0,
644 AC_VERB_SET_AMP_GAIN_MUTE,
645 AMP_IN_UNMUTE(0));
646 }
647
648 /* init pins */
587 for (i = 0; i < cfg->num_inputs; i++) { 649 for (i = 0; i < cfg->num_inputs; i++) {
588 hda_nid_t nid = cfg->inputs[i].pin; 650 hda_nid_t nid = cfg->inputs[i].pin;
589 if (spec->smart51_enabled && is_smart51_pins(spec, nid)) 651 if (spec->smart51_enabled && is_smart51_pins(codec, nid))
590 ctl = PIN_OUT; 652 ctl = PIN_OUT;
591 else if (cfg->inputs[i].type == AUTO_PIN_MIC) 653 else if (cfg->inputs[i].type == AUTO_PIN_MIC)
592 ctl = PIN_VREF50; 654 ctl = PIN_VREF50;
@@ -595,6 +657,32 @@ static void via_auto_init_analog_input(struct hda_codec *codec)
595 snd_hda_codec_write(codec, nid, 0, 657 snd_hda_codec_write(codec, nid, 0,
596 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl); 658 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
597 } 659 }
660
661 /* init input-src */
662 for (i = 0; i < spec->num_adc_nids; i++) {
663 int adc_idx = spec->inputs[spec->cur_mux[i]].adc_idx;
664 if (spec->mux_nids[adc_idx]) {
665 int mux_idx = spec->inputs[spec->cur_mux[i]].mux_idx;
666 snd_hda_codec_write(codec, spec->mux_nids[adc_idx], 0,
667 AC_VERB_SET_CONNECT_SEL,
668 mux_idx);
669 }
670 if (spec->dyn_adc_switch)
671 break; /* only one input-src */
672 }
673
674 /* init aa-mixer */
675 if (!spec->aa_mix_nid)
676 return;
677 num_conns = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
678 ARRAY_SIZE(conn));
679 for (i = 0; i < num_conns; i++) {
680 unsigned int caps = get_wcaps(codec, conn[i]);
681 if (get_wcaps_type(caps) == AC_WID_PIN)
682 snd_hda_codec_write(codec, spec->aa_mix_nid, 0,
683 AC_VERB_SET_AMP_GAIN_MUTE,
684 AMP_IN_MUTE(i));
685 }
598} 686}
599 687
600static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, 688static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
@@ -605,9 +693,13 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid,
605 unsigned no_presence = (def_conf & AC_DEFCFG_MISC) 693 unsigned no_presence = (def_conf & AC_DEFCFG_MISC)
606 >> AC_DEFCFG_MISC_SHIFT 694 >> AC_DEFCFG_MISC_SHIFT
607 & AC_DEFCFG_MISC_NO_PRESENCE; /* do not support pin sense */ 695 & 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; 696 struct via_spec *spec = codec->spec;
610 if ((spec->smart51_enabled && is_smart51_pins(spec, nid)) 697 unsigned present = 0;
698
699 no_presence |= spec->no_pin_power_ctl;
700 if (!no_presence)
701 present = snd_hda_jack_detect(codec, nid);
702 if ((spec->smart51_enabled && is_smart51_pins(codec, nid))
611 || ((no_presence || present) 703 || ((no_presence || present)
612 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) { 704 && get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)) {
613 *affected_parm = AC_PWRST_D0; /* if it's connected */ 705 *affected_parm = AC_PWRST_D0; /* if it's connected */
@@ -618,124 +710,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); 710 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm);
619} 711}
620 712
621/* 713static int via_pin_power_ctl_info(struct snd_kcontrol *kcontrol,
622 * input MUX handling 714 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{ 715{
627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 716 static const char * const texts[] = {
628 struct via_spec *spec = codec->spec; 717 "Disabled", "Enabled"
629 return snd_hda_input_mux_info(spec->input_mux, uinfo); 718 };
719
720 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
721 uinfo->count = 1;
722 uinfo->value.enumerated.items = 2;
723 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
724 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
725 strcpy(uinfo->value.enumerated.name,
726 texts[uinfo->value.enumerated.item]);
727 return 0;
630} 728}
631 729
632static int via_mux_enum_get(struct snd_kcontrol *kcontrol, 730static int via_pin_power_ctl_get(struct snd_kcontrol *kcontrol,
633 struct snd_ctl_elem_value *ucontrol) 731 struct snd_ctl_elem_value *ucontrol)
634{ 732{
635 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 733 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
636 struct via_spec *spec = codec->spec; 734 struct via_spec *spec = codec->spec;
637 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 735 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; 736 return 0;
641} 737}
642 738
643static int via_mux_enum_put(struct snd_kcontrol *kcontrol, 739static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol) 740 struct snd_ctl_elem_value *ucontrol)
645{ 741{
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 struct via_spec *spec = codec->spec; 743 struct via_spec *spec = codec->spec;
648 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 744 unsigned int val = !ucontrol->value.enumerated.item[0];
649 int ret;
650 745
651 if (!spec->mux_nids[adc_idx]) 746 if (val == spec->no_pin_power_ctl)
652 return -EINVAL; 747 return 0;
653 /* switch to D0 beofre change index */ 748 spec->no_pin_power_ctl = val;
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
659 ret = snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
660 spec->mux_nids[adc_idx],
661 &spec->cur_mux[adc_idx]);
662 /* update jack power state */
663 set_widgets_power_state(codec); 749 set_widgets_power_state(codec);
664 750 return 1;
665 return ret;
666} 751}
667 752
753static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
754 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
755 .name = "Dynamic Power-Control",
756 .info = via_pin_power_ctl_info,
757 .get = via_pin_power_ctl_get,
758 .put = via_pin_power_ctl_put,
759};
760
761
668static int via_independent_hp_info(struct snd_kcontrol *kcontrol, 762static int via_independent_hp_info(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_info *uinfo) 763 struct snd_ctl_elem_info *uinfo)
670{ 764{
671 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 765 static const char * const texts[] = { "OFF", "ON" };
672 struct via_spec *spec = codec->spec; 766
673 return snd_hda_input_mux_info(spec->hp_mux, uinfo); 767 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
768 uinfo->count = 1;
769 uinfo->value.enumerated.items = 2;
770 if (uinfo->value.enumerated.item >= 2)
771 uinfo->value.enumerated.item = 1;
772 strcpy(uinfo->value.enumerated.name,
773 texts[uinfo->value.enumerated.item]);
774 return 0;
674} 775}
675 776
676static int via_independent_hp_get(struct snd_kcontrol *kcontrol, 777static int via_independent_hp_get(struct snd_kcontrol *kcontrol,
677 struct snd_ctl_elem_value *ucontrol) 778 struct snd_ctl_elem_value *ucontrol)
678{ 779{
679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 780 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
680 hda_nid_t nid = kcontrol->private_value; 781 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 782
783 ucontrol->value.enumerated.item[0] = spec->hp_independent_mode;
689 return 0; 784 return 0;
690} 785}
691 786
692static void activate_ctl(struct hda_codec *codec, const char *name, int active) 787/* adjust spec->multiout setup according to the current flags */
788static void setup_playback_multi_pcm(struct via_spec *spec)
693{ 789{
694 struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); 790 const struct auto_pin_cfg *cfg = &spec->autocfg;
695 if (ctl) { 791 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
696 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 792 spec->multiout.hp_nid = 0;
697 ctl->vd[0].access |= active 793 if (!spec->hp_independent_mode) {
698 ? 0 : SNDRV_CTL_ELEM_ACCESS_INACTIVE; 794 if (!spec->hp_indep_shared)
699 snd_ctl_notify(codec->bus->card, 795 spec->multiout.hp_nid = spec->hp_dac_nid;
700 SNDRV_CTL_EVENT_MASK_VALUE, &ctl->id); 796 } else {
701 } 797 if (spec->hp_indep_shared)
702} 798 spec->multiout.num_dacs = cfg->line_outs - 1;
703
704static hda_nid_t side_mute_channel(struct via_spec *spec)
705{
706 switch (spec->codec_type) {
707 case VT1708: return 0x1b;
708 case VT1709_10CH: return 0x29;
709 case VT1708B_8CH: /* fall thru */
710 case VT1708S: return 0x27;
711 case VT2002P: return 0x19;
712 case VT1802: return 0x15;
713 case VT1812: return 0x15;
714 default: return 0;
715 } 799 }
716} 800}
717 801
718static int update_side_mute_status(struct hda_codec *codec) 802/* update DAC setups according to indep-HP switch;
803 * this function is called only when indep-HP is modified
804 */
805static void switch_indep_hp_dacs(struct hda_codec *codec)
719{ 806{
720 /* mute side channel */
721 struct via_spec *spec = codec->spec; 807 struct via_spec *spec = codec->spec;
722 unsigned int parm; 808 int shared = spec->hp_indep_shared;
723 hda_nid_t sw3 = side_mute_channel(spec); 809 hda_nid_t shared_dac, hp_dac;
724 810
725 if (sw3) { 811 if (!spec->opened_streams)
726 if (VT2002P_COMPATIBLE(spec)) 812 return;
727 parm = spec->hp_independent_mode ? 813
728 AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); 814 shared_dac = shared ? spec->multiout.dac_nids[shared] : 0;
729 else 815 hp_dac = spec->hp_dac_nid;
730 parm = spec->hp_independent_mode ? 816 if (spec->hp_independent_mode) {
731 AMP_OUT_MUTE : AMP_OUT_UNMUTE; 817 /* switch to indep-HP mode */
732 snd_hda_codec_write(codec, sw3, 0, 818 if (spec->active_streams & STREAM_MULTI_OUT) {
733 AC_VERB_SET_AMP_GAIN_MUTE, parm); 819 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
734 if (spec->codec_type == VT1812) 820 __snd_hda_codec_cleanup_stream(codec, shared_dac, 1);
735 snd_hda_codec_write(codec, 0x1d, 0, 821 }
736 AC_VERB_SET_AMP_GAIN_MUTE, parm); 822 if (spec->active_streams & STREAM_INDEP_HP)
823 snd_hda_codec_setup_stream(codec, hp_dac,
824 spec->cur_hp_stream_tag, 0,
825 spec->cur_hp_format);
826 } else {
827 /* back to HP or shared-DAC */
828 if (spec->active_streams & STREAM_INDEP_HP)
829 __snd_hda_codec_cleanup_stream(codec, hp_dac, 1);
830 if (spec->active_streams & STREAM_MULTI_OUT) {
831 hda_nid_t dac;
832 int ch;
833 if (shared_dac) { /* reset mutli-ch DAC */
834 dac = shared_dac;
835 ch = shared * 2;
836 } else { /* reset HP DAC */
837 dac = hp_dac;
838 ch = 0;
839 }
840 snd_hda_codec_setup_stream(codec, dac,
841 spec->cur_dac_stream_tag, ch,
842 spec->cur_dac_format);
843 }
737 } 844 }
738 return 0; 845 setup_playback_multi_pcm(spec);
739} 846}
740 847
741static int via_independent_hp_put(struct snd_kcontrol *kcontrol, 848static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
@@ -743,66 +850,46 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol,
743{ 850{
744 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 851 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
745 struct via_spec *spec = codec->spec; 852 struct via_spec *spec = codec->spec;
746 hda_nid_t nid = kcontrol->private_value; 853 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 854
769 if (spec->codec_type == VT1812) 855 mutex_lock(&spec->config_mutex);
770 snd_hda_codec_write(codec, 0x35, 0, 856 cur = !!ucontrol->value.enumerated.item[0];
771 AC_VERB_SET_CONNECT_SEL, pinsel); 857 if (spec->hp_independent_mode == cur) {
772 if (spec->multiout.hp_nid && spec->multiout.hp_nid 858 mutex_unlock(&spec->config_mutex);
773 != spec->multiout.dac_nids[HDA_FRONT]) 859 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 } 860 }
861 spec->hp_independent_mode = cur;
862 shared = spec->hp_indep_shared;
863 deactivate_hp_paths(codec);
864 if (cur)
865 activate_output_path(codec, &spec->hp_indep_path, true, false);
866 else {
867 if (shared)
868 activate_output_path(codec, &spec->out_path[shared],
869 true, false);
870 if (spec->aamix_mode || !spec->hp_path.depth)
871 activate_output_path(codec, &spec->hp_mix_path,
872 true, false);
873 else
874 activate_output_path(codec, &spec->hp_path,
875 true, false);
876 }
877
878 switch_indep_hp_dacs(codec);
879 mutex_unlock(&spec->config_mutex);
880
789 /* update jack power state */ 881 /* update jack power state */
790 set_widgets_power_state(codec); 882 set_widgets_power_state(codec);
791 return 0; 883 via_hp_automute(codec);
884 return 1;
792} 885}
793 886
794static const struct snd_kcontrol_new via_hp_mixer[2] = { 887static const struct snd_kcontrol_new via_hp_mixer = {
795 { 888 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 889 .name = "Independent HP",
797 .name = "Independent HP", 890 .info = via_independent_hp_info,
798 .info = via_independent_hp_info, 891 .get = via_independent_hp_get,
799 .get = via_independent_hp_get, 892 .put = via_independent_hp_put,
800 .put = via_independent_hp_put,
801 },
802 {
803 .iface = NID_MAPPING,
804 .name = "Independent HP",
805 },
806}; 893};
807 894
808static int via_hp_build(struct hda_codec *codec) 895static int via_hp_build(struct hda_codec *codec)
@@ -810,61 +897,28 @@ static int via_hp_build(struct hda_codec *codec)
810 struct via_spec *spec = codec->spec; 897 struct via_spec *spec = codec->spec;
811 struct snd_kcontrol_new *knew; 898 struct snd_kcontrol_new *knew;
812 hda_nid_t nid; 899 hda_nid_t nid;
813 int nums;
814 hda_nid_t conn[HDA_MAX_CONNECTIONS];
815
816 switch (spec->codec_type) {
817 case VT1718S:
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 900
832 if (spec->codec_type != VT1708) { 901 nid = spec->autocfg.hp_pins[0];
833 nums = snd_hda_get_connections(codec, nid, 902 knew = via_clone_control(spec, &via_hp_mixer);
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) 903 if (knew == NULL)
841 return -ENOMEM; 904 return -ENOMEM;
842 905
843 knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; 906 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 907
854 return 0; 908 return 0;
855} 909}
856 910
857static void notify_aa_path_ctls(struct hda_codec *codec) 911static void notify_aa_path_ctls(struct hda_codec *codec)
858{ 912{
913 struct via_spec *spec = codec->spec;
859 int i; 914 int i;
860 struct snd_ctl_elem_id id; 915
861 const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; 916 for (i = 0; i < spec->smart51_nums; i++) {
862 struct snd_kcontrol *ctl; 917 struct snd_kcontrol *ctl;
863 918 struct snd_ctl_elem_id id;
864 memset(&id, 0, sizeof(id)); 919 memset(&id, 0, sizeof(id));
865 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 920 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
866 for (i = 0; i < ARRAY_SIZE(labels); i++) { 921 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); 922 ctl = snd_hda_find_mixer_ctl(codec, id.name);
869 if (ctl) 923 if (ctl)
870 snd_ctl_notify(codec->bus->card, 924 snd_ctl_notify(codec->bus->card,
@@ -876,66 +930,28 @@ static void notify_aa_path_ctls(struct hda_codec *codec)
876static void mute_aa_path(struct hda_codec *codec, int mute) 930static void mute_aa_path(struct hda_codec *codec, int mute)
877{ 931{
878 struct via_spec *spec = codec->spec; 932 struct via_spec *spec = codec->spec;
879 hda_nid_t nid_mixer; 933 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE;
880 int start_idx;
881 int end_idx;
882 int i; 934 int i;
883 /* get nid of MW0 and start & end index */ 935
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 */ 936 /* check AA path's mute status */
913 for (i = start_idx; i <= end_idx; i++) { 937 for (i = 0; i < spec->smart51_nums; i++) {
914 int val = mute ? HDA_AMP_MUTE : HDA_AMP_UNMUTE; 938 if (spec->smart51_idxs[i] < 0)
915 snd_hda_codec_amp_stereo(codec, nid_mixer, HDA_INPUT, i, 939 continue;
940 snd_hda_codec_amp_stereo(codec, spec->aa_mix_nid,
941 HDA_INPUT, spec->smart51_idxs[i],
916 HDA_AMP_MUTE, val); 942 HDA_AMP_MUTE, val);
917 } 943 }
918} 944}
919static int is_smart51_pins(struct via_spec *spec, hda_nid_t pin) 945
946static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin)
920{ 947{
921 const struct auto_pin_cfg *cfg = &spec->autocfg; 948 struct via_spec *spec = codec->spec;
922 int i; 949 int i;
923 950
924 for (i = 0; i < cfg->num_inputs; i++) { 951 for (i = 0; i < spec->smart51_nums; i++)
925 if (pin == cfg->inputs[i].pin) 952 if (spec->smart51_pins[i] == pin)
926 return cfg->inputs[i].type <= AUTO_PIN_LINE_IN; 953 return true;
927 } 954 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} 955}
940 956
941static int via_smart51_get(struct snd_kcontrol *kcontrol, 957static int via_smart51_get(struct snd_kcontrol *kcontrol,
@@ -943,23 +959,8 @@ static int via_smart51_get(struct snd_kcontrol *kcontrol,
943{ 959{
944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 960 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
945 struct via_spec *spec = codec->spec; 961 struct via_spec *spec = codec->spec;
946 const struct auto_pin_cfg *cfg = &spec->autocfg;
947 int on = 1;
948 int i;
949 962
950 for (i = 0; i < cfg->num_inputs; i++) { 963 *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; 964 return 0;
964} 965}
965 966
@@ -968,21 +969,14 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
968{ 969{
969 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
970 struct via_spec *spec = codec->spec; 971 struct via_spec *spec = codec->spec;
971 const struct auto_pin_cfg *cfg = &spec->autocfg;
972 int out_in = *ucontrol->value.integer.value 972 int out_in = *ucontrol->value.integer.value
973 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN; 973 ? AC_PINCTL_OUT_EN : AC_PINCTL_IN_EN;
974 int i; 974 int i;
975 975
976 for (i = 0; i < cfg->num_inputs; i++) { 976 for (i = 0; i < spec->smart51_nums; i++) {
977 hda_nid_t nid = cfg->inputs[i].pin; 977 hda_nid_t nid = spec->smart51_pins[i];
978 unsigned int parm; 978 unsigned int parm;
979 979
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, 980 parm = snd_hda_codec_read(codec, nid, 0,
987 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 981 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
988 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); 982 parm &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN);
@@ -994,171 +988,59 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol,
994 mute_aa_path(codec, 1); 988 mute_aa_path(codec, 1);
995 notify_aa_path_ctls(codec); 989 notify_aa_path_ctls(codec);
996 } 990 }
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 } 991 }
1015 spec->smart51_enabled = *ucontrol->value.integer.value; 992 spec->smart51_enabled = *ucontrol->value.integer.value;
1016 set_widgets_power_state(codec); 993 set_widgets_power_state(codec);
1017 return 1; 994 return 1;
1018} 995}
1019 996
1020static const struct snd_kcontrol_new via_smart51_mixer[2] = { 997static const struct snd_kcontrol_new via_smart51_mixer = {
1021 { 998 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 999 .name = "Smart 5.1",
1023 .name = "Smart 5.1", 1000 .count = 1,
1024 .count = 1, 1001 .info = snd_ctl_boolean_mono_info,
1025 .info = via_smart51_info, 1002 .get = via_smart51_get,
1026 .get = via_smart51_get, 1003 .put = via_smart51_put,
1027 .put = via_smart51_put,
1028 },
1029 {
1030 .iface = NID_MAPPING,
1031 .name = "Smart 5.1",
1032 }
1033}; 1004};
1034 1005
1035static int via_smart51_build(struct via_spec *spec) 1006static int via_smart51_build(struct hda_codec *codec)
1036{ 1007{
1037 struct snd_kcontrol_new *knew; 1008 struct via_spec *spec = codec->spec;
1038 const struct auto_pin_cfg *cfg = &spec->autocfg;
1039 hda_nid_t nid;
1040 int i;
1041 1009
1042 if (!cfg) 1010 if (!spec->smart51_nums)
1043 return 0;
1044 if (cfg->line_outs > 2)
1045 return 0; 1011 return 0;
1046 1012 if (!via_clone_control(spec, &via_smart51_mixer))
1047 knew = via_clone_control(spec, &via_smart51_mixer[0]);
1048 if (knew == NULL)
1049 return -ENOMEM; 1013 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; 1014 return 0;
1063} 1015}
1064 1016
1065/* capture mixer elements */ 1017/* check AA path's mute status */
1066static const struct snd_kcontrol_new vt1708_capture_mixer[] = { 1018static 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{ 1019{
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; 1020 struct via_spec *spec = codec->spec;
1095 /* get nid of MW0 and start & end index */ 1021 const struct hda_amp_list *p;
1096 switch (spec->codec_type) { 1022 int i, ch, v;
1097 case VT1708B_8CH: 1023
1098 case VT1708B_4CH: 1024 for (i = 0; i < spec->num_loopbacks; i++) {
1099 case VT1708S: 1025 p = &spec->loopback_list[i];
1100 case VT1716S: 1026 for (ch = 0; ch < 2; ch++) {
1101 nid_mixer = 0x16; 1027 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
1102 start_idx = 2; 1028 p->idx);
1103 end_idx = 4; 1029 if (!(v & HDA_AMP_MUTE) && v > 0)
1104 break; 1030 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 } 1031 }
1143 } 1032 }
1144 return mute; 1033 return true;
1145} 1034}
1146 1035
1147/* enter/exit analog low-current mode */ 1036/* enter/exit analog low-current mode */
1148static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) 1037static void analog_low_current_mode(struct hda_codec *codec)
1149{ 1038{
1150 struct via_spec *spec = codec->spec; 1039 struct via_spec *spec = codec->spec;
1151 static int saved_stream_idle = 1; /* saved stream idle status */ 1040 bool enable;
1152 int enable = is_aa_path_mute(codec); 1041 unsigned int verb, parm;
1153 unsigned int verb = 0;
1154 unsigned int parm = 0;
1155 1042
1156 if (stream_idle == -1) /* stream status did not change */ 1043 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 1044
1163 /* decide low current mode's verb & parameter */ 1045 /* decide low current mode's verb & parameter */
1164 switch (spec->codec_type) { 1046 switch (spec->codec_type) {
@@ -1193,119 +1075,69 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle)
1193/* 1075/*
1194 * generic initialization of ADC, input mixers and output mixers 1076 * generic initialization of ADC, input mixers and output mixers
1195 */ 1077 */
1196static const struct hda_verb vt1708_volume_init_verbs[] = { 1078static 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 */ 1079 /* power down jack detect function */
1227 {0x1, 0xf81, 0x1}, 1080 {0x1, 0xf81, 0x1},
1228 { } 1081 { }
1229}; 1082};
1230 1083
1231static int via_playback_pcm_open(struct hda_pcm_stream *hinfo, 1084static void set_stream_open(struct hda_codec *codec, int bit, bool active)
1085{
1086 struct via_spec *spec = codec->spec;
1087
1088 if (active)
1089 spec->opened_streams |= bit;
1090 else
1091 spec->opened_streams &= ~bit;
1092 analog_low_current_mode(codec);
1093}
1094
1095static int via_playback_multi_pcm_open(struct hda_pcm_stream *hinfo,
1232 struct hda_codec *codec, 1096 struct hda_codec *codec,
1233 struct snd_pcm_substream *substream) 1097 struct snd_pcm_substream *substream)
1234{ 1098{
1235 struct via_spec *spec = codec->spec; 1099 struct via_spec *spec = codec->spec;
1236 int idle = substream->pstr->substream_opened == 1 1100 const struct auto_pin_cfg *cfg = &spec->autocfg;
1237 && substream->ref_count == 0; 1101 int err;
1238 analog_low_current_mode(codec, idle); 1102
1239 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 1103 spec->multiout.num_dacs = cfg->line_outs + spec->smart51_nums;
1240 hinfo); 1104 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1105 set_stream_open(codec, STREAM_MULTI_OUT, true);
1106 err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
1107 hinfo);
1108 if (err < 0) {
1109 set_stream_open(codec, STREAM_MULTI_OUT, false);
1110 return err;
1111 }
1112 return 0;
1241} 1113}
1242 1114
1243static void playback_multi_pcm_prep_0(struct hda_codec *codec, 1115static int via_playback_multi_pcm_close(struct hda_pcm_stream *hinfo,
1244 unsigned int stream_tag, 1116 struct hda_codec *codec,
1245 unsigned int format, 1117 struct snd_pcm_substream *substream)
1246 struct snd_pcm_substream *substream) 1118{
1119 set_stream_open(codec, STREAM_MULTI_OUT, false);
1120 return 0;
1121}
1122
1123static int via_playback_hp_pcm_open(struct hda_pcm_stream *hinfo,
1124 struct hda_codec *codec,
1125 struct snd_pcm_substream *substream)
1247{ 1126{
1248 struct via_spec *spec = codec->spec; 1127 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 1128
1254 mutex_lock(&codec->spdif_mutex); 1129 if (snd_BUG_ON(!spec->hp_dac_nid))
1255 if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { 1130 return -EINVAL;
1256 if (chs == 2 && 1131 set_stream_open(codec, STREAM_INDEP_HP, true);
1257 snd_hda_is_supported_format(codec, mout->dig_out_nid, 1132 return 0;
1258 format) && 1133}
1259 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { 1134
1260 mout->dig_out_used = HDA_DIG_ANALOG_DUP; 1135static int via_playback_hp_pcm_close(struct hda_pcm_stream *hinfo,
1261 /* turn off SPDIF once; otherwise the IEC958 bits won't 1136 struct hda_codec *codec,
1262 * be updated */ 1137 struct snd_pcm_substream *substream)
1263 if (codec->spdif_ctls & AC_DIG1_ENABLE) 1138{
1264 snd_hda_codec_write(codec, mout->dig_out_nid, 0, 1139 set_stream_open(codec, STREAM_INDEP_HP, false);
1265 AC_VERB_SET_DIGI_CONVERT_1, 1140 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} 1141}
1310 1142
1311static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, 1143static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
@@ -1315,19 +1147,37 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo,
1315 struct snd_pcm_substream *substream) 1147 struct snd_pcm_substream *substream)
1316{ 1148{
1317 struct via_spec *spec = codec->spec; 1149 struct via_spec *spec = codec->spec;
1318 struct hda_multi_out *mout = &spec->multiout;
1319 const hda_nid_t *nids = mout->dac_nids;
1320 1150
1321 if (substream->number == 0) 1151 mutex_lock(&spec->config_mutex);
1322 playback_multi_pcm_prep_0(codec, stream_tag, format, 1152 setup_playback_multi_pcm(spec);
1323 substream); 1153 snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
1324 else { 1154 format, substream);
1325 if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && 1155 /* remember for dynamic DAC switch with indep-HP */
1326 spec->hp_independent_mode) 1156 spec->active_streams |= STREAM_MULTI_OUT;
1327 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1157 spec->cur_dac_stream_tag = stream_tag;
1328 stream_tag, 0, format); 1158 spec->cur_dac_format = format;
1329 } 1159 mutex_unlock(&spec->config_mutex);
1330 vt1708_start_hp_work(spec); 1160 vt1708_update_hp_work(spec);
1161 return 0;
1162}
1163
1164static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo,
1165 struct hda_codec *codec,
1166 unsigned int stream_tag,
1167 unsigned int format,
1168 struct snd_pcm_substream *substream)
1169{
1170 struct via_spec *spec = codec->spec;
1171
1172 mutex_lock(&spec->config_mutex);
1173 if (spec->hp_independent_mode)
1174 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid,
1175 stream_tag, 0, format);
1176 spec->active_streams |= STREAM_INDEP_HP;
1177 spec->cur_hp_stream_tag = stream_tag;
1178 spec->cur_hp_format = format;
1179 mutex_unlock(&spec->config_mutex);
1180 vt1708_update_hp_work(spec);
1331 return 0; 1181 return 0;
1332} 1182}
1333 1183
@@ -1336,38 +1186,27 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo,
1336 struct snd_pcm_substream *substream) 1186 struct snd_pcm_substream *substream)
1337{ 1187{
1338 struct via_spec *spec = codec->spec; 1188 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 1189
1343 if (substream->number == 0) { 1190 mutex_lock(&spec->config_mutex);
1344 for (i = 0; i < mout->num_dacs; i++) 1191 snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
1345 snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); 1192 spec->active_streams &= ~STREAM_MULTI_OUT;
1346 1193 mutex_unlock(&spec->config_mutex);
1347 if (mout->hp_nid && !spec->hp_independent_mode) 1194 vt1708_update_hp_work(spec);
1348 snd_hda_codec_setup_stream(codec, mout->hp_nid, 1195 return 0;
1349 0, 0, 0); 1196}
1350 1197
1351 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) 1198static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo,
1352 if (mout->extra_out_nid[i]) 1199 struct hda_codec *codec,
1353 snd_hda_codec_setup_stream(codec, 1200 struct snd_pcm_substream *substream)
1354 mout->extra_out_nid[i], 1201{
1355 0, 0, 0); 1202 struct via_spec *spec = codec->spec;
1356 mutex_lock(&codec->spdif_mutex); 1203
1357 if (mout->dig_out_nid && 1204 mutex_lock(&spec->config_mutex);
1358 mout->dig_out_used == HDA_DIG_ANALOG_DUP) { 1205 if (spec->hp_independent_mode)
1359 snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 1206 snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0);
1360 0, 0, 0); 1207 spec->active_streams &= ~STREAM_INDEP_HP;
1361 mout->dig_out_used = 0; 1208 mutex_unlock(&spec->config_mutex);
1362 } 1209 vt1708_update_hp_work(spec);
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);
1371 return 0; 1210 return 0;
1372} 1211}
1373 1212
@@ -1435,47 +1274,127 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1435 return 0; 1274 return 0;
1436} 1275}
1437 1276
1438static const struct hda_pcm_stream vt1708_pcm_analog_playback = { 1277/* analog capture with dynamic ADC switching */
1439 .substreams = 2, 1278static int via_dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1279 struct hda_codec *codec,
1280 unsigned int stream_tag,
1281 unsigned int format,
1282 struct snd_pcm_substream *substream)
1283{
1284 struct via_spec *spec = codec->spec;
1285 int adc_idx = spec->inputs[spec->cur_mux[0]].adc_idx;
1286
1287 mutex_lock(&spec->config_mutex);
1288 spec->cur_adc = spec->adc_nids[adc_idx];
1289 spec->cur_adc_stream_tag = stream_tag;
1290 spec->cur_adc_format = format;
1291 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
1292 mutex_unlock(&spec->config_mutex);
1293 return 0;
1294}
1295
1296static int via_dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1297 struct hda_codec *codec,
1298 struct snd_pcm_substream *substream)
1299{
1300 struct via_spec *spec = codec->spec;
1301
1302 mutex_lock(&spec->config_mutex);
1303 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
1304 spec->cur_adc = 0;
1305 mutex_unlock(&spec->config_mutex);
1306 return 0;
1307}
1308
1309/* re-setup the stream if running; called from input-src put */
1310static bool via_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
1311{
1312 struct via_spec *spec = codec->spec;
1313 int adc_idx = spec->inputs[cur].adc_idx;
1314 hda_nid_t adc = spec->adc_nids[adc_idx];
1315 bool ret = false;
1316
1317 mutex_lock(&spec->config_mutex);
1318 if (spec->cur_adc && spec->cur_adc != adc) {
1319 /* stream is running, let's swap the current ADC */
1320 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1321 spec->cur_adc = adc;
1322 snd_hda_codec_setup_stream(codec, adc,
1323 spec->cur_adc_stream_tag, 0,
1324 spec->cur_adc_format);
1325 ret = true;
1326 }
1327 mutex_unlock(&spec->config_mutex);
1328 return ret;
1329}
1330
1331static const struct hda_pcm_stream via_pcm_analog_playback = {
1332 .substreams = 1,
1440 .channels_min = 2, 1333 .channels_min = 2,
1441 .channels_max = 8, 1334 .channels_max = 8,
1442 .nid = 0x10, /* NID to query formats and rates */ 1335 /* NID is set in via_build_pcms */
1443 .ops = { 1336 .ops = {
1444 .open = via_playback_pcm_open, 1337 .open = via_playback_multi_pcm_open,
1338 .close = via_playback_multi_pcm_close,
1445 .prepare = via_playback_multi_pcm_prepare, 1339 .prepare = via_playback_multi_pcm_prepare,
1446 .cleanup = via_playback_multi_pcm_cleanup 1340 .cleanup = via_playback_multi_pcm_cleanup
1447 }, 1341 },
1448}; 1342};
1449 1343
1344static const struct hda_pcm_stream via_pcm_hp_playback = {
1345 .substreams = 1,
1346 .channels_min = 2,
1347 .channels_max = 2,
1348 /* NID is set in via_build_pcms */
1349 .ops = {
1350 .open = via_playback_hp_pcm_open,
1351 .close = via_playback_hp_pcm_close,
1352 .prepare = via_playback_hp_pcm_prepare,
1353 .cleanup = via_playback_hp_pcm_cleanup
1354 },
1355};
1356
1450static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { 1357static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = {
1451 .substreams = 2, 1358 .substreams = 1,
1452 .channels_min = 2, 1359 .channels_min = 2,
1453 .channels_max = 8, 1360 .channels_max = 8,
1454 .nid = 0x10, /* NID to query formats and rates */ 1361 /* NID is set in via_build_pcms */
1455 /* We got noisy outputs on the right channel on VT1708 when 1362 /* We got noisy outputs on the right channel on VT1708 when
1456 * 24bit samples are used. Until any workaround is found, 1363 * 24bit samples are used. Until any workaround is found,
1457 * disable the 24bit format, so far. 1364 * disable the 24bit format, so far.
1458 */ 1365 */
1459 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1366 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1460 .ops = { 1367 .ops = {
1461 .open = via_playback_pcm_open, 1368 .open = via_playback_multi_pcm_open,
1369 .close = via_playback_multi_pcm_close,
1462 .prepare = via_playback_multi_pcm_prepare, 1370 .prepare = via_playback_multi_pcm_prepare,
1463 .cleanup = via_playback_multi_pcm_cleanup 1371 .cleanup = via_playback_multi_pcm_cleanup
1464 }, 1372 },
1465}; 1373};
1466 1374
1467static const struct hda_pcm_stream vt1708_pcm_analog_capture = { 1375static const struct hda_pcm_stream via_pcm_analog_capture = {
1468 .substreams = 2, 1376 .substreams = 1, /* will be changed in via_build_pcms() */
1469 .channels_min = 2, 1377 .channels_min = 2,
1470 .channels_max = 2, 1378 .channels_max = 2,
1471 .nid = 0x15, /* NID to query formats and rates */ 1379 /* NID is set in via_build_pcms */
1472 .ops = { 1380 .ops = {
1473 .prepare = via_capture_pcm_prepare, 1381 .prepare = via_capture_pcm_prepare,
1474 .cleanup = via_capture_pcm_cleanup 1382 .cleanup = via_capture_pcm_cleanup
1475 }, 1383 },
1476}; 1384};
1477 1385
1478static const struct hda_pcm_stream vt1708_pcm_digital_playback = { 1386static const struct hda_pcm_stream via_pcm_dyn_adc_analog_capture = {
1387 .substreams = 1,
1388 .channels_min = 2,
1389 .channels_max = 2,
1390 /* NID is set in via_build_pcms */
1391 .ops = {
1392 .prepare = via_dyn_adc_capture_pcm_prepare,
1393 .cleanup = via_dyn_adc_capture_pcm_cleanup,
1394 },
1395};
1396
1397static const struct hda_pcm_stream via_pcm_digital_playback = {
1479 .substreams = 1, 1398 .substreams = 1,
1480 .channels_min = 2, 1399 .channels_min = 2,
1481 .channels_max = 2, 1400 .channels_max = 2,
@@ -1488,19 +1407,47 @@ static const struct hda_pcm_stream vt1708_pcm_digital_playback = {
1488 }, 1407 },
1489}; 1408};
1490 1409
1491static const struct hda_pcm_stream vt1708_pcm_digital_capture = { 1410static const struct hda_pcm_stream via_pcm_digital_capture = {
1492 .substreams = 1, 1411 .substreams = 1,
1493 .channels_min = 2, 1412 .channels_min = 2,
1494 .channels_max = 2, 1413 .channels_max = 2,
1495}; 1414};
1496 1415
1416/*
1417 * slave controls for virtual master
1418 */
1419static const char * const via_slave_vols[] = {
1420 "Front Playback Volume",
1421 "Surround Playback Volume",
1422 "Center Playback Volume",
1423 "LFE Playback Volume",
1424 "Side Playback Volume",
1425 "Headphone Playback Volume",
1426 "Speaker Playback Volume",
1427 NULL,
1428};
1429
1430static const char * const via_slave_sws[] = {
1431 "Front Playback Switch",
1432 "Surround Playback Switch",
1433 "Center Playback Switch",
1434 "LFE Playback Switch",
1435 "Side Playback Switch",
1436 "Headphone Playback Switch",
1437 "Speaker Playback Switch",
1438 NULL,
1439};
1440
1497static int via_build_controls(struct hda_codec *codec) 1441static int via_build_controls(struct hda_codec *codec)
1498{ 1442{
1499 struct via_spec *spec = codec->spec; 1443 struct via_spec *spec = codec->spec;
1500 struct snd_kcontrol *kctl; 1444 struct snd_kcontrol *kctl;
1501 const struct snd_kcontrol_new *knew;
1502 int err, i; 1445 int err, i;
1503 1446
1447 if (spec->set_widgets_power_state)
1448 if (!via_clone_control(spec, &via_pin_power_ctl_enum))
1449 return -ENOMEM;
1450
1504 for (i = 0; i < spec->num_mixers; i++) { 1451 for (i = 0; i < spec->num_mixers; i++) {
1505 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1452 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1506 if (err < 0) 1453 if (err < 0)
@@ -1509,6 +1456,7 @@ static int via_build_controls(struct hda_codec *codec)
1509 1456
1510 if (spec->multiout.dig_out_nid) { 1457 if (spec->multiout.dig_out_nid) {
1511 err = snd_hda_create_spdif_out_ctls(codec, 1458 err = snd_hda_create_spdif_out_ctls(codec,
1459 spec->multiout.dig_out_nid,
1512 spec->multiout.dig_out_nid); 1460 spec->multiout.dig_out_nid);
1513 if (err < 0) 1461 if (err < 0)
1514 return err; 1462 return err;
@@ -1524,6 +1472,23 @@ static int via_build_controls(struct hda_codec *codec)
1524 return err; 1472 return err;
1525 } 1473 }
1526 1474
1475 /* if we have no master control, let's create it */
1476 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1477 unsigned int vmaster_tlv[4];
1478 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
1479 HDA_OUTPUT, vmaster_tlv);
1480 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1481 vmaster_tlv, via_slave_vols);
1482 if (err < 0)
1483 return err;
1484 }
1485 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
1486 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
1487 NULL, via_slave_sws);
1488 if (err < 0)
1489 return err;
1490 }
1491
1527 /* assign Capture Source enums to NID */ 1492 /* assign Capture Source enums to NID */
1528 kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 1493 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
1529 for (i = 0; kctl && i < kctl->count; i++) { 1494 for (i = 0; kctl && i < kctl->count; i++) {
@@ -1532,22 +1497,9 @@ static int via_build_controls(struct hda_codec *codec)
1532 return err; 1497 return err;
1533 } 1498 }
1534 1499
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 */ 1500 /* init power states */
1549 set_widgets_power_state(codec); 1501 set_widgets_power_state(codec);
1550 analog_low_current_mode(codec, 1); 1502 analog_low_current_mode(codec);
1551 1503
1552 via_free_kctls(codec); /* no longer needed */ 1504 via_free_kctls(codec); /* no longer needed */
1553 return 0; 1505 return 0;
@@ -1561,36 +1513,71 @@ static int via_build_pcms(struct hda_codec *codec)
1561 codec->num_pcms = 1; 1513 codec->num_pcms = 1;
1562 codec->pcm_info = info; 1514 codec->pcm_info = info;
1563 1515
1516 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
1517 "%s Analog", codec->chip_name);
1564 info->name = spec->stream_name_analog; 1518 info->name = spec->stream_name_analog;
1519
1520 if (!spec->stream_analog_playback)
1521 spec->stream_analog_playback = &via_pcm_analog_playback;
1565 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1522 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1566 *(spec->stream_analog_playback); 1523 *spec->stream_analog_playback;
1567 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1524 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1568 spec->multiout.dac_nids[0]; 1525 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 = 1526 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
1573 spec->multiout.max_channels; 1527 spec->multiout.max_channels;
1574 1528
1529 if (!spec->stream_analog_capture) {
1530 if (spec->dyn_adc_switch)
1531 spec->stream_analog_capture =
1532 &via_pcm_dyn_adc_analog_capture;
1533 else
1534 spec->stream_analog_capture = &via_pcm_analog_capture;
1535 }
1536 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1537 *spec->stream_analog_capture;
1538 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
1539 if (!spec->dyn_adc_switch)
1540 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
1541 spec->num_adc_nids;
1542
1575 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 1543 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
1576 codec->num_pcms++; 1544 codec->num_pcms++;
1577 info++; 1545 info++;
1546 snprintf(spec->stream_name_digital,
1547 sizeof(spec->stream_name_digital),
1548 "%s Digital", codec->chip_name);
1578 info->name = spec->stream_name_digital; 1549 info->name = spec->stream_name_digital;
1579 info->pcm_type = HDA_PCM_TYPE_SPDIF; 1550 info->pcm_type = HDA_PCM_TYPE_SPDIF;
1580 if (spec->multiout.dig_out_nid) { 1551 if (spec->multiout.dig_out_nid) {
1552 if (!spec->stream_digital_playback)
1553 spec->stream_digital_playback =
1554 &via_pcm_digital_playback;
1581 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = 1555 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
1582 *(spec->stream_digital_playback); 1556 *spec->stream_digital_playback;
1583 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 1557 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1584 spec->multiout.dig_out_nid; 1558 spec->multiout.dig_out_nid;
1585 } 1559 }
1586 if (spec->dig_in_nid) { 1560 if (spec->dig_in_nid) {
1561 if (!spec->stream_digital_capture)
1562 spec->stream_digital_capture =
1563 &via_pcm_digital_capture;
1587 info->stream[SNDRV_PCM_STREAM_CAPTURE] = 1564 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
1588 *(spec->stream_digital_capture); 1565 *spec->stream_digital_capture;
1589 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 1566 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
1590 spec->dig_in_nid; 1567 spec->dig_in_nid;
1591 } 1568 }
1592 } 1569 }
1593 1570
1571 if (spec->hp_dac_nid) {
1572 codec->num_pcms++;
1573 info++;
1574 snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp),
1575 "%s HP", codec->chip_name);
1576 info->name = spec->stream_name_hp;
1577 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback;
1578 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
1579 spec->hp_dac_nid;
1580 }
1594 return 0; 1581 return 0;
1595} 1582}
1596 1583
@@ -1603,57 +1590,63 @@ static void via_free(struct hda_codec *codec)
1603 1590
1604 via_free_kctls(codec); 1591 via_free_kctls(codec);
1605 vt1708_stop_hp_work(spec); 1592 vt1708_stop_hp_work(spec);
1606 kfree(codec->spec); 1593 kfree(spec->bind_cap_vol);
1594 kfree(spec->bind_cap_sw);
1595 kfree(spec);
1607} 1596}
1608 1597
1609/* mute internal speaker if HP is plugged */ 1598/* mute/unmute outputs */
1610static void via_hp_automute(struct hda_codec *codec) 1599static void toggle_output_mutes(struct hda_codec *codec, int num_pins,
1600 hda_nid_t *pins, bool mute)
1611{ 1601{
1612 unsigned int present = 0; 1602 int i;
1613 struct via_spec *spec = codec->spec; 1603 for (i = 0; i < num_pins; i++) {
1614 1604 unsigned int parm = snd_hda_codec_read(codec, pins[i], 0,
1615 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1605 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1616 1606 if (parm & AC_PINCTL_IN_EN)
1617 if (!spec->hp_independent_mode) { 1607 continue;
1618 struct snd_ctl_elem_id id; 1608 if (mute)
1619 /* auto mute */ 1609 parm &= ~AC_PINCTL_OUT_EN;
1620 snd_hda_codec_amp_stereo( 1610 else
1621 codec, spec->autocfg.line_out_pins[0], HDA_OUTPUT, 0, 1611 parm |= AC_PINCTL_OUT_EN;
1622 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1612 snd_hda_codec_write(codec, pins[i], 0,
1623 /* notify change */ 1613 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 } 1614 }
1630} 1615}
1631 1616
1632/* mute mono out if HP or Line out is plugged */ 1617/* mute internal speaker if line-out is plugged */
1633static void via_mono_automute(struct hda_codec *codec) 1618static void via_line_automute(struct hda_codec *codec, int present)
1634{ 1619{
1635 unsigned int hp_present, lineout_present;
1636 struct via_spec *spec = codec->spec; 1620 struct via_spec *spec = codec->spec;
1637 1621
1638 if (spec->codec_type != VT1716S) 1622 if (!spec->autocfg.speaker_outs)
1639 return; 1623 return;
1640 1624 if (!present)
1641 lineout_present = snd_hda_jack_detect(codec, 1625 present = snd_hda_jack_detect(codec,
1642 spec->autocfg.line_out_pins[0]); 1626 spec->autocfg.line_out_pins[0]);
1627 toggle_output_mutes(codec, spec->autocfg.speaker_outs,
1628 spec->autocfg.speaker_pins,
1629 present);
1630}
1643 1631
1644 /* Mute Mono Out if Line Out is plugged */ 1632/* mute internal speaker if HP is plugged */
1645 if (lineout_present) { 1633static void via_hp_automute(struct hda_codec *codec)
1646 snd_hda_codec_amp_stereo( 1634{
1647 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, HDA_AMP_MUTE); 1635 int present = 0;
1648 return; 1636 int nums;
1649 } 1637 struct via_spec *spec = codec->spec;
1650 1638
1651 hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); 1639 if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] &&
1640 (spec->codec_type != VT1708 || spec->vt1708_jack_detect))
1641 present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]);
1652 1642
1653 if (!spec->hp_independent_mode) 1643 if (spec->smart51_enabled)
1654 snd_hda_codec_amp_stereo( 1644 nums = spec->autocfg.line_outs + spec->smart51_nums;
1655 codec, 0x2A, HDA_OUTPUT, 0, HDA_AMP_MUTE, 1645 else
1656 hp_present ? HDA_AMP_MUTE : 0); 1646 nums = spec->autocfg.line_outs;
1647 toggle_output_mutes(codec, nums, spec->autocfg.line_out_pins, present);
1648
1649 via_line_automute(codec, present);
1657} 1650}
1658 1651
1659static void via_gpio_control(struct hda_codec *codec) 1652static void via_gpio_control(struct hda_codec *codec)
@@ -1678,9 +1671,9 @@ static void via_gpio_control(struct hda_codec *codec)
1678 1671
1679 if (gpio_data == 0x02) { 1672 if (gpio_data == 0x02) {
1680 /* unmute line out */ 1673 /* unmute line out */
1681 snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], 1674 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1682 HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); 1675 AC_VERB_SET_PIN_WIDGET_CONTROL,
1683 1676 PIN_OUT);
1684 if (vol_counter & 0x20) { 1677 if (vol_counter & 0x20) {
1685 /* decrease volume */ 1678 /* decrease volume */
1686 if (vol > master_vol) 1679 if (vol > master_vol)
@@ -1697,73 +1690,12 @@ static void via_gpio_control(struct hda_codec *codec)
1697 } 1690 }
1698 } else if (!(gpio_data & 0x02)) { 1691 } else if (!(gpio_data & 0x02)) {
1699 /* mute line out */ 1692 /* mute line out */
1700 snd_hda_codec_amp_stereo(codec, 1693 snd_hda_codec_write(codec, spec->autocfg.line_out_pins[0], 0,
1701 spec->autocfg.line_out_pins[0], 1694 AC_VERB_SET_PIN_WIDGET_CONTROL,
1702 HDA_OUTPUT, 0, HDA_AMP_MUTE, 1695 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 } 1696 }
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} 1697}
1765 1698
1766
1767/* unsolicited event for jack sensing */ 1699/* unsolicited event for jack sensing */
1768static void via_unsol_event(struct hda_codec *codec, 1700static void via_unsol_event(struct hda_codec *codec,
1769 unsigned int res) 1701 unsigned int res)
@@ -1775,46 +1707,13 @@ static void via_unsol_event(struct hda_codec *codec,
1775 1707
1776 res &= ~VIA_JACK_EVENT; 1708 res &= ~VIA_JACK_EVENT;
1777 1709
1778 if (res == VIA_HP_EVENT) 1710 if (res == VIA_HP_EVENT || res == VIA_LINE_EVENT)
1779 via_hp_automute(codec); 1711 via_hp_automute(codec);
1780 else if (res == VIA_GPIO_EVENT) 1712 else if (res == VIA_GPIO_EVENT)
1781 via_gpio_control(codec); 1713 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} 1714}
1816 1715
1817#ifdef SND_HDA_NEEDS_RESUME 1716#ifdef CONFIG_PM
1818static int via_suspend(struct hda_codec *codec, pm_message_t state) 1717static int via_suspend(struct hda_codec *codec, pm_message_t state)
1819{ 1718{
1820 struct via_spec *spec = codec->spec; 1719 struct via_spec *spec = codec->spec;
@@ -1833,12 +1732,16 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1833 1732
1834/* 1733/*
1835 */ 1734 */
1735
1736static int via_init(struct hda_codec *codec);
1737
1836static const struct hda_codec_ops via_patch_ops = { 1738static const struct hda_codec_ops via_patch_ops = {
1837 .build_controls = via_build_controls, 1739 .build_controls = via_build_controls,
1838 .build_pcms = via_build_pcms, 1740 .build_pcms = via_build_pcms,
1839 .init = via_init, 1741 .init = via_init,
1840 .free = via_free, 1742 .free = via_free,
1841#ifdef SND_HDA_NEEDS_RESUME 1743 .unsol_event = via_unsol_event,
1744#ifdef CONFIG_PM
1842 .suspend = via_suspend, 1745 .suspend = via_suspend,
1843#endif 1746#endif
1844#ifdef CONFIG_SND_HDA_POWER_SAVE 1747#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -1846,237 +1749,838 @@ static const struct hda_codec_ops via_patch_ops = {
1846#endif 1749#endif
1847}; 1750};
1848 1751
1849/* fill in the dac_nids table from the parsed pin configuration */ 1752static 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{ 1753{
1754 struct via_spec *spec = codec->spec;
1853 int i; 1755 int i;
1854 hda_nid_t nid;
1855 1756
1856 spec->multiout.num_dacs = cfg->line_outs; 1757 for (i = 0; i < spec->multiout.num_dacs; i++) {
1758 if (spec->multiout.dac_nids[i] == dac)
1759 return false;
1760 }
1761 if (spec->hp_dac_nid == dac)
1762 return false;
1763 return true;
1764}
1857 1765
1858 spec->multiout.dac_nids = spec->private_dac_nids; 1766static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1767 hda_nid_t target_dac, int with_aa_mix,
1768 struct nid_path *path, int depth)
1769{
1770 struct via_spec *spec = codec->spec;
1771 hda_nid_t conn[8];
1772 int i, nums;
1859 1773
1860 for (i = 0; i < 4; i++) { 1774 if (nid == spec->aa_mix_nid) {
1775 if (!with_aa_mix)
1776 return false;
1777 with_aa_mix = 2; /* mark aa-mix is included */
1778 }
1779
1780 nums = snd_hda_get_connections(codec, nid, conn, ARRAY_SIZE(conn));
1781 for (i = 0; i < nums; i++) {
1782 if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT)
1783 continue;
1784 if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) {
1785 /* aa-mix is requested but not included? */
1786 if (!(spec->aa_mix_nid && with_aa_mix == 1))
1787 goto found;
1788 }
1789 }
1790 if (depth >= MAX_NID_PATH_DEPTH)
1791 return false;
1792 for (i = 0; i < nums; i++) {
1793 unsigned int type;
1794 type = get_wcaps_type(get_wcaps(codec, conn[i]));
1795 if (type == AC_WID_AUD_OUT)
1796 continue;
1797 if (__parse_output_path(codec, conn[i], target_dac,
1798 with_aa_mix, path, depth + 1))
1799 goto found;
1800 }
1801 return false;
1802
1803 found:
1804 path->path[path->depth] = conn[i];
1805 path->idx[path->depth] = i;
1806 if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX)
1807 path->multi[path->depth] = 1;
1808 path->depth++;
1809 return true;
1810}
1811
1812static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid,
1813 hda_nid_t target_dac, int with_aa_mix,
1814 struct nid_path *path)
1815{
1816 if (__parse_output_path(codec, nid, target_dac, with_aa_mix, path, 1)) {
1817 path->path[path->depth] = nid;
1818 path->depth++;
1819 snd_printdd("output-path: depth=%d, %02x/%02x/%02x/%02x/%02x\n",
1820 path->depth, path->path[0], path->path[1],
1821 path->path[2], path->path[3], path->path[4]);
1822 return true;
1823 }
1824 return false;
1825}
1826
1827static int via_auto_fill_dac_nids(struct hda_codec *codec)
1828{
1829 struct via_spec *spec = codec->spec;
1830 const struct auto_pin_cfg *cfg = &spec->autocfg;
1831 int i, dac_num;
1832 hda_nid_t nid;
1833
1834 spec->multiout.dac_nids = spec->private_dac_nids;
1835 dac_num = 0;
1836 for (i = 0; i < cfg->line_outs; i++) {
1837 hda_nid_t dac = 0;
1861 nid = cfg->line_out_pins[i]; 1838 nid = cfg->line_out_pins[i];
1862 if (nid) { 1839 if (!nid)
1863 /* config dac list */ 1840 continue;
1864 switch (i) { 1841 if (parse_output_path(codec, nid, 0, 0, &spec->out_path[i]))
1865 case AUTO_SEQ_FRONT: 1842 dac = spec->out_path[i].path[0];
1866 spec->private_dac_nids[i] = 0x10; 1843 if (!i && parse_output_path(codec, nid, dac, 1,
1867 break; 1844 &spec->out_mix_path))
1868 case AUTO_SEQ_CENLFE: 1845 dac = spec->out_mix_path.path[0];
1869 spec->private_dac_nids[i] = 0x12; 1846 if (dac) {
1870 break; 1847 spec->private_dac_nids[i] = dac;
1871 case AUTO_SEQ_SURROUND: 1848 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 } 1849 }
1879 } 1850 }
1851 if (!spec->out_path[0].depth && spec->out_mix_path.depth) {
1852 spec->out_path[0] = spec->out_mix_path;
1853 spec->out_mix_path.depth = 0;
1854 }
1855 spec->multiout.num_dacs = dac_num;
1856 return 0;
1857}
1858
1859static int create_ch_ctls(struct hda_codec *codec, const char *pfx,
1860 int chs, bool check_dac, struct nid_path *path)
1861{
1862 struct via_spec *spec = codec->spec;
1863 char name[32];
1864 hda_nid_t dac, pin, sel, nid;
1865 int err;
1880 1866
1867 dac = check_dac ? path->path[0] : 0;
1868 pin = path->path[path->depth - 1];
1869 sel = path->depth > 1 ? path->path[1] : 0;
1870
1871 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1872 nid = dac;
1873 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1874 nid = pin;
1875 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS))
1876 nid = sel;
1877 else
1878 nid = 0;
1879 if (nid) {
1880 sprintf(name, "%s Playback Volume", pfx);
1881 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1882 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1883 if (err < 0)
1884 return err;
1885 path->vol_ctl = nid;
1886 }
1887
1888 if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE))
1889 nid = dac;
1890 else if (check_amp_caps(codec, pin, HDA_OUTPUT, AC_AMPCAP_MUTE))
1891 nid = pin;
1892 else if (check_amp_caps(codec, sel, HDA_OUTPUT, AC_AMPCAP_MUTE))
1893 nid = sel;
1894 else
1895 nid = 0;
1896 if (nid) {
1897 sprintf(name, "%s Playback Switch", pfx);
1898 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1899 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
1900 if (err < 0)
1901 return err;
1902 path->mute_ctl = nid;
1903 }
1881 return 0; 1904 return 0;
1882} 1905}
1883 1906
1907static void mangle_smart51(struct hda_codec *codec)
1908{
1909 struct via_spec *spec = codec->spec;
1910 struct auto_pin_cfg *cfg = &spec->autocfg;
1911 struct auto_pin_cfg_item *ins = cfg->inputs;
1912 int i, j, nums, attr;
1913 int pins[AUTO_CFG_MAX_INS];
1914
1915 for (attr = INPUT_PIN_ATTR_REAR; attr >= INPUT_PIN_ATTR_NORMAL; attr--) {
1916 nums = 0;
1917 for (i = 0; i < cfg->num_inputs; i++) {
1918 unsigned int def;
1919 if (ins[i].type > AUTO_PIN_LINE_IN)
1920 continue;
1921 def = snd_hda_codec_get_pincfg(codec, ins[i].pin);
1922 if (snd_hda_get_input_pin_attr(def) != attr)
1923 continue;
1924 for (j = 0; j < nums; j++)
1925 if (ins[pins[j]].type < ins[i].type) {
1926 memmove(pins + j + 1, pins + j,
1927 (nums - j) * sizeof(int));
1928 break;
1929 }
1930 pins[j] = i;
1931 nums++;
1932 }
1933 if (cfg->line_outs + nums < 3)
1934 continue;
1935 for (i = 0; i < nums; i++) {
1936 hda_nid_t pin = ins[pins[i]].pin;
1937 spec->smart51_pins[spec->smart51_nums++] = pin;
1938 cfg->line_out_pins[cfg->line_outs++] = pin;
1939 if (cfg->line_outs == 3)
1940 break;
1941 }
1942 return;
1943 }
1944}
1945
1946static void copy_path_mixer_ctls(struct nid_path *dst, struct nid_path *src)
1947{
1948 dst->vol_ctl = src->vol_ctl;
1949 dst->mute_ctl = src->mute_ctl;
1950}
1951
1884/* add playback controls from the parsed DAC table */ 1952/* add playback controls from the parsed DAC table */
1885static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, 1953static int via_auto_create_multi_out_ctls(struct hda_codec *codec)
1886 const struct auto_pin_cfg *cfg)
1887{ 1954{
1888 char name[32]; 1955 struct via_spec *spec = codec->spec;
1956 struct auto_pin_cfg *cfg = &spec->autocfg;
1957 struct nid_path *path;
1889 static const char * const chname[4] = { 1958 static const char * const chname[4] = {
1890 "Front", "Surround", "C/LFE", "Side" 1959 "Front", "Surround", "C/LFE", "Side"
1891 }; 1960 };
1892 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 1961 int i, idx, err;
1893 int i, err; 1962 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 1963
1901 nid_vol = nid_vols[i]; 1964 /* check smart51 */
1965 old_line_outs = cfg->line_outs;
1966 if (cfg->line_outs == 1)
1967 mangle_smart51(codec);
1902 1968
1903 if (i == AUTO_SEQ_CENLFE) { 1969 err = via_auto_fill_dac_nids(codec);
1904 /* Center/LFE */ 1970 if (err < 0)
1905 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 1971 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 1972
1944 /* add control to PW3 */ 1973 if (spec->multiout.num_dacs < 3) {
1945 sprintf(name, "%s Playback Volume", chname[i]); 1974 spec->smart51_nums = 0;
1946 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1975 cfg->line_outs = old_line_outs;
1947 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 1976 }
1948 HDA_OUTPUT)); 1977 for (i = 0; i < cfg->line_outs; i++) {
1978 hda_nid_t pin, dac;
1979 pin = cfg->line_out_pins[i];
1980 dac = spec->multiout.dac_nids[i];
1981 if (!pin || !dac)
1982 continue;
1983 path = spec->out_path + i;
1984 if (i == HDA_CLFE) {
1985 err = create_ch_ctls(codec, "Center", 1, true, path);
1949 if (err < 0) 1986 if (err < 0)
1950 return err; 1987 return err;
1951 sprintf(name, "%s Playback Switch", chname[i]); 1988 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) 1989 if (err < 0)
1956 return err; 1990 return err;
1957 } else { 1991 } else {
1958 sprintf(name, "%s Playback Volume", chname[i]); 1992 const char *pfx = chname[i];
1959 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, 1993 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
1960 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, 1994 cfg->line_outs == 1)
1961 HDA_OUTPUT)); 1995 pfx = "Speaker";
1962 if (err < 0) 1996 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) 1997 if (err < 0)
1969 return err; 1998 return err;
1970 } 1999 }
2000 if (path != spec->out_path + i)
2001 copy_path_mixer_ctls(&spec->out_path[i], path);
2002 if (path == spec->out_path && spec->out_mix_path.depth)
2003 copy_path_mixer_ctls(&spec->out_mix_path, path);
2004 }
2005
2006 idx = get_connection_index(codec, spec->aa_mix_nid,
2007 spec->multiout.dac_nids[0]);
2008 if (idx >= 0) {
2009 /* add control to mixer */
2010 const char *name;
2011 name = spec->out_mix_path.depth ?
2012 "PCM Loopback Playback Volume" : "PCM Playback Volume";
2013 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2014 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2015 idx, HDA_INPUT));
2016 if (err < 0)
2017 return err;
2018 name = spec->out_mix_path.depth ?
2019 "PCM Loopback Playback Switch" : "PCM Playback Switch";
2020 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
2021 HDA_COMPOSE_AMP_VAL(spec->aa_mix_nid, 3,
2022 idx, HDA_INPUT));
2023 if (err < 0)
2024 return err;
1971 } 2025 }
1972 2026
2027 cfg->line_outs = old_line_outs;
2028
1973 return 0; 2029 return 0;
1974} 2030}
1975 2031
1976static void create_hp_imux(struct via_spec *spec) 2032static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
1977{ 2033{
1978 int i; 2034 struct via_spec *spec = codec->spec;
1979 struct hda_input_mux *imux = &spec->private_imux[1]; 2035 struct nid_path *path;
1980 static const char * const texts[] = { "OFF", "ON", NULL}; 2036 bool check_dac;
2037 int i, err;
2038
2039 if (!pin)
2040 return 0;
2041
2042 if (!parse_output_path(codec, pin, 0, 0, &spec->hp_indep_path)) {
2043 for (i = HDA_SIDE; i >= HDA_CLFE; i--) {
2044 if (i < spec->multiout.num_dacs &&
2045 parse_output_path(codec, pin,
2046 spec->multiout.dac_nids[i], 0,
2047 &spec->hp_indep_path)) {
2048 spec->hp_indep_shared = i;
2049 break;
2050 }
2051 }
2052 }
2053 if (spec->hp_indep_path.depth) {
2054 spec->hp_dac_nid = spec->hp_indep_path.path[0];
2055 if (!spec->hp_indep_shared)
2056 spec->hp_path = spec->hp_indep_path;
2057 }
2058 /* optionally check front-path w/o AA-mix */
2059 if (!spec->hp_path.depth)
2060 parse_output_path(codec, pin,
2061 spec->multiout.dac_nids[HDA_FRONT], 0,
2062 &spec->hp_path);
1981 2063
1982 /* for hp mode select */ 2064 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
1983 for (i = 0; texts[i]; i++) 2065 1, &spec->hp_mix_path) && !spec->hp_path.depth)
1984 snd_hda_add_imux_item(imux, texts[i], i, NULL); 2066 return 0;
1985 2067
1986 spec->hp_mux = &spec->private_imux[1]; 2068 if (spec->hp_path.depth) {
2069 path = &spec->hp_path;
2070 check_dac = true;
2071 } else {
2072 path = &spec->hp_mix_path;
2073 check_dac = false;
2074 }
2075 err = create_ch_ctls(codec, "Headphone", 3, check_dac, path);
2076 if (err < 0)
2077 return err;
2078 if (check_dac)
2079 copy_path_mixer_ctls(&spec->hp_mix_path, path);
2080 else
2081 copy_path_mixer_ctls(&spec->hp_path, path);
2082 if (spec->hp_indep_path.depth)
2083 copy_path_mixer_ctls(&spec->hp_indep_path, path);
2084 return 0;
1987} 2085}
1988 2086
1989static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) 2087static int via_auto_create_speaker_ctls(struct hda_codec *codec)
1990{ 2088{
2089 struct via_spec *spec = codec->spec;
2090 struct nid_path *path;
2091 bool check_dac;
2092 hda_nid_t pin, dac = 0;
1991 int err; 2093 int err;
1992 2094
1993 if (!pin) 2095 pin = spec->autocfg.speaker_pins[0];
2096 if (!spec->autocfg.speaker_outs || !pin)
2097 return 0;
2098
2099 if (parse_output_path(codec, pin, 0, 0, &spec->speaker_path))
2100 dac = spec->speaker_path.path[0];
2101 if (!dac)
2102 parse_output_path(codec, pin,
2103 spec->multiout.dac_nids[HDA_FRONT], 0,
2104 &spec->speaker_path);
2105 if (!parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT],
2106 1, &spec->speaker_mix_path) && !dac)
1994 return 0; 2107 return 0;
1995 2108
1996 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */ 2109 /* no AA-path for front? */
1997 spec->hp_independent_mode_index = 1; 2110 if (!spec->out_mix_path.depth && spec->speaker_mix_path.depth)
2111 dac = 0;
1998 2112
1999 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, 2113 spec->speaker_dac_nid = dac;
2000 "Headphone Playback Volume", 2114 spec->multiout.extra_out_nid[0] = dac;
2001 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2115 if (dac) {
2116 path = &spec->speaker_path;
2117 check_dac = true;
2118 } else {
2119 path = &spec->speaker_mix_path;
2120 check_dac = false;
2121 }
2122 err = create_ch_ctls(codec, "Speaker", 3, check_dac, path);
2002 if (err < 0) 2123 if (err < 0)
2003 return err; 2124 return err;
2004 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, 2125 if (check_dac)
2005 "Headphone Playback Switch", 2126 copy_path_mixer_ctls(&spec->speaker_mix_path, path);
2006 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); 2127 else
2128 copy_path_mixer_ctls(&spec->speaker_path, path);
2129 return 0;
2130}
2131
2132#define via_aamix_ctl_info via_pin_power_ctl_info
2133
2134static int via_aamix_ctl_get(struct snd_kcontrol *kcontrol,
2135 struct snd_ctl_elem_value *ucontrol)
2136{
2137 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2138 struct via_spec *spec = codec->spec;
2139 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2140 return 0;
2141}
2142
2143static void update_aamix_paths(struct hda_codec *codec, int do_mix,
2144 struct nid_path *nomix, struct nid_path *mix)
2145{
2146 if (do_mix) {
2147 activate_output_path(codec, nomix, false, false);
2148 activate_output_path(codec, mix, true, false);
2149 } else {
2150 activate_output_path(codec, mix, false, false);
2151 activate_output_path(codec, nomix, true, false);
2152 }
2153}
2154
2155static int via_aamix_ctl_put(struct snd_kcontrol *kcontrol,
2156 struct snd_ctl_elem_value *ucontrol)
2157{
2158 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2159 struct via_spec *spec = codec->spec;
2160 unsigned int val = ucontrol->value.enumerated.item[0];
2161
2162 if (val == spec->aamix_mode)
2163 return 0;
2164 spec->aamix_mode = val;
2165 /* update front path */
2166 update_aamix_paths(codec, val, &spec->out_path[0], &spec->out_mix_path);
2167 /* update HP path */
2168 if (!spec->hp_independent_mode) {
2169 update_aamix_paths(codec, val, &spec->hp_path,
2170 &spec->hp_mix_path);
2171 }
2172 /* update speaker path */
2173 update_aamix_paths(codec, val, &spec->speaker_path,
2174 &spec->speaker_mix_path);
2175 return 1;
2176}
2177
2178static const struct snd_kcontrol_new via_aamix_ctl_enum = {
2179 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2180 .name = "Loopback Mixing",
2181 .info = via_aamix_ctl_info,
2182 .get = via_aamix_ctl_get,
2183 .put = via_aamix_ctl_put,
2184};
2185
2186static int via_auto_create_loopback_switch(struct hda_codec *codec)
2187{
2188 struct via_spec *spec = codec->spec;
2189
2190 if (!spec->aa_mix_nid)
2191 return 0; /* no loopback switching available */
2192 if (!(spec->out_mix_path.depth || spec->hp_mix_path.depth ||
2193 spec->speaker_path.depth))
2194 return 0; /* no loopback switching available */
2195 if (!via_clone_control(spec, &via_aamix_ctl_enum))
2196 return -ENOMEM;
2197 return 0;
2198}
2199
2200/* look for ADCs */
2201static int via_fill_adcs(struct hda_codec *codec)
2202{
2203 struct via_spec *spec = codec->spec;
2204 hda_nid_t nid = codec->start_nid;
2205 int i;
2206
2207 for (i = 0; i < codec->num_nodes; i++, nid++) {
2208 unsigned int wcaps = get_wcaps(codec, nid);
2209 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2210 continue;
2211 if (wcaps & AC_WCAP_DIGITAL)
2212 continue;
2213 if (!(wcaps & AC_WCAP_CONN_LIST))
2214 continue;
2215 if (spec->num_adc_nids >= ARRAY_SIZE(spec->adc_nids))
2216 return -ENOMEM;
2217 spec->adc_nids[spec->num_adc_nids++] = nid;
2218 }
2219 return 0;
2220}
2221
2222/* input-src control */
2223static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
2224 struct snd_ctl_elem_info *uinfo)
2225{
2226 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2227 struct via_spec *spec = codec->spec;
2228
2229 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2230 uinfo->count = 1;
2231 uinfo->value.enumerated.items = spec->num_inputs;
2232 if (uinfo->value.enumerated.item >= spec->num_inputs)
2233 uinfo->value.enumerated.item = spec->num_inputs - 1;
2234 strcpy(uinfo->value.enumerated.name,
2235 spec->inputs[uinfo->value.enumerated.item].label);
2236 return 0;
2237}
2238
2239static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
2240 struct snd_ctl_elem_value *ucontrol)
2241{
2242 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2243 struct via_spec *spec = codec->spec;
2244 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2245
2246 ucontrol->value.enumerated.item[0] = spec->cur_mux[idx];
2247 return 0;
2248}
2249
2250static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
2251 struct snd_ctl_elem_value *ucontrol)
2252{
2253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2254 struct via_spec *spec = codec->spec;
2255 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2256 hda_nid_t mux;
2257 int cur;
2258
2259 cur = ucontrol->value.enumerated.item[0];
2260 if (cur < 0 || cur >= spec->num_inputs)
2261 return -EINVAL;
2262 if (spec->cur_mux[idx] == cur)
2263 return 0;
2264 spec->cur_mux[idx] = cur;
2265 if (spec->dyn_adc_switch) {
2266 int adc_idx = spec->inputs[cur].adc_idx;
2267 mux = spec->mux_nids[adc_idx];
2268 via_dyn_adc_pcm_resetup(codec, cur);
2269 } else {
2270 mux = spec->mux_nids[idx];
2271 if (snd_BUG_ON(!mux))
2272 return -EINVAL;
2273 }
2274
2275 if (mux) {
2276 /* switch to D0 beofre change index */
2277 if (snd_hda_codec_read(codec, mux, 0,
2278 AC_VERB_GET_POWER_STATE, 0x00) != AC_PWRST_D0)
2279 snd_hda_codec_write(codec, mux, 0,
2280 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2281 snd_hda_codec_write(codec, mux, 0,
2282 AC_VERB_SET_CONNECT_SEL,
2283 spec->inputs[cur].mux_idx);
2284 }
2285
2286 /* update jack power state */
2287 set_widgets_power_state(codec);
2288 return 0;
2289}
2290
2291static const struct snd_kcontrol_new via_input_src_ctl = {
2292 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2293 /* The multiple "Capture Source" controls confuse alsamixer
2294 * So call somewhat different..
2295 */
2296 /* .name = "Capture Source", */
2297 .name = "Input Source",
2298 .info = via_mux_enum_info,
2299 .get = via_mux_enum_get,
2300 .put = via_mux_enum_put,
2301};
2302
2303static int create_input_src_ctls(struct hda_codec *codec, int count)
2304{
2305 struct via_spec *spec = codec->spec;
2306 struct snd_kcontrol_new *knew;
2307
2308 if (spec->num_inputs <= 1 || !count)
2309 return 0; /* no need for single src */
2310
2311 knew = via_clone_control(spec, &via_input_src_ctl);
2312 if (!knew)
2313 return -ENOMEM;
2314 knew->count = count;
2315 return 0;
2316}
2317
2318/* add the powersave loopback-list entry */
2319static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2320{
2321 struct hda_amp_list *list;
2322
2323 if (spec->num_loopbacks >= ARRAY_SIZE(spec->loopback_list) - 1)
2324 return;
2325 list = spec->loopback_list + spec->num_loopbacks;
2326 list->nid = mix;
2327 list->dir = HDA_INPUT;
2328 list->idx = idx;
2329 spec->num_loopbacks++;
2330 spec->loopback.amplist = spec->loopback_list;
2331}
2332
2333static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
2334 hda_nid_t dst)
2335{
2336 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
2337}
2338
2339/* add the input-route to the given pin */
2340static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
2341{
2342 struct via_spec *spec = codec->spec;
2343 int c, idx;
2344
2345 spec->inputs[spec->num_inputs].adc_idx = -1;
2346 spec->inputs[spec->num_inputs].pin = pin;
2347 for (c = 0; c < spec->num_adc_nids; c++) {
2348 if (spec->mux_nids[c]) {
2349 idx = get_connection_index(codec, spec->mux_nids[c],
2350 pin);
2351 if (idx < 0)
2352 continue;
2353 spec->inputs[spec->num_inputs].mux_idx = idx;
2354 } else {
2355 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
2356 continue;
2357 }
2358 spec->inputs[spec->num_inputs].adc_idx = c;
2359 /* Can primary ADC satisfy all inputs? */
2360 if (!spec->dyn_adc_switch &&
2361 spec->num_inputs > 0 && spec->inputs[0].adc_idx != c) {
2362 snd_printd(KERN_INFO
2363 "via: dynamic ADC switching enabled\n");
2364 spec->dyn_adc_switch = 1;
2365 }
2366 return true;
2367 }
2368 return false;
2369}
2370
2371static int get_mux_nids(struct hda_codec *codec);
2372
2373/* parse input-routes; fill ADCs, MUXs and input-src entries */
2374static int parse_analog_inputs(struct hda_codec *codec)
2375{
2376 struct via_spec *spec = codec->spec;
2377 const struct auto_pin_cfg *cfg = &spec->autocfg;
2378 int i, err;
2379
2380 err = via_fill_adcs(codec);
2007 if (err < 0) 2381 if (err < 0)
2008 return err; 2382 return err;
2383 err = get_mux_nids(codec);
2384 if (err < 0)
2385 return err;
2386
2387 /* fill all input-routes */
2388 for (i = 0; i < cfg->num_inputs; i++) {
2389 if (add_input_route(codec, cfg->inputs[i].pin))
2390 spec->inputs[spec->num_inputs++].label =
2391 hda_get_autocfg_input_label(codec, cfg, i);
2392 }
2009 2393
2010 create_hp_imux(spec); 2394 /* check for internal loopback recording */
2395 if (spec->aa_mix_nid &&
2396 add_input_route(codec, spec->aa_mix_nid))
2397 spec->inputs[spec->num_inputs++].label = "Stereo Mixer";
2011 2398
2012 return 0; 2399 return 0;
2013} 2400}
2014 2401
2015/* create playback/capture controls for input pins */ 2402/* create analog-loopback volume/switch controls */
2016static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, 2403static 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{ 2404{
2022 struct via_spec *spec = codec->spec; 2405 struct via_spec *spec = codec->spec;
2023 struct hda_input_mux *imux = &spec->private_imux[0]; 2406 const struct auto_pin_cfg *cfg = &spec->autocfg;
2024 int i, err, idx, type, type_idx = 0; 2407 const char *prev_label = NULL;
2408 int type_idx = 0;
2409 int i, j, err, idx;
2025 2410
2026 /* for internal loopback recording select */ 2411 if (!spec->aa_mix_nid)
2027 for (idx = 0; idx < num_idxs; idx++) { 2412 return 0;
2028 if (pin_idxs[idx] == 0xff) { 2413
2029 snd_hda_add_imux_item(imux, "Stereo Mixer", idx, NULL); 2414 for (i = 0; i < cfg->num_inputs; i++) {
2030 break; 2415 hda_nid_t pin = cfg->inputs[i].pin;
2416 const char *label = hda_get_autocfg_input_label(codec, cfg, i);
2417
2418 if (prev_label && !strcmp(label, prev_label))
2419 type_idx++;
2420 else
2421 type_idx = 0;
2422 prev_label = label;
2423 idx = get_connection_index(codec, spec->aa_mix_nid, pin);
2424 if (idx >= 0) {
2425 err = via_new_analog_input(spec, label, type_idx,
2426 idx, spec->aa_mix_nid);
2427 if (err < 0)
2428 return err;
2429 add_loopback_list(spec, spec->aa_mix_nid, idx);
2430 }
2431
2432 /* remember the label for smart51 control */
2433 for (j = 0; j < spec->smart51_nums; j++) {
2434 if (spec->smart51_pins[j] == pin) {
2435 spec->smart51_idxs[j] = idx;
2436 spec->smart51_labels[j] = label;
2437 break;
2438 }
2031 } 2439 }
2032 } 2440 }
2441 return 0;
2442}
2443
2444/* create mic-boost controls (if present) */
2445static int create_mic_boost_ctls(struct hda_codec *codec)
2446{
2447 struct via_spec *spec = codec->spec;
2448 const struct auto_pin_cfg *cfg = &spec->autocfg;
2449 int i, err;
2033 2450
2034 for (i = 0; i < cfg->num_inputs; i++) { 2451 for (i = 0; i < cfg->num_inputs; i++) {
2452 hda_nid_t pin = cfg->inputs[i].pin;
2453 unsigned int caps;
2035 const char *label; 2454 const char *label;
2036 type = cfg->inputs[i].type; 2455 char name[32];
2037 for (idx = 0; idx < num_idxs; idx++) 2456
2038 if (pin_idxs[idx] == cfg->inputs[i].pin) 2457 if (cfg->inputs[i].type != AUTO_PIN_MIC)
2039 break; 2458 continue;
2040 if (idx >= num_idxs) 2459 caps = query_amp_caps(codec, pin, HDA_INPUT);
2460 if (caps == -1 || !(caps & AC_AMPCAP_NUM_STEPS))
2041 continue; 2461 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); 2462 label = hda_get_autocfg_input_label(codec, cfg, i);
2047 if (spec->codec_type == VT1708S || 2463 snprintf(name, sizeof(name), "%s Boost Volume", label);
2048 spec->codec_type == VT1702 || 2464 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
2049 spec->codec_type == VT1716S) 2465 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_INPUT));
2050 err = via_new_analog_input(spec, label, type_idx, 2466 if (err < 0)
2051 idx+1, cap_nid); 2467 return err;
2052 else 2468 }
2053 err = via_new_analog_input(spec, label, type_idx, 2469 return 0;
2054 idx, cap_nid); 2470}
2471
2472/* create capture and input-src controls for multiple streams */
2473static int create_multi_adc_ctls(struct hda_codec *codec)
2474{
2475 struct via_spec *spec = codec->spec;
2476 int i, err;
2477
2478 /* create capture mixer elements */
2479 for (i = 0; i < spec->num_adc_nids; i++) {
2480 hda_nid_t adc = spec->adc_nids[i];
2481 err = __via_add_control(spec, VIA_CTL_WIDGET_VOL,
2482 "Capture Volume", i,
2483 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2484 HDA_INPUT));
2485 if (err < 0)
2486 return err;
2487 err = __via_add_control(spec, VIA_CTL_WIDGET_MUTE,
2488 "Capture Switch", i,
2489 HDA_COMPOSE_AMP_VAL(adc, 3, 0,
2490 HDA_INPUT));
2055 if (err < 0) 2491 if (err < 0)
2056 return err; 2492 return err;
2057 snd_hda_add_imux_item(imux, label, idx, NULL);
2058 } 2493 }
2494
2495 /* input-source control */
2496 for (i = 0; i < spec->num_adc_nids; i++)
2497 if (!spec->mux_nids[i])
2498 break;
2499 err = create_input_src_ctls(codec, i);
2500 if (err < 0)
2501 return err;
2059 return 0; 2502 return 0;
2060} 2503}
2061 2504
2062/* create playback/capture controls for input pins */ 2505/* bind capture volume/switch */
2063static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, 2506static struct snd_kcontrol_new via_bind_cap_vol_ctl =
2064 const struct auto_pin_cfg *cfg) 2507 HDA_BIND_VOL("Capture Volume", 0);
2508static struct snd_kcontrol_new via_bind_cap_sw_ctl =
2509 HDA_BIND_SW("Capture Switch", 0);
2510
2511static int init_bind_ctl(struct via_spec *spec, struct hda_bind_ctls **ctl_ret,
2512 struct hda_ctl_ops *ops)
2065{ 2513{
2066 static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; 2514 struct hda_bind_ctls *ctl;
2067 return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, 2515 int i;
2068 ARRAY_SIZE(pin_idxs)); 2516
2517 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * 4, GFP_KERNEL);
2518 if (!ctl)
2519 return -ENOMEM;
2520 ctl->ops = ops;
2521 for (i = 0; i < spec->num_adc_nids; i++)
2522 ctl->values[i] =
2523 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 3, 0, HDA_INPUT);
2524 *ctl_ret = ctl;
2525 return 0;
2069} 2526}
2070 2527
2071#ifdef CONFIG_SND_HDA_POWER_SAVE 2528/* create capture and input-src controls for dynamic ADC-switch case */
2072static const struct hda_amp_list vt1708_loopbacks[] = { 2529static int create_dyn_adc_ctls(struct hda_codec *codec)
2073 { 0x17, HDA_INPUT, 1 }, 2530{
2074 { 0x17, HDA_INPUT, 2 }, 2531 struct via_spec *spec = codec->spec;
2075 { 0x17, HDA_INPUT, 3 }, 2532 struct snd_kcontrol_new *knew;
2076 { 0x17, HDA_INPUT, 4 }, 2533 int err;
2077 { } /* end */ 2534
2078}; 2535 /* set up the bind capture ctls */
2079#endif 2536 err = init_bind_ctl(spec, &spec->bind_cap_vol, &snd_hda_bind_vol);
2537 if (err < 0)
2538 return err;
2539 err = init_bind_ctl(spec, &spec->bind_cap_sw, &snd_hda_bind_sw);
2540 if (err < 0)
2541 return err;
2542
2543 /* create capture mixer elements */
2544 knew = via_clone_control(spec, &via_bind_cap_vol_ctl);
2545 if (!knew)
2546 return -ENOMEM;
2547 knew->private_value = (long)spec->bind_cap_vol;
2548
2549 knew = via_clone_control(spec, &via_bind_cap_sw_ctl);
2550 if (!knew)
2551 return -ENOMEM;
2552 knew->private_value = (long)spec->bind_cap_sw;
2553
2554 /* input-source control */
2555 err = create_input_src_ctls(codec, 1);
2556 if (err < 0)
2557 return err;
2558 return 0;
2559}
2560
2561/* parse and create capture-related stuff */
2562static int via_auto_create_analog_input_ctls(struct hda_codec *codec)
2563{
2564 struct via_spec *spec = codec->spec;
2565 int err;
2566
2567 err = parse_analog_inputs(codec);
2568 if (err < 0)
2569 return err;
2570 if (spec->dyn_adc_switch)
2571 err = create_dyn_adc_ctls(codec);
2572 else
2573 err = create_multi_adc_ctls(codec);
2574 if (err < 0)
2575 return err;
2576 err = create_loopback_ctls(codec);
2577 if (err < 0)
2578 return err;
2579 err = create_mic_boost_ctls(codec);
2580 if (err < 0)
2581 return err;
2582 return 0;
2583}
2080 2584
2081static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) 2585static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2082{ 2586{
@@ -2095,7 +2599,7 @@ static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid)
2095 return; 2599 return;
2096} 2600}
2097 2601
2098static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol, 2602static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol,
2099 struct snd_ctl_elem_value *ucontrol) 2603 struct snd_ctl_elem_value *ucontrol)
2100{ 2604{
2101 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2605 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -2103,113 +2607,168 @@ static int vt1708_jack_detectect_get(struct snd_kcontrol *kcontrol,
2103 2607
2104 if (spec->codec_type != VT1708) 2608 if (spec->codec_type != VT1708)
2105 return 0; 2609 return 0;
2106 spec->vt1708_jack_detectect = 2610 ucontrol->value.integer.value[0] = spec->vt1708_jack_detect;
2107 !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1);
2108 ucontrol->value.integer.value[0] = spec->vt1708_jack_detectect;
2109 return 0; 2611 return 0;
2110} 2612}
2111 2613
2112static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, 2614static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
2113 struct snd_ctl_elem_value *ucontrol) 2615 struct snd_ctl_elem_value *ucontrol)
2114{ 2616{
2115 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2617 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2116 struct via_spec *spec = codec->spec; 2618 struct via_spec *spec = codec->spec;
2117 int change; 2619 int val;
2118 2620
2119 if (spec->codec_type != VT1708) 2621 if (spec->codec_type != VT1708)
2120 return 0; 2622 return 0;
2121 spec->vt1708_jack_detectect = ucontrol->value.integer.value[0]; 2623 val = !!ucontrol->value.integer.value[0];
2122 change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) 2624 if (spec->vt1708_jack_detect == val)
2123 == !spec->vt1708_jack_detectect; 2625 return 0;
2124 if (spec->vt1708_jack_detectect) { 2626 spec->vt1708_jack_detect = val;
2627 if (spec->vt1708_jack_detect &&
2628 snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) {
2125 mute_aa_path(codec, 1); 2629 mute_aa_path(codec, 1);
2126 notify_aa_path_ctls(codec); 2630 notify_aa_path_ctls(codec);
2127 } 2631 }
2128 return change; 2632 via_hp_automute(codec);
2633 vt1708_update_hp_work(spec);
2634 return 1;
2129} 2635}
2130 2636
2131static const struct snd_kcontrol_new vt1708_jack_detectect[] = { 2637static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
2132 { 2638 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2133 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2639 .name = "Jack Detect",
2134 .name = "Jack Detect", 2640 .count = 1,
2135 .count = 1, 2641 .info = snd_ctl_boolean_mono_info,
2136 .info = snd_ctl_boolean_mono_info, 2642 .get = vt1708_jack_detect_get,
2137 .get = vt1708_jack_detectect_get, 2643 .put = vt1708_jack_detect_put,
2138 .put = vt1708_jack_detectect_put,
2139 },
2140 {} /* end */
2141}; 2644};
2142 2645
2143static int vt1708_parse_auto_config(struct hda_codec *codec) 2646static void fill_dig_outs(struct hda_codec *codec);
2647static void fill_dig_in(struct hda_codec *codec);
2648
2649static int via_parse_auto_config(struct hda_codec *codec)
2144{ 2650{
2145 struct via_spec *spec = codec->spec; 2651 struct via_spec *spec = codec->spec;
2146 int err; 2652 int err;
2147 2653
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); 2654 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
2153 if (err < 0) 2655 if (err < 0)
2154 return err; 2656 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]) 2657 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
2159 return 0; /* can't find valid BIOS pin config */ 2658 return -EINVAL;
2160 2659
2161 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg); 2660 err = via_auto_create_multi_out_ctls(codec);
2162 if (err < 0) 2661 if (err < 0)
2163 return err; 2662 return err;
2164 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 2663 err = via_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
2165 if (err < 0) 2664 if (err < 0)
2166 return err; 2665 return err;
2167 err = vt1708_auto_create_analog_input_ctls(codec, &spec->autocfg); 2666 err = via_auto_create_speaker_ctls(codec);
2168 if (err < 0) 2667 if (err < 0)
2169 return err; 2668 return err;
2170 /* add jack detect on/off control */ 2669 err = via_auto_create_loopback_switch(codec);
2171 err = snd_hda_add_new_ctls(codec, vt1708_jack_detectect); 2670 if (err < 0)
2671 return err;
2672 err = via_auto_create_analog_input_ctls(codec);
2172 if (err < 0) 2673 if (err < 0)
2173 return err; 2674 return err;
2174 2675
2175 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2676 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
2176 2677
2177 if (spec->autocfg.dig_outs) 2678 fill_dig_outs(codec);
2178 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID; 2679 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 2680
2183 if (spec->kctls.list) 2681 if (spec->kctls.list)
2184 spec->mixers[spec->num_mixers++] = spec->kctls.list; 2682 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2185 2683
2186 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
2187 2684
2188 spec->input_mux = &spec->private_imux[0]; 2685 if (spec->hp_dac_nid && spec->hp_mix_path.depth) {
2686 err = via_hp_build(codec);
2687 if (err < 0)
2688 return err;
2689 }
2690
2691 err = via_smart51_build(codec);
2692 if (err < 0)
2693 return err;
2189 2694
2190 if (spec->hp_mux) 2695 /* assign slave outs */
2191 via_hp_build(codec); 2696 if (spec->slave_dig_outs[0])
2697 codec->slave_dig_outs = spec->slave_dig_outs;
2192 2698
2193 via_smart51_build(spec);
2194 return 1; 2699 return 1;
2195} 2700}
2196 2701
2197/* init callback for auto-configuration model -- overriding the default init */ 2702static void via_auto_init_dig_outs(struct hda_codec *codec)
2198static int via_auto_init(struct hda_codec *codec)
2199{ 2703{
2200 struct via_spec *spec = codec->spec; 2704 struct via_spec *spec = codec->spec;
2705 if (spec->multiout.dig_out_nid)
2706 init_output_pin(codec, spec->autocfg.dig_out_pins[0], PIN_OUT);
2707 if (spec->slave_dig_outs[0])
2708 init_output_pin(codec, spec->autocfg.dig_out_pins[1], PIN_OUT);
2709}
2710
2711static void via_auto_init_dig_in(struct hda_codec *codec)
2712{
2713 struct via_spec *spec = codec->spec;
2714 if (!spec->dig_in_nid)
2715 return;
2716 snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0,
2717 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN);
2718}
2719
2720/* initialize the unsolicited events */
2721static void via_auto_init_unsol_event(struct hda_codec *codec)
2722{
2723 struct via_spec *spec = codec->spec;
2724 struct auto_pin_cfg *cfg = &spec->autocfg;
2725 unsigned int ev;
2726 int i;
2727
2728 if (cfg->hp_pins[0] && is_jack_detectable(codec, cfg->hp_pins[0]))
2729 snd_hda_codec_write(codec, cfg->hp_pins[0], 0,
2730 AC_VERB_SET_UNSOLICITED_ENABLE,
2731 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT);
2732
2733 if (cfg->speaker_pins[0])
2734 ev = VIA_LINE_EVENT;
2735 else
2736 ev = 0;
2737 for (i = 0; i < cfg->line_outs; i++) {
2738 if (cfg->line_out_pins[i] &&
2739 is_jack_detectable(codec, cfg->line_out_pins[i]))
2740 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
2741 AC_VERB_SET_UNSOLICITED_ENABLE,
2742 AC_USRSP_EN | ev | VIA_JACK_EVENT);
2743 }
2744
2745 for (i = 0; i < cfg->num_inputs; i++) {
2746 if (is_jack_detectable(codec, cfg->inputs[i].pin))
2747 snd_hda_codec_write(codec, cfg->inputs[i].pin, 0,
2748 AC_VERB_SET_UNSOLICITED_ENABLE,
2749 AC_USRSP_EN | VIA_JACK_EVENT);
2750 }
2751}
2752
2753static int via_init(struct hda_codec *codec)
2754{
2755 struct via_spec *spec = codec->spec;
2756 int i;
2757
2758 for (i = 0; i < spec->num_iverbs; i++)
2759 snd_hda_sequence_write(codec, spec->init_verbs[i]);
2201 2760
2202 via_init(codec);
2203 via_auto_init_multi_out(codec); 2761 via_auto_init_multi_out(codec);
2204 via_auto_init_hp_out(codec); 2762 via_auto_init_hp_out(codec);
2763 via_auto_init_speaker_out(codec);
2205 via_auto_init_analog_input(codec); 2764 via_auto_init_analog_input(codec);
2765 via_auto_init_dig_outs(codec);
2766 via_auto_init_dig_in(codec);
2206 2767
2207 if (VT2002P_COMPATIBLE(spec)) { 2768 via_auto_init_unsol_event(codec);
2208 via_hp_bind_automute(codec); 2769
2209 } else { 2770 via_hp_automute(codec);
2210 via_hp_automute(codec); 2771 vt1708_update_hp_work(spec);
2211 via_speaker_automute(codec);
2212 }
2213 2772
2214 return 0; 2773 return 0;
2215} 2774}
@@ -2226,7 +2785,9 @@ static void vt1708_update_hp_jack_state(struct work_struct *work)
2226 spec->vt1708_hp_present ^= 1; 2785 spec->vt1708_hp_present ^= 1;
2227 via_hp_automute(spec->codec); 2786 via_hp_automute(spec->codec);
2228 } 2787 }
2229 vt1708_start_hp_work(spec); 2788 if (spec->vt1708_jack_detect)
2789 schedule_delayed_work(&spec->vt1708_hp_work,
2790 msecs_to_jiffies(100));
2230} 2791}
2231 2792
2232static int get_mux_nids(struct hda_codec *codec) 2793static int get_mux_nids(struct hda_codec *codec)
@@ -2266,437 +2827,36 @@ static int patch_vt1708(struct hda_codec *codec)
2266 if (spec == NULL) 2827 if (spec == NULL)
2267 return -ENOMEM; 2828 return -ENOMEM;
2268 2829
2830 spec->aa_mix_nid = 0x17;
2831
2832 /* Add HP and CD pin config connect bit re-config action */
2833 vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
2834 vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
2835
2269 /* automatic parse from the BIOS config */ 2836 /* automatic parse from the BIOS config */
2270 err = vt1708_parse_auto_config(codec); 2837 err = via_parse_auto_config(codec);
2271 if (err < 0) { 2838 if (err < 0) {
2272 via_free(codec); 2839 via_free(codec);
2273 return err; 2840 return err;
2274 } else if (!err) {
2275 printk(KERN_INFO "hda_codec: Cannot set up configuration "
2276 "from BIOS. Using genenic mode...\n");
2277 } 2841 }
2278 2842
2843 /* add jack detect on/off control */
2844 if (!via_clone_control(spec, &vt1708_jack_detect_ctl))
2845 return -ENOMEM;
2279 2846
2280 spec->stream_name_analog = "VT1708 Analog";
2281 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
2282 /* disable 32bit format on VT1708 */ 2847 /* disable 32bit format on VT1708 */
2283 if (codec->vendor_id == 0x11061708) 2848 if (codec->vendor_id == 0x11061708)
2284 spec->stream_analog_playback = &vt1708_pcm_analog_s16_playback; 2849 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 2850
2291 2851 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 2852
2300 codec->patch_ops = via_patch_ops; 2853 codec->patch_ops = via_patch_ops;
2301 2854
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); 2855 INIT_DELAYED_WORK(&spec->vt1708_hp_work, vt1708_update_hp_jack_state);
2307 return 0; 2856 return 0;
2308} 2857}
2309 2858
2310/* capture mixer elements */ 2859static 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{ 2860{
2701 struct via_spec *spec; 2861 struct via_spec *spec;
2702 int err; 2862 int err;
@@ -2706,528 +2866,19 @@ static int patch_vt1709_10ch(struct hda_codec *codec)
2706 if (spec == NULL) 2866 if (spec == NULL)
2707 return -ENOMEM; 2867 return -ENOMEM;
2708 2868
2709 err = vt1709_parse_auto_config(codec); 2869 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 2870
2796 /* create a codec specific record */ 2871 err = via_parse_auto_config(codec);
2797 spec = via_new_spec(codec);
2798 if (spec == NULL)
2799 return -ENOMEM;
2800
2801 err = vt1709_parse_auto_config(codec);
2802 if (err < 0) { 2872 if (err < 0) {
2803 via_free(codec); 2873 via_free(codec);
2804 return err; 2874 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 } 2875 }
2829 2876
2830 codec->patch_ops = via_patch_ops; 2877 codec->patch_ops = via_patch_ops;
2831 2878
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; 2879 return 0;
3047} 2880}
3048 2881
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;
3166}
3167
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) 2882static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3232{ 2883{
3233 struct via_spec *spec = codec->spec; 2884 struct via_spec *spec = codec->spec;
@@ -3309,157 +2960,37 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3309} 2960}
3310 2961
3311static int patch_vt1708S(struct hda_codec *codec); 2962static int patch_vt1708S(struct hda_codec *codec);
3312static int patch_vt1708B_8ch(struct hda_codec *codec) 2963static int patch_vt1708B(struct hda_codec *codec)
3313{ 2964{
3314 struct via_spec *spec; 2965 struct via_spec *spec;
3315 int err; 2966 int err;
3316 2967
3317 if (get_codec_type(codec) == VT1708BCE) 2968 if (get_codec_type(codec) == VT1708BCE)
3318 return patch_vt1708S(codec); 2969 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 2970
3371 /* create a codec specific record */ 2971 /* create a codec specific record */
3372 spec = via_new_spec(codec); 2972 spec = via_new_spec(codec);
3373 if (spec == NULL) 2973 if (spec == NULL)
3374 return -ENOMEM; 2974 return -ENOMEM;
3375 2975
2976 spec->aa_mix_nid = 0x16;
2977
3376 /* automatic parse from the BIOS config */ 2978 /* automatic parse from the BIOS config */
3377 err = vt1708B_parse_auto_config(codec); 2979 err = via_parse_auto_config(codec);
3378 if (err < 0) { 2980 if (err < 0) {
3379 via_free(codec); 2981 via_free(codec);
3380 return err; 2982 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 } 2983 }
3404 2984
3405 codec->patch_ops = via_patch_ops; 2985 codec->patch_ops = via_patch_ops;
3406 2986
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; 2987 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3414 2988
3415 return 0; 2989 return 0;
3416} 2990}
3417 2991
3418/* Patch for VT1708S */ 2992/* Patch for VT1708S */
3419 2993static 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 */ 2994 /* Enable Mic Boost Volume backdoor */
3464 {0x1, 0xf98, 0x1}, 2995 {0x1, 0xf98, 0x1},
3465 /* don't bybass mixer */ 2996 /* don't bybass mixer */
@@ -3467,277 +2998,6 @@ static const struct hda_verb vt1708S_volume_init_verbs[] = {
3467 { } 2998 { }
3468}; 2999};
3469 3000
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 */ 3001/* fill out digital output widgets; one for master and one for slave outputs */
3742static void fill_dig_outs(struct hda_codec *codec) 3002static void fill_dig_outs(struct hda_codec *codec)
3743{ 3003{
@@ -3763,56 +3023,33 @@ static void fill_dig_outs(struct hda_codec *codec)
3763 } 3023 }
3764} 3024}
3765 3025
3766static int vt1708S_parse_auto_config(struct hda_codec *codec) 3026static void fill_dig_in(struct hda_codec *codec)
3767{ 3027{
3768 struct via_spec *spec = codec->spec; 3028 struct via_spec *spec = codec->spec;
3769 int err; 3029 hda_nid_t dig_nid;
3770 3030 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 3031
3799 if (spec->hp_mux) 3032 if (!spec->autocfg.dig_in_pin)
3800 via_hp_build(codec); 3033 return;
3801 3034
3802 via_smart51_build(spec); 3035 dig_nid = codec->start_nid;
3803 return 1; 3036 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
3037 unsigned int wcaps = get_wcaps(codec, dig_nid);
3038 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
3039 continue;
3040 if (!(wcaps & AC_WCAP_DIGITAL))
3041 continue;
3042 if (!(wcaps & AC_WCAP_CONN_LIST))
3043 continue;
3044 err = get_connection_index(codec, dig_nid,
3045 spec->autocfg.dig_in_pin);
3046 if (err >= 0) {
3047 spec->dig_in_nid = dig_nid;
3048 break;
3049 }
3050 }
3804} 3051}
3805 3052
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, 3053static void override_mic_boost(struct hda_codec *codec, hda_nid_t pin,
3817 int offset, int num_steps, int step_size) 3054 int offset, int num_steps, int step_size)
3818{ 3055{
@@ -3833,62 +3070,21 @@ static int patch_vt1708S(struct hda_codec *codec)
3833 if (spec == NULL) 3070 if (spec == NULL)
3834 return -ENOMEM; 3071 return -ENOMEM;
3835 3072
3073 spec->aa_mix_nid = 0x16;
3074 override_mic_boost(codec, 0x1a, 0, 3, 40);
3075 override_mic_boost(codec, 0x1e, 0, 3, 40);
3076
3836 /* automatic parse from the BIOS config */ 3077 /* automatic parse from the BIOS config */
3837 err = vt1708S_parse_auto_config(codec); 3078 err = via_parse_auto_config(codec);
3838 if (err < 0) { 3079 if (err < 0) {
3839 via_free(codec); 3080 via_free(codec);
3840 return err; 3081 return err;
3841 } else if (!err) {
3842 printk(KERN_INFO "hda_codec: Cannot set up configuration "
3843 "from BIOS. Using genenic mode...\n");
3844 } 3082 }
3845 3083
3846 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3084 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 3085
3884 codec->patch_ops = via_patch_ops; 3086 codec->patch_ops = via_patch_ops;
3885 3087
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 */ 3088 /* correct names for VT1708BCE */
3893 if (get_codec_type(codec) == VT1708BCE) { 3089 if (get_codec_type(codec) == VT1708BCE) {
3894 kfree(codec->chip_name); 3090 kfree(codec->chip_name);
@@ -3896,13 +3092,6 @@ static int patch_vt1708S(struct hda_codec *codec)
3896 snprintf(codec->bus->card->mixername, 3092 snprintf(codec->bus->card->mixername,
3897 sizeof(codec->bus->card->mixername), 3093 sizeof(codec->bus->card->mixername),
3898 "%s %s", codec->vendor_name, codec->chip_name); 3094 "%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 } 3095 }
3907 /* correct names for VT1705 */ 3096 /* correct names for VT1705 */
3908 if (codec->vendor_id == 0x11064397) { 3097 if (codec->vendor_id == 0x11064397) {
@@ -3918,55 +3107,7 @@ static int patch_vt1708S(struct hda_codec *codec)
3918 3107
3919/* Patch for VT1702 */ 3108/* Patch for VT1702 */
3920 3109
3921/* capture mixer elements */ 3110static 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 */ 3111 /* mixer enable */
3971 {0x1, 0xF88, 0x3}, 3112 {0x1, 0xF88, 0x3},
3972 /* GPIO 0~2 */ 3113 /* GPIO 0~2 */
@@ -3974,202 +3115,6 @@ static const struct hda_verb vt1702_volume_init_verbs[] = {
3974 { } 3115 { }
3975}; 3116};
3976 3117
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) 3118static void set_widgets_power_state_vt1702(struct hda_codec *codec)
4174{ 3119{
4175 int imux_is_smixer = 3120 int imux_is_smixer =
@@ -4211,393 +3156,41 @@ static int patch_vt1702(struct hda_codec *codec)
4211 if (spec == NULL) 3156 if (spec == NULL)
4212 return -ENOMEM; 3157 return -ENOMEM;
4213 3158
3159 spec->aa_mix_nid = 0x1a;
3160
3161 /* limit AA path volume to 0 dB */
3162 snd_hda_override_amp_caps(codec, 0x1A, HDA_INPUT,
3163 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
3164 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
3165 (0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
3166 (1 << AC_AMPCAP_MUTE_SHIFT));
3167
4214 /* automatic parse from the BIOS config */ 3168 /* automatic parse from the BIOS config */
4215 err = vt1702_parse_auto_config(codec); 3169 err = via_parse_auto_config(codec);
4216 if (err < 0) { 3170 if (err < 0) {
4217 via_free(codec); 3171 via_free(codec);
4218 return err; 3172 return err;
4219 } else if (!err) {
4220 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4221 "from BIOS. Using genenic mode...\n");
4222 } 3173 }
4223 3174
4224 spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs; 3175 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 3176
4242 codec->patch_ops = via_patch_ops; 3177 codec->patch_ops = via_patch_ops;
4243 3178
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; 3179 spec->set_widgets_power_state = set_widgets_power_state_vt1702;
4251 return 0; 3180 return 0;
4252} 3181}
4253 3182
4254/* Patch for VT1718S */ 3183/* Patch for VT1718S */
4255 3184
4256/* capture mixer elements */ 3185static 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 */ 3186 /* Enable MW0 adjust Gain 5 */
4287 {0x1, 0xfb2, 0x10}, 3187 {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 */ 3188 /* Enable Boost Volume backdoor */
4303 {0x1, 0xf88, 0x8}, 3189 {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
4321 3190
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 { } 3191 { }
4333}; 3192};
4334 3193
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) 3194static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4602{ 3195{
4603 struct via_spec *spec = codec->spec; 3196 struct via_spec *spec = codec->spec;
@@ -4664,6 +3257,41 @@ static void set_widgets_power_state_vt1718S(struct hda_codec *codec)
4664 } 3257 }
4665} 3258}
4666 3259
3260/* Add a connection to the primary DAC from AA-mixer for some codecs
3261 * This isn't listed from the raw info, but the chip has a secret connection.
3262 */
3263static int add_secret_dac_path(struct hda_codec *codec)
3264{
3265 struct via_spec *spec = codec->spec;
3266 int i, nums;
3267 hda_nid_t conn[8];
3268 hda_nid_t nid;
3269
3270 if (!spec->aa_mix_nid)
3271 return 0;
3272 nums = snd_hda_get_connections(codec, spec->aa_mix_nid, conn,
3273 ARRAY_SIZE(conn) - 1);
3274 for (i = 0; i < nums; i++) {
3275 if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT)
3276 return 0;
3277 }
3278
3279 /* find the primary DAC and add to the connection list */
3280 nid = codec->start_nid;
3281 for (i = 0; i < codec->num_nodes; i++, nid++) {
3282 unsigned int caps = get_wcaps(codec, nid);
3283 if (get_wcaps_type(caps) == AC_WID_AUD_OUT &&
3284 !(caps & AC_WCAP_DIGITAL)) {
3285 conn[nums++] = nid;
3286 return snd_hda_override_conn_list(codec,
3287 spec->aa_mix_nid,
3288 nums, conn);
3289 }
3290 }
3291 return 0;
3292}
3293
3294
4667static int patch_vt1718S(struct hda_codec *codec) 3295static int patch_vt1718S(struct hda_codec *codec)
4668{ 3296{
4669 struct via_spec *spec; 3297 struct via_spec *spec;
@@ -4674,57 +3302,22 @@ static int patch_vt1718S(struct hda_codec *codec)
4674 if (spec == NULL) 3302 if (spec == NULL)
4675 return -ENOMEM; 3303 return -ENOMEM;
4676 3304
3305 spec->aa_mix_nid = 0x21;
3306 override_mic_boost(codec, 0x2b, 0, 3, 40);
3307 override_mic_boost(codec, 0x29, 0, 3, 40);
3308 add_secret_dac_path(codec);
3309
4677 /* automatic parse from the BIOS config */ 3310 /* automatic parse from the BIOS config */
4678 err = vt1718S_parse_auto_config(codec); 3311 err = via_parse_auto_config(codec);
4679 if (err < 0) { 3312 if (err < 0) {
4680 via_free(codec); 3313 via_free(codec);
4681 return err; 3314 return err;
4682 } else if (!err) {
4683 printk(KERN_INFO "hda_codec: Cannot set up configuration "
4684 "from BIOS. Using genenic mode...\n");
4685 } 3315 }
4686 3316
4687 spec->init_verbs[spec->num_iverbs++] = vt1718S_volume_init_verbs; 3317 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 3318
4719 codec->patch_ops = via_patch_ops; 3319 codec->patch_ops = via_patch_ops;
4720 3320
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; 3321 spec->set_widgets_power_state = set_widgets_power_state_vt1718S;
4729 3322
4730 return 0; 3323 return 0;
@@ -4770,26 +3363,6 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
4770 return 1; 3363 return 1;
4771} 3364}
4772 3365
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[] = { 3366static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
4794 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), 3367 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
4795 { 3368 {
@@ -4811,45 +3384,7 @@ static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
4811 { } /* end */ 3384 { } /* end */
4812}; 3385};
4813 3386
4814static const struct hda_verb vt1716S_volume_init_verbs[] = { 3387static 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 */ 3388 /* Enable Boost Volume backdoor */
4854 {0x1, 0xf8a, 0x80}, 3389 {0x1, 0xf8a, 0x80},
4855 /* don't bybass mixer */ 3390 /* don't bybass mixer */
@@ -4859,272 +3394,6 @@ static const struct hda_verb vt1716S_volume_init_verbs[] = {
4859 { } 3394 { }
4860}; 3395};
4861 3396
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) 3397static void set_widgets_power_state_vt1716S(struct hda_codec *codec)
5129{ 3398{
5130 struct via_spec *spec = codec->spec; 3399 struct via_spec *spec = codec->spec;
@@ -5228,35 +3497,18 @@ static int patch_vt1716S(struct hda_codec *codec)
5228 if (spec == NULL) 3497 if (spec == NULL)
5229 return -ENOMEM; 3498 return -ENOMEM;
5230 3499
3500 spec->aa_mix_nid = 0x16;
3501 override_mic_boost(codec, 0x1a, 0, 3, 40);
3502 override_mic_boost(codec, 0x1e, 0, 3, 40);
3503
5231 /* automatic parse from the BIOS config */ 3504 /* automatic parse from the BIOS config */
5232 err = vt1716S_parse_auto_config(codec); 3505 err = via_parse_auto_config(codec);
5233 if (err < 0) { 3506 if (err < 0) {
5234 via_free(codec); 3507 via_free(codec);
5235 return err; 3508 return err;
5236 } else if (!err) {
5237 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5238 "from BIOS. Using genenic mode...\n");
5239 } 3509 }
5240 3510
5241 spec->init_verbs[spec->num_iverbs++] = vt1716S_volume_init_verbs; 3511 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 3512
5261 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer; 3513 spec->mixers[spec->num_mixers] = vt1716s_dmic_mixer;
5262 spec->num_mixers++; 3514 spec->num_mixers++;
@@ -5265,354 +3517,32 @@ static int patch_vt1716S(struct hda_codec *codec)
5265 3517
5266 codec->patch_ops = via_patch_ops; 3518 codec->patch_ops = via_patch_ops;
5267 3519
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; 3520 spec->set_widgets_power_state = set_widgets_power_state_vt1716S;
5276 return 0; 3521 return 0;
5277} 3522}
5278 3523
5279/* for vt2002P */ 3524/* for vt2002P */
5280 3525
5281/* capture mixer elements */ 3526static 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 */ 3527 /* Class-D speaker related verbs */
5307 {0x1, 0xfe0, 0x4}, 3528 {0x1, 0xfe0, 0x4},
5308 {0x1, 0xfe9, 0x80}, 3529 {0x1, 0xfe9, 0x80},
5309 {0x1, 0xfe2, 0x22}, 3530 {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 */ 3531 /* Enable Boost Volume backdoor */
5335 {0x1, 0xfb9, 0x24}, 3532 {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 */ 3533 /* Enable AOW0 to MW9 */
5357 {0x1, 0xfb8, 0x88}, 3534 {0x1, 0xfb8, 0x88},
5358 { } 3535 { }
5359}; 3536};
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 3537
3538static const struct hda_verb vt1802_init_verbs[] = {
5385 /* Enable Boost Volume backdoor */ 3539 /* Enable Boost Volume backdoor */
5386 {0x1, 0xfb9, 0x24}, 3540 {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 */ 3541 /* Enable AOW0 to MW9 */
5408 {0x1, 0xfb8, 0x88}, 3542 {0x1, 0xfb8, 0x88},
5409 { } 3543 { }
5410}; 3544};
5411 3545
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) 3546static void set_widgets_power_state_vt2002P(struct hda_codec *codec)
5617{ 3547{
5618 struct via_spec *spec = codec->spec; 3548 struct via_spec *spec = codec->spec;
@@ -5735,334 +3665,39 @@ static int patch_vt2002P(struct hda_codec *codec)
5735 if (spec == NULL) 3665 if (spec == NULL)
5736 return -ENOMEM; 3666 return -ENOMEM;
5737 3667
3668 spec->aa_mix_nid = 0x21;
3669 override_mic_boost(codec, 0x2b, 0, 3, 40);
3670 override_mic_boost(codec, 0x29, 0, 3, 40);
3671 add_secret_dac_path(codec);
3672
5738 /* automatic parse from the BIOS config */ 3673 /* automatic parse from the BIOS config */
5739 err = vt2002P_parse_auto_config(codec); 3674 err = via_parse_auto_config(codec);
5740 if (err < 0) { 3675 if (err < 0) {
5741 via_free(codec); 3676 via_free(codec);
5742 return err; 3677 return err;
5743 } else if (!err) {
5744 printk(KERN_INFO "hda_codec: Cannot set up configuration "
5745 "from BIOS. Using genenic mode...\n");
5746 } 3678 }
5747 3679
5748 if (spec->codec_type == VT1802) 3680 if (spec->codec_type == VT1802)
5749 spec->init_verbs[spec->num_iverbs++] = 3681 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
5759 spec->init_verbs[spec->num_iverbs++] =
5760 vt2002P_uniwill_init_verbs;
5761
5762 if (spec->codec_type == VT1802)
5763 spec->stream_name_analog = "VT1802 Analog";
5764 else 3682 else
5765 spec->stream_name_analog = "VT2002P Analog"; 3683 spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
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 3684
5785 codec->patch_ops = via_patch_ops; 3685 codec->patch_ops = via_patch_ops;
5786 3686
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; 3687 spec->set_widgets_power_state = set_widgets_power_state_vt2002P;
5795 return 0; 3688 return 0;
5796} 3689}
5797 3690
5798/* for vt1812 */ 3691/* for vt1812 */
5799 3692
5800/* capture mixer elements */ 3693static 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 */ 3694 /* Enable Boost Volume backdoor */
5849 {0x1, 0xfb9, 0x24}, 3695 {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 */ 3696 /* Enable AOW0 to MW9 */
5871 {0x1, 0xfb8, 0xa8}, 3697 {0x1, 0xfb8, 0xa8},
5872 { } 3698 { }
5873}; 3699};
5874 3700
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) 3701static void set_widgets_power_state_vt1812(struct hda_codec *codec)
6067{ 3702{
6068 struct via_spec *spec = codec->spec; 3703 struct via_spec *spec = codec->spec;
@@ -6166,47 +3801,22 @@ static int patch_vt1812(struct hda_codec *codec)
6166 if (spec == NULL) 3801 if (spec == NULL)
6167 return -ENOMEM; 3802 return -ENOMEM;
6168 3803
3804 spec->aa_mix_nid = 0x21;
3805 override_mic_boost(codec, 0x2b, 0, 3, 40);
3806 override_mic_boost(codec, 0x29, 0, 3, 40);
3807 add_secret_dac_path(codec);
3808
6169 /* automatic parse from the BIOS config */ 3809 /* automatic parse from the BIOS config */
6170 err = vt1812_parse_auto_config(codec); 3810 err = via_parse_auto_config(codec);
6171 if (err < 0) { 3811 if (err < 0) {
6172 via_free(codec); 3812 via_free(codec);
6173 return err; 3813 return err;
6174 } else if (!err) {
6175 printk(KERN_INFO "hda_codec: Cannot set up configuration "
6176 "from BIOS. Using genenic mode...\n");
6177 } 3814 }
6178 3815
6179 3816 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 3817
6201 codec->patch_ops = via_patch_ops; 3818 codec->patch_ops = via_patch_ops;
6202 3819
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; 3820 spec->set_widgets_power_state = set_widgets_power_state_vt1812;
6211 return 0; 3821 return 0;
6212} 3822}
@@ -6220,37 +3830,37 @@ static const struct hda_codec_preset snd_hda_preset_via[] = {
6220 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, 3830 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
6221 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708}, 3831 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
6222 { .id = 0x1106e710, .name = "VT1709 10-Ch", 3832 { .id = 0x1106e710, .name = "VT1709 10-Ch",
6223 .patch = patch_vt1709_10ch}, 3833 .patch = patch_vt1709},
6224 { .id = 0x1106e711, .name = "VT1709 10-Ch", 3834 { .id = 0x1106e711, .name = "VT1709 10-Ch",
6225 .patch = patch_vt1709_10ch}, 3835 .patch = patch_vt1709},
6226 { .id = 0x1106e712, .name = "VT1709 10-Ch", 3836 { .id = 0x1106e712, .name = "VT1709 10-Ch",
6227 .patch = patch_vt1709_10ch}, 3837 .patch = patch_vt1709},
6228 { .id = 0x1106e713, .name = "VT1709 10-Ch", 3838 { .id = 0x1106e713, .name = "VT1709 10-Ch",
6229 .patch = patch_vt1709_10ch}, 3839 .patch = patch_vt1709},
6230 { .id = 0x1106e714, .name = "VT1709 6-Ch", 3840 { .id = 0x1106e714, .name = "VT1709 6-Ch",
6231 .patch = patch_vt1709_6ch}, 3841 .patch = patch_vt1709},
6232 { .id = 0x1106e715, .name = "VT1709 6-Ch", 3842 { .id = 0x1106e715, .name = "VT1709 6-Ch",
6233 .patch = patch_vt1709_6ch}, 3843 .patch = patch_vt1709},
6234 { .id = 0x1106e716, .name = "VT1709 6-Ch", 3844 { .id = 0x1106e716, .name = "VT1709 6-Ch",
6235 .patch = patch_vt1709_6ch}, 3845 .patch = patch_vt1709},
6236 { .id = 0x1106e717, .name = "VT1709 6-Ch", 3846 { .id = 0x1106e717, .name = "VT1709 6-Ch",
6237 .patch = patch_vt1709_6ch}, 3847 .patch = patch_vt1709},
6238 { .id = 0x1106e720, .name = "VT1708B 8-Ch", 3848 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
6239 .patch = patch_vt1708B_8ch}, 3849 .patch = patch_vt1708B},
6240 { .id = 0x1106e721, .name = "VT1708B 8-Ch", 3850 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
6241 .patch = patch_vt1708B_8ch}, 3851 .patch = patch_vt1708B},
6242 { .id = 0x1106e722, .name = "VT1708B 8-Ch", 3852 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
6243 .patch = patch_vt1708B_8ch}, 3853 .patch = patch_vt1708B},
6244 { .id = 0x1106e723, .name = "VT1708B 8-Ch", 3854 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
6245 .patch = patch_vt1708B_8ch}, 3855 .patch = patch_vt1708B},
6246 { .id = 0x1106e724, .name = "VT1708B 4-Ch", 3856 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
6247 .patch = patch_vt1708B_4ch}, 3857 .patch = patch_vt1708B},
6248 { .id = 0x1106e725, .name = "VT1708B 4-Ch", 3858 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
6249 .patch = patch_vt1708B_4ch}, 3859 .patch = patch_vt1708B},
6250 { .id = 0x1106e726, .name = "VT1708B 4-Ch", 3860 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
6251 .patch = patch_vt1708B_4ch}, 3861 .patch = patch_vt1708B},
6252 { .id = 0x1106e727, .name = "VT1708B 4-Ch", 3862 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
6253 .patch = patch_vt1708B_4ch}, 3863 .patch = patch_vt1708B},
6254 { .id = 0x11060397, .name = "VT1708S", 3864 { .id = 0x11060397, .name = "VT1708S",
6255 .patch = patch_vt1708S}, 3865 .patch = patch_vt1708S},
6256 { .id = 0x11061397, .name = "VT1708S", 3866 { .id = 0x11061397, .name = "VT1708S",