]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: VIA HDA: Create a master amplifier control for VT1718S.
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
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,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
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,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
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
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 351
840b64c0
TI
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
1da177e4 358 /* capture source */
a1e8d2da 359 unsigned int num_mux_defs;
1da177e4
LT
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
6c819492 362 struct alc_mic_route ext_mic;
8ed99d97 363 struct alc_mic_route dock_mic;
6c819492 364 struct alc_mic_route int_mic;
1da177e4
LT
365
366 /* channel model */
d2a6d7dc 367 const struct hda_channel_mode *channel_mode;
1da177e4 368 int num_channel_mode;
4e195a7b 369 int need_dac_fix;
3b315d70
HM
370 int const_channel_count;
371 int ext_channel_count;
1da177e4
LT
372
373 /* PCM information */
4c5186ed 374 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 375
e9edcee0
TI
376 /* dynamic controls, init_verbs and input_mux */
377 struct auto_pin_cfg autocfg;
da00c244 378 struct alc_customize_define cdefine;
603c4019 379 struct snd_array kctls;
61b9b9b1 380 struct hda_input_mux private_imux[3];
41923e44 381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 384
ae6b813a
TI
385 /* hooks */
386 void (*init_hook)(struct hda_codec *codec);
387 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 388#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 389 void (*power_hook)(struct hda_codec *codec);
f5de24b0 390#endif
1c716153 391 void (*shutup)(struct hda_codec *codec);
ae6b813a 392
834be88d 393 /* for pin sensing */
834be88d 394 unsigned int jack_present: 1;
e6a5e1b7 395 unsigned int line_jack_present:1;
e9427969 396 unsigned int master_mute:1;
6c819492 397 unsigned int auto_mic:1;
d922b51d 398 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
399 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 401 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 402
e64f14f4
TI
403 /* other flags */
404 unsigned int no_analog :1; /* digital I/O only */
840b64c0 405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 406 unsigned int single_input_src:1;
d922b51d
TI
407
408 /* auto-mute control */
409 int automute_mode;
3b8510ce 410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 411
4a79ba34 412 int init_amp;
d433a678 413 int codec_variant; /* flag for other variants */
e64f14f4 414
2134ea4f
TI
415 /* for virtual master */
416 hda_nid_t vmaster_nid;
cb53c626
TI
417#ifdef CONFIG_SND_HDA_POWER_SAVE
418 struct hda_loopback_check loopback;
419#endif
2c3bf9ab
TI
420
421 /* for PLL fix */
422 hda_nid_t pll_nid;
423 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
424
425 /* fix-up list */
426 int fixup_id;
427 const struct alc_fixup *fixup_list;
428 const char *fixup_name;
ce764ab2
TI
429
430 /* multi-io */
431 int multi_ios;
432 struct alc_multi_io multi_io[4];
df694daa
KY
433};
434
435/*
436 * configuration template - to be copied to the spec instance
437 */
438struct alc_config_preset {
a9111321 439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
440 * with spec
441 */
a9111321 442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
443 const struct hda_verb *init_verbs[5];
444 unsigned int num_dacs;
4c6d72d1 445 const hda_nid_t *dac_nids;
df694daa
KY
446 hda_nid_t dig_out_nid; /* optional */
447 hda_nid_t hp_nid; /* optional */
4c6d72d1 448 const hda_nid_t *slave_dig_outs;
df694daa 449 unsigned int num_adc_nids;
4c6d72d1
TI
450 const hda_nid_t *adc_nids;
451 const hda_nid_t *capsrc_nids;
df694daa
KY
452 hda_nid_t dig_in_nid;
453 unsigned int num_channel_mode;
454 const struct hda_channel_mode *channel_mode;
4e195a7b 455 int need_dac_fix;
3b315d70 456 int const_channel_count;
a1e8d2da 457 unsigned int num_mux_defs;
df694daa 458 const struct hda_input_mux *input_mux;
ae6b813a 459 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 460 void (*setup)(struct hda_codec *);
ae6b813a 461 void (*init_hook)(struct hda_codec *);
cb53c626 462#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 463 const struct hda_amp_list *loopbacks;
c97259df 464 void (*power_hook)(struct hda_codec *codec);
cb53c626 465#endif
1da177e4
LT
466};
467
1da177e4
LT
468
469/*
470 * input MUX handling
471 */
9c7f852e
TI
472static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
477 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
478 if (mux_idx >= spec->num_mux_defs)
479 mux_idx = 0;
5311114d
TI
480 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
481 mux_idx = 0;
a1e8d2da 482 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
483}
484
9c7f852e
TI
485static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
487{
488 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489 struct alc_spec *spec = codec->spec;
490 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
491
492 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
493 return 0;
494}
495
9c7f852e
TI
496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
498{
499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500 struct alc_spec *spec = codec->spec;
cd896c33 501 const struct hda_input_mux *imux;
1da177e4 502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 503 unsigned int mux_idx;
e1406348
TI
504 hda_nid_t nid = spec->capsrc_nids ?
505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 506 unsigned int type;
1da177e4 507
cd896c33
TI
508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509 imux = &spec->input_mux[mux_idx];
5311114d
TI
510 if (!imux->num_items && mux_idx > 0)
511 imux = &spec->input_mux[0];
cd896c33 512
a22d543a 513 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 514 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
515 /* Matrix-mixer style (e.g. ALC882) */
516 unsigned int *cur_val = &spec->cur_mux[adc_idx];
517 unsigned int i, idx;
518
519 idx = ucontrol->value.enumerated.item[0];
520 if (idx >= imux->num_items)
521 idx = imux->num_items - 1;
522 if (*cur_val == idx)
523 return 0;
524 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index,
528 HDA_AMP_MUTE, v);
529 }
530 *cur_val = idx;
531 return 1;
532 } else {
533 /* MUX style (e.g. ALC880) */
cd896c33 534 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
535 &spec->cur_mux[adc_idx]);
536 }
537}
e9edcee0 538
1da177e4
LT
539/*
540 * channel mode setting
541 */
9c7f852e
TI
542static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
544{
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
547 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548 spec->num_channel_mode);
1da177e4
LT
549}
550
9c7f852e
TI
551static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
553{
554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555 struct alc_spec *spec = codec->spec;
d2a6d7dc 556 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 557 spec->num_channel_mode,
3b315d70 558 spec->ext_channel_count);
1da177e4
LT
559}
560
9c7f852e
TI
561static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
563{
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 struct alc_spec *spec = codec->spec;
4e195a7b
TI
566 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567 spec->num_channel_mode,
3b315d70
HM
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 }
4e195a7b 574 return err;
1da177e4
LT
575}
576
a9430dd8 577/*
4c5186ed 578 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 579 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
580 * being part of a format specifier. Maximum allowed length of a value is
581 * 63 characters plus NULL terminator.
7cf51e48
JW
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.
a1e8d2da
JW
587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588 * March 2006.
4c5186ed 589 */
a9111321 590static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
591 "Mic 50pc bias", "Mic 80pc bias",
592 "Line in", "Line out", "Headphone out",
4c5186ed 593};
a9111321 594static const unsigned char alc_pin_mode_values[] = {
7cf51e48 595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
596};
597/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
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.
a9430dd8 603 */
a1e8d2da
JW
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
4c5186ed 609
ea1fb29a 610/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
611 * For each direction the minimum and maximum values are given.
612 */
a9111321 613static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
614 { 0, 2 }, /* ALC_PIN_DIR_IN */
615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
617 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
618 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
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
9c7f852e
TI
625static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_info *uinfo)
a9430dd8 627{
4c5186ed
JW
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;
a9430dd8 632 uinfo->count = 1;
4c5186ed
JW
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]);
a9430dd8
JW
638 return 0;
639}
640
9c7f852e
TI
641static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
a9430dd8 643{
4c5186ed 644 unsigned int i;
a9430dd8
JW
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 647 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 648 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
649 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_PIN_WIDGET_CONTROL,
651 0x00);
a9430dd8 652
4c5186ed
JW
653 /* Find enumerated value for current pinctl setting */
654 i = alc_pin_mode_min(dir);
4b35d2ca 655 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 656 i++;
9c7f852e 657 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
658 return 0;
659}
660
9c7f852e
TI
661static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662 struct snd_ctl_elem_value *ucontrol)
a9430dd8 663{
4c5186ed 664 signed int change;
a9430dd8
JW
665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
667 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668 long val = *ucontrol->value.integer.value;
9c7f852e
TI
669 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_PIN_WIDGET_CONTROL,
671 0x00);
a9430dd8 672
f12ab1e0 673 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
674 val = alc_pin_mode_min(dir);
675
676 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
677 if (change) {
678 /* Set pin mode to that requested */
82beb8fd
TI
679 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL,
681 alc_pin_mode_values[val]);
cdcd9268 682
ea1fb29a 683 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
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
a1e8d2da
JW
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.
cdcd9268
JW
692 */
693 if (val <= 2) {
47fd830a
TI
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);
cdcd9268 698 } else {
47fd830a
TI
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);
cdcd9268
JW
703 }
704 }
a9430dd8
JW
705 return change;
706}
707
4c5186ed 708#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
711 .info = alc_pin_mode_info, \
712 .get = alc_pin_mode_get, \
713 .put = alc_pin_mode_put, \
714 .private_value = nid | (dir<<16) }
df694daa 715
5c8f858d
JW
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
a5ce8890 722#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 723
9c7f852e
TI
724static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
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;
9c7f852e
TI
731 unsigned int val = snd_hda_codec_read(codec, nid, 0,
732 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
733
734 *valp = (val & mask) != 0;
735 return 0;
736}
9c7f852e
TI
737static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
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;
9c7f852e
TI
745 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746 AC_VERB_GET_GPIO_DATA,
747 0x00);
5c8f858d
JW
748
749 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
750 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751 if (val == 0)
5c8f858d
JW
752 gpio_data &= ~mask;
753 else
754 gpio_data |= mask;
82beb8fd
TI
755 snd_hda_codec_write_cache(codec, nid, 0,
756 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
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, \
5b0cb1d8 762 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
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
92621f13
JW
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
a5ce8890 777#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 778
9c7f852e
TI
779static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
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;
9c7f852e 786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 787 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
788
789 *valp = (val & mask) != 0;
790 return 0;
791}
9c7f852e
TI
792static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
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;
9c7f852e 800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 801 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 802 0x00);
92621f13
JW
803
804 /* Set/unset the masked control bit(s) as needed */
9c7f852e 805 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
806 if (val==0)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
82beb8fd
TI
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811 ctrl_data);
92621f13
JW
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, \
5b0cb1d8 817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
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
f8225f6d
JW
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}
844
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol)
847{
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff;
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
852 long val = *ucontrol->value.integer.value;
853 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_EAPD_BTLENABLE,
855 0x00);
856
857 /* Set/unset the masked control bit(s) as needed */
858 change = (!val ? 0 : mask) != (ctrl_data & mask);
859 if (!val)
860 ctrl_data &= ~mask;
861 else
862 ctrl_data |= mask;
863 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864 ctrl_data);
865
866 return change;
867}
868
869#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 871 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
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
23f0c048
TI
878/*
879 * set up the input pin config (depending on the given auto-pin type)
880 */
881static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
882 int auto_pin_type)
883{
884 unsigned int val = PIN_IN;
885
86e2959a 886 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 887 unsigned int pincap;
954a29c8
TI
888 unsigned int oldval;
889 oldval = snd_hda_codec_read(codec, nid, 0,
890 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 891 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 892 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
893 /* if the default pin setup is vref50, we give it priority */
894 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 895 val = PIN_VREF80;
461c6c3a
TI
896 else if (pincap & AC_PINCAP_VREF_50)
897 val = PIN_VREF50;
898 else if (pincap & AC_PINCAP_VREF_100)
899 val = PIN_VREF100;
900 else if (pincap & AC_PINCAP_VREF_GRD)
901 val = PIN_VREFGRD;
23f0c048
TI
902 }
903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904}
905
f6837bbd
TI
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
d88897ea
TI
928/*
929 */
a9111321 930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
931{
932 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
933 return;
934 spec->mixers[spec->num_mixers++] = mix;
935}
936
937static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
938{
939 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
940 return;
941 spec->init_verbs[spec->num_init_verbs++] = verb;
942}
943
df694daa
KY
944/*
945 * set up from the preset table
946 */
e9c364c0 947static void setup_preset(struct hda_codec *codec,
9c7f852e 948 const struct alc_config_preset *preset)
df694daa 949{
e9c364c0 950 struct alc_spec *spec = codec->spec;
df694daa
KY
951 int i;
952
953 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 954 add_mixer(spec, preset->mixers[i]);
f9e336f6 955 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
956 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957 i++)
d88897ea 958 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 959
df694daa
KY
960 spec->channel_mode = preset->channel_mode;
961 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 962 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 963 spec->const_channel_count = preset->const_channel_count;
df694daa 964
3b315d70
HM
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;
df694daa
KY
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;
b25c9da1 974 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 975 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 976
a1e8d2da 977 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 978 if (!spec->num_mux_defs)
a1e8d2da 979 spec->num_mux_defs = 1;
df694daa
KY
980 spec->input_mux = preset->input_mux;
981
982 spec->num_adc_nids = preset->num_adc_nids;
983 spec->adc_nids = preset->adc_nids;
e1406348 984 spec->capsrc_nids = preset->capsrc_nids;
df694daa 985 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
986
987 spec->unsol_event = preset->unsol_event;
988 spec->init_hook = preset->init_hook;
cb53c626 989#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 990 spec->power_hook = preset->power_hook;
cb53c626
TI
991 spec->loopback.amplist = preset->loopbacks;
992#endif
e9c364c0
TI
993
994 if (preset->setup)
995 preset->setup(codec);
f6837bbd
TI
996
997 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
998}
999
bc9f98a9 1000/* Enable GPIO mask and set output */
a9111321 1001static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1003 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1005 { }
1006};
1007
a9111321 1008static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1009 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1012 { }
1013};
1014
a9111321 1015static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1016 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1017 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1019 { }
1020};
1021
2c3bf9ab
TI
1022/*
1023 * Fix hardware PLL issue
1024 * On some codecs, the analog PLL gating control must be off while
1025 * the default value is 1.
1026 */
1027static void alc_fix_pll(struct hda_codec *codec)
1028{
1029 struct alc_spec *spec = codec->spec;
1030 unsigned int val;
1031
1032 if (!spec->pll_nid)
1033 return;
1034 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1035 spec->pll_coef_idx);
1036 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1037 AC_VERB_GET_PROC_COEF, 0);
1038 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1039 spec->pll_coef_idx);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1041 val & ~(1 << spec->pll_coef_bit));
1042}
1043
1044static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1045 unsigned int coef_idx, unsigned int coef_bit)
1046{
1047 struct alc_spec *spec = codec->spec;
1048 spec->pll_nid = nid;
1049 spec->pll_coef_idx = coef_idx;
1050 spec->pll_coef_bit = coef_bit;
1051 alc_fix_pll(codec);
1052}
1053
9ad0e496
KY
1054static int alc_init_jacks(struct hda_codec *codec)
1055{
cd372fb3 1056#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1057 struct alc_spec *spec = codec->spec;
1058 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin;
8ed99d97 1061 unsigned int dock_nid = spec->dock_mic.pin;
9ad0e496 1062
265a0247 1063 if (hp_nid) {
cd372fb3
TI
1064 err = snd_hda_input_jack_add(codec, hp_nid,
1065 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1066 if (err < 0)
1067 return err;
cd372fb3 1068 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1069 }
9ad0e496 1070
265a0247 1071 if (mic_nid) {
cd372fb3
TI
1072 err = snd_hda_input_jack_add(codec, mic_nid,
1073 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1074 if (err < 0)
1075 return err;
cd372fb3 1076 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1077 }
8ed99d97
TI
1078 if (dock_nid) {
1079 err = snd_hda_input_jack_add(codec, dock_nid,
1080 SND_JACK_MICROPHONE, NULL);
1081 if (err < 0)
1082 return err;
1083 snd_hda_input_jack_report(codec, dock_nid);
1084 }
cd372fb3 1085#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1086 return 0;
1087}
9ad0e496 1088
e6a5e1b7 1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1090{
e6a5e1b7 1091 int i, present = 0;
c9b58006 1092
e6a5e1b7
TI
1093 for (i = 0; i < num_pins; i++) {
1094 hda_nid_t nid = pins[i];
bb35febd
TI
1095 if (!nid)
1096 break;
cd372fb3 1097 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1098 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1099 }
e6a5e1b7
TI
1100 return present;
1101}
bb35febd 1102
e6a5e1b7 1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1104 bool mute, bool hp_out)
e6a5e1b7
TI
1105{
1106 struct alc_spec *spec = codec->spec;
1107 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1108 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1109 int i;
1110
1111 for (i = 0; i < num_pins; i++) {
1112 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1113 if (!nid)
1114 break;
3b8510ce
TI
1115 switch (spec->automute_mode) {
1116 case ALC_AUTOMUTE_PIN:
bb35febd 1117 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1118 AC_VERB_SET_PIN_WIDGET_CONTROL,
1119 pin_bits);
3b8510ce
TI
1120 break;
1121 case ALC_AUTOMUTE_AMP:
bb35febd 1122 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1123 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1124 break;
1125 case ALC_AUTOMUTE_MIXER:
1126 nid = spec->automute_mixer_nid[i];
1127 if (!nid)
1128 break;
1129 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1130 HDA_AMP_MUTE, mute_bits);
3b8510ce 1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1132 HDA_AMP_MUTE, mute_bits);
3b8510ce 1133 break;
bb35febd 1134 }
a9fd4f3f 1135 }
c9b58006
KY
1136}
1137
e6a5e1b7
TI
1138/* Toggle internal speakers muting */
1139static void update_speakers(struct hda_codec *codec)
1140{
1141 struct alc_spec *spec = codec->spec;
1a1455de 1142 int on;
e6a5e1b7 1143
c0a20263
TI
1144 /* Control HP pins/amps depending on master_mute state;
1145 * in general, HP pins/amps control should be enabled in all cases,
1146 * but currently set only for master_mute, just to be safe
1147 */
1148 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1149 spec->autocfg.hp_pins, spec->master_mute, true);
1150
1a1455de
TI
1151 if (!spec->automute)
1152 on = 0;
1153 else
1154 on = spec->jack_present | spec->line_jack_present;
1155 on |= spec->master_mute;
e6a5e1b7 1156 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1157 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1158
1159 /* toggle line-out mutes if needed, too */
1a1455de
TI
1160 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1161 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1163 return;
1a1455de
TI
1164 if (!spec->automute_lines || !spec->automute)
1165 on = 0;
1166 else
1167 on = spec->jack_present;
1168 on |= spec->master_mute;
e6a5e1b7 1169 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1170 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1171}
1172
1173static void alc_hp_automute(struct hda_codec *codec)
1174{
1175 struct alc_spec *spec = codec->spec;
1176
1177 if (!spec->automute)
1178 return;
1179 spec->jack_present =
1180 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181 spec->autocfg.hp_pins);
1182 update_speakers(codec);
1183}
1184
1185static void alc_line_automute(struct hda_codec *codec)
1186{
1187 struct alc_spec *spec = codec->spec;
1188
1189 if (!spec->automute || !spec->detect_line)
1190 return;
1191 spec->line_jack_present =
1192 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193 spec->autocfg.line_out_pins);
1194 update_speakers(codec);
1195}
1196
6c819492
TI
1197static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1198 hda_nid_t nid)
1199{
1200 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1201 int i, nums;
1202
1203 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1204 for (i = 0; i < nums; i++)
1205 if (conn[i] == nid)
1206 return i;
1207 return -1;
1208}
1209
840b64c0
TI
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 */
f0cea797 1225 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
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
7fb0d78f
KY
1233static void alc_mic_automute(struct hda_codec *codec)
1234{
1235 struct alc_spec *spec = codec->spec;
8ed99d97 1236 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1237 unsigned int present, type;
1238 hda_nid_t cap_nid;
1239
b59bdf3b
TI
1240 if (!spec->auto_mic)
1241 return;
6c819492
TI
1242 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243 return;
1244 if (snd_BUG_ON(!spec->adc_nids))
1245 return;
1246
840b64c0
TI
1247 if (spec->dual_adc_switch) {
1248 alc_dual_mic_adc_auto_switch(codec);
1249 return;
1250 }
1251
6c819492
TI
1252 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1253
8ed99d97
TI
1254 alive = &spec->int_mic;
1255 dead1 = &spec->ext_mic;
1256 dead2 = &spec->dock_mic;
1257
864f92be 1258 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1259 if (present) {
1260 alive = &spec->ext_mic;
8ed99d97
TI
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);
6c819492
TI
1272 }
1273
6c819492
TI
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);
8ed99d97
TI
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);
6c819492
TI
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 }
cd372fb3 1294 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1295
1296 /* FIXME: analog mixer */
7fb0d78f
KY
1297}
1298
c9b58006
KY
1299/* unsolicited event for HP jack sensing */
1300static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1301{
1302 if (codec->vendor_id == 0x10ec0880)
1303 res >>= 28;
1304 else
1305 res >>= 26;
a9fd4f3f
TI
1306 switch (res) {
1307 case ALC880_HP_EVENT:
d922b51d 1308 alc_hp_automute(codec);
a9fd4f3f 1309 break;
e6a5e1b7
TI
1310 case ALC880_FRONT_EVENT:
1311 alc_line_automute(codec);
1312 break;
a9fd4f3f 1313 case ALC880_MIC_EVENT:
7fb0d78f 1314 alc_mic_automute(codec);
a9fd4f3f
TI
1315 break;
1316 }
7fb0d78f
KY
1317}
1318
1319static void alc_inithook(struct hda_codec *codec)
1320{
d922b51d 1321 alc_hp_automute(codec);
e6a5e1b7 1322 alc_line_automute(codec);
7fb0d78f 1323 alc_mic_automute(codec);
c9b58006
KY
1324}
1325
f9423e7a
KY
1326/* additional initialization for ALC888 variants */
1327static void alc888_coef_init(struct hda_codec *codec)
1328{
1329 unsigned int tmp;
1330
1331 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1332 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1333 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1334 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1335 /* alc888S-VC */
1336 snd_hda_codec_read(codec, 0x20, 0,
1337 AC_VERB_SET_PROC_COEF, 0x830);
1338 else
1339 /* alc888-VB */
1340 snd_hda_codec_read(codec, 0x20, 0,
1341 AC_VERB_SET_PROC_COEF, 0x3030);
1342}
1343
87a8c370
JK
1344static void alc889_coef_init(struct hda_codec *codec)
1345{
1346 unsigned int tmp;
1347
1348 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1349 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1350 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1352}
1353
3fb4a508
TI
1354/* turn on/off EAPD control (only if available) */
1355static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1356{
1357 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1358 return;
1359 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1360 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1361 on ? 2 : 0);
1362}
1363
691f1fcc
TI
1364/* turn on/off EAPD controls of the codec */
1365static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366{
1367 /* We currently only handle front, HP */
1368 switch (codec->vendor_id) {
1369 case 0x10ec0260:
1370 set_eapd(codec, 0x0f, on);
1371 set_eapd(codec, 0x10, on);
1372 break;
1373 case 0x10ec0262:
1374 case 0x10ec0267:
1375 case 0x10ec0268:
1376 case 0x10ec0269:
1377 case 0x10ec0270:
1378 case 0x10ec0272:
1379 case 0x10ec0660:
1380 case 0x10ec0662:
1381 case 0x10ec0663:
1382 case 0x10ec0665:
1383 case 0x10ec0862:
1384 case 0x10ec0889:
1385 case 0x10ec0892:
1386 set_eapd(codec, 0x14, on);
1387 set_eapd(codec, 0x15, on);
1388 break;
1389 }
1390}
1391
1c716153
TI
1392/* generic shutup callback;
1393 * just turning off EPAD and a little pause for avoiding pop-noise
1394 */
1395static void alc_eapd_shutup(struct hda_codec *codec)
1396{
1397 alc_auto_setup_eapd(codec, false);
1398 msleep(200);
1399}
1400
4a79ba34 1401static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1402{
4a79ba34 1403 unsigned int tmp;
bc9f98a9 1404
4a79ba34
TI
1405 switch (type) {
1406 case ALC_INIT_GPIO1:
bc9f98a9
KY
1407 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1408 break;
4a79ba34 1409 case ALC_INIT_GPIO2:
bc9f98a9
KY
1410 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1411 break;
4a79ba34 1412 case ALC_INIT_GPIO3:
bdd148a3
KY
1413 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414 break;
4a79ba34 1415 case ALC_INIT_DEFAULT:
691f1fcc 1416 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1417 switch (codec->vendor_id) {
1418 case 0x10ec0260:
1419 snd_hda_codec_write(codec, 0x1a, 0,
1420 AC_VERB_SET_COEF_INDEX, 7);
1421 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1422 AC_VERB_GET_PROC_COEF, 0);
1423 snd_hda_codec_write(codec, 0x1a, 0,
1424 AC_VERB_SET_COEF_INDEX, 7);
1425 snd_hda_codec_write(codec, 0x1a, 0,
1426 AC_VERB_SET_PROC_COEF,
1427 tmp | 0x2010);
1428 break;
1429 case 0x10ec0262:
1430 case 0x10ec0880:
1431 case 0x10ec0882:
1432 case 0x10ec0883:
1433 case 0x10ec0885:
4a5a4c56 1434 case 0x10ec0887:
20b67ddd 1435 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1436 alc889_coef_init(codec);
c9b58006 1437 break;
f9423e7a 1438 case 0x10ec0888:
4a79ba34 1439 alc888_coef_init(codec);
f9423e7a 1440 break;
0aea778e 1441#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1442 case 0x10ec0267:
1443 case 0x10ec0268:
1444 snd_hda_codec_write(codec, 0x20, 0,
1445 AC_VERB_SET_COEF_INDEX, 7);
1446 tmp = snd_hda_codec_read(codec, 0x20, 0,
1447 AC_VERB_GET_PROC_COEF, 0);
1448 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1449 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1450 snd_hda_codec_write(codec, 0x20, 0,
1451 AC_VERB_SET_PROC_COEF,
1452 tmp | 0x3000);
1453 break;
0aea778e 1454#endif /* XXX */
bc9f98a9 1455 }
4a79ba34
TI
1456 break;
1457 }
1458}
1459
1a1455de
TI
1460static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_info *uinfo)
1462{
ae8a60a5
TI
1463 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464 struct alc_spec *spec = codec->spec;
1465 static const char * const texts2[] = {
1466 "Disabled", "Enabled"
1467 };
1468 static const char * const texts3[] = {
1a1455de
TI
1469 "Disabled", "Speaker Only", "Line-Out+Speaker"
1470 };
ae8a60a5 1471 const char * const *texts;
1a1455de
TI
1472
1473 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1474 uinfo->count = 1;
ae8a60a5
TI
1475 if (spec->automute_hp_lo) {
1476 uinfo->value.enumerated.items = 3;
1477 texts = texts3;
1478 } else {
1479 uinfo->value.enumerated.items = 2;
1480 texts = texts2;
1481 }
1482 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1483 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1484 strcpy(uinfo->value.enumerated.name,
1485 texts[uinfo->value.enumerated.item]);
1486 return 0;
1487}
1488
1489static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1490 struct snd_ctl_elem_value *ucontrol)
1491{
1492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1493 struct alc_spec *spec = codec->spec;
1494 unsigned int val;
1495 if (!spec->automute)
1496 val = 0;
1497 else if (!spec->automute_lines)
1498 val = 1;
1499 else
1500 val = 2;
1501 ucontrol->value.enumerated.item[0] = val;
1502 return 0;
1503}
1504
1505static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1506 struct snd_ctl_elem_value *ucontrol)
1507{
1508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1509 struct alc_spec *spec = codec->spec;
1510
1511 switch (ucontrol->value.enumerated.item[0]) {
1512 case 0:
1513 if (!spec->automute)
1514 return 0;
1515 spec->automute = 0;
1516 break;
1517 case 1:
1518 if (spec->automute && !spec->automute_lines)
1519 return 0;
1520 spec->automute = 1;
1521 spec->automute_lines = 0;
1522 break;
1523 case 2:
ae8a60a5
TI
1524 if (!spec->automute_hp_lo)
1525 return -EINVAL;
1a1455de
TI
1526 if (spec->automute && spec->automute_lines)
1527 return 0;
1528 spec->automute = 1;
1529 spec->automute_lines = 1;
1530 break;
1531 default:
1532 return -EINVAL;
1533 }
1534 update_speakers(codec);
1535 return 1;
1536}
1537
a9111321 1538static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1539 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1540 .name = "Auto-Mute Mode",
1541 .info = alc_automute_mode_info,
1542 .get = alc_automute_mode_get,
1543 .put = alc_automute_mode_put,
1544};
1545
1546static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1547
1548static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549{
1550 struct alc_spec *spec = codec->spec;
1551 struct snd_kcontrol_new *knew;
1552
1553 knew = alc_kcontrol_new(spec);
1554 if (!knew)
1555 return -ENOMEM;
1556 *knew = alc_automute_mode_enum;
1557 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1558 if (!knew->name)
1559 return -ENOMEM;
1560 return 0;
1561}
1562
4a79ba34
TI
1563static void alc_init_auto_hp(struct hda_codec *codec)
1564{
1565 struct alc_spec *spec = codec->spec;
bb35febd 1566 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1567 int present = 0;
bb35febd 1568 int i;
4a79ba34 1569
1daf5f46
TI
1570 if (cfg->hp_pins[0])
1571 present++;
1572 if (cfg->line_out_pins[0])
1573 present++;
1574 if (cfg->speaker_pins[0])
1575 present++;
1576 if (present < 2) /* need two different output types */
1577 return;
ae8a60a5
TI
1578 if (present == 3)
1579 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1580
bb35febd 1581 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1582 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1583 sizeof(cfg->speaker_pins));
1584 cfg->speaker_outs = cfg->line_outs;
1585 }
1586
1587 if (!cfg->hp_pins[0]) {
1588 memcpy(cfg->hp_pins, cfg->line_out_pins,
1589 sizeof(cfg->hp_pins));
1590 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1591 }
1592
bb35febd 1593 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1594 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1595 if (!is_jack_detectable(codec, nid))
1a1455de 1596 continue;
bb35febd 1597 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1598 nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1602 spec->automute = 1;
1603 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1604 }
1a1455de
TI
1605 if (spec->automute && cfg->line_out_pins[0] &&
1606 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1607 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1608 for (i = 0; i < cfg->line_outs; i++) {
1609 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1610 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1611 continue;
1612 snd_printdd("realtek: Enable Line-Out auto-muting "
1613 "on NID 0x%x\n", nid);
1614 snd_hda_codec_write_cache(codec, nid, 0,
1615 AC_VERB_SET_UNSOLICITED_ENABLE,
1616 AC_USRSP_EN | ALC880_FRONT_EVENT);
1617 spec->detect_line = 1;
1618 }
52d3cb88 1619 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1620 }
1621
1622 if (spec->automute) {
1a1455de
TI
1623 /* create a control for automute mode */
1624 alc_add_automute_mode_enum(codec);
ae8a60a5 1625 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1626 }
4a79ba34
TI
1627}
1628
6c819492
TI
1629static void alc_init_auto_mic(struct hda_codec *codec)
1630{
1631 struct alc_spec *spec = codec->spec;
1632 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1633 hda_nid_t fixed, ext, dock;
6c819492
TI
1634 int i;
1635
8ed99d97 1636 fixed = ext = dock = 0;
66ceeb6b
TI
1637 for (i = 0; i < cfg->num_inputs; i++) {
1638 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1639 unsigned int defcfg;
6c819492 1640 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1641 switch (snd_hda_get_input_pin_attr(defcfg)) {
1642 case INPUT_PIN_ATTR_INT:
6c819492
TI
1643 if (fixed)
1644 return; /* already occupied */
8ed99d97
TI
1645 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1646 return; /* invalid type */
6c819492
TI
1647 fixed = nid;
1648 break;
99ae28be
TI
1649 case INPUT_PIN_ATTR_UNUSED:
1650 return; /* invalid entry */
8ed99d97
TI
1651 case INPUT_PIN_ATTR_DOCK:
1652 if (dock)
1653 return; /* already occupied */
1654 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1655 return; /* invalid type */
1656 dock = nid;
1657 break;
99ae28be 1658 default:
6c819492
TI
1659 if (ext)
1660 return; /* already occupied */
8ed99d97
TI
1661 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1662 return; /* invalid type */
6c819492
TI
1663 ext = nid;
1664 break;
6c819492
TI
1665 }
1666 }
8ed99d97
TI
1667 if (!ext && dock) {
1668 ext = dock;
1669 dock = 0;
1670 }
eaa9b3a7
TI
1671 if (!ext || !fixed)
1672 return;
e35d9d6a 1673 if (!is_jack_detectable(codec, ext))
6c819492 1674 return; /* no unsol support */
8ed99d97
TI
1675 if (dock && !is_jack_detectable(codec, dock))
1676 return; /* no unsol support */
1677 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1678 ext, fixed, dock);
6c819492 1679 spec->ext_mic.pin = ext;
8ed99d97 1680 spec->dock_mic.pin = dock;
6c819492
TI
1681 spec->int_mic.pin = fixed;
1682 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1683 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1684 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1685 spec->auto_mic = 1;
1686 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1687 AC_VERB_SET_UNSOLICITED_ENABLE,
1688 AC_USRSP_EN | ALC880_MIC_EVENT);
1689 spec->unsol_event = alc_sku_unsol_event;
1690}
1691
90622917
DH
1692/* Could be any non-zero and even value. When used as fixup, tells
1693 * the driver to ignore any present sku defines.
1694 */
1695#define ALC_FIXUP_SKU_IGNORE (2)
1696
da00c244
KY
1697static int alc_auto_parse_customize_define(struct hda_codec *codec)
1698{
1699 unsigned int ass, tmp, i;
7fb56223 1700 unsigned nid = 0;
da00c244
KY
1701 struct alc_spec *spec = codec->spec;
1702
b6cbe517
TI
1703 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1704
90622917
DH
1705 if (spec->cdefine.fixup) {
1706 ass = spec->cdefine.sku_cfg;
1707 if (ass == ALC_FIXUP_SKU_IGNORE)
1708 return -1;
1709 goto do_sku;
1710 }
1711
da00c244 1712 ass = codec->subsystem_id & 0xffff;
b6cbe517 1713 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1714 goto do_sku;
1715
1716 nid = 0x1d;
1717 if (codec->vendor_id == 0x10ec0260)
1718 nid = 0x17;
1719 ass = snd_hda_codec_get_pincfg(codec, nid);
1720
1721 if (!(ass & 1)) {
1722 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1723 codec->chip_name, ass);
1724 return -1;
1725 }
1726
1727 /* check sum */
1728 tmp = 0;
1729 for (i = 1; i < 16; i++) {
1730 if ((ass >> i) & 1)
1731 tmp++;
1732 }
1733 if (((ass >> 16) & 0xf) != tmp)
1734 return -1;
1735
1736 spec->cdefine.port_connectivity = ass >> 30;
1737 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1738 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1739 spec->cdefine.customization = ass >> 8;
1740do_sku:
1741 spec->cdefine.sku_cfg = ass;
1742 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1743 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1744 spec->cdefine.swap = (ass & 0x2) >> 1;
1745 spec->cdefine.override = ass & 0x1;
1746
1747 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1748 nid, spec->cdefine.sku_cfg);
1749 snd_printd("SKU: port_connectivity=0x%x\n",
1750 spec->cdefine.port_connectivity);
1751 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1752 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1753 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1754 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1755 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1756 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1757 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1758
1759 return 0;
1760}
1761
4a79ba34
TI
1762/* check subsystem ID and set up device-specific initialization;
1763 * return 1 if initialized, 0 if invalid SSID
1764 */
1765/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1766 * 31 ~ 16 : Manufacture ID
1767 * 15 ~ 8 : SKU ID
1768 * 7 ~ 0 : Assembly ID
1769 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1770 */
1771static int alc_subsystem_id(struct hda_codec *codec,
1772 hda_nid_t porta, hda_nid_t porte,
6227cdce 1773 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1774{
1775 unsigned int ass, tmp, i;
1776 unsigned nid;
1777 struct alc_spec *spec = codec->spec;
1778
90622917
DH
1779 if (spec->cdefine.fixup) {
1780 ass = spec->cdefine.sku_cfg;
1781 if (ass == ALC_FIXUP_SKU_IGNORE)
1782 return 0;
1783 goto do_sku;
1784 }
1785
4a79ba34
TI
1786 ass = codec->subsystem_id & 0xffff;
1787 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1788 goto do_sku;
1789
1790 /* invalid SSID, check the special NID pin defcfg instead */
1791 /*
def319f9 1792 * 31~30 : port connectivity
4a79ba34
TI
1793 * 29~21 : reserve
1794 * 20 : PCBEEP input
1795 * 19~16 : Check sum (15:1)
1796 * 15~1 : Custom
1797 * 0 : override
1798 */
1799 nid = 0x1d;
1800 if (codec->vendor_id == 0x10ec0260)
1801 nid = 0x17;
1802 ass = snd_hda_codec_get_pincfg(codec, nid);
1803 snd_printd("realtek: No valid SSID, "
1804 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1805 ass, nid);
6227cdce 1806 if (!(ass & 1))
4a79ba34
TI
1807 return 0;
1808 if ((ass >> 30) != 1) /* no physical connection */
1809 return 0;
1810
1811 /* check sum */
1812 tmp = 0;
1813 for (i = 1; i < 16; i++) {
1814 if ((ass >> i) & 1)
1815 tmp++;
1816 }
1817 if (((ass >> 16) & 0xf) != tmp)
1818 return 0;
1819do_sku:
1820 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1821 ass & 0xffff, codec->vendor_id);
1822 /*
1823 * 0 : override
1824 * 1 : Swap Jack
1825 * 2 : 0 --> Desktop, 1 --> Laptop
1826 * 3~5 : External Amplifier control
1827 * 7~6 : Reserved
1828 */
1829 tmp = (ass & 0x38) >> 3; /* external Amp control */
1830 switch (tmp) {
1831 case 1:
1832 spec->init_amp = ALC_INIT_GPIO1;
1833 break;
1834 case 3:
1835 spec->init_amp = ALC_INIT_GPIO2;
1836 break;
1837 case 7:
1838 spec->init_amp = ALC_INIT_GPIO3;
1839 break;
1840 case 5:
5a8cfb4e 1841 default:
4a79ba34 1842 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1843 break;
1844 }
ea1fb29a 1845
8c427226 1846 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1847 * when the external headphone out jack is plugged"
1848 */
8c427226 1849 if (!(ass & 0x8000))
4a79ba34 1850 return 1;
c9b58006
KY
1851 /*
1852 * 10~8 : Jack location
1853 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1854 * 14~13: Resvered
1855 * 15 : 1 --> enable the function "Mute internal speaker
1856 * when the external headphone out jack is plugged"
1857 */
c9b58006 1858 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1859 hda_nid_t nid;
c9b58006
KY
1860 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1861 if (tmp == 0)
01d4825d 1862 nid = porta;
c9b58006 1863 else if (tmp == 1)
01d4825d 1864 nid = porte;
c9b58006 1865 else if (tmp == 2)
01d4825d 1866 nid = portd;
6227cdce
KY
1867 else if (tmp == 3)
1868 nid = porti;
c9b58006 1869 else
4a79ba34 1870 return 1;
01d4825d
TI
1871 for (i = 0; i < spec->autocfg.line_outs; i++)
1872 if (spec->autocfg.line_out_pins[i] == nid)
1873 return 1;
1874 spec->autocfg.hp_pins[0] = nid;
c9b58006 1875 }
4a79ba34
TI
1876 return 1;
1877}
ea1fb29a 1878
4a79ba34 1879static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1880 hda_nid_t porta, hda_nid_t porte,
1881 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1882{
6227cdce 1883 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1884 struct alc_spec *spec = codec->spec;
1885 snd_printd("realtek: "
1886 "Enable default setup for auto mode as fallback\n");
1887 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1888 }
1a1455de
TI
1889
1890 alc_init_auto_hp(codec);
1891 alc_init_auto_mic(codec);
bc9f98a9
KY
1892}
1893
f95474ec 1894/*
f8f25ba3 1895 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1896 */
1897
1898struct alc_pincfg {
1899 hda_nid_t nid;
1900 u32 val;
1901};
1902
e1eb5f10
TB
1903struct alc_model_fixup {
1904 const int id;
1905 const char *name;
1906};
1907
f8f25ba3 1908struct alc_fixup {
b5bfbc67 1909 int type;
361fe6e9
TI
1910 bool chained;
1911 int chain_id;
b5bfbc67
TI
1912 union {
1913 unsigned int sku;
1914 const struct alc_pincfg *pins;
1915 const struct hda_verb *verbs;
1916 void (*func)(struct hda_codec *codec,
1917 const struct alc_fixup *fix,
1918 int action);
1919 } v;
f8f25ba3
TI
1920};
1921
b5bfbc67
TI
1922enum {
1923 ALC_FIXUP_INVALID,
1924 ALC_FIXUP_SKU,
1925 ALC_FIXUP_PINS,
1926 ALC_FIXUP_VERBS,
1927 ALC_FIXUP_FUNC,
1928};
1929
1930enum {
1931 ALC_FIXUP_ACT_PRE_PROBE,
1932 ALC_FIXUP_ACT_PROBE,
58701120 1933 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1934};
1935
1936static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1937{
b5bfbc67
TI
1938 struct alc_spec *spec = codec->spec;
1939 int id = spec->fixup_id;
aa1d0c52 1940#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1941 const char *modelname = spec->fixup_name;
aa1d0c52 1942#endif
b5bfbc67 1943 int depth = 0;
f95474ec 1944
b5bfbc67
TI
1945 if (!spec->fixup_list)
1946 return;
1947
1948 while (id >= 0) {
1949 const struct alc_fixup *fix = spec->fixup_list + id;
1950 const struct alc_pincfg *cfg;
1951
1952 switch (fix->type) {
1953 case ALC_FIXUP_SKU:
1954 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1955 break;;
1956 snd_printdd(KERN_INFO "hda_codec: %s: "
1957 "Apply sku override for %s\n",
1958 codec->chip_name, modelname);
1959 spec->cdefine.sku_cfg = fix->v.sku;
1960 spec->cdefine.fixup = 1;
1961 break;
1962 case ALC_FIXUP_PINS:
1963 cfg = fix->v.pins;
1964 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1965 break;
1966 snd_printdd(KERN_INFO "hda_codec: %s: "
1967 "Apply pincfg for %s\n",
1968 codec->chip_name, modelname);
1969 for (; cfg->nid; cfg++)
1970 snd_hda_codec_set_pincfg(codec, cfg->nid,
1971 cfg->val);
1972 break;
1973 case ALC_FIXUP_VERBS:
1974 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1975 break;
1976 snd_printdd(KERN_INFO "hda_codec: %s: "
1977 "Apply fix-verbs for %s\n",
1978 codec->chip_name, modelname);
1979 add_verb(codec->spec, fix->v.verbs);
1980 break;
1981 case ALC_FIXUP_FUNC:
1982 if (!fix->v.func)
1983 break;
1984 snd_printdd(KERN_INFO "hda_codec: %s: "
1985 "Apply fix-func for %s\n",
1986 codec->chip_name, modelname);
1987 fix->v.func(codec, fix, action);
1988 break;
1989 default:
1990 snd_printk(KERN_ERR "hda_codec: %s: "
1991 "Invalid fixup type %d\n",
1992 codec->chip_name, fix->type);
1993 break;
1994 }
24af2b1c 1995 if (!fix->chained)
b5bfbc67
TI
1996 break;
1997 if (++depth > 10)
1998 break;
24af2b1c 1999 id = fix->chain_id;
9d57883f 2000 }
f95474ec
TI
2001}
2002
e1eb5f10 2003static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
2004 const struct alc_model_fixup *models,
2005 const struct snd_pci_quirk *quirk,
2006 const struct alc_fixup *fixlist)
e1eb5f10 2007{
b5bfbc67
TI
2008 struct alc_spec *spec = codec->spec;
2009 int id = -1;
2010 const char *name = NULL;
e1eb5f10 2011
e1eb5f10
TB
2012 if (codec->modelname && models) {
2013 while (models->name) {
2014 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2015 id = models->id;
2016 name = models->name;
e1eb5f10
TB
2017 break;
2018 }
2019 models++;
2020 }
b5bfbc67
TI
2021 }
2022 if (id < 0) {
2023 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2024 if (quirk) {
2025 id = quirk->value;
2026#ifdef CONFIG_SND_DEBUG_VERBOSE
2027 name = quirk->name;
2028#endif
2029 }
2030 }
2031
2032 spec->fixup_id = id;
2033 if (id >= 0) {
2034 spec->fixup_list = fixlist;
2035 spec->fixup_name = name;
e1eb5f10 2036 }
f95474ec
TI
2037}
2038
274693f3
KY
2039static int alc_read_coef_idx(struct hda_codec *codec,
2040 unsigned int coef_idx)
2041{
2042 unsigned int val;
2043 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2044 coef_idx);
2045 val = snd_hda_codec_read(codec, 0x20, 0,
2046 AC_VERB_GET_PROC_COEF, 0);
2047 return val;
2048}
2049
977ddd6b
KY
2050static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2051 unsigned int coef_val)
2052{
2053 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2054 coef_idx);
2055 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2056 coef_val);
2057}
2058
757899ac
TI
2059/* set right pin controls for digital I/O */
2060static void alc_auto_init_digital(struct hda_codec *codec)
2061{
2062 struct alc_spec *spec = codec->spec;
2063 int i;
2064 hda_nid_t pin;
2065
2066 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2067 pin = spec->autocfg.dig_out_pins[i];
2068 if (pin) {
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2071 PIN_OUT);
2072 }
2073 }
2074 pin = spec->autocfg.dig_in_pin;
2075 if (pin)
2076 snd_hda_codec_write(codec, pin, 0,
2077 AC_VERB_SET_PIN_WIDGET_CONTROL,
2078 PIN_IN);
2079}
2080
2081/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2082static void alc_auto_parse_digital(struct hda_codec *codec)
2083{
2084 struct alc_spec *spec = codec->spec;
2085 int i, err;
2086 hda_nid_t dig_nid;
2087
2088 /* support multiple SPDIFs; the secondary is set up as a slave */
2089 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2090 err = snd_hda_get_connections(codec,
2091 spec->autocfg.dig_out_pins[i],
2092 &dig_nid, 1);
2093 if (err < 0)
2094 continue;
2095 if (!i) {
2096 spec->multiout.dig_out_nid = dig_nid;
2097 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2098 } else {
2099 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2100 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2101 break;
2102 spec->slave_dig_outs[i - 1] = dig_nid;
2103 }
2104 }
2105
2106 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2107 dig_nid = codec->start_nid;
2108 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2109 unsigned int wcaps = get_wcaps(codec, dig_nid);
2110 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2111 continue;
2112 if (!(wcaps & AC_WCAP_DIGITAL))
2113 continue;
2114 if (!(wcaps & AC_WCAP_CONN_LIST))
2115 continue;
2116 err = get_connection_index(codec, dig_nid,
2117 spec->autocfg.dig_in_pin);
2118 if (err >= 0) {
2119 spec->dig_in_nid = dig_nid;
2120 break;
2121 }
2122 }
757899ac
TI
2123 }
2124}
2125
ef8ef5fb
VP
2126/*
2127 * ALC888
2128 */
2129
2130/*
2131 * 2ch mode
2132 */
a9111321 2133static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
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 */
a9111321 2148static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
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 */
a9111321 2163static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
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 */
a9111321 2178static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
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
a9111321 2190static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
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
a9111321 2201static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
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
4f5d1706 2234static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
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;
d922b51d
TI
2244 spec->automute = 1;
2245 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2246}
2247
2248static void alc889_intel_init_hook(struct hda_codec *codec)
2249{
2250 alc889_coef_init(codec);
d922b51d 2251 alc_hp_automute(codec);
6732bd0d
WF
2252}
2253
4f5d1706 2254static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
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 */
d922b51d
TI
2262 spec->automute = 1;
2263 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2264}
ef8ef5fb 2265
5b2d1eca
VP
2266/*
2267 * ALC888 Acer Aspire 4930G model
2268 */
2269
a9111321 2270static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
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)},
ef8ef5fb 2275/* Enable unsolicited event for HP jack */
5b2d1eca
VP
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},
e2e93296 2285 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2286 { }
2287};
2288
d2fd4b09
TV
2289/*
2290 * ALC888 Acer Aspire 6530G model
2291 */
2292
a9111321 2293static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
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)},
d2fd4b09
TV
2299/* Bias voltage on for external mic port */
2300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
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)},
d2fd4b09
TV
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},
d1284182 2310 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
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},
d1284182 2315 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2316 { }
2317};
2318
d9477207
DK
2319/*
2320 *ALC888 Acer Aspire 7730G model
2321 */
2322
a9111321 2323static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
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
3b315d70 2349/*
018df418 2350 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2351 */
2352
a9111321 2353static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
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 */
018df418 2373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
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},
018df418
HM
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},
3b315d70
HM
2396 { }
2397};
2398
a9111321 2399static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
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
a9111321 2420static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2421 /* Interal mic only available on one ADC */
2422 {
684a8842 2423 .num_items = 5,
d2fd4b09 2424 .items = {
8607f7c4 2425 { "Mic", 0x0 },
684a8842 2426 { "Line In", 0x2 },
d2fd4b09 2427 { "CD", 0x4 },
684a8842 2428 { "Input Mix", 0xa },
28c4edb7 2429 { "Internal Mic", 0xb },
d2fd4b09
TV
2430 },
2431 },
2432 {
684a8842 2433 .num_items = 4,
d2fd4b09 2434 .items = {
8607f7c4 2435 { "Mic", 0x0 },
684a8842 2436 { "Line In", 0x2 },
d2fd4b09 2437 { "CD", 0x4 },
684a8842 2438 { "Input Mix", 0xa },
d2fd4b09
TV
2439 },
2440 }
2441};
2442
a9111321 2443static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
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
a9111321 2475static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
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),
5f99f86a 2492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2494 { } /* end */
2495};
2496
a9111321 2497static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
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),
786c51f9 2502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2503 HDA_OUTPUT),
786c51f9
ŁW
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),
460c92fa
ŁW
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
a9111321 2519static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
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),
5f99f86a 2532 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2534 { } /* end */
2535};
2536
2537
4f5d1706 2538static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2539{
a9fd4f3f 2540 struct alc_spec *spec = codec->spec;
5b2d1eca 2541
a9fd4f3f
TI
2542 spec->autocfg.hp_pins[0] = 0x15;
2543 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2544 spec->autocfg.speaker_pins[1] = 0x16;
2545 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2546 spec->automute = 1;
2547 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2548}
2549
4f5d1706 2550static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
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;
d922b51d
TI
2558 spec->automute = 1;
2559 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2560}
2561
d9477207
DK
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;
d922b51d
TI
2570 spec->automute = 1;
2571 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2572}
2573
4f5d1706 2574static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
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;
d922b51d
TI
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2584}
2585
1da177e4 2586/*
e9edcee0
TI
2587 * ALC880 3-stack model
2588 *
2589 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2590 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2591 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2592 */
2593
4c6d72d1 2594static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2595 /* front, rear, clfe, rear_surr */
2596 0x02, 0x05, 0x04, 0x03
2597};
2598
4c6d72d1 2599static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
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.
df694daa 2606 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2607 */
4c6d72d1 2608static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2609 /* ADC1-2 */
2610 0x08, 0x09,
2611};
2612
2613#define ALC880_DIGOUT_NID 0x06
2614#define ALC880_DIGIN_NID 0x0a
2615
a9111321 2616static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
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 */
a9111321 2628static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
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 */
a9111321 2639static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
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
a9111321 2649static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2650 { 2, alc880_threestack_ch2_init },
2651 { 6, alc880_threestack_ch6_init },
2652};
2653
a9111321 2654static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
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),
985be54b
TI
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),
1da177e4
LT
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),
e9edcee0
TI
2671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2672 {
2673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674 .name = "Channel Mode",
df694daa
KY
2675 .info = alc_ch_mode_info,
2676 .get = alc_ch_mode_get,
2677 .put = alc_ch_mode_put,
e9edcee0
TI
2678 },
2679 { } /* end */
2680};
2681
2682/* capture mixer elements */
f9e336f6
TI
2683static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_info *uinfo)
2685{
2686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2687 struct alc_spec *spec = codec->spec;
2688 int err;
1da177e4 2689
5a9e02e9 2690 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2691 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2692 HDA_INPUT);
2693 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2694 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2695 return err;
2696}
2697
2698static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2699 unsigned int size, unsigned int __user *tlv)
2700{
2701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2702 struct alc_spec *spec = codec->spec;
2703 int err;
1da177e4 2704
5a9e02e9 2705 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2706 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2707 HDA_INPUT);
2708 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2709 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2710 return err;
2711}
2712
2713typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2714 struct snd_ctl_elem_value *ucontrol);
2715
2716static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2717 struct snd_ctl_elem_value *ucontrol,
2718 getput_call_t func)
2719{
2720 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2721 struct alc_spec *spec = codec->spec;
2722 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2723 int err;
2724
5a9e02e9 2725 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2726 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2727 3, 0, HDA_INPUT);
2728 err = func(kcontrol, ucontrol);
5a9e02e9 2729 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2730 return err;
2731}
2732
2733static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2734 struct snd_ctl_elem_value *ucontrol)
2735{
2736 return alc_cap_getput_caller(kcontrol, ucontrol,
2737 snd_hda_mixer_amp_volume_get);
2738}
2739
2740static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2741 struct snd_ctl_elem_value *ucontrol)
2742{
2743 return alc_cap_getput_caller(kcontrol, ucontrol,
2744 snd_hda_mixer_amp_volume_put);
2745}
2746
2747/* capture mixer elements */
2748#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2749
2750static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2751 struct snd_ctl_elem_value *ucontrol)
2752{
2753 return alc_cap_getput_caller(kcontrol, ucontrol,
2754 snd_hda_mixer_amp_switch_get);
2755}
2756
2757static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2758 struct snd_ctl_elem_value *ucontrol)
2759{
2760 return alc_cap_getput_caller(kcontrol, ucontrol,
2761 snd_hda_mixer_amp_switch_put);
2762}
2763
a23b688f 2764#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2765 { \
2766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2767 .name = "Capture Switch", \
2768 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2769 .count = num, \
2770 .info = alc_cap_sw_info, \
2771 .get = alc_cap_sw_get, \
2772 .put = alc_cap_sw_put, \
2773 }, \
2774 { \
2775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2776 .name = "Capture Volume", \
2777 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2778 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2779 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2780 .count = num, \
2781 .info = alc_cap_vol_info, \
2782 .get = alc_cap_vol_get, \
2783 .put = alc_cap_vol_put, \
2784 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2785 }
2786
2787#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2788 { \
2789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2790 /* .name = "Capture Source", */ \
2791 .name = "Input Source", \
2792 .count = num, \
2793 .info = alc_mux_enum_info, \
2794 .get = alc_mux_enum_get, \
2795 .put = alc_mux_enum_put, \
a23b688f
TI
2796 }
2797
2798#define DEFINE_CAPMIX(num) \
a9111321 2799static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2800 _DEFINE_CAPMIX(num), \
2801 _DEFINE_CAPSRC(num), \
2802 { } /* end */ \
2803}
2804
2805#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2806static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2807 _DEFINE_CAPMIX(num), \
2808 { } /* end */ \
f9e336f6
TI
2809}
2810
2811/* up to three ADCs */
2812DEFINE_CAPMIX(1);
2813DEFINE_CAPMIX(2);
2814DEFINE_CAPMIX(3);
a23b688f
TI
2815DEFINE_CAPMIX_NOSRC(1);
2816DEFINE_CAPMIX_NOSRC(2);
2817DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2818
2819/*
2820 * ALC880 5-stack model
2821 *
9c7f852e
TI
2822 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2823 * Side = 0x02 (0xd)
e9edcee0
TI
2824 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2825 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2826 */
2827
2828/* additional mixers to alc880_three_stack_mixer */
a9111321 2829static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2830 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2831 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2832 { } /* end */
2833};
2834
e9edcee0
TI
2835/* channel source setting (6/8 channel selection for 5-stack) */
2836/* 6ch mode */
a9111321 2837static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2838 /* set line-in to input, mute it */
2839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2841 { } /* end */
2842};
2843
e9edcee0 2844/* 8ch mode */
a9111321 2845static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2846 /* set line-in to output, unmute it */
2847 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2848 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2849 { } /* end */
2850};
2851
a9111321 2852static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2853 { 6, alc880_fivestack_ch6_init },
2854 { 8, alc880_fivestack_ch8_init },
2855};
2856
2857
2858/*
2859 * ALC880 6-stack model
2860 *
9c7f852e
TI
2861 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2862 * Side = 0x05 (0x0f)
e9edcee0
TI
2863 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2864 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2865 */
2866
4c6d72d1 2867static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2868 /* front, rear, clfe, rear_surr */
2869 0x02, 0x03, 0x04, 0x05
f12ab1e0 2870};
e9edcee0 2871
a9111321 2872static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2873 .num_items = 4,
2874 .items = {
2875 { "Mic", 0x0 },
2876 { "Front Mic", 0x1 },
2877 { "Line", 0x2 },
2878 { "CD", 0x4 },
2879 },
2880};
2881
2882/* fixed 8-channels */
a9111321 2883static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2884 { 8, NULL },
2885};
2886
a9111321 2887static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2888 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2889 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2890 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2891 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2892 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2893 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2894 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2895 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2896 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2897 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2903 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2906 {
2907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2908 .name = "Channel Mode",
df694daa
KY
2909 .info = alc_ch_mode_info,
2910 .get = alc_ch_mode_get,
2911 .put = alc_ch_mode_put,
16ded525
TI
2912 },
2913 { } /* end */
2914};
2915
e9edcee0
TI
2916
2917/*
2918 * ALC880 W810 model
2919 *
2920 * W810 has rear IO for:
2921 * Front (DAC 02)
2922 * Surround (DAC 03)
2923 * Center/LFE (DAC 04)
2924 * Digital out (06)
2925 *
2926 * The system also has a pair of internal speakers, and a headphone jack.
2927 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2928 *
e9edcee0
TI
2929 * There is a variable resistor to control the speaker or headphone
2930 * volume. This is a hardware-only device without a software API.
2931 *
2932 * Plugging headphones in will disable the internal speakers. This is
2933 * implemented in hardware, not via the driver using jack sense. In
2934 * a similar fashion, plugging into the rear socket marked "front" will
2935 * disable both the speakers and headphones.
2936 *
2937 * For input, there's a microphone jack, and an "audio in" jack.
2938 * These may not do anything useful with this driver yet, because I
2939 * haven't setup any initialization verbs for these yet...
2940 */
2941
4c6d72d1 2942static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2943 /* front, rear/surround, clfe */
2944 0x02, 0x03, 0x04
16ded525
TI
2945};
2946
e9edcee0 2947/* fixed 6 channels */
a9111321 2948static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2949 { 6, NULL }
2950};
2951
2952/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2953static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2955 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2956 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2957 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2958 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2959 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2960 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2961 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2962 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2963 { } /* end */
2964};
2965
2966
2967/*
2968 * Z710V model
2969 *
2970 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2971 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2972 * Line = 0x1a
e9edcee0
TI
2973 */
2974
4c6d72d1 2975static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2976 0x02
2977};
2978#define ALC880_Z71V_HP_DAC 0x03
2979
2980/* fixed 2 channels */
a9111321 2981static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2982 { 2, NULL }
2983};
2984
a9111321 2985static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2989 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2994 { } /* end */
2995};
2996
e9edcee0 2997
e9edcee0
TI
2998/*
2999 * ALC880 F1734 model
3000 *
3001 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3002 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3003 */
3004
4c6d72d1 3005static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
3006 0x03
3007};
3008#define ALC880_F1734_HP_DAC 0x02
3009
a9111321 3010static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3012 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3013 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3014 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3015 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3016 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3019 { } /* end */
3020};
3021
a9111321 3022static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3023 .num_items = 2,
3024 .items = {
3025 { "Mic", 0x1 },
3026 { "CD", 0x4 },
3027 },
3028};
3029
e9edcee0 3030
e9edcee0
TI
3031/*
3032 * ALC880 ASUS model
3033 *
3034 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3035 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3036 * Mic = 0x18, Line = 0x1a
3037 */
3038
3039#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3040#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3041
a9111321 3042static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3045 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3046 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3047 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3048 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3049 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3050 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3051 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3052 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3053 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3054 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3057 {
3058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3059 .name = "Channel Mode",
df694daa
KY
3060 .info = alc_ch_mode_info,
3061 .get = alc_ch_mode_get,
3062 .put = alc_ch_mode_put,
16ded525
TI
3063 },
3064 { } /* end */
3065};
e9edcee0 3066
e9edcee0
TI
3067/*
3068 * ALC880 ASUS W1V model
3069 *
3070 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3071 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3072 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3073 */
3074
3075/* additional mixers to alc880_asus_mixer */
a9111321 3076static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3077 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3078 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3079 { } /* end */
3080};
3081
df694daa 3082/* TCL S700 */
a9111321 3083static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3084 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3085 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3086 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3088 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3092 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3093 { } /* end */
3094};
3095
ccc656ce 3096/* Uniwill */
a9111321 3097static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3098 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3099 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3102 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3103 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3104 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3105 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3107 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3108 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3109 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3111 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3113 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3114 {
3115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3116 .name = "Channel Mode",
3117 .info = alc_ch_mode_info,
3118 .get = alc_ch_mode_get,
3119 .put = alc_ch_mode_put,
3120 },
3121 { } /* end */
3122};
3123
a9111321 3124static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3125 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3126 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3127 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3133 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3134 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3135 { } /* end */
3136};
3137
a9111321 3138static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3139 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3140 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3141 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3145 { } /* end */
3146};
3147
2134ea4f
TI
3148/*
3149 * virtual master controls
3150 */
3151
3152/*
3153 * slave controls for virtual master
3154 */
ea734963 3155static const char * const alc_slave_vols[] = {
2134ea4f
TI
3156 "Front Playback Volume",
3157 "Surround Playback Volume",
3158 "Center Playback Volume",
3159 "LFE Playback Volume",
3160 "Side Playback Volume",
3161 "Headphone Playback Volume",
3162 "Speaker Playback Volume",
3163 "Mono Playback Volume",
2134ea4f
TI
3164 "Line-Out Playback Volume",
3165 NULL,
3166};
3167
ea734963 3168static const char * const alc_slave_sws[] = {
2134ea4f
TI
3169 "Front Playback Switch",
3170 "Surround Playback Switch",
3171 "Center Playback Switch",
3172 "LFE Playback Switch",
3173 "Side Playback Switch",
3174 "Headphone Playback Switch",
3175 "Speaker Playback Switch",
3176 "Mono Playback Switch",
edb54a55 3177 "IEC958 Playback Switch",
23033b2b 3178 "Line-Out Playback Switch",
2134ea4f
TI
3179 NULL,
3180};
3181
1da177e4 3182/*
e9edcee0 3183 * build control elements
1da177e4 3184 */
603c4019 3185
5b0cb1d8
JK
3186#define NID_MAPPING (-1)
3187
3188#define SUBDEV_SPEAKER_ (0 << 6)
3189#define SUBDEV_HP_ (1 << 6)
3190#define SUBDEV_LINE_ (2 << 6)
3191#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3192#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3193#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3194
603c4019
TI
3195static void alc_free_kctls(struct hda_codec *codec);
3196
67d634c0 3197#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3198/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3199static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3200 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3201 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3202 { } /* end */
3203};
67d634c0 3204#endif
45bdd1c1 3205
1da177e4
LT
3206static int alc_build_controls(struct hda_codec *codec)
3207{
3208 struct alc_spec *spec = codec->spec;
2f44f847 3209 struct snd_kcontrol *kctl = NULL;
a9111321 3210 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3211 int i, j, err;
3212 unsigned int u;
3213 hda_nid_t nid;
1da177e4
LT
3214
3215 for (i = 0; i < spec->num_mixers; i++) {
3216 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3217 if (err < 0)
3218 return err;
3219 }
f9e336f6
TI
3220 if (spec->cap_mixer) {
3221 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3222 if (err < 0)
3223 return err;
3224 }
1da177e4 3225 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3226 err = snd_hda_create_spdif_out_ctls(codec,
3227 spec->multiout.dig_out_nid);
1da177e4
LT
3228 if (err < 0)
3229 return err;
e64f14f4
TI
3230 if (!spec->no_analog) {
3231 err = snd_hda_create_spdif_share_sw(codec,
3232 &spec->multiout);
3233 if (err < 0)
3234 return err;
3235 spec->multiout.share_spdif = 1;
3236 }
1da177e4
LT
3237 }
3238 if (spec->dig_in_nid) {
3239 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3240 if (err < 0)
3241 return err;
3242 }
2134ea4f 3243
67d634c0 3244#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3245 /* create beep controls if needed */
3246 if (spec->beep_amp) {
a9111321 3247 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3248 for (knew = alc_beep_mixer; knew->name; knew++) {
3249 struct snd_kcontrol *kctl;
3250 kctl = snd_ctl_new1(knew, codec);
3251 if (!kctl)
3252 return -ENOMEM;
3253 kctl->private_value = spec->beep_amp;
5e26dfd0 3254 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3255 if (err < 0)
3256 return err;
3257 }
3258 }
67d634c0 3259#endif
45bdd1c1 3260
2134ea4f 3261 /* if we have no master control, let's create it */
e64f14f4
TI
3262 if (!spec->no_analog &&
3263 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3264 unsigned int vmaster_tlv[4];
2134ea4f 3265 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3266 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3267 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3268 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3269 if (err < 0)
3270 return err;
3271 }
e64f14f4
TI
3272 if (!spec->no_analog &&
3273 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3274 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3275 NULL, alc_slave_sws);
3276 if (err < 0)
3277 return err;
3278 }
3279
5b0cb1d8 3280 /* assign Capture Source enums to NID */
fbe618f2
TI
3281 if (spec->capsrc_nids || spec->adc_nids) {
3282 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3283 if (!kctl)
3284 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3285 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3286 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3287 if (!nids)
3288 nids = spec->adc_nids;
3289 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3290 if (err < 0)
3291 return err;
3292 }
5b0cb1d8
JK
3293 }
3294 if (spec->cap_mixer) {
3295 const char *kname = kctl ? kctl->id.name : NULL;
3296 for (knew = spec->cap_mixer; knew->name; knew++) {
3297 if (kname && strcmp(knew->name, kname) == 0)
3298 continue;
3299 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3300 for (i = 0; kctl && i < kctl->count; i++) {
3301 err = snd_hda_add_nid(codec, kctl, i,
3302 spec->adc_nids[i]);
3303 if (err < 0)
3304 return err;
3305 }
3306 }
3307 }
3308
3309 /* other nid->control mapping */
3310 for (i = 0; i < spec->num_mixers; i++) {
3311 for (knew = spec->mixers[i]; knew->name; knew++) {
3312 if (knew->iface != NID_MAPPING)
3313 continue;
3314 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3315 if (kctl == NULL)
3316 continue;
3317 u = knew->subdevice;
3318 for (j = 0; j < 4; j++, u >>= 8) {
3319 nid = u & 0x3f;
3320 if (nid == 0)
3321 continue;
3322 switch (u & 0xc0) {
3323 case SUBDEV_SPEAKER_:
3324 nid = spec->autocfg.speaker_pins[nid];
3325 break;
3326 case SUBDEV_LINE_:
3327 nid = spec->autocfg.line_out_pins[nid];
3328 break;
3329 case SUBDEV_HP_:
3330 nid = spec->autocfg.hp_pins[nid];
3331 break;
3332 default:
3333 continue;
3334 }
3335 err = snd_hda_add_nid(codec, kctl, 0, nid);
3336 if (err < 0)
3337 return err;
3338 }
3339 u = knew->private_value;
3340 for (j = 0; j < 4; j++, u >>= 8) {
3341 nid = u & 0xff;
3342 if (nid == 0)
3343 continue;
3344 err = snd_hda_add_nid(codec, kctl, 0, nid);
3345 if (err < 0)
3346 return err;
3347 }
3348 }
3349 }
bae84e70
TI
3350
3351 alc_free_kctls(codec); /* no longer needed */
3352
1da177e4
LT
3353 return 0;
3354}
3355
e9edcee0 3356
1da177e4
LT
3357/*
3358 * initialize the codec volumes, etc
3359 */
3360
e9edcee0
TI
3361/*
3362 * generic initialization of ADC, input mixers and output mixers
3363 */
a9111321 3364static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3365 /*
3366 * Unmute ADC0-2 and set the default input to mic-in
3367 */
71fe7b82 3368 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3370 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3372 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3374
e9edcee0
TI
3375 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3376 * mixer widget
9c7f852e
TI
3377 * Note: PASD motherboards uses the Line In 2 as the input for front
3378 * panel mic (mic 2)
1da177e4 3379 */
e9edcee0 3380 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3388
e9edcee0
TI
3389 /*
3390 * Set up output mixers (0x0c - 0x0f)
1da177e4 3391 */
e9edcee0
TI
3392 /* set vol=0 to output mixers */
3393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3397 /* set up input amps for analog loopback */
3398 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3407
3408 { }
3409};
3410
e9edcee0
TI
3411/*
3412 * 3-stack pin configuration:
3413 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3414 */
a9111321 3415static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3416 /*
3417 * preset connection lists of input pins
3418 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3419 */
3420 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3421 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3422 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3423
3424 /*
3425 * Set pin mode and muting
3426 */
3427 /* set front pin widgets 0x14 for output */
05acb863 3428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3430 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3433 /* Mic2 (as headphone out) for HP output */
3434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3435 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3436 /* Line In pin widget for input */
05acb863 3437 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3438 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3439 /* Line2 (as front mic) pin widget for input and vref at 80% */
3440 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3441 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3442 /* CD pin widget for input */
05acb863 3443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3444
e9edcee0
TI
3445 { }
3446};
1da177e4 3447
e9edcee0
TI
3448/*
3449 * 5-stack pin configuration:
3450 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3451 * line-in/side = 0x1a, f-mic = 0x1b
3452 */
a9111321 3453static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3454 /*
3455 * preset connection lists of input pins
3456 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3457 */
e9edcee0
TI
3458 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3459 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3460
e9edcee0
TI
3461 /*
3462 * Set pin mode and muting
1da177e4 3463 */
e9edcee0
TI
3464 /* set pin widgets 0x14-0x17 for output */
3465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3467 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3468 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3469 /* unmute pins for output (no gain on this amp) */
3470 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3472 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3473 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474
3475 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3477 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3478 /* Mic2 (as headphone out) for HP output */
3479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3481 /* Line In pin widget for input */
3482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3484 /* Line2 (as front mic) pin widget for input and vref at 80% */
3485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3486 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 /* CD pin widget for input */
3488 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3489
3490 { }
3491};
3492
e9edcee0
TI
3493/*
3494 * W810 pin configuration:
3495 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3496 */
a9111321 3497static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3498 /* hphone/speaker input selector: front DAC */
3499 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3500
05acb863 3501 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3505 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3507
e9edcee0 3508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3510
1da177e4
LT
3511 { }
3512};
3513
e9edcee0
TI
3514/*
3515 * Z71V pin configuration:
3516 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3517 */
a9111321 3518static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3522 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3523
16ded525 3524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3525 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3526 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3527 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3528
3529 { }
3530};
3531
e9edcee0
TI
3532/*
3533 * 6-stack pin configuration:
9c7f852e
TI
3534 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3535 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3536 */
a9111321 3537static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3538 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3539
16ded525 3540 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3544 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3545 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3546 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3547 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3548
16ded525 3549 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3550 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3551 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3552 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3558
e9edcee0
TI
3559 { }
3560};
3561
ccc656ce
KY
3562/*
3563 * Uniwill pin configuration:
3564 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3565 * line = 0x1a
3566 */
a9111321 3567static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3568 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3569
3570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3571 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3576 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3584
3585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3591 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3592 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3593 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3594
3595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3596 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3597
3598 { }
3599};
3600
3601/*
3602* Uniwill P53
ea1fb29a 3603* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3604 */
a9111321 3605static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3606 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3607
3608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3609 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3610 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3620
3621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3623 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3624 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3626 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3627
3628 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3629 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3630
3631 { }
3632};
3633
a9111321 3634static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3635 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3636 { }
3637};
3638
458a4fab 3639/* auto-toggle front mic */
eeb43387 3640static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3641{
3642 unsigned int present;
3643 unsigned char bits;
ccc656ce 3644
864f92be 3645 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3646 bits = present ? HDA_AMP_MUTE : 0;
3647 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3648}
3649
4f5d1706 3650static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3651{
a9fd4f3f
TI
3652 struct alc_spec *spec = codec->spec;
3653
3654 spec->autocfg.hp_pins[0] = 0x14;
3655 spec->autocfg.speaker_pins[0] = 0x15;
3656 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3657 spec->automute = 1;
3658 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3659}
3660
3661static void alc880_uniwill_init_hook(struct hda_codec *codec)
3662{
d922b51d 3663 alc_hp_automute(codec);
eeb43387 3664 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3665}
3666
3667static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3668 unsigned int res)
3669{
3670 /* Looks like the unsol event is incompatible with the standard
3671 * definition. 4bit tag is placed at 28 bit!
3672 */
458a4fab 3673 switch (res >> 28) {
458a4fab 3674 case ALC880_MIC_EVENT:
eeb43387 3675 alc88x_simple_mic_automute(codec);
458a4fab 3676 break;
a9fd4f3f 3677 default:
d922b51d 3678 alc_sku_unsol_event(codec, res);
a9fd4f3f 3679 break;
458a4fab 3680 }
ccc656ce
KY
3681}
3682
4f5d1706 3683static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3684{
a9fd4f3f 3685 struct alc_spec *spec = codec->spec;
ccc656ce 3686
a9fd4f3f
TI
3687 spec->autocfg.hp_pins[0] = 0x14;
3688 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3689 spec->automute = 1;
3690 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3691}
3692
3693static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3694{
3695 unsigned int present;
ea1fb29a 3696
ccc656ce 3697 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3698 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3699 present &= HDA_AMP_VOLMASK;
3700 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3701 HDA_AMP_VOLMASK, present);
3702 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3703 HDA_AMP_VOLMASK, present);
ccc656ce 3704}
47fd830a 3705
ccc656ce
KY
3706static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3707 unsigned int res)
3708{
3709 /* Looks like the unsol event is incompatible with the standard
3710 * definition. 4bit tag is placed at 28 bit!
3711 */
f12ab1e0 3712 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3713 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3714 else
d922b51d 3715 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3716}
3717
e9edcee0
TI
3718/*
3719 * F1734 pin configuration:
3720 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3721 */
a9111321 3722static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3723 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3724 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3725 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3726 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3727 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3728
e9edcee0 3729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3733
e9edcee0
TI
3734 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3735 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3736 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3737 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3739 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3740 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3741 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3742 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3743
937b4160
TI
3744 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3745 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3746
dfc0ff62
TI
3747 { }
3748};
3749
e9edcee0
TI
3750/*
3751 * ASUS pin configuration:
3752 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3753 */
a9111321 3754static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3755 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3756 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3757 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3758 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3759
3760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3764 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3768
3769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3774 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3775 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3778
e9edcee0
TI
3779 { }
3780};
16ded525 3781
e9edcee0 3782/* Enable GPIO mask and set output */
bc9f98a9
KY
3783#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3784#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3785#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3786
3787/* Clevo m520g init */
a9111321 3788static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3789 /* headphone output */
3790 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3791 /* line-out */
3792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3794 /* Line-in */
3795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3797 /* CD */
3798 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3799 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3800 /* Mic1 (rear panel) */
3801 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3802 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803 /* Mic2 (front panel) */
3804 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* headphone */
3807 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3808 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809 /* change to EAPD mode */
3810 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3811 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3812
3813 { }
16ded525
TI
3814};
3815
a9111321 3816static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3817 /* change to EAPD mode */
3818 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3819 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3820
df694daa
KY
3821 /* Headphone output */
3822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3823 /* Front output*/
3824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3826
3827 /* Line In pin widget for input */
3828 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3829 /* CD pin widget for input */
3830 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3831 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3833
3834 /* change to EAPD mode */
3835 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3836 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3837
3838 { }
3839};
16ded525 3840
e9edcee0 3841/*
ae6b813a
TI
3842 * LG m1 express dual
3843 *
3844 * Pin assignment:
3845 * Rear Line-In/Out (blue): 0x14
3846 * Build-in Mic-In: 0x15
3847 * Speaker-out: 0x17
3848 * HP-Out (green): 0x1b
3849 * Mic-In/Out (red): 0x19
3850 * SPDIF-Out: 0x1e
3851 */
3852
3853/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3854static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3855 0x05, 0x02, 0x03
3856};
3857
3858/* seems analog CD is not working */
a9111321 3859static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3860 .num_items = 3,
3861 .items = {
3862 { "Mic", 0x1 },
3863 { "Line", 0x5 },
3864 { "Internal Mic", 0x6 },
3865 },
3866};
3867
3868/* 2,4,6 channel modes */
a9111321 3869static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3870 /* set line-in and mic-in to input */
3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3873 { }
3874};
3875
a9111321 3876static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3877 /* set line-in to out and mic-in to input */
3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3880 { }
3881};
3882
a9111321 3883static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3884 /* set line-in and mic-in to output */
3885 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3886 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3887 { }
3888};
3889
a9111321 3890static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3891 { 2, alc880_lg_ch2_init },
3892 { 4, alc880_lg_ch4_init },
3893 { 6, alc880_lg_ch6_init },
3894};
3895
a9111321 3896static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3897 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3898 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3900 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3907 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3908 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3909 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3910 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3911 {
3912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3913 .name = "Channel Mode",
3914 .info = alc_ch_mode_info,
3915 .get = alc_ch_mode_get,
3916 .put = alc_ch_mode_put,
3917 },
3918 { } /* end */
3919};
3920
a9111321 3921static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3922 /* set capture source to mic-in */
3923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3925 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3926 /* mute all amp mixer inputs */
3927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3930 /* line-in to input */
3931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3932 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3933 /* built-in mic */
3934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* speaker-out */
3937 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3938 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* mic-in to input */
3940 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3941 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3942 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3943 /* HP-out */
3944 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3945 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3947 /* jack sense */
a9fd4f3f 3948 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3949 { }
3950};
3951
3952/* toggle speaker-output according to the hp-jack state */
4f5d1706 3953static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3954{
a9fd4f3f 3955 struct alc_spec *spec = codec->spec;
ae6b813a 3956
a9fd4f3f
TI
3957 spec->autocfg.hp_pins[0] = 0x1b;
3958 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3959 spec->automute = 1;
3960 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3961}
3962
d681518a
TI
3963/*
3964 * LG LW20
3965 *
3966 * Pin assignment:
3967 * Speaker-out: 0x14
3968 * Mic-In: 0x18
e4f41da9
CM
3969 * Built-in Mic-In: 0x19
3970 * Line-In: 0x1b
3971 * HP-Out: 0x1a
d681518a
TI
3972 * SPDIF-Out: 0x1e
3973 */
3974
a9111321 3975static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3976 .num_items = 3,
d681518a
TI
3977 .items = {
3978 { "Mic", 0x0 },
3979 { "Internal Mic", 0x1 },
e4f41da9 3980 { "Line In", 0x2 },
d681518a
TI
3981 },
3982};
3983
0a8c5da3
CM
3984#define alc880_lg_lw_modes alc880_threestack_modes
3985
a9111321 3986static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3987 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3988 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3989 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3990 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3991 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3999 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4000 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
4001 {
4002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4003 .name = "Channel Mode",
4004 .info = alc_ch_mode_info,
4005 .get = alc_ch_mode_get,
4006 .put = alc_ch_mode_put,
4007 },
d681518a
TI
4008 { } /* end */
4009};
4010
a9111321 4011static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4012 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4013 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4014 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4015
d681518a
TI
4016 /* set capture source to mic-in */
4017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4021 /* speaker-out */
4022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4024 /* HP-out */
d681518a
TI
4025 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4027 /* mic-in to input */
4028 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4029 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030 /* built-in mic */
4031 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4033 /* jack sense */
a9fd4f3f 4034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4035 { }
4036};
4037
4038/* toggle speaker-output according to the hp-jack state */
4f5d1706 4039static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4040{
a9fd4f3f 4041 struct alc_spec *spec = codec->spec;
d681518a 4042
a9fd4f3f
TI
4043 spec->autocfg.hp_pins[0] = 0x1b;
4044 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4045 spec->automute = 1;
4046 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4047}
4048
a9111321 4049static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4050 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4051 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4054 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4055 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4056 { } /* end */
4057};
4058
a9111321 4059static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4060 .num_items = 2,
4061 .items = {
4062 { "Mic", 0x0 },
4063 { "Internal Mic", 0x1 },
4064 },
4065};
4066
a9111321 4067static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4068 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4069
4070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4071 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4072
4073 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4076 /* Mic2 (as headphone out) for HP output */
4077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079 /* Internal Speaker */
4080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4082
4083 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4084 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4085
4086 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4087 { }
4088};
4089
4090/* toggle speaker-output according to the hp-jack state */
4091static void alc880_medion_rim_automute(struct hda_codec *codec)
4092{
a9fd4f3f 4093 struct alc_spec *spec = codec->spec;
d922b51d 4094 alc_hp_automute(codec);
a9fd4f3f
TI
4095 /* toggle EAPD */
4096 if (spec->jack_present)
df99cd33
TI
4097 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4098 else
4099 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4100}
4101
4102static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4103 unsigned int res)
4104{
4105 /* Looks like the unsol event is incompatible with the standard
4106 * definition. 4bit tag is placed at 28 bit!
4107 */
4108 if ((res >> 28) == ALC880_HP_EVENT)
4109 alc880_medion_rim_automute(codec);
4110}
4111
4f5d1706 4112static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4113{
4114 struct alc_spec *spec = codec->spec;
4115
4116 spec->autocfg.hp_pins[0] = 0x14;
4117 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4118 spec->automute = 1;
4119 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4120}
4121
cb53c626 4122#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4123static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4124 { 0x0b, HDA_INPUT, 0 },
4125 { 0x0b, HDA_INPUT, 1 },
4126 { 0x0b, HDA_INPUT, 2 },
4127 { 0x0b, HDA_INPUT, 3 },
4128 { 0x0b, HDA_INPUT, 4 },
4129 { } /* end */
4130};
4131
a9111321 4132static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4133 { 0x0b, HDA_INPUT, 1 },
4134 { 0x0b, HDA_INPUT, 6 },
4135 { 0x0b, HDA_INPUT, 7 },
4136 { } /* end */
4137};
4138#endif
4139
ae6b813a
TI
4140/*
4141 * Common callbacks
e9edcee0
TI
4142 */
4143
584c0c4c
TI
4144static void alc_init_special_input_src(struct hda_codec *codec);
4145
1da177e4
LT
4146static int alc_init(struct hda_codec *codec)
4147{
4148 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4149 unsigned int i;
4150
2c3bf9ab 4151 alc_fix_pll(codec);
4a79ba34 4152 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4153
e9edcee0
TI
4154 for (i = 0; i < spec->num_init_verbs; i++)
4155 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4156 alc_init_special_input_src(codec);
ae6b813a
TI
4157
4158 if (spec->init_hook)
4159 spec->init_hook(codec);
4160
58701120
TI
4161 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4162
9e5341b9 4163 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4164 return 0;
4165}
4166
ae6b813a
TI
4167static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4168{
4169 struct alc_spec *spec = codec->spec;
4170
4171 if (spec->unsol_event)
4172 spec->unsol_event(codec, res);
4173}
4174
cb53c626
TI
4175#ifdef CONFIG_SND_HDA_POWER_SAVE
4176static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4177{
4178 struct alc_spec *spec = codec->spec;
4179 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4180}
4181#endif
4182
1da177e4
LT
4183/*
4184 * Analog playback callbacks
4185 */
4186static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4187 struct hda_codec *codec,
c8b6bf9b 4188 struct snd_pcm_substream *substream)
1da177e4
LT
4189{
4190 struct alc_spec *spec = codec->spec;
9a08160b
TI
4191 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4192 hinfo);
1da177e4
LT
4193}
4194
4195static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4196 struct hda_codec *codec,
4197 unsigned int stream_tag,
4198 unsigned int format,
c8b6bf9b 4199 struct snd_pcm_substream *substream)
1da177e4
LT
4200{
4201 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4202 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4203 stream_tag, format, substream);
1da177e4
LT
4204}
4205
4206static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4207 struct hda_codec *codec,
c8b6bf9b 4208 struct snd_pcm_substream *substream)
1da177e4
LT
4209{
4210 struct alc_spec *spec = codec->spec;
4211 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4212}
4213
4214/*
4215 * Digital out
4216 */
4217static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4218 struct hda_codec *codec,
c8b6bf9b 4219 struct snd_pcm_substream *substream)
1da177e4
LT
4220{
4221 struct alc_spec *spec = codec->spec;
4222 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4223}
4224
6b97eb45
TI
4225static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4226 struct hda_codec *codec,
4227 unsigned int stream_tag,
4228 unsigned int format,
4229 struct snd_pcm_substream *substream)
4230{
4231 struct alc_spec *spec = codec->spec;
4232 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4233 stream_tag, format, substream);
4234}
4235
9b5f12e5
TI
4236static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4237 struct hda_codec *codec,
4238 struct snd_pcm_substream *substream)
4239{
4240 struct alc_spec *spec = codec->spec;
4241 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4242}
4243
1da177e4
LT
4244static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4245 struct hda_codec *codec,
c8b6bf9b 4246 struct snd_pcm_substream *substream)
1da177e4
LT
4247{
4248 struct alc_spec *spec = codec->spec;
4249 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4250}
4251
4252/*
4253 * Analog capture
4254 */
6330079f 4255static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4256 struct hda_codec *codec,
4257 unsigned int stream_tag,
4258 unsigned int format,
c8b6bf9b 4259 struct snd_pcm_substream *substream)
1da177e4
LT
4260{
4261 struct alc_spec *spec = codec->spec;
4262
6330079f 4263 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4264 stream_tag, 0, format);
4265 return 0;
4266}
4267
6330079f 4268static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4269 struct hda_codec *codec,
c8b6bf9b 4270 struct snd_pcm_substream *substream)
1da177e4
LT
4271{
4272 struct alc_spec *spec = codec->spec;
4273
888afa15
TI
4274 snd_hda_codec_cleanup_stream(codec,
4275 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4276 return 0;
4277}
4278
840b64c0
TI
4279/* analog capture with dynamic dual-adc changes */
4280static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4281 struct hda_codec *codec,
4282 unsigned int stream_tag,
4283 unsigned int format,
4284 struct snd_pcm_substream *substream)
4285{
4286 struct alc_spec *spec = codec->spec;
4287 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4288 spec->cur_adc_stream_tag = stream_tag;
4289 spec->cur_adc_format = format;
4290 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4291 return 0;
4292}
4293
4294static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4295 struct hda_codec *codec,
4296 struct snd_pcm_substream *substream)
4297{
4298 struct alc_spec *spec = codec->spec;
4299 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4300 spec->cur_adc = 0;
4301 return 0;
4302}
4303
a9111321 4304static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4305 .substreams = 1,
4306 .channels_min = 2,
4307 .channels_max = 2,
4308 .nid = 0, /* fill later */
4309 .ops = {
4310 .prepare = dualmic_capture_pcm_prepare,
4311 .cleanup = dualmic_capture_pcm_cleanup
4312 },
4313};
1da177e4
LT
4314
4315/*
4316 */
a9111321 4317static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4318 .substreams = 1,
4319 .channels_min = 2,
4320 .channels_max = 8,
e9edcee0 4321 /* NID is set in alc_build_pcms */
1da177e4
LT
4322 .ops = {
4323 .open = alc880_playback_pcm_open,
4324 .prepare = alc880_playback_pcm_prepare,
4325 .cleanup = alc880_playback_pcm_cleanup
4326 },
4327};
4328
a9111321 4329static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4330 .substreams = 1,
4331 .channels_min = 2,
4332 .channels_max = 2,
4333 /* NID is set in alc_build_pcms */
4334};
4335
a9111321 4336static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4337 .substreams = 1,
4338 .channels_min = 2,
4339 .channels_max = 2,
4340 /* NID is set in alc_build_pcms */
4341};
4342
a9111321 4343static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4344 .substreams = 2, /* can be overridden */
1da177e4
LT
4345 .channels_min = 2,
4346 .channels_max = 2,
e9edcee0 4347 /* NID is set in alc_build_pcms */
1da177e4 4348 .ops = {
6330079f
TI
4349 .prepare = alc880_alt_capture_pcm_prepare,
4350 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4351 },
4352};
4353
a9111321 4354static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4355 .substreams = 1,
4356 .channels_min = 2,
4357 .channels_max = 2,
4358 /* NID is set in alc_build_pcms */
4359 .ops = {
4360 .open = alc880_dig_playback_pcm_open,
6b97eb45 4361 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4362 .prepare = alc880_dig_playback_pcm_prepare,
4363 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4364 },
4365};
4366
a9111321 4367static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4368 .substreams = 1,
4369 .channels_min = 2,
4370 .channels_max = 2,
4371 /* NID is set in alc_build_pcms */
4372};
4373
4c5186ed 4374/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4375static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4376 .substreams = 0,
4377 .channels_min = 0,
4378 .channels_max = 0,
4379};
4380
1da177e4
LT
4381static int alc_build_pcms(struct hda_codec *codec)
4382{
4383 struct alc_spec *spec = codec->spec;
4384 struct hda_pcm *info = spec->pcm_rec;
4385 int i;
4386
4387 codec->num_pcms = 1;
4388 codec->pcm_info = info;
4389
e64f14f4
TI
4390 if (spec->no_analog)
4391 goto skip_analog;
4392
812a2cca
TI
4393 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4394 "%s Analog", codec->chip_name);
1da177e4 4395 info->name = spec->stream_name_analog;
274693f3 4396
4a471b7d 4397 if (spec->stream_analog_playback) {
da3cec35
TI
4398 if (snd_BUG_ON(!spec->multiout.dac_nids))
4399 return -EINVAL;
4a471b7d
TI
4400 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4401 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4402 }
4403 if (spec->stream_analog_capture) {
da3cec35
TI
4404 if (snd_BUG_ON(!spec->adc_nids))
4405 return -EINVAL;
4a471b7d
TI
4406 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4407 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4408 }
4409
4410 if (spec->channel_mode) {
4411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4412 for (i = 0; i < spec->num_channel_mode; i++) {
4413 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4415 }
1da177e4
LT
4416 }
4417 }
4418
e64f14f4 4419 skip_analog:
e08a007d 4420 /* SPDIF for stream index #1 */
1da177e4 4421 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4422 snprintf(spec->stream_name_digital,
4423 sizeof(spec->stream_name_digital),
4424 "%s Digital", codec->chip_name);
e08a007d 4425 codec->num_pcms = 2;
b25c9da1 4426 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4427 info = spec->pcm_rec + 1;
1da177e4 4428 info->name = spec->stream_name_digital;
8c441982
TI
4429 if (spec->dig_out_type)
4430 info->pcm_type = spec->dig_out_type;
4431 else
4432 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4433 if (spec->multiout.dig_out_nid &&
4434 spec->stream_digital_playback) {
1da177e4
LT
4435 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4436 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4437 }
4a471b7d
TI
4438 if (spec->dig_in_nid &&
4439 spec->stream_digital_capture) {
1da177e4
LT
4440 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4441 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4442 }
963f803f
TI
4443 /* FIXME: do we need this for all Realtek codec models? */
4444 codec->spdif_status_reset = 1;
1da177e4
LT
4445 }
4446
e64f14f4
TI
4447 if (spec->no_analog)
4448 return 0;
4449
e08a007d
TI
4450 /* If the use of more than one ADC is requested for the current
4451 * model, configure a second analog capture-only PCM.
4452 */
4453 /* Additional Analaog capture for index #2 */
6330079f
TI
4454 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4455 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4456 codec->num_pcms = 3;
c06134d7 4457 info = spec->pcm_rec + 2;
e08a007d 4458 info->name = spec->stream_name_analog;
6330079f
TI
4459 if (spec->alt_dac_nid) {
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4461 *spec->stream_analog_alt_playback;
4462 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4463 spec->alt_dac_nid;
4464 } else {
4465 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4466 alc_pcm_null_stream;
4467 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4468 }
ce85c9ac 4469 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4470 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4471 *spec->stream_analog_alt_capture;
4472 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4473 spec->adc_nids[1];
4474 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4475 spec->num_adc_nids - 1;
4476 } else {
4477 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4478 alc_pcm_null_stream;
4479 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4480 }
4481 }
4482
1da177e4
LT
4483 return 0;
4484}
4485
a4e09aa3
TI
4486static inline void alc_shutup(struct hda_codec *codec)
4487{
1c716153
TI
4488 struct alc_spec *spec = codec->spec;
4489
4490 if (spec && spec->shutup)
4491 spec->shutup(codec);
a4e09aa3
TI
4492 snd_hda_shutup_pins(codec);
4493}
4494
603c4019
TI
4495static void alc_free_kctls(struct hda_codec *codec)
4496{
4497 struct alc_spec *spec = codec->spec;
4498
4499 if (spec->kctls.list) {
4500 struct snd_kcontrol_new *kctl = spec->kctls.list;
4501 int i;
4502 for (i = 0; i < spec->kctls.used; i++)
4503 kfree(kctl[i].name);
4504 }
4505 snd_array_free(&spec->kctls);
4506}
4507
1da177e4
LT
4508static void alc_free(struct hda_codec *codec)
4509{
e9edcee0 4510 struct alc_spec *spec = codec->spec;
e9edcee0 4511
f12ab1e0 4512 if (!spec)
e9edcee0
TI
4513 return;
4514
a4e09aa3 4515 alc_shutup(codec);
cd372fb3 4516 snd_hda_input_jack_free(codec);
603c4019 4517 alc_free_kctls(codec);
e9edcee0 4518 kfree(spec);
680cd536 4519 snd_hda_detach_beep_device(codec);
1da177e4
LT
4520}
4521
f5de24b0 4522#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4523static void alc_power_eapd(struct hda_codec *codec)
4524{
691f1fcc 4525 alc_auto_setup_eapd(codec, false);
c97259df
DC
4526}
4527
f5de24b0
HM
4528static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4529{
4530 struct alc_spec *spec = codec->spec;
a4e09aa3 4531 alc_shutup(codec);
f5de24b0 4532 if (spec && spec->power_hook)
c97259df 4533 spec->power_hook(codec);
f5de24b0
HM
4534 return 0;
4535}
4536#endif
4537
e044c39a 4538#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4539static int alc_resume(struct hda_codec *codec)
4540{
1c716153 4541 msleep(150); /* to avoid pop noise */
e044c39a
TI
4542 codec->patch_ops.init(codec);
4543 snd_hda_codec_resume_amp(codec);
4544 snd_hda_codec_resume_cache(codec);
9e5341b9 4545 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4546 return 0;
4547}
e044c39a
TI
4548#endif
4549
1da177e4
LT
4550/*
4551 */
a9111321 4552static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4553 .build_controls = alc_build_controls,
4554 .build_pcms = alc_build_pcms,
4555 .init = alc_init,
4556 .free = alc_free,
ae6b813a 4557 .unsol_event = alc_unsol_event,
e044c39a
TI
4558#ifdef SND_HDA_NEEDS_RESUME
4559 .resume = alc_resume,
4560#endif
cb53c626 4561#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4562 .suspend = alc_suspend,
cb53c626
TI
4563 .check_power_status = alc_check_power_status,
4564#endif
c97259df 4565 .reboot_notify = alc_shutup,
1da177e4
LT
4566};
4567
c027ddcd
KY
4568/* replace the codec chip_name with the given string */
4569static int alc_codec_rename(struct hda_codec *codec, const char *name)
4570{
4571 kfree(codec->chip_name);
4572 codec->chip_name = kstrdup(name, GFP_KERNEL);
4573 if (!codec->chip_name) {
4574 alc_free(codec);
4575 return -ENOMEM;
4576 }
4577 return 0;
4578}
4579
2fa522be
TI
4580/*
4581 * Test configuration for debugging
4582 *
4583 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4584 * enum controls.
4585 */
4586#ifdef CONFIG_SND_DEBUG
4c6d72d1 4587static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4588 0x02, 0x03, 0x04, 0x05
4589};
4590
a9111321 4591static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4592 .num_items = 7,
2fa522be
TI
4593 .items = {
4594 { "In-1", 0x0 },
4595 { "In-2", 0x1 },
4596 { "In-3", 0x2 },
4597 { "In-4", 0x3 },
4598 { "CD", 0x4 },
ae6b813a
TI
4599 { "Front", 0x5 },
4600 { "Surround", 0x6 },
2fa522be
TI
4601 },
4602};
4603
a9111321 4604static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4605 { 2, NULL },
fd2c326d 4606 { 4, NULL },
2fa522be 4607 { 6, NULL },
fd2c326d 4608 { 8, NULL },
2fa522be
TI
4609};
4610
9c7f852e
TI
4611static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4612 struct snd_ctl_elem_info *uinfo)
2fa522be 4613{
4c6d72d1 4614 static const char * const texts[] = {
2fa522be
TI
4615 "N/A", "Line Out", "HP Out",
4616 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4617 };
4618 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4619 uinfo->count = 1;
4620 uinfo->value.enumerated.items = 8;
4621 if (uinfo->value.enumerated.item >= 8)
4622 uinfo->value.enumerated.item = 7;
4623 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4624 return 0;
4625}
4626
9c7f852e
TI
4627static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4628 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4629{
4630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4631 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4632 unsigned int pin_ctl, item = 0;
4633
4634 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4635 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4636 if (pin_ctl & AC_PINCTL_OUT_EN) {
4637 if (pin_ctl & AC_PINCTL_HP_EN)
4638 item = 2;
4639 else
4640 item = 1;
4641 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4642 switch (pin_ctl & AC_PINCTL_VREFEN) {
4643 case AC_PINCTL_VREF_HIZ: item = 3; break;
4644 case AC_PINCTL_VREF_50: item = 4; break;
4645 case AC_PINCTL_VREF_GRD: item = 5; break;
4646 case AC_PINCTL_VREF_80: item = 6; break;
4647 case AC_PINCTL_VREF_100: item = 7; break;
4648 }
4649 }
4650 ucontrol->value.enumerated.item[0] = item;
4651 return 0;
4652}
4653
9c7f852e
TI
4654static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4655 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4656{
4657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4658 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4659 static const unsigned int ctls[] = {
2fa522be
TI
4660 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4661 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4662 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4663 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4666 };
4667 unsigned int old_ctl, new_ctl;
4668
4669 old_ctl = snd_hda_codec_read(codec, nid, 0,
4670 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4671 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4672 if (old_ctl != new_ctl) {
82beb8fd
TI
4673 int val;
4674 snd_hda_codec_write_cache(codec, nid, 0,
4675 AC_VERB_SET_PIN_WIDGET_CONTROL,
4676 new_ctl);
47fd830a
TI
4677 val = ucontrol->value.enumerated.item[0] >= 3 ?
4678 HDA_AMP_MUTE : 0;
4679 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4680 HDA_AMP_MUTE, val);
2fa522be
TI
4681 return 1;
4682 }
4683 return 0;
4684}
4685
9c7f852e
TI
4686static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4687 struct snd_ctl_elem_info *uinfo)
2fa522be 4688{
4c6d72d1 4689 static const char * const texts[] = {
2fa522be
TI
4690 "Front", "Surround", "CLFE", "Side"
4691 };
4692 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4693 uinfo->count = 1;
4694 uinfo->value.enumerated.items = 4;
4695 if (uinfo->value.enumerated.item >= 4)
4696 uinfo->value.enumerated.item = 3;
4697 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4698 return 0;
4699}
4700
9c7f852e
TI
4701static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4702 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4703{
4704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4705 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4706 unsigned int sel;
4707
4708 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4709 ucontrol->value.enumerated.item[0] = sel & 3;
4710 return 0;
4711}
4712
9c7f852e
TI
4713static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4714 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4715{
4716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4717 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4718 unsigned int sel;
4719
4720 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4721 if (ucontrol->value.enumerated.item[0] != sel) {
4722 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4723 snd_hda_codec_write_cache(codec, nid, 0,
4724 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4725 return 1;
4726 }
4727 return 0;
4728}
4729
4730#define PIN_CTL_TEST(xname,nid) { \
4731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4732 .name = xname, \
5b0cb1d8 4733 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4734 .info = alc_test_pin_ctl_info, \
4735 .get = alc_test_pin_ctl_get, \
4736 .put = alc_test_pin_ctl_put, \
4737 .private_value = nid \
4738 }
4739
4740#define PIN_SRC_TEST(xname,nid) { \
4741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4742 .name = xname, \
5b0cb1d8 4743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4744 .info = alc_test_pin_src_info, \
4745 .get = alc_test_pin_src_get, \
4746 .put = alc_test_pin_src_put, \
4747 .private_value = nid \
4748 }
4749
a9111321 4750static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4752 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4753 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4754 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4755 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4756 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4757 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4758 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4759 PIN_CTL_TEST("Front Pin Mode", 0x14),
4760 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4761 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4762 PIN_CTL_TEST("Side Pin Mode", 0x17),
4763 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4764 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4765 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4766 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4767 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4768 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4769 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4770 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4771 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4772 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4773 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4774 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4775 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4776 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4777 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4778 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4779 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4780 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4781 {
4782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4783 .name = "Channel Mode",
df694daa
KY
4784 .info = alc_ch_mode_info,
4785 .get = alc_ch_mode_get,
4786 .put = alc_ch_mode_put,
2fa522be
TI
4787 },
4788 { } /* end */
4789};
4790
a9111321 4791static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4792 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4795 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4798 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4801 /* Vol output for 0x0c-0x0f */
05acb863
TI
4802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4805 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4806 /* Set output pins 0x14-0x17 */
05acb863
TI
4807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4809 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4810 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4811 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4815 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4816 /* Set input pins 0x18-0x1c */
16ded525
TI
4817 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4822 /* Mute input pins 0x18-0x1b */
05acb863
TI
4823 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4827 /* ADC set up */
05acb863 4828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4829 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4831 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4833 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4834 /* Analog input/passthru */
4835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4840 { }
4841};
4842#endif
4843
1da177e4
LT
4844/*
4845 */
4846
ea734963 4847static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4848 [ALC880_3ST] = "3stack",
4849 [ALC880_TCL_S700] = "tcl",
4850 [ALC880_3ST_DIG] = "3stack-digout",
4851 [ALC880_CLEVO] = "clevo",
4852 [ALC880_5ST] = "5stack",
4853 [ALC880_5ST_DIG] = "5stack-digout",
4854 [ALC880_W810] = "w810",
4855 [ALC880_Z71V] = "z71v",
4856 [ALC880_6ST] = "6stack",
4857 [ALC880_6ST_DIG] = "6stack-digout",
4858 [ALC880_ASUS] = "asus",
4859 [ALC880_ASUS_W1V] = "asus-w1v",
4860 [ALC880_ASUS_DIG] = "asus-dig",
4861 [ALC880_ASUS_DIG2] = "asus-dig2",
4862 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4863 [ALC880_UNIWILL_P53] = "uniwill-p53",
4864 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4865 [ALC880_F1734] = "F1734",
4866 [ALC880_LG] = "lg",
4867 [ALC880_LG_LW] = "lg-lw",
df99cd33 4868 [ALC880_MEDION_RIM] = "medion",
2fa522be 4869#ifdef CONFIG_SND_DEBUG
f5fcc13c 4870 [ALC880_TEST] = "test",
2fa522be 4871#endif
f5fcc13c
TI
4872 [ALC880_AUTO] = "auto",
4873};
4874
a9111321 4875static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4876 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4877 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4878 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4879 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4880 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4881 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4882 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4883 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4884 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c 4885 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
f5fcc13c
TI
4886 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4887 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4888 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4890 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4893 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4894 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4895 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4896 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4897 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4899 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4900 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4901 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4902 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4903 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4904 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4905 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4906 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4907 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4908 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4909 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4910 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4911 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4912 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4913 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4914 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4915 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4916 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4917 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4918 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4919 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4920 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4921 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4922 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4923 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4924 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4925 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4926 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4927 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4928 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4929 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4930 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4931 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4932 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4933 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4934 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4935 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4936 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4937 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4938 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4939 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4940 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4941 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4942 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4943 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4944 /* default Intel */
4945 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4946 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4947 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4948 {}
4949};
4950
16ded525 4951/*
df694daa 4952 * ALC880 codec presets
16ded525 4953 */
a9111321 4954static const struct alc_config_preset alc880_presets[] = {
16ded525 4955 [ALC880_3ST] = {
e9edcee0 4956 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4957 .init_verbs = { alc880_volume_init_verbs,
4958 alc880_pin_3stack_init_verbs },
16ded525 4959 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4960 .dac_nids = alc880_dac_nids,
16ded525
TI
4961 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4962 .channel_mode = alc880_threestack_modes,
4e195a7b 4963 .need_dac_fix = 1,
16ded525
TI
4964 .input_mux = &alc880_capture_source,
4965 },
4966 [ALC880_3ST_DIG] = {
e9edcee0 4967 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4968 .init_verbs = { alc880_volume_init_verbs,
4969 alc880_pin_3stack_init_verbs },
16ded525 4970 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4971 .dac_nids = alc880_dac_nids,
4972 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4973 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4974 .channel_mode = alc880_threestack_modes,
4e195a7b 4975 .need_dac_fix = 1,
16ded525
TI
4976 .input_mux = &alc880_capture_source,
4977 },
df694daa
KY
4978 [ALC880_TCL_S700] = {
4979 .mixers = { alc880_tcl_s700_mixer },
4980 .init_verbs = { alc880_volume_init_verbs,
4981 alc880_pin_tcl_S700_init_verbs,
4982 alc880_gpio2_init_verbs },
4983 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4984 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4985 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4986 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4987 .hp_nid = 0x03,
4988 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4989 .channel_mode = alc880_2_jack_modes,
4990 .input_mux = &alc880_capture_source,
4991 },
16ded525 4992 [ALC880_5ST] = {
f12ab1e0
TI
4993 .mixers = { alc880_three_stack_mixer,
4994 alc880_five_stack_mixer},
4995 .init_verbs = { alc880_volume_init_verbs,
4996 alc880_pin_5stack_init_verbs },
16ded525
TI
4997 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4998 .dac_nids = alc880_dac_nids,
16ded525
TI
4999 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5000 .channel_mode = alc880_fivestack_modes,
5001 .input_mux = &alc880_capture_source,
5002 },
5003 [ALC880_5ST_DIG] = {
f12ab1e0
TI
5004 .mixers = { alc880_three_stack_mixer,
5005 alc880_five_stack_mixer },
5006 .init_verbs = { alc880_volume_init_verbs,
5007 alc880_pin_5stack_init_verbs },
16ded525
TI
5008 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5009 .dac_nids = alc880_dac_nids,
5010 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5011 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5012 .channel_mode = alc880_fivestack_modes,
5013 .input_mux = &alc880_capture_source,
5014 },
b6482d48
TI
5015 [ALC880_6ST] = {
5016 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5017 .init_verbs = { alc880_volume_init_verbs,
5018 alc880_pin_6stack_init_verbs },
b6482d48
TI
5019 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5020 .dac_nids = alc880_6st_dac_nids,
5021 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5022 .channel_mode = alc880_sixstack_modes,
5023 .input_mux = &alc880_6stack_capture_source,
5024 },
16ded525 5025 [ALC880_6ST_DIG] = {
e9edcee0 5026 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5027 .init_verbs = { alc880_volume_init_verbs,
5028 alc880_pin_6stack_init_verbs },
16ded525
TI
5029 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5030 .dac_nids = alc880_6st_dac_nids,
5031 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5032 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5033 .channel_mode = alc880_sixstack_modes,
5034 .input_mux = &alc880_6stack_capture_source,
5035 },
5036 [ALC880_W810] = {
e9edcee0 5037 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5038 .init_verbs = { alc880_volume_init_verbs,
5039 alc880_pin_w810_init_verbs,
b0af0de5 5040 alc880_gpio2_init_verbs },
16ded525
TI
5041 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5042 .dac_nids = alc880_w810_dac_nids,
5043 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5044 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5045 .channel_mode = alc880_w810_modes,
5046 .input_mux = &alc880_capture_source,
5047 },
5048 [ALC880_Z71V] = {
e9edcee0 5049 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5050 .init_verbs = { alc880_volume_init_verbs,
5051 alc880_pin_z71v_init_verbs },
16ded525
TI
5052 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5053 .dac_nids = alc880_z71v_dac_nids,
5054 .dig_out_nid = ALC880_DIGOUT_NID,
5055 .hp_nid = 0x03,
e9edcee0
TI
5056 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5057 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5058 .input_mux = &alc880_capture_source,
5059 },
5060 [ALC880_F1734] = {
e9edcee0 5061 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5062 .init_verbs = { alc880_volume_init_verbs,
5063 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5064 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5065 .dac_nids = alc880_f1734_dac_nids,
5066 .hp_nid = 0x02,
5067 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5068 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5069 .input_mux = &alc880_f1734_capture_source,
5070 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5071 .setup = alc880_uniwill_p53_setup,
d922b51d 5072 .init_hook = alc_hp_automute,
16ded525
TI
5073 },
5074 [ALC880_ASUS] = {
e9edcee0 5075 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5076 .init_verbs = { alc880_volume_init_verbs,
5077 alc880_pin_asus_init_verbs,
e9edcee0
TI
5078 alc880_gpio1_init_verbs },
5079 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5080 .dac_nids = alc880_asus_dac_nids,
5081 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5082 .channel_mode = alc880_asus_modes,
4e195a7b 5083 .need_dac_fix = 1,
16ded525
TI
5084 .input_mux = &alc880_capture_source,
5085 },
5086 [ALC880_ASUS_DIG] = {
e9edcee0 5087 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5088 .init_verbs = { alc880_volume_init_verbs,
5089 alc880_pin_asus_init_verbs,
e9edcee0
TI
5090 alc880_gpio1_init_verbs },
5091 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5092 .dac_nids = alc880_asus_dac_nids,
16ded525 5093 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5094 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5095 .channel_mode = alc880_asus_modes,
4e195a7b 5096 .need_dac_fix = 1,
16ded525
TI
5097 .input_mux = &alc880_capture_source,
5098 },
df694daa
KY
5099 [ALC880_ASUS_DIG2] = {
5100 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_asus_init_verbs,
df694daa
KY
5103 alc880_gpio2_init_verbs }, /* use GPIO2 */
5104 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5105 .dac_nids = alc880_asus_dac_nids,
5106 .dig_out_nid = ALC880_DIGOUT_NID,
5107 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5108 .channel_mode = alc880_asus_modes,
4e195a7b 5109 .need_dac_fix = 1,
df694daa
KY
5110 .input_mux = &alc880_capture_source,
5111 },
16ded525 5112 [ALC880_ASUS_W1V] = {
e9edcee0 5113 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5114 .init_verbs = { alc880_volume_init_verbs,
5115 alc880_pin_asus_init_verbs,
e9edcee0
TI
5116 alc880_gpio1_init_verbs },
5117 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5118 .dac_nids = alc880_asus_dac_nids,
16ded525 5119 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5120 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5121 .channel_mode = alc880_asus_modes,
4e195a7b 5122 .need_dac_fix = 1,
16ded525
TI
5123 .input_mux = &alc880_capture_source,
5124 },
5125 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5126 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5127 .init_verbs = { alc880_volume_init_verbs,
5128 alc880_pin_asus_init_verbs },
e9edcee0
TI
5129 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5130 .dac_nids = alc880_asus_dac_nids,
16ded525 5131 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5132 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5133 .channel_mode = alc880_asus_modes,
4e195a7b 5134 .need_dac_fix = 1,
16ded525
TI
5135 .input_mux = &alc880_capture_source,
5136 },
ccc656ce
KY
5137 [ALC880_UNIWILL] = {
5138 .mixers = { alc880_uniwill_mixer },
5139 .init_verbs = { alc880_volume_init_verbs,
5140 alc880_uniwill_init_verbs },
5141 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5142 .dac_nids = alc880_asus_dac_nids,
5143 .dig_out_nid = ALC880_DIGOUT_NID,
5144 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5145 .channel_mode = alc880_threestack_modes,
5146 .need_dac_fix = 1,
5147 .input_mux = &alc880_capture_source,
5148 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5149 .setup = alc880_uniwill_setup,
a9fd4f3f 5150 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5151 },
5152 [ALC880_UNIWILL_P53] = {
5153 .mixers = { alc880_uniwill_p53_mixer },
5154 .init_verbs = { alc880_volume_init_verbs,
5155 alc880_uniwill_p53_init_verbs },
5156 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5157 .dac_nids = alc880_asus_dac_nids,
5158 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5159 .channel_mode = alc880_threestack_modes,
5160 .input_mux = &alc880_capture_source,
5161 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5162 .setup = alc880_uniwill_p53_setup,
d922b51d 5163 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5164 },
5165 [ALC880_FUJITSU] = {
45bdd1c1 5166 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5167 .init_verbs = { alc880_volume_init_verbs,
5168 alc880_uniwill_p53_init_verbs,
5169 alc880_beep_init_verbs },
5170 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5171 .dac_nids = alc880_dac_nids,
d53d7d9e 5172 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5173 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5174 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5175 .input_mux = &alc880_capture_source,
5176 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5177 .setup = alc880_uniwill_p53_setup,
d922b51d 5178 .init_hook = alc_hp_automute,
ccc656ce 5179 },
df694daa
KY
5180 [ALC880_CLEVO] = {
5181 .mixers = { alc880_three_stack_mixer },
5182 .init_verbs = { alc880_volume_init_verbs,
5183 alc880_pin_clevo_init_verbs },
5184 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5185 .dac_nids = alc880_dac_nids,
5186 .hp_nid = 0x03,
5187 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5188 .channel_mode = alc880_threestack_modes,
4e195a7b 5189 .need_dac_fix = 1,
df694daa
KY
5190 .input_mux = &alc880_capture_source,
5191 },
ae6b813a
TI
5192 [ALC880_LG] = {
5193 .mixers = { alc880_lg_mixer },
5194 .init_verbs = { alc880_volume_init_verbs,
5195 alc880_lg_init_verbs },
5196 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5197 .dac_nids = alc880_lg_dac_nids,
5198 .dig_out_nid = ALC880_DIGOUT_NID,
5199 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5200 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5201 .need_dac_fix = 1,
ae6b813a 5202 .input_mux = &alc880_lg_capture_source,
d922b51d 5203 .unsol_event = alc_sku_unsol_event,
4f5d1706 5204 .setup = alc880_lg_setup,
d922b51d 5205 .init_hook = alc_hp_automute,
cb53c626
TI
5206#ifdef CONFIG_SND_HDA_POWER_SAVE
5207 .loopbacks = alc880_lg_loopbacks,
5208#endif
ae6b813a 5209 },
d681518a
TI
5210 [ALC880_LG_LW] = {
5211 .mixers = { alc880_lg_lw_mixer },
5212 .init_verbs = { alc880_volume_init_verbs,
5213 alc880_lg_lw_init_verbs },
0a8c5da3 5214 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5215 .dac_nids = alc880_dac_nids,
5216 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5217 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5218 .channel_mode = alc880_lg_lw_modes,
d681518a 5219 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5220 .unsol_event = alc_sku_unsol_event,
4f5d1706 5221 .setup = alc880_lg_lw_setup,
d922b51d 5222 .init_hook = alc_hp_automute,
d681518a 5223 },
df99cd33
TI
5224 [ALC880_MEDION_RIM] = {
5225 .mixers = { alc880_medion_rim_mixer },
5226 .init_verbs = { alc880_volume_init_verbs,
5227 alc880_medion_rim_init_verbs,
5228 alc_gpio2_init_verbs },
5229 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5230 .dac_nids = alc880_dac_nids,
5231 .dig_out_nid = ALC880_DIGOUT_NID,
5232 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5233 .channel_mode = alc880_2_jack_modes,
5234 .input_mux = &alc880_medion_rim_capture_source,
5235 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5236 .setup = alc880_medion_rim_setup,
5237 .init_hook = alc880_medion_rim_automute,
df99cd33 5238 },
16ded525
TI
5239#ifdef CONFIG_SND_DEBUG
5240 [ALC880_TEST] = {
e9edcee0
TI
5241 .mixers = { alc880_test_mixer },
5242 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5243 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5244 .dac_nids = alc880_test_dac_nids,
5245 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5246 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5247 .channel_mode = alc880_test_modes,
5248 .input_mux = &alc880_test_capture_source,
5249 },
5250#endif
5251};
5252
e9edcee0
TI
5253/*
5254 * Automatic parse of I/O pins from the BIOS configuration
5255 */
5256
e9edcee0
TI
5257enum {
5258 ALC_CTL_WIDGET_VOL,
5259 ALC_CTL_WIDGET_MUTE,
5260 ALC_CTL_BIND_MUTE,
5261};
a9111321 5262static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5263 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5264 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5265 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5266};
5267
ce764ab2
TI
5268static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5269{
5270 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5271 return snd_array_new(&spec->kctls);
5272}
5273
e9edcee0 5274/* add dynamic controls */
f12ab1e0 5275static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5276 int cidx, unsigned long val)
e9edcee0 5277{
c8b6bf9b 5278 struct snd_kcontrol_new *knew;
e9edcee0 5279
ce764ab2 5280 knew = alc_kcontrol_new(spec);
603c4019
TI
5281 if (!knew)
5282 return -ENOMEM;
e9edcee0 5283 *knew = alc880_control_templates[type];
543537bd 5284 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5285 if (!knew->name)
e9edcee0 5286 return -ENOMEM;
66ceeb6b 5287 knew->index = cidx;
4d02d1b6 5288 if (get_amp_nid_(val))
5e26dfd0 5289 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5290 knew->private_value = val;
e9edcee0
TI
5291 return 0;
5292}
5293
0afe5f89
TI
5294static int add_control_with_pfx(struct alc_spec *spec, int type,
5295 const char *pfx, const char *dir,
66ceeb6b 5296 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5297{
5298 char name[32];
5299 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5300 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5301}
5302
66ceeb6b
TI
5303#define add_pb_vol_ctrl(spec, type, pfx, val) \
5304 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5305#define add_pb_sw_ctrl(spec, type, pfx, val) \
5306 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5307#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5308 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5309#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5310 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5311
e9edcee0
TI
5312#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5313#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5314#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5315#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5316#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5317#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5318#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5319#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5320#define ALC880_PIN_CD_NID 0x1c
5321
5322/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5323static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5324 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5325{
5326 hda_nid_t nid;
5327 int assigned[4];
5328 int i, j;
5329
5330 memset(assigned, 0, sizeof(assigned));
b0af0de5 5331 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5332
5333 /* check the pins hardwired to audio widget */
5334 for (i = 0; i < cfg->line_outs; i++) {
5335 nid = cfg->line_out_pins[i];
5336 if (alc880_is_fixed_pin(nid)) {
5337 int idx = alc880_fixed_pin_idx(nid);
dda14410 5338 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5339 assigned[idx] = 1;
5340 }
5341 }
5342 /* left pins can be connect to any audio widget */
5343 for (i = 0; i < cfg->line_outs; i++) {
5344 nid = cfg->line_out_pins[i];
5345 if (alc880_is_fixed_pin(nid))
5346 continue;
5347 /* search for an empty channel */
5348 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5349 if (!assigned[j]) {
dda14410 5350 spec->private_dac_nids[i] =
f12ab1e0 5351 alc880_idx_to_dac(j);
e9edcee0
TI
5352 assigned[j] = 1;
5353 break;
5354 }
5355 }
5356 }
5357 spec->multiout.num_dacs = cfg->line_outs;
5358 return 0;
5359}
5360
ce764ab2 5361static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5362 bool can_be_master)
5363{
ce764ab2
TI
5364 struct auto_pin_cfg *cfg = &spec->autocfg;
5365
5366 if (cfg->line_outs == 1 && !spec->multi_ios &&
5367 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5368 return "Master";
5369
5370 switch (cfg->line_out_type) {
5371 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5372 if (cfg->line_outs == 1)
5373 return "Speaker";
5374 break;
bcb2f0f5
TI
5375 case AUTO_PIN_HP_OUT:
5376 return "Headphone";
5377 default:
ce764ab2 5378 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5379 return "PCM";
5380 break;
5381 }
5382 return NULL;
5383}
5384
e9edcee0 5385/* add playback controls from the parsed DAC table */
df694daa
KY
5386static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5387 const struct auto_pin_cfg *cfg)
e9edcee0 5388{
ea734963 5389 static const char * const chname[4] = {
f12ab1e0
TI
5390 "Front", "Surround", NULL /*CLFE*/, "Side"
5391 };
ce764ab2 5392 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5393 hda_nid_t nid;
ce764ab2 5394 int i, err, noutputs;
e9edcee0 5395
ce764ab2
TI
5396 noutputs = cfg->line_outs;
5397 if (spec->multi_ios > 0)
5398 noutputs += spec->multi_ios;
5399
5400 for (i = 0; i < noutputs; i++) {
f12ab1e0 5401 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5402 continue;
5403 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5404 if (!pfx && i == 2) {
e9edcee0 5405 /* Center/LFE */
0afe5f89
TI
5406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5407 "Center",
f12ab1e0
TI
5408 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5409 HDA_OUTPUT));
5410 if (err < 0)
e9edcee0 5411 return err;
0afe5f89
TI
5412 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5413 "LFE",
f12ab1e0
TI
5414 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5415 HDA_OUTPUT));
5416 if (err < 0)
e9edcee0 5417 return err;
0afe5f89
TI
5418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5419 "Center",
f12ab1e0
TI
5420 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5421 HDA_INPUT));
5422 if (err < 0)
e9edcee0 5423 return err;
0afe5f89
TI
5424 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5425 "LFE",
f12ab1e0
TI
5426 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5427 HDA_INPUT));
5428 if (err < 0)
e9edcee0
TI
5429 return err;
5430 } else {
bcb2f0f5 5431 const char *name = pfx;
7e59e097
DH
5432 int index = i;
5433 if (!name) {
bcb2f0f5 5434 name = chname[i];
7e59e097
DH
5435 index = 0;
5436 }
bcb2f0f5 5437 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5438 name, index,
f12ab1e0
TI
5439 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5440 HDA_OUTPUT));
5441 if (err < 0)
e9edcee0 5442 return err;
bcb2f0f5 5443 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5444 name, index,
f12ab1e0
TI
5445 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5446 HDA_INPUT));
5447 if (err < 0)
e9edcee0
TI
5448 return err;
5449 }
5450 }
e9edcee0
TI
5451 return 0;
5452}
5453
8d88bc3d
TI
5454/* add playback controls for speaker and HP outputs */
5455static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5456 const char *pfx)
e9edcee0
TI
5457{
5458 hda_nid_t nid;
5459 int err;
5460
f12ab1e0 5461 if (!pin)
e9edcee0
TI
5462 return 0;
5463
5464 if (alc880_is_fixed_pin(pin)) {
5465 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5466 /* specify the DAC as the extra output */
f12ab1e0 5467 if (!spec->multiout.hp_nid)
e9edcee0 5468 spec->multiout.hp_nid = nid;
82bc955f
TI
5469 else
5470 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5471 /* control HP volume/switch on the output mixer amp */
5472 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5473 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5474 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5475 if (err < 0)
e9edcee0 5476 return err;
0afe5f89 5477 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5478 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5479 if (err < 0)
e9edcee0
TI
5480 return err;
5481 } else if (alc880_is_multi_pin(pin)) {
5482 /* set manual connection */
e9edcee0 5483 /* we have only a switch on HP-out PIN */
0afe5f89 5484 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5485 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5486 if (err < 0)
e9edcee0
TI
5487 return err;
5488 }
5489 return 0;
5490}
5491
5492/* create input playback/capture controls for the given pin */
f12ab1e0 5493static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5494 const char *ctlname, int ctlidx,
df694daa 5495 int idx, hda_nid_t mix_nid)
e9edcee0 5496{
df694daa 5497 int err;
e9edcee0 5498
66ceeb6b 5499 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5500 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5501 if (err < 0)
e9edcee0 5502 return err;
66ceeb6b 5503 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5504 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5505 if (err < 0)
e9edcee0
TI
5506 return err;
5507 return 0;
5508}
5509
05f5f477
TI
5510static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5511{
5512 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5513 return (pincap & AC_PINCAP_IN) != 0;
5514}
5515
e9edcee0 5516/* create playback/capture controls for input pins */
05f5f477
TI
5517static int alc_auto_create_input_ctls(struct hda_codec *codec,
5518 const struct auto_pin_cfg *cfg,
5519 hda_nid_t mixer,
5520 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5521{
05f5f477 5522 struct alc_spec *spec = codec->spec;
61b9b9b1 5523 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5524 int i, err, idx, type_idx = 0;
5525 const char *prev_label = NULL;
e9edcee0 5526
66ceeb6b 5527 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5528 hda_nid_t pin;
10a20af7 5529 const char *label;
05f5f477 5530
66ceeb6b 5531 pin = cfg->inputs[i].pin;
05f5f477
TI
5532 if (!alc_is_input_pin(codec, pin))
5533 continue;
5534
5322bf27
DH
5535 label = hda_get_autocfg_input_label(codec, cfg, i);
5536 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5537 type_idx++;
5538 else
5539 type_idx = 0;
5322bf27
DH
5540 prev_label = label;
5541
05f5f477
TI
5542 if (mixer) {
5543 idx = get_connection_index(codec, mixer, pin);
5544 if (idx >= 0) {
5545 err = new_analog_input(spec, pin,
10a20af7
TI
5546 label, type_idx,
5547 idx, mixer);
05f5f477
TI
5548 if (err < 0)
5549 return err;
5550 }
5551 }
5552
5553 if (!cap1)
5554 continue;
5555 idx = get_connection_index(codec, cap1, pin);
5556 if (idx < 0 && cap2)
5557 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5558 if (idx >= 0)
5559 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5560 }
5561 return 0;
5562}
5563
05f5f477
TI
5564static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5565 const struct auto_pin_cfg *cfg)
5566{
5567 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5568}
5569
f6c7e546
TI
5570static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5571 unsigned int pin_type)
5572{
5573 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5574 pin_type);
5575 /* unmute pin */
d260cdf6
TI
5576 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5577 AMP_OUT_UNMUTE);
f6c7e546
TI
5578}
5579
df694daa
KY
5580static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5581 hda_nid_t nid, int pin_type,
e9edcee0
TI
5582 int dac_idx)
5583{
f6c7e546 5584 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5585 /* need the manual connection? */
5586 if (alc880_is_multi_pin(nid)) {
5587 struct alc_spec *spec = codec->spec;
5588 int idx = alc880_multi_pin_idx(nid);
5589 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5590 AC_VERB_SET_CONNECT_SEL,
5591 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5592 }
5593}
5594
baba8ee9
TI
5595static int get_pin_type(int line_out_type)
5596{
5597 if (line_out_type == AUTO_PIN_HP_OUT)
5598 return PIN_HP;
5599 else
5600 return PIN_OUT;
5601}
5602
e9edcee0
TI
5603static void alc880_auto_init_multi_out(struct hda_codec *codec)
5604{
5605 struct alc_spec *spec = codec->spec;
5606 int i;
ea1fb29a 5607
e9edcee0
TI
5608 for (i = 0; i < spec->autocfg.line_outs; i++) {
5609 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5610 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5611 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5612 }
5613}
5614
8d88bc3d 5615static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5616{
5617 struct alc_spec *spec = codec->spec;
5618 hda_nid_t pin;
5619
82bc955f 5620 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5621 if (pin) /* connect to front */
5622 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5623 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5624 if (pin) /* connect to front */
5625 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5626}
5627
5628static void alc880_auto_init_analog_input(struct hda_codec *codec)
5629{
5630 struct alc_spec *spec = codec->spec;
66ceeb6b 5631 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5632 int i;
5633
66ceeb6b
TI
5634 for (i = 0; i < cfg->num_inputs; i++) {
5635 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5636 if (alc_is_input_pin(codec, nid)) {
30ea098f 5637 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5638 if (nid != ALC880_PIN_CD_NID &&
5639 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5640 snd_hda_codec_write(codec, nid, 0,
5641 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5642 AMP_OUT_MUTE);
5643 }
5644 }
5645}
5646
7f311a46
TI
5647static void alc880_auto_init_input_src(struct hda_codec *codec)
5648{
5649 struct alc_spec *spec = codec->spec;
5650 int c;
5651
5652 for (c = 0; c < spec->num_adc_nids; c++) {
5653 unsigned int mux_idx;
5654 const struct hda_input_mux *imux;
5655 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5656 imux = &spec->input_mux[mux_idx];
5657 if (!imux->num_items && mux_idx > 0)
5658 imux = &spec->input_mux[0];
5659 if (imux)
5660 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5661 AC_VERB_SET_CONNECT_SEL,
5662 imux->items[0].index);
5663 }
5664}
5665
ce764ab2
TI
5666static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5667
e9edcee0 5668/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5669/* return 1 if successful, 0 if the proper config is not found,
5670 * or a negative error code
5671 */
e9edcee0
TI
5672static int alc880_parse_auto_config(struct hda_codec *codec)
5673{
5674 struct alc_spec *spec = codec->spec;
757899ac 5675 int err;
4c6d72d1 5676 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5677
f12ab1e0
TI
5678 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5679 alc880_ignore);
5680 if (err < 0)
e9edcee0 5681 return err;
f12ab1e0 5682 if (!spec->autocfg.line_outs)
e9edcee0 5683 return 0; /* can't find valid BIOS pin config */
df694daa 5684
f12ab1e0 5685 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5686 if (err < 0)
5687 return err;
5688 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5689 if (err < 0)
5690 return err;
5691 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5692 if (err < 0)
5693 return err;
5694 err = alc880_auto_create_extra_out(spec,
5695 spec->autocfg.speaker_pins[0],
5696 "Speaker");
5697 if (err < 0)
5698 return err;
5699 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5700 "Headphone");
5701 if (err < 0)
5702 return err;
05f5f477 5703 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5704 if (err < 0)
e9edcee0
TI
5705 return err;
5706
5707 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5708
757899ac 5709 alc_auto_parse_digital(codec);
e9edcee0 5710
603c4019 5711 if (spec->kctls.list)
d88897ea 5712 add_mixer(spec, spec->kctls.list);
e9edcee0 5713
d88897ea 5714 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5715
a1e8d2da 5716 spec->num_mux_defs = 1;
61b9b9b1 5717 spec->input_mux = &spec->private_imux[0];
e9edcee0 5718
6227cdce 5719 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5720
e9edcee0
TI
5721 return 1;
5722}
5723
ae6b813a
TI
5724/* additional initialization for auto-configuration model */
5725static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5726{
f6c7e546 5727 struct alc_spec *spec = codec->spec;
e9edcee0 5728 alc880_auto_init_multi_out(codec);
8d88bc3d 5729 alc880_auto_init_extra_out(codec);
e9edcee0 5730 alc880_auto_init_analog_input(codec);
7f311a46 5731 alc880_auto_init_input_src(codec);
757899ac 5732 alc_auto_init_digital(codec);
f6c7e546 5733 if (spec->unsol_event)
7fb0d78f 5734 alc_inithook(codec);
e9edcee0
TI
5735}
5736
b59bdf3b
TI
5737/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5738 * one of two digital mic pins, e.g. on ALC272
5739 */
5740static void fixup_automic_adc(struct hda_codec *codec)
5741{
5742 struct alc_spec *spec = codec->spec;
5743 int i;
5744
5745 for (i = 0; i < spec->num_adc_nids; i++) {
5746 hda_nid_t cap = spec->capsrc_nids ?
5747 spec->capsrc_nids[i] : spec->adc_nids[i];
5748 int iidx, eidx;
5749
5750 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5751 if (iidx < 0)
5752 continue;
5753 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5754 if (eidx < 0)
5755 continue;
5756 spec->int_mic.mux_idx = iidx;
5757 spec->ext_mic.mux_idx = eidx;
5758 if (spec->capsrc_nids)
5759 spec->capsrc_nids += i;
5760 spec->adc_nids += i;
5761 spec->num_adc_nids = 1;
8ed99d97
TI
5762 /* optional dock-mic */
5763 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5764 if (eidx < 0)
5765 spec->dock_mic.pin = 0;
5766 else
5767 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5768 return;
5769 }
5770 snd_printd(KERN_INFO "hda_codec: %s: "
5771 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5772 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5773 spec->auto_mic = 0; /* disable auto-mic to be sure */
5774}
5775
748cce43
TI
5776/* select or unmute the given capsrc route */
5777static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5778 int idx)
5779{
5780 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5781 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5782 HDA_AMP_MUTE, 0);
5783 } else {
5784 snd_hda_codec_write_cache(codec, cap, 0,
5785 AC_VERB_SET_CONNECT_SEL, idx);
5786 }
5787}
5788
840b64c0
TI
5789/* set the default connection to that pin */
5790static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5791{
5792 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5793 int i;
5794
8ed99d97
TI
5795 if (!pin)
5796 return 0;
eaa9b3a7
TI
5797 for (i = 0; i < spec->num_adc_nids; i++) {
5798 hda_nid_t cap = spec->capsrc_nids ?
5799 spec->capsrc_nids[i] : spec->adc_nids[i];
5800 int idx;
5801
5802 idx = get_connection_index(codec, cap, pin);
5803 if (idx < 0)
5804 continue;
748cce43 5805 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5806 return i; /* return the found index */
5807 }
5808 return -1; /* not found */
5809}
5810
5811/* choose the ADC/MUX containing the input pin and initialize the setup */
5812static void fixup_single_adc(struct hda_codec *codec)
5813{
5814 struct alc_spec *spec = codec->spec;
66ceeb6b 5815 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5816 int i;
5817
5818 /* search for the input pin; there must be only one */
66ceeb6b 5819 if (cfg->num_inputs != 1)
eaa9b3a7 5820 return;
66ceeb6b 5821 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5822 if (i >= 0) {
5823 /* use only this ADC */
5824 if (spec->capsrc_nids)
5825 spec->capsrc_nids += i;
5826 spec->adc_nids += i;
5827 spec->num_adc_nids = 1;
584c0c4c 5828 spec->single_input_src = 1;
eaa9b3a7
TI
5829 }
5830}
5831
840b64c0
TI
5832/* initialize dual adcs */
5833static void fixup_dual_adc_switch(struct hda_codec *codec)
5834{
5835 struct alc_spec *spec = codec->spec;
5836 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5837 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5838 init_capsrc_for_pin(codec, spec->int_mic.pin);
5839}
5840
584c0c4c
TI
5841/* initialize some special cases for input sources */
5842static void alc_init_special_input_src(struct hda_codec *codec)
5843{
5844 struct alc_spec *spec = codec->spec;
5845 if (spec->dual_adc_switch)
5846 fixup_dual_adc_switch(codec);
5847 else if (spec->single_input_src)
5848 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5849}
5850
b59bdf3b 5851static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5852{
b59bdf3b 5853 struct alc_spec *spec = codec->spec;
a9111321 5854 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5855 { alc_capture_mixer_nosrc1,
5856 alc_capture_mixer_nosrc2,
5857 alc_capture_mixer_nosrc3 },
5858 { alc_capture_mixer1,
5859 alc_capture_mixer2,
5860 alc_capture_mixer3 },
f9e336f6 5861 };
a23b688f 5862 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5863 int mux = 0;
840b64c0
TI
5864 int num_adcs = spec->num_adc_nids;
5865 if (spec->dual_adc_switch)
584c0c4c 5866 num_adcs = 1;
840b64c0 5867 else if (spec->auto_mic)
b59bdf3b 5868 fixup_automic_adc(codec);
eaa9b3a7
TI
5869 else if (spec->input_mux) {
5870 if (spec->input_mux->num_items > 1)
5871 mux = 1;
5872 else if (spec->input_mux->num_items == 1)
5873 fixup_single_adc(codec);
5874 }
840b64c0 5875 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5876 }
f9e336f6
TI
5877}
5878
6694635d 5879/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5880static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5881 int num_nids)
5882{
5883 struct alc_spec *spec = codec->spec;
66ceeb6b 5884 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5885 int n;
5886 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5887
5888 for (n = 0; n < num_nids; n++) {
5889 hda_nid_t adc, cap;
5890 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5891 int nconns, i, j;
5892
5893 adc = nids[n];
5894 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5895 continue;
5896 cap = adc;
5897 nconns = snd_hda_get_connections(codec, cap, conn,
5898 ARRAY_SIZE(conn));
5899 if (nconns == 1) {
5900 cap = conn[0];
5901 nconns = snd_hda_get_connections(codec, cap, conn,
5902 ARRAY_SIZE(conn));
5903 }
5904 if (nconns <= 0)
5905 continue;
5906 if (!fallback_adc) {
5907 fallback_adc = adc;
5908 fallback_cap = cap;
5909 }
66ceeb6b
TI
5910 for (i = 0; i < cfg->num_inputs; i++) {
5911 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5912 for (j = 0; j < nconns; j++) {
5913 if (conn[j] == nid)
5914 break;
5915 }
5916 if (j >= nconns)
5917 break;
5918 }
66ceeb6b 5919 if (i >= cfg->num_inputs) {
6694635d
TI
5920 int num_adcs = spec->num_adc_nids;
5921 spec->private_adc_nids[num_adcs] = adc;
5922 spec->private_capsrc_nids[num_adcs] = cap;
5923 spec->num_adc_nids++;
5924 spec->adc_nids = spec->private_adc_nids;
5925 if (adc != cap)
5926 spec->capsrc_nids = spec->private_capsrc_nids;
5927 }
5928 }
5929 if (!spec->num_adc_nids) {
5930 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5931 " using fallback 0x%x\n",
5932 codec->chip_name, fallback_adc);
6694635d
TI
5933 spec->private_adc_nids[0] = fallback_adc;
5934 spec->adc_nids = spec->private_adc_nids;
5935 if (fallback_adc != fallback_cap) {
5936 spec->private_capsrc_nids[0] = fallback_cap;
5937 spec->capsrc_nids = spec->private_adc_nids;
5938 }
5939 }
5940}
5941
67d634c0 5942#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5943#define set_beep_amp(spec, nid, idx, dir) \
5944 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5945
a9111321 5946static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5947 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5948 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5949 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5950 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5951 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5952 {}
5953};
5954
5955static inline int has_cdefine_beep(struct hda_codec *codec)
5956{
5957 struct alc_spec *spec = codec->spec;
5958 const struct snd_pci_quirk *q;
5959 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5960 if (q)
5961 return q->value;
5962 return spec->cdefine.enable_pcbeep;
5963}
67d634c0
TI
5964#else
5965#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5966#define has_cdefine_beep(codec) 0
67d634c0 5967#endif
45bdd1c1
TI
5968
5969/*
5970 * OK, here we have finally the patch for ALC880
5971 */
5972
1da177e4
LT
5973static int patch_alc880(struct hda_codec *codec)
5974{
5975 struct alc_spec *spec;
5976 int board_config;
df694daa 5977 int err;
1da177e4 5978
e560d8d8 5979 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5980 if (spec == NULL)
5981 return -ENOMEM;
5982
5983 codec->spec = spec;
5984
f5fcc13c
TI
5985 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5986 alc880_models,
5987 alc880_cfg_tbl);
5988 if (board_config < 0) {
9a11f1aa
TI
5989 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5990 codec->chip_name);
e9edcee0 5991 board_config = ALC880_AUTO;
1da177e4 5992 }
1da177e4 5993
e9edcee0
TI
5994 if (board_config == ALC880_AUTO) {
5995 /* automatic parse from the BIOS config */
5996 err = alc880_parse_auto_config(codec);
5997 if (err < 0) {
5998 alc_free(codec);
5999 return err;
f12ab1e0 6000 } else if (!err) {
9c7f852e
TI
6001 printk(KERN_INFO
6002 "hda_codec: Cannot set up configuration "
6003 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
6004 board_config = ALC880_3ST;
6005 }
1da177e4
LT
6006 }
6007
680cd536
KK
6008 err = snd_hda_attach_beep_device(codec, 0x1);
6009 if (err < 0) {
6010 alc_free(codec);
6011 return err;
6012 }
6013
df694daa 6014 if (board_config != ALC880_AUTO)
e9c364c0 6015 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 6016
1da177e4
LT
6017 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6018 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 6019 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6020
1da177e4
LT
6021 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6022 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6023
f12ab1e0 6024 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 6025 /* check whether NID 0x07 is valid */
54d17403 6026 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 6027 /* get type */
a22d543a 6028 wcap = get_wcaps_type(wcap);
e9edcee0
TI
6029 if (wcap != AC_WID_AUD_IN) {
6030 spec->adc_nids = alc880_adc_nids_alt;
6031 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
6032 } else {
6033 spec->adc_nids = alc880_adc_nids;
6034 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
6035 }
6036 }
b59bdf3b 6037 set_capture_mixer(codec);
45bdd1c1 6038 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 6039
2134ea4f
TI
6040 spec->vmaster_nid = 0x0c;
6041
1da177e4 6042 codec->patch_ops = alc_patch_ops;
e9edcee0 6043 if (board_config == ALC880_AUTO)
ae6b813a 6044 spec->init_hook = alc880_auto_init;
cb53c626
TI
6045#ifdef CONFIG_SND_HDA_POWER_SAVE
6046 if (!spec->loopback.amplist)
6047 spec->loopback.amplist = alc880_loopbacks;
6048#endif
1da177e4
LT
6049
6050 return 0;
6051}
6052
e9edcee0 6053
1da177e4
LT
6054/*
6055 * ALC260 support
6056 */
6057
4c6d72d1 6058static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6059 /* front */
6060 0x02,
6061};
6062
4c6d72d1 6063static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6064 /* ADC0 */
6065 0x04,
6066};
6067
4c6d72d1 6068static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6069 /* ADC1 */
6070 0x05,
6071};
6072
d57fdac0
JW
6073/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6074 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6075 */
4c6d72d1 6076static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6077 /* ADC0, ADC1 */
6078 0x04, 0x05
6079};
6080
e9edcee0
TI
6081#define ALC260_DIGOUT_NID 0x03
6082#define ALC260_DIGIN_NID 0x06
6083
a9111321 6084static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6085 .num_items = 4,
6086 .items = {
6087 { "Mic", 0x0 },
6088 { "Front Mic", 0x1 },
6089 { "Line", 0x2 },
6090 { "CD", 0x4 },
6091 },
6092};
6093
17e7aec6 6094/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6095 * headphone jack and the internal CD lines since these are the only pins at
6096 * which audio can appear. For flexibility, also allow the option of
6097 * recording the mixer output on the second ADC (ADC0 doesn't have a
6098 * connection to the mixer output).
a9430dd8 6099 */
a9111321 6100static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6101 {
6102 .num_items = 3,
6103 .items = {
6104 { "Mic/Line", 0x0 },
6105 { "CD", 0x4 },
6106 { "Headphone", 0x2 },
6107 },
a9430dd8 6108 },
a1e8d2da
JW
6109 {
6110 .num_items = 4,
6111 .items = {
6112 { "Mic/Line", 0x0 },
6113 { "CD", 0x4 },
6114 { "Headphone", 0x2 },
6115 { "Mixer", 0x5 },
6116 },
6117 },
6118
a9430dd8
JW
6119};
6120
a1e8d2da
JW
6121/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6122 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6123 */
a9111321 6124static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6125 {
6126 .num_items = 4,
6127 .items = {
6128 { "Mic", 0x0 },
6129 { "Line", 0x2 },
6130 { "CD", 0x4 },
6131 { "Headphone", 0x5 },
6132 },
6133 },
6134 {
6135 .num_items = 5,
6136 .items = {
6137 { "Mic", 0x0 },
6138 { "Line", 0x2 },
6139 { "CD", 0x4 },
6140 { "Headphone", 0x6 },
6141 { "Mixer", 0x5 },
6142 },
0bfc90e9
JW
6143 },
6144};
cc959489
MS
6145
6146/* Maxdata Favorit 100XS */
a9111321 6147static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6148 {
6149 .num_items = 2,
6150 .items = {
6151 { "Line/Mic", 0x0 },
6152 { "CD", 0x4 },
6153 },
6154 },
6155 {
6156 .num_items = 3,
6157 .items = {
6158 { "Line/Mic", 0x0 },
6159 { "CD", 0x4 },
6160 { "Mixer", 0x5 },
6161 },
6162 },
6163};
6164
1da177e4
LT
6165/*
6166 * This is just place-holder, so there's something for alc_build_pcms to look
6167 * at when it calculates the maximum number of channels. ALC260 has no mixer
6168 * element which allows changing the channel mode, so the verb list is
6169 * never used.
6170 */
a9111321 6171static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6172 { 2, NULL },
6173};
6174
df694daa
KY
6175
6176/* Mixer combinations
6177 *
6178 * basic: base_output + input + pc_beep + capture
6179 * HP: base_output + input + capture_alt
6180 * HP_3013: hp_3013 + input + capture
6181 * fujitsu: fujitsu + capture
0bfc90e9 6182 * acer: acer + capture
df694daa
KY
6183 */
6184
a9111321 6185static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6186 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6187 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6188 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6189 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6190 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6191 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6192 { } /* end */
f12ab1e0 6193};
1da177e4 6194
a9111321 6195static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6196 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6197 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6198 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6199 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6201 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6202 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6203 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6204 { } /* end */
6205};
6206
bec15c3a 6207/* update HP, line and mono out pins according to the master switch */
e9427969 6208static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a 6209{
e9427969 6210 update_speakers(codec);
bec15c3a
TI
6211}
6212
6213static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6214 struct snd_ctl_elem_value *ucontrol)
6215{
6216 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6217 struct alc_spec *spec = codec->spec;
e9427969 6218 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6219 return 0;
6220}
6221
6222static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6223 struct snd_ctl_elem_value *ucontrol)
6224{
6225 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6226 struct alc_spec *spec = codec->spec;
e9427969 6227 int val = !*ucontrol->value.integer.value;
bec15c3a 6228
e9427969 6229 if (val == spec->master_mute)
bec15c3a 6230 return 0;
e9427969
TI
6231 spec->master_mute = val;
6232 alc260_hp_master_update(codec);
bec15c3a
TI
6233 return 1;
6234}
6235
a9111321 6236static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6237 {
6238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6239 .name = "Master Playback Switch",
5b0cb1d8 6240 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6241 .info = snd_ctl_boolean_mono_info,
6242 .get = alc260_hp_master_sw_get,
6243 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6244 },
6245 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6246 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6247 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6248 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6249 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6250 HDA_OUTPUT),
6251 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6252 { } /* end */
6253};
6254
a9111321 6255static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6256 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6257 {},
6258};
6259
e9427969 6260static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6261{
6262 struct alc_spec *spec = codec->spec;
bec15c3a 6263
e9427969
TI
6264 spec->autocfg.hp_pins[0] = 0x0f;
6265 spec->autocfg.speaker_pins[0] = 0x10;
6266 spec->autocfg.speaker_pins[1] = 0x11;
6267 spec->automute = 1;
6268 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6269}
6270
a9111321 6271static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6272 {
6273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6274 .name = "Master Playback Switch",
5b0cb1d8 6275 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6276 .info = snd_ctl_boolean_mono_info,
6277 .get = alc260_hp_master_sw_get,
6278 .put = alc260_hp_master_sw_put,
bec15c3a 6279 },
df694daa
KY
6280 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6282 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6283 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6286 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6287 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6288 { } /* end */
6289};
6290
e9427969
TI
6291static void alc260_hp_3013_setup(struct hda_codec *codec)
6292{
6293 struct alc_spec *spec = codec->spec;
6294
6295 spec->autocfg.hp_pins[0] = 0x15;
6296 spec->autocfg.speaker_pins[0] = 0x10;
6297 spec->autocfg.speaker_pins[1] = 0x11;
6298 spec->automute = 1;
6299 spec->automute_mode = ALC_AUTOMUTE_PIN;
6300}
6301
a9111321 6302static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6303 .ops = &snd_hda_bind_vol,
6304 .values = {
6305 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6306 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6307 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6308 0
6309 },
6310};
6311
a9111321 6312static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6313 .ops = &snd_hda_bind_sw,
6314 .values = {
6315 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6316 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6317 0
6318 },
6319};
6320
a9111321 6321static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6322 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6323 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6324 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6326 { } /* end */
6327};
6328
a9111321 6329static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6331 {},
6332};
6333
e9427969 6334static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6335{
6336 struct alc_spec *spec = codec->spec;
bec15c3a 6337
e9427969
TI
6338 spec->autocfg.hp_pins[0] = 0x10;
6339 spec->autocfg.speaker_pins[0] = 0x0f;
6340 spec->autocfg.speaker_pins[1] = 0x11;
6341 spec->autocfg.speaker_pins[2] = 0x15;
6342 spec->automute = 1;
6343 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6344}
6345
6346/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6347 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6348 */
a9111321 6349static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6351 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6352 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6353 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6354 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6355 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6356 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6357 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6358 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6359 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6360 { } /* end */
6361};
6362
a1e8d2da
JW
6363/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6364 * versions of the ALC260 don't act on requests to enable mic bias from NID
6365 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6366 * datasheet doesn't mention this restriction. At this stage it's not clear
6367 * whether this behaviour is intentional or is a hardware bug in chip
6368 * revisions available in early 2006. Therefore for now allow the
6369 * "Headphone Jack Mode" control to span all choices, but if it turns out
6370 * that the lack of mic bias for this NID is intentional we could change the
6371 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6372 *
6373 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6374 * don't appear to make the mic bias available from the "line" jack, even
6375 * though the NID used for this jack (0x14) can supply it. The theory is
6376 * that perhaps Acer have included blocking capacitors between the ALC260
6377 * and the output jack. If this turns out to be the case for all such
6378 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6379 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6380 *
6381 * The C20x Tablet series have a mono internal speaker which is controlled
6382 * via the chip's Mono sum widget and pin complex, so include the necessary
6383 * controls for such models. On models without a "mono speaker" the control
6384 * won't do anything.
a1e8d2da 6385 */
a9111321 6386static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6387 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6388 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6389 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6390 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6391 HDA_OUTPUT),
31bffaa9 6392 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6393 HDA_INPUT),
0bfc90e9
JW
6394 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6395 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6397 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6398 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6399 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6400 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6401 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6402 { } /* end */
6403};
6404
cc959489
MS
6405/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6406 */
a9111321 6407static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6408 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6409 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6410 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6411 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6412 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6413 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6414 { } /* end */
6415};
6416
bc9f98a9
KY
6417/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6418 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6419 */
a9111321 6420static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6421 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6422 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6424 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6425 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6426 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6427 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6428 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6429 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6430 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6431 { } /* end */
6432};
6433
6434/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6435 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6436 */
a9111321 6437static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6438 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6439 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6441 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6442 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6443 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6444 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6446 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6447 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6448 { } /* end */
6449};
6450
df694daa
KY
6451/*
6452 * initialization verbs
6453 */
a9111321 6454static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6455 /* Line In pin widget for input */
05acb863 6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6457 /* CD pin widget for input */
05acb863 6458 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6459 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6460 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6461 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6462 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6463 /* LINE-2 is used for line-out in rear */
05acb863 6464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6465 /* select line-out */
fd56f2db 6466 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6467 /* LINE-OUT pin */
05acb863 6468 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6469 /* enable HP */
05acb863 6470 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6471 /* enable Mono */
05acb863
TI
6472 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6473 /* mute capture amp left and right */
16ded525 6474 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6475 /* set connection select to line in (default select for this ADC) */
6476 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6477 /* mute capture amp left and right */
6478 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6479 /* set connection select to line in (default select for this ADC) */
6480 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6481 /* set vol=0 Line-Out mixer amp left and right */
6482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6483 /* unmute pin widget amp left and right (no gain on this amp) */
6484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6485 /* set vol=0 HP mixer amp left and right */
6486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6487 /* unmute pin widget amp left and right (no gain on this amp) */
6488 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6489 /* set vol=0 Mono mixer amp left and right */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6491 /* unmute pin widget amp left and right (no gain on this amp) */
6492 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6493 /* unmute LINE-2 out pin */
6494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6495 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6496 * Line In 2 = 0x03
6497 */
cb53c626
TI
6498 /* mute analog inputs */
6499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6504 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6505 /* mute Front out path */
6506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6508 /* mute Headphone out path */
6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6511 /* mute Mono out path */
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6514 { }
6515};
6516
474167d6 6517#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6518static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6519 /* Headphone and output */
6520 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6521 /* mono output */
6522 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6523 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6524 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6525 /* Mic2 (front panel) pin widget for input and vref at 80% */
6526 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6527 /* Line In pin widget for input */
6528 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6529 /* Line-2 pin widget for output */
6530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6531 /* CD pin widget for input */
6532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6533 /* unmute amp left and right */
6534 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6535 /* set connection select to line in (default select for this ADC) */
6536 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6537 /* unmute Line-Out mixer amp left and right (volume = 0) */
6538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6539 /* mute pin widget amp left and right (no gain on this amp) */
6540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6541 /* unmute HP mixer amp left and right (volume = 0) */
6542 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6543 /* mute pin widget amp left and right (no gain on this amp) */
6544 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6545 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6546 * Line In 2 = 0x03
6547 */
cb53c626
TI
6548 /* mute analog inputs */
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6554 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6555 /* Unmute Front out path */
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6557 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6558 /* Unmute Headphone out path */
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6561 /* Unmute Mono out path */
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6563 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6564 { }
6565};
474167d6 6566#endif
df694daa 6567
a9111321 6568static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6569 /* Line out and output */
6570 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6571 /* mono output */
6572 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6573 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6574 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6575 /* Mic2 (front panel) pin widget for input and vref at 80% */
6576 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6577 /* Line In pin widget for input */
6578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6579 /* Headphone pin widget for output */
6580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6581 /* CD pin widget for input */
6582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6583 /* unmute amp left and right */
6584 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6585 /* set connection select to line in (default select for this ADC) */
6586 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6587 /* unmute Line-Out mixer amp left and right (volume = 0) */
6588 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6589 /* mute pin widget amp left and right (no gain on this amp) */
6590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6591 /* unmute HP mixer amp left and right (volume = 0) */
6592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6593 /* mute pin widget amp left and right (no gain on this amp) */
6594 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6595 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6596 * Line In 2 = 0x03
6597 */
cb53c626
TI
6598 /* mute analog inputs */
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6603 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6604 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6605 /* Unmute Front out path */
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6608 /* Unmute Headphone out path */
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6611 /* Unmute Mono out path */
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6613 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6614 { }
6615};
6616
a9430dd8 6617/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6618 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6619 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6620 */
a9111321 6621static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6622 /* Disable all GPIOs */
6623 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6624 /* Internal speaker is connected to headphone pin */
6625 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6626 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6628 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6629 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6630 /* Ensure all other unused pins are disabled and muted. */
6631 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6632 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6633 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6634 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6635 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6636 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639
6640 /* Disable digital (SPDIF) pins */
6641 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6642 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6643
ea1fb29a 6644 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6645 * when acting as an output.
6646 */
6647 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6648
f7ace40d 6649 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6652 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6655 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6657 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6658 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6659
f7ace40d
JW
6660 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6661 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6662 /* Unmute Line1 pin widget output buffer since it starts as an output.
6663 * If the pin mode is changed by the user the pin mode control will
6664 * take care of enabling the pin's input/output buffers as needed.
6665 * Therefore there's no need to enable the input buffer at this
6666 * stage.
cdcd9268 6667 */
f7ace40d 6668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6669 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6670 * mixer ctrl)
6671 */
f7ace40d
JW
6672 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6673
6674 /* Mute capture amp left and right */
6675 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6676 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6677 * in (on mic1 pin)
6678 */
6679 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6680
6681 /* Do the same for the second ADC: mute capture input amp and
6682 * set ADC connection to line in (on mic1 pin)
6683 */
6684 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6685 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6686
6687 /* Mute all inputs to mixer widget (even unconnected ones) */
6688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6696
6697 { }
a9430dd8
JW
6698};
6699
0bfc90e9
JW
6700/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6701 * similar laptops (adapted from Fujitsu init verbs).
6702 */
a9111321 6703static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6704 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6705 * the headphone jack. Turn this on and rely on the standard mute
6706 * methods whenever the user wants to turn these outputs off.
6707 */
6708 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6709 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6710 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6711 /* Internal speaker/Headphone jack is connected to Line-out pin */
6712 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6713 /* Internal microphone/Mic jack is connected to Mic1 pin */
6714 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6715 /* Line In jack is connected to Line1 pin */
6716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6717 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6718 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6719 /* Ensure all other unused pins are disabled and muted. */
6720 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6721 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6722 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6723 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6726 /* Disable digital (SPDIF) pins */
6727 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6728 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6729
ea1fb29a 6730 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6731 * bus when acting as outputs.
6732 */
6733 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6734 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6735
6736 /* Start with output sum widgets muted and their output gains at min */
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6739 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6742 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6745 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6746
f12ab1e0
TI
6747 /* Unmute Line-out pin widget amp left and right
6748 * (no equiv mixer ctrl)
6749 */
0bfc90e9 6750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6751 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6752 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6753 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6754 * inputs. If the pin mode is changed by the user the pin mode control
6755 * will take care of enabling the pin's input/output buffers as needed.
6756 * Therefore there's no need to enable the input buffer at this
6757 * stage.
6758 */
6759 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6761
6762 /* Mute capture amp left and right */
6763 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6764 /* Set ADC connection select to match default mixer setting - mic
6765 * (on mic1 pin)
6766 */
6767 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6768
6769 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6770 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6771 */
6772 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6773 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6774
6775 /* Mute all inputs to mixer widget (even unconnected ones) */
6776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6784
6785 { }
6786};
6787
cc959489
MS
6788/* Initialisation sequence for Maxdata Favorit 100XS
6789 * (adapted from Acer init verbs).
6790 */
a9111321 6791static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6792 /* GPIO 0 enables the output jack.
6793 * Turn this on and rely on the standard mute
6794 * methods whenever the user wants to turn these outputs off.
6795 */
6796 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6797 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6798 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6799 /* Line/Mic input jack is connected to Mic1 pin */
6800 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6801 /* Ensure all other unused pins are disabled and muted. */
6802 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6804 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6805 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6806 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6807 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6812 /* Disable digital (SPDIF) pins */
6813 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6814 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6815
6816 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6817 * bus when acting as outputs.
6818 */
6819 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6820 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6821
6822 /* Start with output sum widgets muted and their output gains at min */
6823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6825 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6828 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6830 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6831 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6832
6833 /* Unmute Line-out pin widget amp left and right
6834 * (no equiv mixer ctrl)
6835 */
6836 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6837 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6838 * inputs. If the pin mode is changed by the user the pin mode control
6839 * will take care of enabling the pin's input/output buffers as needed.
6840 * Therefore there's no need to enable the input buffer at this
6841 * stage.
6842 */
6843 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6844
6845 /* Mute capture amp left and right */
6846 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6847 /* Set ADC connection select to match default mixer setting - mic
6848 * (on mic1 pin)
6849 */
6850 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6851
6852 /* Do similar with the second ADC: mute capture input amp and
6853 * set ADC connection to mic to match ALSA's default state.
6854 */
6855 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6856 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6857
6858 /* Mute all inputs to mixer widget (even unconnected ones) */
6859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6866 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6867
6868 { }
6869};
6870
a9111321 6871static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6872 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6873 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6874 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6875 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6876 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6877 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6878 {}
6879};
6880
a9111321 6881static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6882 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6883 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6884 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6885
6886 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6887 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6888 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6889
6890 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6891 {}
6892};
6893
6894/* toggle speaker-output according to the hp-jack state */
6895static void alc260_replacer_672v_automute(struct hda_codec *codec)
6896{
6897 unsigned int present;
6898
6899 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6900 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6901 if (present) {
82beb8fd
TI
6902 snd_hda_codec_write_cache(codec, 0x01, 0,
6903 AC_VERB_SET_GPIO_DATA, 1);
6904 snd_hda_codec_write_cache(codec, 0x0f, 0,
6905 AC_VERB_SET_PIN_WIDGET_CONTROL,
6906 PIN_HP);
bc9f98a9 6907 } else {
82beb8fd
TI
6908 snd_hda_codec_write_cache(codec, 0x01, 0,
6909 AC_VERB_SET_GPIO_DATA, 0);
6910 snd_hda_codec_write_cache(codec, 0x0f, 0,
6911 AC_VERB_SET_PIN_WIDGET_CONTROL,
6912 PIN_OUT);
bc9f98a9
KY
6913 }
6914}
6915
6916static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6917 unsigned int res)
6918{
6919 if ((res >> 26) == ALC880_HP_EVENT)
6920 alc260_replacer_672v_automute(codec);
6921}
6922
a9111321 6923static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6924 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6926 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6927 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6928 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6930 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6931 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6932 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6933 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6934 {}
6935};
6936
7cf51e48
JW
6937/* Test configuration for debugging, modelled after the ALC880 test
6938 * configuration.
6939 */
6940#ifdef CONFIG_SND_DEBUG
4c6d72d1 6941static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6942 0x02,
6943};
4c6d72d1 6944static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6945 0x04, 0x05,
6946};
a1e8d2da 6947/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6948 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6949 * is NID 0x04.
17e7aec6 6950 */
a9111321 6951static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6952 {
6953 .num_items = 7,
6954 .items = {
6955 { "MIC1 pin", 0x0 },
6956 { "MIC2 pin", 0x1 },
6957 { "LINE1 pin", 0x2 },
6958 { "LINE2 pin", 0x3 },
6959 { "CD pin", 0x4 },
6960 { "LINE-OUT pin", 0x5 },
6961 { "HP-OUT pin", 0x6 },
6962 },
6963 },
6964 {
6965 .num_items = 8,
6966 .items = {
6967 { "MIC1 pin", 0x0 },
6968 { "MIC2 pin", 0x1 },
6969 { "LINE1 pin", 0x2 },
6970 { "LINE2 pin", 0x3 },
6971 { "CD pin", 0x4 },
6972 { "Mixer", 0x5 },
6973 { "LINE-OUT pin", 0x6 },
6974 { "HP-OUT pin", 0x7 },
6975 },
7cf51e48
JW
6976 },
6977};
a9111321 6978static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6979 /* Output driver widgets */
6980 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6981 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6982 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6983 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6984 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6985 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6986
a1e8d2da
JW
6987 /* Modes for retasking pin widgets
6988 * Note: the ALC260 doesn't seem to act on requests to enable mic
6989 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6990 * mention this restriction. At this stage it's not clear whether
6991 * this behaviour is intentional or is a hardware bug in chip
6992 * revisions available at least up until early 2006. Therefore for
6993 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6994 * choices, but if it turns out that the lack of mic bias for these
6995 * NIDs is intentional we could change their modes from
6996 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6997 */
7cf51e48
JW
6998 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6999 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7000 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7001 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7002 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7003 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7004
7005 /* Loopback mixer controls */
7006 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7007 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7008 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7009 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7010 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7011 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7012 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7013 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7014 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7015 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
7016 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7017 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7018 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7019 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
7020
7021 /* Controls for GPIO pins, assuming they are configured as outputs */
7022 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7023 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7024 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7025 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7026
92621f13
JW
7027 /* Switches to allow the digital IO pins to be enabled. The datasheet
7028 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 7029 * make this output available should provide clarification.
92621f13
JW
7030 */
7031 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7032 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7033
f8225f6d
JW
7034 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7035 * this output to turn on an external amplifier.
7036 */
7037 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7038 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7039
7cf51e48
JW
7040 { } /* end */
7041};
a9111321 7042static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
7043 /* Enable all GPIOs as outputs with an initial value of 0 */
7044 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7045 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7046 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7047
7cf51e48
JW
7048 /* Enable retasking pins as output, initially without power amp */
7049 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7053 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7055
92621f13
JW
7056 /* Disable digital (SPDIF) pins initially, but users can enable
7057 * them via a mixer switch. In the case of SPDIF-out, this initverb
7058 * payload also sets the generation to 0, output to be in "consumer"
7059 * PCM format, copyright asserted, no pre-emphasis and no validity
7060 * control.
7061 */
7cf51e48
JW
7062 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7063 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7064
ea1fb29a 7065 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7066 * OUT1 sum bus when acting as an output.
7067 */
7068 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7069 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7070 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7071 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7072
7073 /* Start with output sum widgets muted and their output gains at min */
7074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7076 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7077 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7080 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7081 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7082 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7083
cdcd9268
JW
7084 /* Unmute retasking pin widget output buffers since the default
7085 * state appears to be output. As the pin mode is changed by the
7086 * user the pin mode control will take care of enabling the pin's
7087 * input/output buffers as needed.
7088 */
7cf51e48
JW
7089 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7093 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7094 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7095 /* Also unmute the mono-out pin widget */
7096 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7097
7cf51e48
JW
7098 /* Mute capture amp left and right */
7099 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7100 /* Set ADC connection select to match default mixer setting (mic1
7101 * pin)
7cf51e48
JW
7102 */
7103 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7104
7105 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7106 * set ADC connection to mic1 pin
7cf51e48
JW
7107 */
7108 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7109 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7110
7111 /* Mute all inputs to mixer widget (even unconnected ones) */
7112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7120
7121 { }
7122};
7123#endif
7124
6330079f
TI
7125#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7126#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7127
a3bcba38
TI
7128#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7129#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7130
df694daa
KY
7131/*
7132 * for BIOS auto-configuration
7133 */
16ded525 7134
df694daa 7135static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7136 const char *pfx, int *vol_bits)
df694daa
KY
7137{
7138 hda_nid_t nid_vol;
7139 unsigned long vol_val, sw_val;
df694daa
KY
7140 int err;
7141
7142 if (nid >= 0x0f && nid < 0x11) {
7143 nid_vol = nid - 0x7;
7144 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7145 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7146 } else if (nid == 0x11) {
7147 nid_vol = nid - 0x7;
7148 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7149 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7150 } else if (nid >= 0x12 && nid <= 0x15) {
7151 nid_vol = 0x08;
7152 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7153 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7154 } else
7155 return 0; /* N/A */
ea1fb29a 7156
863b4518
TI
7157 if (!(*vol_bits & (1 << nid_vol))) {
7158 /* first control for the volume widget */
0afe5f89 7159 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7160 if (err < 0)
7161 return err;
7162 *vol_bits |= (1 << nid_vol);
7163 }
0afe5f89 7164 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7165 if (err < 0)
df694daa
KY
7166 return err;
7167 return 1;
7168}
7169
7170/* add playback controls from the parsed DAC table */
7171static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7172 const struct auto_pin_cfg *cfg)
7173{
7174 hda_nid_t nid;
7175 int err;
863b4518 7176 int vols = 0;
df694daa
KY
7177
7178 spec->multiout.num_dacs = 1;
7179 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7180 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7181
7182 nid = cfg->line_out_pins[0];
7183 if (nid) {
23112d6d
TI
7184 const char *pfx;
7185 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7186 pfx = "Master";
7187 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7188 pfx = "Speaker";
7189 else
7190 pfx = "Front";
7191 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7192 if (err < 0)
7193 return err;
7194 }
7195
82bc955f 7196 nid = cfg->speaker_pins[0];
df694daa 7197 if (nid) {
863b4518 7198 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7199 if (err < 0)
7200 return err;
7201 }
7202
eb06ed8f 7203 nid = cfg->hp_pins[0];
df694daa 7204 if (nid) {
863b4518
TI
7205 err = alc260_add_playback_controls(spec, nid, "Headphone",
7206 &vols);
df694daa
KY
7207 if (err < 0)
7208 return err;
7209 }
f12ab1e0 7210 return 0;
df694daa
KY
7211}
7212
7213/* create playback/capture controls for input pins */
05f5f477 7214static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7215 const struct auto_pin_cfg *cfg)
7216{
05f5f477 7217 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7218}
7219
7220static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7221 hda_nid_t nid, int pin_type,
7222 int sel_idx)
7223{
f6c7e546 7224 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7225 /* need the manual connection? */
7226 if (nid >= 0x12) {
7227 int idx = nid - 0x12;
7228 snd_hda_codec_write(codec, idx + 0x0b, 0,
7229 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7230 }
7231}
7232
7233static void alc260_auto_init_multi_out(struct hda_codec *codec)
7234{
7235 struct alc_spec *spec = codec->spec;
7236 hda_nid_t nid;
7237
f12ab1e0 7238 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7239 if (nid) {
7240 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7241 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7242 }
ea1fb29a 7243
82bc955f 7244 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7245 if (nid)
7246 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7247
eb06ed8f 7248 nid = spec->autocfg.hp_pins[0];
df694daa 7249 if (nid)
baba8ee9 7250 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7251}
df694daa
KY
7252
7253#define ALC260_PIN_CD_NID 0x16
7254static void alc260_auto_init_analog_input(struct hda_codec *codec)
7255{
7256 struct alc_spec *spec = codec->spec;
66ceeb6b 7257 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7258 int i;
7259
66ceeb6b
TI
7260 for (i = 0; i < cfg->num_inputs; i++) {
7261 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7262 if (nid >= 0x12) {
30ea098f 7263 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7264 if (nid != ALC260_PIN_CD_NID &&
7265 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7266 snd_hda_codec_write(codec, nid, 0,
7267 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7268 AMP_OUT_MUTE);
7269 }
7270 }
7271}
7272
7f311a46
TI
7273#define alc260_auto_init_input_src alc880_auto_init_input_src
7274
df694daa
KY
7275/*
7276 * generic initialization of ADC, input mixers and output mixers
7277 */
a9111321 7278static const struct hda_verb alc260_volume_init_verbs[] = {
df694daa
KY
7279 /*
7280 * Unmute ADC0-1 and set the default input to mic-in
7281 */
7282 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7283 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7284 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7285 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7286
df694daa
KY
7287 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7288 * mixer widget
f12ab1e0
TI
7289 * Note: PASD motherboards uses the Line In 2 as the input for
7290 * front panel mic (mic 2)
df694daa
KY
7291 */
7292 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7293 /* mute analog inputs */
7294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7295 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7297 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7298 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7299
7300 /*
7301 * Set up output mixers (0x08 - 0x0a)
7302 */
7303 /* set vol=0 to output mixers */
7304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7307 /* set up input amps for analog loopback */
7308 /* Amp Indices: DAC = 0, mixer = 1 */
7309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7310 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7313 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7315
df694daa
KY
7316 { }
7317};
7318
7319static int alc260_parse_auto_config(struct hda_codec *codec)
7320{
7321 struct alc_spec *spec = codec->spec;
df694daa 7322 int err;
4c6d72d1 7323 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7324
f12ab1e0
TI
7325 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7326 alc260_ignore);
7327 if (err < 0)
df694daa 7328 return err;
f12ab1e0
TI
7329 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7330 if (err < 0)
4a471b7d 7331 return err;
603c4019 7332 if (!spec->kctls.list)
df694daa 7333 return 0; /* can't find valid BIOS pin config */
05f5f477 7334 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7335 if (err < 0)
df694daa
KY
7336 return err;
7337
7338 spec->multiout.max_channels = 2;
7339
0852d7a6 7340 if (spec->autocfg.dig_outs)
df694daa 7341 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7342 if (spec->kctls.list)
d88897ea 7343 add_mixer(spec, spec->kctls.list);
df694daa 7344
d88897ea 7345 add_verb(spec, alc260_volume_init_verbs);
df694daa 7346
a1e8d2da 7347 spec->num_mux_defs = 1;
61b9b9b1 7348 spec->input_mux = &spec->private_imux[0];
df694daa 7349
6227cdce 7350 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7351
df694daa
KY
7352 return 1;
7353}
7354
ae6b813a
TI
7355/* additional initialization for auto-configuration model */
7356static void alc260_auto_init(struct hda_codec *codec)
df694daa 7357{
f6c7e546 7358 struct alc_spec *spec = codec->spec;
df694daa
KY
7359 alc260_auto_init_multi_out(codec);
7360 alc260_auto_init_analog_input(codec);
7f311a46 7361 alc260_auto_init_input_src(codec);
757899ac 7362 alc_auto_init_digital(codec);
f6c7e546 7363 if (spec->unsol_event)
7fb0d78f 7364 alc_inithook(codec);
df694daa
KY
7365}
7366
cb53c626 7367#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7368static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7369 { 0x07, HDA_INPUT, 0 },
7370 { 0x07, HDA_INPUT, 1 },
7371 { 0x07, HDA_INPUT, 2 },
7372 { 0x07, HDA_INPUT, 3 },
7373 { 0x07, HDA_INPUT, 4 },
7374 { } /* end */
7375};
7376#endif
7377
fc091769
TI
7378/*
7379 * Pin config fixes
7380 */
7381enum {
7382 PINFIX_HP_DC5750,
7383};
7384
fc091769
TI
7385static const struct alc_fixup alc260_fixups[] = {
7386 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7387 .type = ALC_FIXUP_PINS,
7388 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7389 { 0x11, 0x90130110 }, /* speaker */
7390 { }
7391 }
fc091769
TI
7392 },
7393};
7394
a9111321 7395static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7396 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7397 {}
7398};
7399
df694daa
KY
7400/*
7401 * ALC260 configurations
7402 */
ea734963 7403static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7404 [ALC260_BASIC] = "basic",
7405 [ALC260_HP] = "hp",
7406 [ALC260_HP_3013] = "hp-3013",
2922c9af 7407 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7408 [ALC260_FUJITSU_S702X] = "fujitsu",
7409 [ALC260_ACER] = "acer",
bc9f98a9
KY
7410 [ALC260_WILL] = "will",
7411 [ALC260_REPLACER_672V] = "replacer",
cc959489 7412 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7413#ifdef CONFIG_SND_DEBUG
f5fcc13c 7414 [ALC260_TEST] = "test",
7cf51e48 7415#endif
f5fcc13c
TI
7416 [ALC260_AUTO] = "auto",
7417};
7418
a9111321 7419static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7420 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7421 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7422 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7423 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7424 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7425 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7426 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7427 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7428 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7429 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7430 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7432 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7433 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7435 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7436 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7437 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7438 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7439 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7440 {}
7441};
7442
a9111321 7443static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7444 [ALC260_BASIC] = {
7445 .mixers = { alc260_base_output_mixer,
45bdd1c1 7446 alc260_input_mixer },
df694daa
KY
7447 .init_verbs = { alc260_init_verbs },
7448 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7449 .dac_nids = alc260_dac_nids,
f9e336f6 7450 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7451 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7452 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7453 .channel_mode = alc260_modes,
7454 .input_mux = &alc260_capture_source,
7455 },
7456 [ALC260_HP] = {
bec15c3a 7457 .mixers = { alc260_hp_output_mixer,
f9e336f6 7458 alc260_input_mixer },
bec15c3a
TI
7459 .init_verbs = { alc260_init_verbs,
7460 alc260_hp_unsol_verbs },
df694daa
KY
7461 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7463 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7464 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7465 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7466 .channel_mode = alc260_modes,
7467 .input_mux = &alc260_capture_source,
e9427969
TI
7468 .unsol_event = alc_sku_unsol_event,
7469 .setup = alc260_hp_setup,
7470 .init_hook = alc_inithook,
df694daa 7471 },
3f878308
KY
7472 [ALC260_HP_DC7600] = {
7473 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7474 alc260_input_mixer },
3f878308
KY
7475 .init_verbs = { alc260_init_verbs,
7476 alc260_hp_dc7600_verbs },
7477 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7478 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7479 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7480 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7482 .channel_mode = alc260_modes,
7483 .input_mux = &alc260_capture_source,
e9427969
TI
7484 .unsol_event = alc_sku_unsol_event,
7485 .setup = alc260_hp_3012_setup,
7486 .init_hook = alc_inithook,
3f878308 7487 },
df694daa
KY
7488 [ALC260_HP_3013] = {
7489 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7490 alc260_input_mixer },
bec15c3a
TI
7491 .init_verbs = { alc260_hp_3013_init_verbs,
7492 alc260_hp_3013_unsol_verbs },
df694daa
KY
7493 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7494 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7495 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7496 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7497 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7498 .channel_mode = alc260_modes,
7499 .input_mux = &alc260_capture_source,
e9427969
TI
7500 .unsol_event = alc_sku_unsol_event,
7501 .setup = alc260_hp_3013_setup,
7502 .init_hook = alc_inithook,
df694daa
KY
7503 },
7504 [ALC260_FUJITSU_S702X] = {
f9e336f6 7505 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7506 .init_verbs = { alc260_fujitsu_init_verbs },
7507 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7508 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7509 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7510 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7511 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7512 .channel_mode = alc260_modes,
a1e8d2da
JW
7513 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7514 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7515 },
0bfc90e9 7516 [ALC260_ACER] = {
f9e336f6 7517 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7518 .init_verbs = { alc260_acer_init_verbs },
7519 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7520 .dac_nids = alc260_dac_nids,
7521 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7522 .adc_nids = alc260_dual_adc_nids,
7523 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7524 .channel_mode = alc260_modes,
a1e8d2da
JW
7525 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7526 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7527 },
cc959489
MS
7528 [ALC260_FAVORIT100] = {
7529 .mixers = { alc260_favorit100_mixer },
7530 .init_verbs = { alc260_favorit100_init_verbs },
7531 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7532 .dac_nids = alc260_dac_nids,
7533 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7534 .adc_nids = alc260_dual_adc_nids,
7535 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7536 .channel_mode = alc260_modes,
7537 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7538 .input_mux = alc260_favorit100_capture_sources,
7539 },
bc9f98a9 7540 [ALC260_WILL] = {
f9e336f6 7541 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7542 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7543 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7544 .dac_nids = alc260_dac_nids,
7545 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7546 .adc_nids = alc260_adc_nids,
7547 .dig_out_nid = ALC260_DIGOUT_NID,
7548 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7549 .channel_mode = alc260_modes,
7550 .input_mux = &alc260_capture_source,
7551 },
7552 [ALC260_REPLACER_672V] = {
f9e336f6 7553 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7554 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7555 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7556 .dac_nids = alc260_dac_nids,
7557 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7558 .adc_nids = alc260_adc_nids,
7559 .dig_out_nid = ALC260_DIGOUT_NID,
7560 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7561 .channel_mode = alc260_modes,
7562 .input_mux = &alc260_capture_source,
7563 .unsol_event = alc260_replacer_672v_unsol_event,
7564 .init_hook = alc260_replacer_672v_automute,
7565 },
7cf51e48
JW
7566#ifdef CONFIG_SND_DEBUG
7567 [ALC260_TEST] = {
f9e336f6 7568 .mixers = { alc260_test_mixer },
7cf51e48
JW
7569 .init_verbs = { alc260_test_init_verbs },
7570 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7571 .dac_nids = alc260_test_dac_nids,
7572 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7573 .adc_nids = alc260_test_adc_nids,
7574 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7575 .channel_mode = alc260_modes,
a1e8d2da
JW
7576 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7577 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7578 },
7579#endif
df694daa
KY
7580};
7581
7582static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7583{
7584 struct alc_spec *spec;
df694daa 7585 int err, board_config;
1da177e4 7586
e560d8d8 7587 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7588 if (spec == NULL)
7589 return -ENOMEM;
7590
7591 codec->spec = spec;
7592
f5fcc13c
TI
7593 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7594 alc260_models,
7595 alc260_cfg_tbl);
7596 if (board_config < 0) {
9a11f1aa 7597 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7598 codec->chip_name);
df694daa 7599 board_config = ALC260_AUTO;
16ded525 7600 }
1da177e4 7601
b5bfbc67
TI
7602 if (board_config == ALC260_AUTO) {
7603 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7604 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7605 }
fc091769 7606
df694daa
KY
7607 if (board_config == ALC260_AUTO) {
7608 /* automatic parse from the BIOS config */
7609 err = alc260_parse_auto_config(codec);
7610 if (err < 0) {
7611 alc_free(codec);
7612 return err;
f12ab1e0 7613 } else if (!err) {
9c7f852e
TI
7614 printk(KERN_INFO
7615 "hda_codec: Cannot set up configuration "
7616 "from BIOS. Using base mode...\n");
df694daa
KY
7617 board_config = ALC260_BASIC;
7618 }
a9430dd8 7619 }
e9edcee0 7620
680cd536
KK
7621 err = snd_hda_attach_beep_device(codec, 0x1);
7622 if (err < 0) {
7623 alc_free(codec);
7624 return err;
7625 }
7626
df694daa 7627 if (board_config != ALC260_AUTO)
e9c364c0 7628 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7629
1da177e4
LT
7630 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7631 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7632 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7633
a3bcba38
TI
7634 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7635 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7636
4ef0ef19
TI
7637 if (!spec->adc_nids && spec->input_mux) {
7638 /* check whether NID 0x04 is valid */
7639 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7640 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7641 /* get type */
7642 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7643 spec->adc_nids = alc260_adc_nids_alt;
7644 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7645 } else {
7646 spec->adc_nids = alc260_adc_nids;
7647 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7648 }
7649 }
b59bdf3b 7650 set_capture_mixer(codec);
45bdd1c1 7651 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7652
b5bfbc67 7653 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7654
2134ea4f
TI
7655 spec->vmaster_nid = 0x08;
7656
1da177e4 7657 codec->patch_ops = alc_patch_ops;
df694daa 7658 if (board_config == ALC260_AUTO)
ae6b813a 7659 spec->init_hook = alc260_auto_init;
1c716153 7660 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7661#ifdef CONFIG_SND_HDA_POWER_SAVE
7662 if (!spec->loopback.amplist)
7663 spec->loopback.amplist = alc260_loopbacks;
7664#endif
1da177e4
LT
7665
7666 return 0;
7667}
7668
e9edcee0 7669
1da177e4 7670/*
4953550a 7671 * ALC882/883/885/888/889 support
1da177e4
LT
7672 *
7673 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7674 * configuration. Each pin widget can choose any input DACs and a mixer.
7675 * Each ADC is connected from a mixer of all inputs. This makes possible
7676 * 6-channel independent captures.
7677 *
7678 * In addition, an independent DAC for the multi-playback (not used in this
7679 * driver yet).
7680 */
df694daa
KY
7681#define ALC882_DIGOUT_NID 0x06
7682#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7683#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7684#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7685#define ALC1200_DIGOUT_NID 0x10
7686
1da177e4 7687
a9111321 7688static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7689 { 8, NULL }
7690};
7691
4953550a 7692/* DACs */
4c6d72d1 7693static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7694 /* front, rear, clfe, rear_surr */
7695 0x02, 0x03, 0x04, 0x05
7696};
4953550a 7697#define alc883_dac_nids alc882_dac_nids
1da177e4 7698
4953550a 7699/* ADCs */
df694daa
KY
7700#define alc882_adc_nids alc880_adc_nids
7701#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7702#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7703static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7704static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7705#define alc889_adc_nids alc880_adc_nids
1da177e4 7706
4c6d72d1
TI
7707static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7708static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7709#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7710static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7711#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7712
1da177e4
LT
7713/* input MUX */
7714/* FIXME: should be a matrix-type input source selection */
7715
a9111321 7716static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7717 .num_items = 4,
7718 .items = {
7719 { "Mic", 0x0 },
7720 { "Front Mic", 0x1 },
7721 { "Line", 0x2 },
7722 { "CD", 0x4 },
7723 },
7724};
41d5545d 7725
4953550a
TI
7726#define alc883_capture_source alc882_capture_source
7727
a9111321 7728static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7729 .num_items = 3,
7730 .items = {
7731 { "Front Mic", 0x0 },
7732 { "Mic", 0x3 },
7733 { "Line", 0x2 },
7734 },
7735};
7736
a9111321 7737static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7738 .num_items = 3,
7739 .items = {
7740 { "Mic", 0x1 },
b8f171e7 7741 { "Line", 0x7 },
41d5545d
KS
7742 { "CD", 0x4 },
7743 },
7744};
7745
a9111321 7746static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7747 .num_items = 2,
7748 .items = {
7749 { "Line", 0x2 },
7750 { "CD", 0x4 },
7751 },
7752};
7753
a9111321 7754static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7755 .num_items = 4,
7756 .items = {
7757 { "Mic", 0x1 },
7758 { "Front Mic", 0x0 },
7759 { "Line", 0x2 },
7760 { "CD", 0x4 },
7761 },
7762};
7763
a9111321 7764static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7765 .num_items = 2,
7766 .items = {
7767 { "Mic", 0x1 },
7768 { "Line", 0x2 },
7769 },
7770};
7771
a9111321 7772static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7773 .num_items = 4,
7774 .items = {
7775 { "Mic", 0x0 },
28c4edb7 7776 { "Internal Mic", 0x1 },
4953550a
TI
7777 { "Line", 0x2 },
7778 { "CD", 0x4 },
7779 },
7780};
7781
a9111321 7782static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7783 .num_items = 2,
7784 .items = {
7785 { "Mic", 0x0 },
28c4edb7 7786 { "Internal Mic", 0x1 },
4953550a
TI
7787 },
7788};
7789
a9111321 7790static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7791 .num_items = 3,
7792 .items = {
7793 { "Mic", 0x0 },
7794 { "Front Mic", 0x1 },
7795 { "Line", 0x4 },
7796 },
7797};
7798
a9111321 7799static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7800 .num_items = 2,
7801 .items = {
7802 { "Mic", 0x0 },
7803 { "Line", 0x2 },
7804 },
7805};
7806
a9111321 7807static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7808 .num_items = 2,
7809 .items = {
7810 { "Mic", 0x0 },
7811 /* Front Mic (0x01) unused */
7812 { "Line", 0x2 },
7813 /* Line 2 (0x03) unused */
af901ca1 7814 /* CD (0x04) unused? */
4953550a
TI
7815 },
7816};
7817
a9111321 7818static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7819 .num_items = 2,
7820 .items = {
7821 { "Mic", 0x01 },
7822 { "Line", 0x2 }, /* Not sure! */
7823 },
7824};
7825
4953550a
TI
7826/*
7827 * 2ch mode
7828 */
a9111321 7829static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7830 { 2, NULL }
7831};
7832
272a527c
KY
7833/*
7834 * 2ch mode
7835 */
a9111321 7836static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7841 { } /* end */
7842};
7843
4953550a
TI
7844/*
7845 * 4ch mode
7846 */
a9111321 7847static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7852 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7853 { } /* end */
7854};
7855
272a527c
KY
7856/*
7857 * 6ch mode
7858 */
a9111321 7859static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867};
7868
a9111321 7869static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7870 { 2, alc882_3ST_ch2_init },
4953550a 7871 { 4, alc882_3ST_ch4_init },
272a527c
KY
7872 { 6, alc882_3ST_ch6_init },
7873};
7874
4953550a
TI
7875#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7876
a65cc60f 7877/*
7878 * 2ch mode
7879 */
a9111321 7880static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7886 { } /* end */
7887};
7888
7889/*
7890 * 4ch mode
7891 */
a9111321 7892static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7893 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7898 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7899 { } /* end */
7900};
7901
7902/*
7903 * 6ch mode
7904 */
a9111321 7905static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7913 { } /* end */
7914};
7915
a9111321 7916static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7917 { 2, alc883_3ST_ch2_clevo_init },
7918 { 4, alc883_3ST_ch4_clevo_init },
7919 { 6, alc883_3ST_ch6_clevo_init },
7920};
7921
7922
df694daa
KY
7923/*
7924 * 6ch mode
7925 */
a9111321 7926static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7927 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931 { } /* end */
7932};
7933
7934/*
7935 * 8ch mode
7936 */
a9111321 7937static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { } /* end */
7943};
7944
a9111321 7945static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7946 { 6, alc882_sixstack_ch6_init },
7947 { 8, alc882_sixstack_ch8_init },
7948};
7949
76e6f5a9
RH
7950
7951/* Macbook Air 2,1 */
7952
a9111321 7953static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7954 { 2, NULL },
7955};
7956
87350ad0 7957/*
def319f9 7958 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7959 */
7960
7961/*
7962 * 2ch mode
7963 */
a9111321 7964static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7968 { } /* end */
7969};
7970
7971/*
a3f730af 7972 * 4ch mode
87350ad0 7973 */
a9111321 7974static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7980 { } /* end */
7981};
7982
a9111321 7983static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7984 { 2, alc885_mbp_ch2_init },
a3f730af 7985 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7986};
7987
92b9de83
KS
7988/*
7989 * 2ch
7990 * Speakers/Woofer/HP = Front
7991 * LineIn = Input
7992 */
a9111321 7993static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7996 { } /* end */
7997};
7998
7999/*
8000 * 6ch mode
8001 * Speakers/HP = Front
8002 * Woofer = LFE
8003 * LineIn = Surround
8004 */
a9111321 8005static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
8006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8009 { } /* end */
8010};
8011
a9111321 8012static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
8013 { 2, alc885_mb5_ch2_init },
8014 { 6, alc885_mb5_ch6_init },
8015};
87350ad0 8016
d01aecdf 8017#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
8018
8019/*
8020 * 2ch mode
8021 */
a9111321 8022static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
8023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8029 { } /* end */
8030};
8031
8032/*
8033 * 4ch mode
8034 */
a9111321 8035static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8043 { } /* end */
8044};
8045
8046/*
8047 * 6ch mode
8048 */
a9111321 8049static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8050 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8051 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8058 { } /* end */
8059};
8060
8061/*
8062 * 8ch mode
8063 */
a9111321 8064static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8065 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8073 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8074 { } /* end */
8075};
8076
a9111321 8077static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8078 { 2, alc883_4ST_ch2_init },
8079 { 4, alc883_4ST_ch4_init },
8080 { 6, alc883_4ST_ch6_init },
8081 { 8, alc883_4ST_ch8_init },
8082};
8083
8084
8085/*
8086 * 2ch mode
8087 */
a9111321 8088static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8090 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8093 { } /* end */
8094};
8095
8096/*
8097 * 4ch mode
8098 */
a9111321 8099static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8100 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8101 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8104 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8105 { } /* end */
8106};
8107
8108/*
8109 * 6ch mode
8110 */
a9111321 8111static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8114 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118 { } /* end */
8119};
8120
a9111321 8121static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8122 { 2, alc883_3ST_ch2_intel_init },
8123 { 4, alc883_3ST_ch4_intel_init },
8124 { 6, alc883_3ST_ch6_intel_init },
8125};
8126
dd7714c9
WF
8127/*
8128 * 2ch mode
8129 */
a9111321 8130static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8131 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8137 { } /* end */
8138};
8139
87a8c370
JK
8140/*
8141 * 6ch mode
8142 */
a9111321 8143static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150 { } /* end */
8151};
8152
8153/*
8154 * 8ch mode
8155 */
a9111321 8156static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8164 { } /* end */
8165};
8166
a9111321 8167static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8168 { 2, alc889_ch2_intel_init },
87a8c370
JK
8169 { 6, alc889_ch6_intel_init },
8170 { 8, alc889_ch8_intel_init },
8171};
8172
4953550a
TI
8173/*
8174 * 6ch mode
8175 */
a9111321 8176static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8177 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8181 { } /* end */
8182};
8183
8184/*
8185 * 8ch mode
8186 */
a9111321 8187static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8188 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192 { } /* end */
8193};
8194
a9111321 8195static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8196 { 6, alc883_sixstack_ch6_init },
8197 { 8, alc883_sixstack_ch8_init },
8198};
8199
8200
1da177e4
LT
8201/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8202 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8203 */
a9111321 8204static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8214 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8224 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8225 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8226 { } /* end */
8227};
8228
76e6f5a9
RH
8229/* Macbook Air 2,1 same control for HP and internal Speaker */
8230
a9111321 8231static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8234 { }
8235};
8236
8237
a9111321 8238static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8248 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8250 { } /* end */
8251};
41d5545d 8252
a9111321 8253static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8261 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8262 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8266 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8268 { } /* end */
8269};
92b9de83 8270
a9111321 8271static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8277 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8279 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8282 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8283 { } /* end */
8284};
8285
a9111321 8286static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8289 { } /* end */
8290};
8291
8292
a9111321 8293static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8303 { } /* end */
8304};
8305
a9111321 8306static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8319 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8320 { } /* end */
8321};
8322
8323/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8325 */
a9111321 8326static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8340 { } /* end */
8341};
8342
a9111321 8343static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8354 { } /* end */
8355};
8356
a9111321 8357static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8358 {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Channel Mode",
8361 .info = alc_ch_mode_info,
8362 .get = alc_ch_mode_get,
8363 .put = alc_ch_mode_put,
8364 },
8365 { } /* end */
8366};
8367
a9111321 8368static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8372 /* Rear mixer */
05acb863
TI
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8375 /* CLFE mixer */
05acb863
TI
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8378 /* Side mixer */
05acb863
TI
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8381
e9edcee0 8382 /* Front Pin: output 0 (0x0c) */
05acb863 8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8386 /* Rear Pin: output 1 (0x0d) */
05acb863 8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8390 /* CLFE Pin: output 2 (0x0e) */
05acb863 8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8393 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8394 /* Side Pin: output 3 (0x0f) */
05acb863 8395 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8397 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8398 /* Mic (rear) pin: input vref at 80% */
16ded525 8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401 /* Front Mic pin: input vref at 80% */
16ded525 8402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8404 /* Line In pin: input */
05acb863 8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8411 /* CD pin widget for input */
05acb863 8412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8413
8414 /* FIXME: use matrix-type input source selection */
8415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8416 /* Input mixer2 */
05acb863 8417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8418 /* Input mixer3 */
05acb863 8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8420 /* ADC2: mute amp left and right */
8421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8422 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8423 /* ADC3: mute amp left and right */
8424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8425 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8426
8427 { }
8428};
8429
a9111321 8430static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8431 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8436 /* ADC1: mute amp left and right */
8437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8439 { }
8440};
8441
a9111321 8442static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8443 /* change to EAPD mode */
8444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8445 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8446 { }
4b146cb0
TI
8447};
8448
a9111321 8449static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8452 { }
8453};
8454
a9111321 8455static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8458 {}
8459};
87a8c370 8460
a9111321 8461static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8462 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8465 /* Rear mixer */
88102f3f
KY
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8468 /* CLFE mixer */
88102f3f
KY
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8471 /* Side mixer */
88102f3f
KY
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8474
8475 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Front Pin: output 0 (0x0c) */
8480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* Rear Pin: output 1 (0x0d) */
8484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8487 /* CLFE Pin: output 2 (0x0e) */
8488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8491 /* Side Pin: output 3 (0x0f) */
8492 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8495 /* Mic (rear) pin: input vref at 80% */
8496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8498 /* Front Mic pin: input vref at 80% */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Line In pin: input */
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504
8505 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8506 /* Input mixer1 */
88102f3f 8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8508 /* Input mixer2 */
8509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8510 /* Input mixer3 */
88102f3f 8511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8512 /* ADC2: mute amp left and right */
8513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 /* ADC3: mute amp left and right */
8515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516
8517 { }
8518};
8519
a9111321 8520static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8524 { }
8525};
8526
8527
8528/* Unmute Selector 24h and set the default input to front mic */
a9111321 8529static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8530 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8532 { }
8533};
8534
8535
4953550a
TI
8536#define alc883_init_verbs alc882_base_init_verbs
8537
9102cd1c 8538/* Mac Pro test */
a9111321 8539static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8545 /* FIXME: this looks suspicious...
d355c82a
JK
8546 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8548 */
9102cd1c
TD
8549 { } /* end */
8550};
8551
a9111321 8552static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8553 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8557 /* Front Pin: output 0 (0x0c) */
8558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 /* Front Mic pin: input vref at 80% */
8562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8564 /* Speaker: output */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8568 /* Headphone output (output 0 - 0x0c) */
8569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8572
8573 /* FIXME: use matrix-type input source selection */
8574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8575 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* Input mixer2 */
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8585 /* Input mixer3 */
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8590 /* ADC1: mute amp left and right */
8591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8593 /* ADC2: mute amp left and right */
8594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* ADC3: mute amp left and right */
8597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8598 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8599
8600 { }
8601};
f12ab1e0 8602
41d5545d 8603/* Macbook 5,1 */
a9111321 8604static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8605 /* DACs */
8606 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8610 /* Front mixer */
41d5545d
KS
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8614 /* Surround mixer */
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8618 /* LFE mixer */
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8622 /* HP mixer */
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8626 /* Front Pin (0x0c) */
41d5545d
KS
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* LFE Pin (0x0e) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8634 /* HP Pin (0x0f) */
41d5545d
KS
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8639 /* Front Mic pin: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 /* Line In pin */
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8645
b8f171e7
AM
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8649 { }
8650};
8651
e458b1fa 8652/* Macmini 3,1 */
a9111321 8653static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8654 /* DACs */
8655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8659 /* Front mixer */
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8663 /* Surround mixer */
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8667 /* LFE mixer */
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8671 /* HP mixer */
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8675 /* Front Pin (0x0c) */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 /* LFE Pin (0x0e) */
8680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8683 /* HP Pin (0x0f) */
8684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8687 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8688 /* Line In pin */
8689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8691
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8696 { }
8697};
8698
76e6f5a9 8699
a9111321 8700static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8701 /*Internal and HP Speaker Mixer*/
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8705 /*Internal Speaker Pin (0x0c)*/
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* HP Pin: output 0 (0x0e) */
8710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8713 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8714 /* Line in (is hp when jack connected)*/
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8717
8718 { }
8719 };
8720
8721
87350ad0 8722/* Macbook Pro rev3 */
a9111321 8723static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8724 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8728 /* Rear mixer */
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8732 /* HP mixer */
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8736 /* Front Pin: output 0 (0x0c) */
8737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8740 /* HP Pin: output 0 (0x0e) */
87350ad0 8741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8745 /* Mic (rear) pin: input vref at 80% */
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8748 /* Front Mic pin: input vref at 80% */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8751 /* Line In pin: use output 1 when in LineOut mode */
8752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8755
8756 /* FIXME: use matrix-type input source selection */
8757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8763 /* Input mixer2 */
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8768 /* Input mixer3 */
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8773 /* ADC1: mute amp left and right */
8774 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8775 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8776 /* ADC2: mute amp left and right */
8777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* ADC3: mute amp left and right */
8780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8781 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8782
8783 { }
8784};
8785
4b7e1803 8786/* iMac 9,1 */
a9111321 8787static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8788 /* Internal Speaker Pin (0x0c) */
8789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8795 /* HP Pin: Rear */
4b7e1803
JM
8796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8800 /* Line in Rear */
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8803 /* Front Mic pin: input vref at 80% */
8804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8806 /* Rear mixer */
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8814 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8819 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8823 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8824 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8829 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8832 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8835 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8837 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8838 { }
8839};
8840
c54728d8 8841/* iMac 24 mixer. */
a9111321 8842static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8843 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8845 { } /* end */
8846};
8847
8848/* iMac 24 init verbs. */
a9111321 8849static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Internal speakers: output 0 (0x0c) */
8855 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8856 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 /* Headphone: output 0 (0x0c) */
8859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8861 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8863 /* Front Mic: input vref at 80% */
8864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8866 { }
8867};
8868
8869/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8870static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8871{
a9fd4f3f 8872 struct alc_spec *spec = codec->spec;
c54728d8 8873
a9fd4f3f
TI
8874 spec->autocfg.hp_pins[0] = 0x14;
8875 spec->autocfg.speaker_pins[0] = 0x18;
8876 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8877 spec->automute = 1;
8878 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8879}
8880
9d54f08b
TI
8881#define alc885_mb5_setup alc885_imac24_setup
8882#define alc885_macmini3_setup alc885_imac24_setup
8883
76e6f5a9
RH
8884/* Macbook Air 2,1 */
8885static void alc885_mba21_setup(struct hda_codec *codec)
8886{
8887 struct alc_spec *spec = codec->spec;
8888
8889 spec->autocfg.hp_pins[0] = 0x14;
8890 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8891 spec->automute = 1;
8892 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8893}
8894
8895
8896
4f5d1706 8897static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8898{
a9fd4f3f 8899 struct alc_spec *spec = codec->spec;
87350ad0 8900
a9fd4f3f
TI
8901 spec->autocfg.hp_pins[0] = 0x15;
8902 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8903 spec->automute = 1;
8904 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8905}
8906
9d54f08b 8907static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8908{
9d54f08b 8909 struct alc_spec *spec = codec->spec;
4b7e1803 8910
9d54f08b 8911 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8912 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8913 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8914 spec->automute = 1;
8915 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8916}
87350ad0 8917
a9111321 8918static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8921
8922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8924
272a527c
KY
8925 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8928
8929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8930 { } /* end */
8931};
8932
8933/* toggle speaker-output according to the hp-jack state */
8934static void alc882_targa_automute(struct hda_codec *codec)
8935{
a9fd4f3f 8936 struct alc_spec *spec = codec->spec;
d922b51d 8937 alc_hp_automute(codec);
82beb8fd 8938 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8939 spec->jack_present ? 1 : 3);
8940}
8941
4f5d1706 8942static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8943{
8944 struct alc_spec *spec = codec->spec;
8945
8946 spec->autocfg.hp_pins[0] = 0x14;
8947 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8948 spec->automute = 1;
8949 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8950}
8951
8952static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8953{
a9fd4f3f 8954 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8955 alc882_targa_automute(codec);
272a527c
KY
8956}
8957
a9111321 8958static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8961
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8965
272a527c
KY
8966 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8969
8970 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8973 { } /* end */
8974};
8975
a9111321 8976static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8979
8980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8983
914759b7
TI
8984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8987
8988 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8989 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8990 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8991 { } /* end */
8992};
8993
9102cd1c
TD
8994static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8995{
8996 unsigned int gpiostate, gpiomask, gpiodir;
8997
8998 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8999 AC_VERB_GET_GPIO_DATA, 0);
9000
9001 if (!muted)
9002 gpiostate |= (1 << pin);
9003 else
9004 gpiostate &= ~(1 << pin);
9005
9006 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_MASK, 0);
9008 gpiomask |= (1 << pin);
9009
9010 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9011 AC_VERB_GET_GPIO_DIRECTION, 0);
9012 gpiodir |= (1 << pin);
9013
9014
9015 snd_hda_codec_write(codec, codec->afg, 0,
9016 AC_VERB_SET_GPIO_MASK, gpiomask);
9017 snd_hda_codec_write(codec, codec->afg, 0,
9018 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9019
9020 msleep(1);
9021
9022 snd_hda_codec_write(codec, codec->afg, 0,
9023 AC_VERB_SET_GPIO_DATA, gpiostate);
9024}
9025
7debbe51
TI
9026/* set up GPIO at initialization */
9027static void alc885_macpro_init_hook(struct hda_codec *codec)
9028{
9029 alc882_gpio_mute(codec, 0, 0);
9030 alc882_gpio_mute(codec, 1, 0);
9031}
9032
9033/* set up GPIO and update auto-muting at initialization */
9034static void alc885_imac24_init_hook(struct hda_codec *codec)
9035{
9036 alc885_macpro_init_hook(codec);
d922b51d 9037 alc_hp_automute(codec);
7debbe51
TI
9038}
9039
df694daa
KY
9040/*
9041 * generic initialization of ADC, input mixers and output mixers
9042 */
a9111321 9043static const struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
9044 /*
9045 * Unmute ADC0-2 and set the default input to mic-in
9046 */
4953550a
TI
9047 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9049 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9050 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 9051
4953550a
TI
9052 /*
9053 * Set up output mixers (0x0c - 0x0f)
9054 */
9055 /* set vol=0 to output mixers */
9056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9057 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9059 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9060 /* set up input amps for analog loopback */
9061 /* Amp Indices: DAC = 0, mixer = 1 */
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9071 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9072
4953550a
TI
9073 /* FIXME: use matrix-type input source selection */
9074 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9075 /* Input mixer2 */
88102f3f 9076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9077 /* Input mixer3 */
88102f3f 9078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9079 { }
9c7f852e
TI
9080};
9081
eb4c41d3 9082/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9083static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9084 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9085 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9086 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9087 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9088 { } /* end */
9089};
9090
9091/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9092static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9097 { } /* end */
9098};
9099
9100/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9101static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9102 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9106 { } /* end */
9107};
9108
9109/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9110static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9111 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9115 { } /* end */
9116};
9117
a9111321 9118static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9119 { 2, alc889A_mb31_ch2_init },
9120 { 4, alc889A_mb31_ch4_init },
9121 { 5, alc889A_mb31_ch5_init },
9122 { 6, alc889A_mb31_ch6_init },
9123};
9124
a9111321 9125static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9126 /* eanable EAPD on medion laptop */
9127 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9128 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9129 { }
9130};
9131
4953550a 9132#define alc883_base_mixer alc882_base_mixer
834be88d 9133
a9111321 9134static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9135 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9136 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9137 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9138 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9140 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9143 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9148 { } /* end */
9149};
9150
a9111321 9151static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9153 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9155 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9157 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9159 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9160 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9161 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9162 { } /* end */
9163};
9164
a9111321 9165static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9167 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9169 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9173 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9174 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9175 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9176 { } /* end */
9177};
9178
a9111321 9179static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9183 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9188 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9191 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9192 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9193 { } /* end */
9194};
df694daa 9195
a9111321 9196static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9197 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9198 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9199 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9200 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9201 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9204 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9214 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9216 { } /* end */
9217};
9218
a9111321 9219static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9225 HDA_OUTPUT),
9226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9229 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9238 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9240 { } /* end */
9241};
9242
a9111321 9243static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9244 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9245 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9247 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9248 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9249 HDA_OUTPUT),
9250 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9251 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9252 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9253 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9254 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9256 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9258 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9259 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9263 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9264 { } /* end */
9265};
9266
a9111321 9267static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9271 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9272 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9273 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9274 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9275 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9280 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9282 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9284 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9285 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9286 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9287 { } /* end */
9288};
9289
a9111321 9290static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9295 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9296 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9297 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9298 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9299 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9300 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9308 { } /* end */
f12ab1e0 9309};
ccc656ce 9310
a9111321 9311static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9312 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9313 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9315 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9317 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9319 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9321 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9322 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9323 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9324 { } /* end */
f12ab1e0 9325};
ccc656ce 9326
a9111321 9327static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9328 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9329 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9330 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9331 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9332 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9333 { } /* end */
9334};
9335
a9111321 9336static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9337 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9338 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9339 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9340 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9343 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9345 { } /* end */
f12ab1e0 9346};
bc9f98a9 9347
a9111321 9348static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9349 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9350 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9354 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9356 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9357 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9358 { } /* end */
ea1fb29a 9359};
272a527c 9360
a9111321 9361static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9362 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9366 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9367 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9368 { } /* end */
9369};
9370
a9111321 9371static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9372 /* Unmute front mixer */
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9375
9376 /* Set speaker pin to front mixer */
9377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9378
9379 /* Init headphone pin */
9380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9383 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384
9385 { } /* end */
9386};
9387
9388/* toggle speaker-output according to the hp-jack state */
9389static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9390{
9391 struct alc_spec *spec = codec->spec;
9392
9393 spec->autocfg.hp_pins[0] = 0x1a;
9394 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9395 spec->automute = 1;
9396 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9397}
9398
a9111321 9399static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9400 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9403 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9404 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9406 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9408 { } /* end */
d1a991a6 9409};
2880a867 9410
a9111321 9411static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9412 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9413 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9417 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9421 { } /* end */
9422};
9423
a9111321 9424static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9427 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9428 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9429 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9430 0x0d, 1, 0x0, HDA_OUTPUT),
9431 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9432 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9433 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9434 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9435 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9436 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9441 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9443 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9444 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9446 { } /* end */
9447};
9448
a9111321 9449static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9450 /* Output mixers */
9451 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9452 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9453 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9454 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9455 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9456 HDA_OUTPUT),
9457 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9459 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9460 /* Output switches */
9461 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9462 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9463 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9464 /* Boost mixers */
5f99f86a
DH
9465 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9466 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9467 /* Input mixers */
9468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9470 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9471 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9472 { } /* end */
9473};
9474
a9111321 9475static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9478 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9480 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9481 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9482 { } /* end */
9483};
9484
a9111321 9485static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9486 .ops = &snd_hda_bind_vol,
9487 .values = {
9488 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9489 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9490 0
9491 },
9492};
9493
a9111321 9494static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9495 .ops = &snd_hda_bind_sw,
9496 .values = {
9497 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9498 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9499 0
9500 },
9501};
9502
a9111321 9503static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9504 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9505 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9510 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9511 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9512 { } /* end */
9513};
df694daa 9514
a9111321 9515static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9516 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9517 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9518 {
9519 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9520 /* .name = "Capture Source", */
9521 .name = "Input Source",
9522 .count = 1,
9523 .info = alc_mux_enum_info,
9524 .get = alc_mux_enum_get,
9525 .put = alc_mux_enum_put,
9526 },
9527 { } /* end */
9528};
9c7f852e 9529
a9111321 9530static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9531 {
9532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9533 .name = "Channel Mode",
9534 .info = alc_ch_mode_info,
9535 .get = alc_ch_mode_get,
9536 .put = alc_ch_mode_put,
9537 },
9538 { } /* end */
9c7f852e
TI
9539};
9540
a8848bd6 9541/* toggle speaker-output according to the hp-jack state */
4f5d1706 9542static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9543{
a9fd4f3f 9544 struct alc_spec *spec = codec->spec;
a8848bd6 9545
a9fd4f3f
TI
9546 spec->autocfg.hp_pins[0] = 0x15;
9547 spec->autocfg.speaker_pins[0] = 0x14;
9548 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9549 spec->automute = 1;
9550 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9551}
9552
a9111321 9553static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9554 /* HP */
9555 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9556 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9557 /* Subwoofer */
9558 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9560
9561 /* enable unsolicited event */
9562 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9563 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9564
9565 { } /* end */
9566};
9567
a9111321 9568static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9569 /* HP */
9570 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9572 /* Int speaker */
9573 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9574
9575 /* enable unsolicited event */
9576 /*
9577 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9578 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9579 */
9580
9581 { } /* end */
9582};
9583
a9111321 9584static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9585 /* HP */
9586 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9588 /* Int speaker */
9589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9591
9592 /* enable unsolicited event */
9593 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9594 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9595
9596 { } /* end */
9597};
9598
a9111321 9599static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9600 /* HP */
9601 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9603 /* Subwoofer */
9604 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9606
9607 /* enable unsolicited event */
9608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9609
9610 { } /* end */
9611};
9612
a9111321 9613static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9616
9617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9618 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9619
64a8be74
DH
9620/* Connect Line-Out side jack (SPDIF) to Side */
9621 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9623 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9624/* Connect Mic jack to CLFE */
9625 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9626 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9627 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9628/* Connect Line-in jack to Surround */
9629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9631 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9632/* Connect HP out jack to Front */
9633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9634 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9636
9637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9638
9639 { } /* end */
9640};
9641
a9111321 9642static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9644 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9645 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9646 { } /* end */
9647};
9648
a9111321 9649static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9650 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9652 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9654 { } /* end */
9655};
9656
a9111321 9657static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9660 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9661 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9662 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9663 { } /* end */
9664};
9665
a9111321 9666static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9669
9670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9671
9672 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9674 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9675 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9676 { } /* end */
9677};
9678
a9111321 9679static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9686 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 { } /* end */
9689};
9690
a9111321 9691static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9692 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9693 { }
9694};
9695
a9111321 9696static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9697 /* HP */
9698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9699 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9700
9701 /* enable unsolicited event */
9702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9703
9704 { } /* end */
9705};
9706
4f5d1706 9707static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9708{
a9fd4f3f 9709 struct alc_spec *spec = codec->spec;
8718b700 9710
a9fd4f3f
TI
9711 spec->autocfg.hp_pins[0] = 0x1b;
9712 spec->autocfg.speaker_pins[0] = 0x14;
9713 spec->autocfg.speaker_pins[1] = 0x16;
9714 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9715 spec->automute = 1;
9716 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9717}
9718
a9111321 9719static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9720 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9721 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9722 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9723 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9724 { } /* end */
5795b9e6
CM
9725};
9726
3ea0d7cf
HRK
9727/*
9728 * 2ch mode
9729 */
a9111321 9730static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9734 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9735 { } /* end */
8341de60
CM
9736};
9737
3ea0d7cf
HRK
9738/*
9739 * 4ch mode
9740 */
a9111321 9741static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9744 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9745 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9746 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9747 { } /* end */
9748};
9749
9750/*
9751 * 6ch mode
9752 */
a9111321 9753static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9754 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9755 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9756 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9757 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9758 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9759 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9760 { } /* end */
8341de60
CM
9761};
9762
a9111321 9763static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9764 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9765 { 4, alc888_3st_hp_4ch_init },
4723c022 9766 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9767};
9768
e6a5e1b7 9769static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9770{
e6a5e1b7 9771 struct alc_spec *spec = codec->spec;
47fd830a 9772
e6a5e1b7
TI
9773 spec->autocfg.hp_pins[0] = 0x1b;
9774 spec->autocfg.line_out_pins[0] = 0x14;
9775 spec->autocfg.speaker_pins[0] = 0x15;
9776 spec->automute = 1;
9777 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9778}
9779
272a527c 9780/* toggle speaker-output according to the hp-jack state */
dc427170 9781static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9782{
a9fd4f3f 9783 struct alc_spec *spec = codec->spec;
272a527c 9784
a9fd4f3f
TI
9785 spec->autocfg.hp_pins[0] = 0x14;
9786 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9787 spec->automute = 1;
9788 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9789}
9790
ccc656ce 9791/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9792#define alc883_targa_init_hook alc882_targa_init_hook
9793#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9794
4f5d1706 9795static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9796{
a9fd4f3f
TI
9797 struct alc_spec *spec = codec->spec;
9798
9799 spec->autocfg.hp_pins[0] = 0x15;
9800 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9801 spec->automute = 1;
9802 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9803}
9804
9805static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9806{
d922b51d 9807 alc_hp_automute(codec);
eeb43387 9808 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9809}
9810
9811static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9812 unsigned int res)
9813{
0c4cc443 9814 switch (res >> 26) {
0c4cc443 9815 case ALC880_MIC_EVENT:
eeb43387 9816 alc88x_simple_mic_automute(codec);
0c4cc443 9817 break;
a9fd4f3f 9818 default:
d922b51d 9819 alc_sku_unsol_event(codec, res);
a9fd4f3f 9820 break;
0c4cc443 9821 }
368c7a95
J
9822}
9823
fb97dc67 9824/* toggle speaker-output according to the hp-jack state */
4f5d1706 9825static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9826{
a9fd4f3f 9827 struct alc_spec *spec = codec->spec;
fb97dc67 9828
a9fd4f3f
TI
9829 spec->autocfg.hp_pins[0] = 0x14;
9830 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9831 spec->automute = 1;
9832 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9833}
9834
4f5d1706 9835static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9836{
a9fd4f3f 9837 struct alc_spec *spec = codec->spec;
189609ae 9838
a9fd4f3f
TI
9839 spec->autocfg.hp_pins[0] = 0x1b;
9840 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9841 spec->automute = 1;
9842 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9843}
9844
e6a5e1b7 9845static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9846{
e6a5e1b7 9847 struct alc_spec *spec = codec->spec;
bc9f98a9 9848
e6a5e1b7
TI
9849 spec->autocfg.hp_pins[0] = 0x1b;
9850 spec->autocfg.line_out_pins[0] = 0x14;
9851 spec->autocfg.speaker_pins[0] = 0x15;
9852 spec->automute = 1;
9853 spec->detect_line = 1;
9854 spec->automute_lines = 1;
9855 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9856}
9857
676a9b53 9858/* toggle speaker-output according to the hp-jack state */
4f5d1706 9859static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9860{
a9fd4f3f 9861 struct alc_spec *spec = codec->spec;
676a9b53 9862
a9fd4f3f
TI
9863 spec->autocfg.hp_pins[0] = 0x14;
9864 spec->autocfg.speaker_pins[0] = 0x15;
9865 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9866 spec->automute = 1;
9867 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9868}
9869
a9111321 9870static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9871 /* HP Pin: output 0 (0x0c) */
9872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9873 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9874 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9875 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9878 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9879 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9880 /* eanable EAPD on medion laptop */
9881 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9882 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9883 /* enable unsolicited event */
9884 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9885 { }
9886};
9887
4f5d1706 9888static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9889{
a9fd4f3f 9890 struct alc_spec *spec = codec->spec;
5795b9e6 9891
a9fd4f3f
TI
9892 spec->autocfg.hp_pins[0] = 0x1b;
9893 spec->autocfg.speaker_pins[0] = 0x14;
9894 spec->autocfg.speaker_pins[1] = 0x15;
9895 spec->autocfg.speaker_pins[2] = 0x16;
9896 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9897 spec->automute = 1;
9898 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9899}
9900
4f5d1706 9901static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9902{
a9fd4f3f 9903 struct alc_spec *spec = codec->spec;
e2757d5e 9904
a9fd4f3f
TI
9905 spec->autocfg.hp_pins[0] = 0x1b;
9906 spec->autocfg.speaker_pins[0] = 0x14;
9907 spec->autocfg.speaker_pins[1] = 0x15;
9908 spec->autocfg.speaker_pins[2] = 0x16;
9909 spec->autocfg.speaker_pins[3] = 0x17;
9910 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9911 spec->automute = 1;
9912 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9913}
9914
4f5d1706 9915static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9916{
9917 struct alc_spec *spec = codec->spec;
9918
9919 spec->autocfg.hp_pins[0] = 0x15;
9920 spec->autocfg.speaker_pins[0] = 0x14;
9921 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9922 spec->automute = 1;
9923 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9924}
9925
a9111321 9926static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9930 /* enable unsolicited event */
9931 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9932 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9933 { } /* end */
9934};
9935
4f5d1706 9936static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9937{
a9fd4f3f 9938 struct alc_spec *spec = codec->spec;
e2757d5e 9939
a9fd4f3f
TI
9940 spec->autocfg.hp_pins[0] = 0x1b;
9941 spec->autocfg.speaker_pins[0] = 0x14;
9942 spec->autocfg.speaker_pins[1] = 0x15;
9943 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9944 spec->ext_mic.pin = 0x18;
9945 spec->int_mic.pin = 0x19;
9946 spec->ext_mic.mux_idx = 0;
9947 spec->int_mic.mux_idx = 1;
9948 spec->auto_mic = 1;
d922b51d
TI
9949 spec->automute = 1;
9950 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9951}
9952
a9111321 9953static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9954 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9959 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9960 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9961 /* enable unsolicited event */
9962 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9963 { } /* end */
9964};
9965
e2757d5e
KY
9966static void alc883_eee1601_inithook(struct hda_codec *codec)
9967{
a9fd4f3f
TI
9968 struct alc_spec *spec = codec->spec;
9969
9970 spec->autocfg.hp_pins[0] = 0x14;
9971 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9972 alc_hp_automute(codec);
e2757d5e
KY
9973}
9974
a9111321 9975static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9976 /* Init rear pin (used as headphone output) */
9977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9978 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9979 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9980 /* Init line pin (used as output in 4ch and 6ch mode) */
9981 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9982 /* Init line 2 pin (used as headphone out by default) */
9983 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9984 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9985 { } /* end */
9986};
9987
9988/* Mute speakers according to the headphone jack state */
9989static void alc889A_mb31_automute(struct hda_codec *codec)
9990{
9991 unsigned int present;
9992
9993 /* Mute only in 2ch or 4ch mode */
9994 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9995 == 0x00) {
864f92be 9996 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9997 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9998 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9999 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10000 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10001 }
10002}
10003
10004static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10005{
10006 if ((res >> 26) == ALC880_HP_EVENT)
10007 alc889A_mb31_automute(codec);
10008}
10009
4953550a 10010
cb53c626 10011#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 10012#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
10013#endif
10014
def319f9 10015/* pcm configuration: identical with ALC880 */
4953550a
TI
10016#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10017#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10018#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10019#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10020
4c6d72d1 10021static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
10022 ALC1200_DIGOUT_NID, 0,
10023};
10024
4c6d72d1 10025static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
10026 ALC883_DIGOUT_NID, 0,
10027};
9c7f852e
TI
10028
10029/*
10030 * configuration and preset
10031 */
ea734963 10032static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
10033 [ALC882_3ST_DIG] = "3stack-dig",
10034 [ALC882_6ST_DIG] = "6stack-dig",
10035 [ALC882_ARIMA] = "arima",
10036 [ALC882_W2JC] = "w2jc",
10037 [ALC882_TARGA] = "targa",
10038 [ALC882_ASUS_A7J] = "asus-a7j",
10039 [ALC882_ASUS_A7M] = "asus-a7m",
10040 [ALC885_MACPRO] = "macpro",
10041 [ALC885_MB5] = "mb5",
e458b1fa 10042 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 10043 [ALC885_MBA21] = "mba21",
4953550a
TI
10044 [ALC885_MBP3] = "mbp3",
10045 [ALC885_IMAC24] = "imac24",
4b7e1803 10046 [ALC885_IMAC91] = "imac91",
4953550a 10047 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10048 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10049 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10050 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10051 [ALC883_TARGA_DIG] = "targa-dig",
10052 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10053 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10054 [ALC883_ACER] = "acer",
2880a867 10055 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10056 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10057 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10058 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10059 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10060 [ALC883_MEDION] = "medion",
7ad7b218 10061 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10062 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10063 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10064 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10065 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10066 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10067 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10068 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10069 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10070 [ALC883_MITAC] = "mitac",
a65cc60f 10071 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10072 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10073 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10074 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10075 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10076 [ALC889A_INTEL] = "intel-alc889a",
10077 [ALC889_INTEL] = "intel-x58",
3ab90935 10078 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10079 [ALC889A_MB31] = "mb31",
3e1647c5 10080 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10081 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10082};
10083
a9111321 10084static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10085 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10086
ac3e3741 10087 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10088 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10089 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10090 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10091 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10092 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10093 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10094 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10095 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10096 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10097 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10098 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10099 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10100 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10101 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10102 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10103 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10104 ALC888_ACER_ASPIRE_6530G),
cc374c47 10105 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10106 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10107 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10108 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10109 /* default Acer -- disabled as it causes more problems.
10110 * model=auto should work fine now
10111 */
10112 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10113
5795b9e6 10114 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10115
25985edc 10116 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10117 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10118 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10119 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10120 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10121 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10122
10123 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10124 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10125 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10126 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10127 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10128 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10129 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10130 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10131 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10132 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10133 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10134
10135 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10136 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10137 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10138 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10139 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10140 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10141 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10142 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10143 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10144
6f3bf657 10145 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10146 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10147 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10148 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10149 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10150 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10151 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10152 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10153 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10154 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10155 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10156 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10157 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10158 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10159 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10160 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10162 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10163 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10164 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10165 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10167 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10168 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10169 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10170 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10171 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10172 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10173 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10174 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10175 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10176
ac3e3741 10177 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10178 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10179 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10180 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10181 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10182 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10183 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10184 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10185 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10186 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10187 ALC883_FUJITSU_PI2515),
bfb53037 10188 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10189 ALC888_FUJITSU_XA3530),
272a527c 10190 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10191 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10192 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10193 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10194 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10195 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10196 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10197 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10198
17bba1b7
J
10199 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10200 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10201 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10202 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10203 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10204 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10205 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10206
4953550a 10207 {}
f3cd3f5d
WF
10208};
10209
4953550a 10210/* codec SSID table for Intel Mac */
a9111321 10211static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10212 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10213 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10214 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10215 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10216 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10217 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10218 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10219 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10220 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10221 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10222 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10223 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10224 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10225 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10226 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10227 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10228 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10229 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10230 * so apparently no perfect solution yet
4953550a
TI
10231 */
10232 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10233 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10234 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10235 {} /* terminator */
b25c9da1
WF
10236};
10237
a9111321 10238static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10239 [ALC882_3ST_DIG] = {
10240 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10241 .init_verbs = { alc882_base_init_verbs,
10242 alc882_adc1_init_verbs },
4953550a
TI
10243 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10244 .dac_nids = alc882_dac_nids,
10245 .dig_out_nid = ALC882_DIGOUT_NID,
10246 .dig_in_nid = ALC882_DIGIN_NID,
10247 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10248 .channel_mode = alc882_ch_modes,
10249 .need_dac_fix = 1,
10250 .input_mux = &alc882_capture_source,
10251 },
10252 [ALC882_6ST_DIG] = {
10253 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10254 .init_verbs = { alc882_base_init_verbs,
10255 alc882_adc1_init_verbs },
4953550a
TI
10256 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10257 .dac_nids = alc882_dac_nids,
10258 .dig_out_nid = ALC882_DIGOUT_NID,
10259 .dig_in_nid = ALC882_DIGIN_NID,
10260 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10261 .channel_mode = alc882_sixstack_modes,
10262 .input_mux = &alc882_capture_source,
10263 },
10264 [ALC882_ARIMA] = {
10265 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10266 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10267 alc882_eapd_verbs },
4953550a
TI
10268 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10269 .dac_nids = alc882_dac_nids,
10270 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10271 .channel_mode = alc882_sixstack_modes,
10272 .input_mux = &alc882_capture_source,
10273 },
10274 [ALC882_W2JC] = {
10275 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10276 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10277 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10278 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10279 .dac_nids = alc882_dac_nids,
10280 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10281 .channel_mode = alc880_threestack_modes,
10282 .need_dac_fix = 1,
10283 .input_mux = &alc882_capture_source,
10284 .dig_out_nid = ALC882_DIGOUT_NID,
10285 },
76e6f5a9
RH
10286 [ALC885_MBA21] = {
10287 .mixers = { alc885_mba21_mixer },
10288 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10289 .num_dacs = 2,
10290 .dac_nids = alc882_dac_nids,
10291 .channel_mode = alc885_mba21_ch_modes,
10292 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10293 .input_mux = &alc882_capture_source,
d922b51d 10294 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10295 .setup = alc885_mba21_setup,
d922b51d 10296 .init_hook = alc_hp_automute,
76e6f5a9 10297 },
4953550a
TI
10298 [ALC885_MBP3] = {
10299 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10300 .init_verbs = { alc885_mbp3_init_verbs,
10301 alc880_gpio1_init_verbs },
be0ae923 10302 .num_dacs = 2,
4953550a 10303 .dac_nids = alc882_dac_nids,
be0ae923
TI
10304 .hp_nid = 0x04,
10305 .channel_mode = alc885_mbp_4ch_modes,
10306 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10307 .input_mux = &alc882_capture_source,
10308 .dig_out_nid = ALC882_DIGOUT_NID,
10309 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10310 .unsol_event = alc_sku_unsol_event,
4f5d1706 10311 .setup = alc885_mbp3_setup,
d922b51d 10312 .init_hook = alc_hp_automute,
4953550a
TI
10313 },
10314 [ALC885_MB5] = {
10315 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10316 .init_verbs = { alc885_mb5_init_verbs,
10317 alc880_gpio1_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10319 .dac_nids = alc882_dac_nids,
10320 .channel_mode = alc885_mb5_6ch_modes,
10321 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10322 .input_mux = &mb5_capture_source,
10323 .dig_out_nid = ALC882_DIGOUT_NID,
10324 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10325 .unsol_event = alc_sku_unsol_event,
9d54f08b 10326 .setup = alc885_mb5_setup,
d922b51d 10327 .init_hook = alc_hp_automute,
4953550a 10328 },
e458b1fa
LY
10329 [ALC885_MACMINI3] = {
10330 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10331 .init_verbs = { alc885_macmini3_init_verbs,
10332 alc880_gpio1_init_verbs },
10333 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10334 .dac_nids = alc882_dac_nids,
10335 .channel_mode = alc885_macmini3_6ch_modes,
10336 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10337 .input_mux = &macmini3_capture_source,
10338 .dig_out_nid = ALC882_DIGOUT_NID,
10339 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10340 .unsol_event = alc_sku_unsol_event,
9d54f08b 10341 .setup = alc885_macmini3_setup,
d922b51d 10342 .init_hook = alc_hp_automute,
e458b1fa 10343 },
4953550a
TI
10344 [ALC885_MACPRO] = {
10345 .mixers = { alc882_macpro_mixer },
10346 .init_verbs = { alc882_macpro_init_verbs },
10347 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10348 .dac_nids = alc882_dac_nids,
10349 .dig_out_nid = ALC882_DIGOUT_NID,
10350 .dig_in_nid = ALC882_DIGIN_NID,
10351 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10352 .channel_mode = alc882_ch_modes,
10353 .input_mux = &alc882_capture_source,
10354 .init_hook = alc885_macpro_init_hook,
10355 },
10356 [ALC885_IMAC24] = {
10357 .mixers = { alc885_imac24_mixer },
10358 .init_verbs = { alc885_imac24_init_verbs },
10359 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10360 .dac_nids = alc882_dac_nids,
10361 .dig_out_nid = ALC882_DIGOUT_NID,
10362 .dig_in_nid = ALC882_DIGIN_NID,
10363 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10364 .channel_mode = alc882_ch_modes,
10365 .input_mux = &alc882_capture_source,
d922b51d 10366 .unsol_event = alc_sku_unsol_event,
4f5d1706 10367 .setup = alc885_imac24_setup,
4953550a
TI
10368 .init_hook = alc885_imac24_init_hook,
10369 },
4b7e1803 10370 [ALC885_IMAC91] = {
b7cccc52 10371 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10372 .init_verbs = { alc885_imac91_init_verbs,
10373 alc880_gpio1_init_verbs },
10374 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10375 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10376 .channel_mode = alc885_mba21_ch_modes,
10377 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10378 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10379 .dig_out_nid = ALC882_DIGOUT_NID,
10380 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10381 .unsol_event = alc_sku_unsol_event,
9d54f08b 10382 .setup = alc885_imac91_setup,
d922b51d 10383 .init_hook = alc_hp_automute,
4b7e1803 10384 },
4953550a
TI
10385 [ALC882_TARGA] = {
10386 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10387 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10388 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10389 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10390 .dac_nids = alc882_dac_nids,
10391 .dig_out_nid = ALC882_DIGOUT_NID,
10392 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10393 .adc_nids = alc882_adc_nids,
10394 .capsrc_nids = alc882_capsrc_nids,
10395 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10396 .channel_mode = alc882_3ST_6ch_modes,
10397 .need_dac_fix = 1,
10398 .input_mux = &alc882_capture_source,
d922b51d 10399 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10400 .setup = alc882_targa_setup,
10401 .init_hook = alc882_targa_automute,
4953550a
TI
10402 },
10403 [ALC882_ASUS_A7J] = {
10404 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10405 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10406 alc882_asus_a7j_verbs},
4953550a
TI
10407 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10408 .dac_nids = alc882_dac_nids,
10409 .dig_out_nid = ALC882_DIGOUT_NID,
10410 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10411 .adc_nids = alc882_adc_nids,
10412 .capsrc_nids = alc882_capsrc_nids,
10413 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10414 .channel_mode = alc882_3ST_6ch_modes,
10415 .need_dac_fix = 1,
10416 .input_mux = &alc882_capture_source,
10417 },
10418 [ALC882_ASUS_A7M] = {
10419 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10420 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10421 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10422 alc882_asus_a7m_verbs },
10423 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10424 .dac_nids = alc882_dac_nids,
10425 .dig_out_nid = ALC882_DIGOUT_NID,
10426 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10427 .channel_mode = alc880_threestack_modes,
10428 .need_dac_fix = 1,
10429 .input_mux = &alc882_capture_source,
10430 },
9c7f852e
TI
10431 [ALC883_3ST_2ch_DIG] = {
10432 .mixers = { alc883_3ST_2ch_mixer },
10433 .init_verbs = { alc883_init_verbs },
10434 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10435 .dac_nids = alc883_dac_nids,
10436 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10437 .dig_in_nid = ALC883_DIGIN_NID,
10438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10439 .channel_mode = alc883_3ST_2ch_modes,
10440 .input_mux = &alc883_capture_source,
10441 },
10442 [ALC883_3ST_6ch_DIG] = {
10443 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10444 .init_verbs = { alc883_init_verbs },
10445 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10446 .dac_nids = alc883_dac_nids,
10447 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10448 .dig_in_nid = ALC883_DIGIN_NID,
10449 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10450 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10451 .need_dac_fix = 1,
9c7f852e 10452 .input_mux = &alc883_capture_source,
f12ab1e0 10453 },
9c7f852e
TI
10454 [ALC883_3ST_6ch] = {
10455 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10456 .init_verbs = { alc883_init_verbs },
10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10460 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10461 .need_dac_fix = 1,
9c7f852e 10462 .input_mux = &alc883_capture_source,
f12ab1e0 10463 },
17bba1b7
J
10464 [ALC883_3ST_6ch_INTEL] = {
10465 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10466 .init_verbs = { alc883_init_verbs },
10467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10468 .dac_nids = alc883_dac_nids,
10469 .dig_out_nid = ALC883_DIGOUT_NID,
10470 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10471 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10472 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10473 .channel_mode = alc883_3ST_6ch_intel_modes,
10474 .need_dac_fix = 1,
10475 .input_mux = &alc883_3stack_6ch_intel,
10476 },
87a8c370
JK
10477 [ALC889A_INTEL] = {
10478 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10479 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10480 alc_hp15_unsol_verbs },
87a8c370
JK
10481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10482 .dac_nids = alc883_dac_nids,
10483 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10484 .adc_nids = alc889_adc_nids,
10485 .dig_out_nid = ALC883_DIGOUT_NID,
10486 .dig_in_nid = ALC883_DIGIN_NID,
10487 .slave_dig_outs = alc883_slave_dig_outs,
10488 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10489 .channel_mode = alc889_8ch_intel_modes,
10490 .capsrc_nids = alc889_capsrc_nids,
10491 .input_mux = &alc889_capture_source,
4f5d1706 10492 .setup = alc889_automute_setup,
d922b51d
TI
10493 .init_hook = alc_hp_automute,
10494 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10495 .need_dac_fix = 1,
10496 },
10497 [ALC889_INTEL] = {
10498 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10499 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10500 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
10503 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10504 .adc_nids = alc889_adc_nids,
10505 .dig_out_nid = ALC883_DIGOUT_NID,
10506 .dig_in_nid = ALC883_DIGIN_NID,
10507 .slave_dig_outs = alc883_slave_dig_outs,
10508 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10509 .channel_mode = alc889_8ch_intel_modes,
10510 .capsrc_nids = alc889_capsrc_nids,
10511 .input_mux = &alc889_capture_source,
4f5d1706 10512 .setup = alc889_automute_setup,
6732bd0d 10513 .init_hook = alc889_intel_init_hook,
d922b51d 10514 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10515 .need_dac_fix = 1,
10516 },
9c7f852e
TI
10517 [ALC883_6ST_DIG] = {
10518 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10519 .init_verbs = { alc883_init_verbs },
10520 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10521 .dac_nids = alc883_dac_nids,
10522 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10523 .dig_in_nid = ALC883_DIGIN_NID,
10524 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10525 .channel_mode = alc883_sixstack_modes,
10526 .input_mux = &alc883_capture_source,
10527 },
ccc656ce 10528 [ALC883_TARGA_DIG] = {
c259249f 10529 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10530 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10531 alc883_targa_verbs},
ccc656ce
KY
10532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10533 .dac_nids = alc883_dac_nids,
10534 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10536 .channel_mode = alc883_3ST_6ch_modes,
10537 .need_dac_fix = 1,
10538 .input_mux = &alc883_capture_source,
c259249f 10539 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10540 .setup = alc882_targa_setup,
10541 .init_hook = alc882_targa_automute,
ccc656ce
KY
10542 },
10543 [ALC883_TARGA_2ch_DIG] = {
c259249f 10544 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10545 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10546 alc883_targa_verbs},
ccc656ce
KY
10547 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10548 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10549 .adc_nids = alc883_adc_nids_alt,
10550 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10551 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10552 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554 .channel_mode = alc883_3ST_2ch_modes,
10555 .input_mux = &alc883_capture_source,
c259249f 10556 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10557 .setup = alc882_targa_setup,
10558 .init_hook = alc882_targa_automute,
ccc656ce 10559 },
64a8be74 10560 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10561 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10562 alc883_chmode_mixer },
64a8be74 10563 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10564 alc883_targa_verbs },
64a8be74
DH
10565 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10566 .dac_nids = alc883_dac_nids,
10567 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10568 .adc_nids = alc883_adc_nids_rev,
10569 .capsrc_nids = alc883_capsrc_nids_rev,
10570 .dig_out_nid = ALC883_DIGOUT_NID,
10571 .dig_in_nid = ALC883_DIGIN_NID,
10572 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10573 .channel_mode = alc883_4ST_8ch_modes,
10574 .need_dac_fix = 1,
10575 .input_mux = &alc883_capture_source,
c259249f 10576 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10577 .setup = alc882_targa_setup,
10578 .init_hook = alc882_targa_automute,
64a8be74 10579 },
bab282b9 10580 [ALC883_ACER] = {
676a9b53 10581 .mixers = { alc883_base_mixer },
bab282b9
VA
10582 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10583 * and the headphone jack. Turn this on and rely on the
10584 * standard mute methods whenever the user wants to turn
10585 * these outputs off.
10586 */
10587 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10588 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10589 .dac_nids = alc883_dac_nids,
bab282b9
VA
10590 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10591 .channel_mode = alc883_3ST_2ch_modes,
10592 .input_mux = &alc883_capture_source,
10593 },
2880a867 10594 [ALC883_ACER_ASPIRE] = {
676a9b53 10595 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10596 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10597 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10598 .dac_nids = alc883_dac_nids,
10599 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10600 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10601 .channel_mode = alc883_3ST_2ch_modes,
10602 .input_mux = &alc883_capture_source,
d922b51d 10603 .unsol_event = alc_sku_unsol_event,
4f5d1706 10604 .setup = alc883_acer_aspire_setup,
d922b51d 10605 .init_hook = alc_hp_automute,
d1a991a6 10606 },
5b2d1eca 10607 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10608 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10609 alc883_chmode_mixer },
10610 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10611 alc888_acer_aspire_4930g_verbs },
10612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10613 .dac_nids = alc883_dac_nids,
10614 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10615 .adc_nids = alc883_adc_nids_rev,
10616 .capsrc_nids = alc883_capsrc_nids_rev,
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10619 .channel_mode = alc883_3ST_6ch_modes,
10620 .need_dac_fix = 1,
973b8cb0 10621 .const_channel_count = 6,
5b2d1eca 10622 .num_mux_defs =
ef8ef5fb
VP
10623 ARRAY_SIZE(alc888_2_capture_sources),
10624 .input_mux = alc888_2_capture_sources,
d922b51d 10625 .unsol_event = alc_sku_unsol_event,
4f5d1706 10626 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10627 .init_hook = alc_hp_automute,
d2fd4b09
TV
10628 },
10629 [ALC888_ACER_ASPIRE_6530G] = {
10630 .mixers = { alc888_acer_aspire_6530_mixer },
10631 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10632 alc888_acer_aspire_6530g_verbs },
10633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10634 .dac_nids = alc883_dac_nids,
10635 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10636 .adc_nids = alc883_adc_nids_rev,
10637 .capsrc_nids = alc883_capsrc_nids_rev,
10638 .dig_out_nid = ALC883_DIGOUT_NID,
10639 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10640 .channel_mode = alc883_3ST_2ch_modes,
10641 .num_mux_defs =
10642 ARRAY_SIZE(alc888_2_capture_sources),
10643 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10644 .unsol_event = alc_sku_unsol_event,
4f5d1706 10645 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10646 .init_hook = alc_hp_automute,
5b2d1eca 10647 },
3b315d70 10648 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10649 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10650 alc883_chmode_mixer },
10651 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10652 alc889_acer_aspire_8930g_verbs,
10653 alc889_eapd_verbs},
3b315d70
HM
10654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10655 .dac_nids = alc883_dac_nids,
018df418
HM
10656 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10657 .adc_nids = alc889_adc_nids,
10658 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10659 .dig_out_nid = ALC883_DIGOUT_NID,
10660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10661 .channel_mode = alc883_3ST_6ch_modes,
10662 .need_dac_fix = 1,
10663 .const_channel_count = 6,
10664 .num_mux_defs =
018df418
HM
10665 ARRAY_SIZE(alc889_capture_sources),
10666 .input_mux = alc889_capture_sources,
d922b51d 10667 .unsol_event = alc_sku_unsol_event,
4f5d1706 10668 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10669 .init_hook = alc_hp_automute,
f5de24b0 10670#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10671 .power_hook = alc_power_eapd,
f5de24b0 10672#endif
3b315d70 10673 },
fc86f954
DK
10674 [ALC888_ACER_ASPIRE_7730G] = {
10675 .mixers = { alc883_3ST_6ch_mixer,
10676 alc883_chmode_mixer },
10677 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10678 alc888_acer_aspire_7730G_verbs },
10679 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10680 .dac_nids = alc883_dac_nids,
10681 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10682 .adc_nids = alc883_adc_nids_rev,
10683 .capsrc_nids = alc883_capsrc_nids_rev,
10684 .dig_out_nid = ALC883_DIGOUT_NID,
10685 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10686 .channel_mode = alc883_3ST_6ch_modes,
10687 .need_dac_fix = 1,
10688 .const_channel_count = 6,
10689 .input_mux = &alc883_capture_source,
d922b51d 10690 .unsol_event = alc_sku_unsol_event,
d9477207 10691 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10692 .init_hook = alc_hp_automute,
fc86f954 10693 },
c07584c8
TD
10694 [ALC883_MEDION] = {
10695 .mixers = { alc883_fivestack_mixer,
10696 alc883_chmode_mixer },
10697 .init_verbs = { alc883_init_verbs,
b373bdeb 10698 alc883_medion_eapd_verbs },
c07584c8
TD
10699 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10700 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10701 .adc_nids = alc883_adc_nids_alt,
10702 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10703 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10704 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10705 .channel_mode = alc883_sixstack_modes,
10706 .input_mux = &alc883_capture_source,
b373bdeb 10707 },
7ad7b218
MC
10708 [ALC883_MEDION_WIM2160] = {
10709 .mixers = { alc883_medion_wim2160_mixer },
10710 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10711 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10712 .dac_nids = alc883_dac_nids,
10713 .dig_out_nid = ALC883_DIGOUT_NID,
10714 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10715 .adc_nids = alc883_adc_nids,
10716 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10717 .channel_mode = alc883_3ST_2ch_modes,
10718 .input_mux = &alc883_capture_source,
d922b51d 10719 .unsol_event = alc_sku_unsol_event,
7ad7b218 10720 .setup = alc883_medion_wim2160_setup,
d922b51d 10721 .init_hook = alc_hp_automute,
7ad7b218 10722 },
b373bdeb 10723 [ALC883_LAPTOP_EAPD] = {
676a9b53 10724 .mixers = { alc883_base_mixer },
b373bdeb
AN
10725 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10726 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10727 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10728 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10729 .channel_mode = alc883_3ST_2ch_modes,
10730 .input_mux = &alc883_capture_source,
10731 },
a65cc60f 10732 [ALC883_CLEVO_M540R] = {
10733 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10734 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10736 .dac_nids = alc883_dac_nids,
10737 .dig_out_nid = ALC883_DIGOUT_NID,
10738 .dig_in_nid = ALC883_DIGIN_NID,
10739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10740 .channel_mode = alc883_3ST_6ch_clevo_modes,
10741 .need_dac_fix = 1,
10742 .input_mux = &alc883_capture_source,
10743 /* This machine has the hardware HP auto-muting, thus
10744 * we need no software mute via unsol event
10745 */
10746 },
0c4cc443
HRK
10747 [ALC883_CLEVO_M720] = {
10748 .mixers = { alc883_clevo_m720_mixer },
10749 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10750 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10751 .dac_nids = alc883_dac_nids,
10752 .dig_out_nid = ALC883_DIGOUT_NID,
10753 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10754 .channel_mode = alc883_3ST_2ch_modes,
10755 .input_mux = &alc883_capture_source,
0c4cc443 10756 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10757 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10758 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10759 },
bc9f98a9
KY
10760 [ALC883_LENOVO_101E_2ch] = {
10761 .mixers = { alc883_lenovo_101e_2ch_mixer},
10762 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10765 .adc_nids = alc883_adc_nids_alt,
10766 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10767 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10769 .channel_mode = alc883_3ST_2ch_modes,
10770 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10771 .setup = alc883_lenovo_101e_setup,
10772 .unsol_event = alc_sku_unsol_event,
10773 .init_hook = alc_inithook,
bc9f98a9 10774 },
272a527c
KY
10775 [ALC883_LENOVO_NB0763] = {
10776 .mixers = { alc883_lenovo_nb0763_mixer },
10777 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10778 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10779 .dac_nids = alc883_dac_nids,
272a527c
KY
10780 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10781 .channel_mode = alc883_3ST_2ch_modes,
10782 .need_dac_fix = 1,
10783 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10784 .unsol_event = alc_sku_unsol_event,
dc427170 10785 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10786 .init_hook = alc_hp_automute,
272a527c
KY
10787 },
10788 [ALC888_LENOVO_MS7195_DIG] = {
10789 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10790 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10791 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10792 .dac_nids = alc883_dac_nids,
10793 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10794 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10795 .channel_mode = alc883_3ST_6ch_modes,
10796 .need_dac_fix = 1,
10797 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10798 .unsol_event = alc_sku_unsol_event,
10799 .setup = alc888_lenovo_ms7195_setup,
10800 .init_hook = alc_inithook,
189609ae
KY
10801 },
10802 [ALC883_HAIER_W66] = {
c259249f 10803 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10804 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10805 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10806 .dac_nids = alc883_dac_nids,
10807 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10808 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10809 .channel_mode = alc883_3ST_2ch_modes,
10810 .input_mux = &alc883_capture_source,
d922b51d 10811 .unsol_event = alc_sku_unsol_event,
4f5d1706 10812 .setup = alc883_haier_w66_setup,
d922b51d 10813 .init_hook = alc_hp_automute,
eea6419e 10814 },
4723c022 10815 [ALC888_3ST_HP] = {
eea6419e 10816 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10817 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10818 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10819 .dac_nids = alc883_dac_nids,
4723c022
CM
10820 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10821 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10822 .need_dac_fix = 1,
10823 .input_mux = &alc883_capture_source,
d922b51d 10824 .unsol_event = alc_sku_unsol_event,
4f5d1706 10825 .setup = alc888_3st_hp_setup,
d922b51d 10826 .init_hook = alc_hp_automute,
8341de60 10827 },
5795b9e6 10828 [ALC888_6ST_DELL] = {
f24dbdc6 10829 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10830 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10832 .dac_nids = alc883_dac_nids,
10833 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10834 .dig_in_nid = ALC883_DIGIN_NID,
10835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10836 .channel_mode = alc883_sixstack_modes,
10837 .input_mux = &alc883_capture_source,
d922b51d 10838 .unsol_event = alc_sku_unsol_event,
4f5d1706 10839 .setup = alc888_6st_dell_setup,
d922b51d 10840 .init_hook = alc_hp_automute,
5795b9e6 10841 },
a8848bd6
AS
10842 [ALC883_MITAC] = {
10843 .mixers = { alc883_mitac_mixer },
10844 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10846 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10847 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10848 .channel_mode = alc883_3ST_2ch_modes,
10849 .input_mux = &alc883_capture_source,
d922b51d 10850 .unsol_event = alc_sku_unsol_event,
4f5d1706 10851 .setup = alc883_mitac_setup,
d922b51d 10852 .init_hook = alc_hp_automute,
a8848bd6 10853 },
fb97dc67
J
10854 [ALC883_FUJITSU_PI2515] = {
10855 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10856 .init_verbs = { alc883_init_verbs,
10857 alc883_2ch_fujitsu_pi2515_verbs},
10858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859 .dac_nids = alc883_dac_nids,
10860 .dig_out_nid = ALC883_DIGOUT_NID,
10861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10862 .channel_mode = alc883_3ST_2ch_modes,
10863 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10864 .unsol_event = alc_sku_unsol_event,
4f5d1706 10865 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10866 .init_hook = alc_hp_automute,
fb97dc67 10867 },
ef8ef5fb
VP
10868 [ALC888_FUJITSU_XA3530] = {
10869 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10870 .init_verbs = { alc883_init_verbs,
10871 alc888_fujitsu_xa3530_verbs },
10872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10873 .dac_nids = alc883_dac_nids,
10874 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10875 .adc_nids = alc883_adc_nids_rev,
10876 .capsrc_nids = alc883_capsrc_nids_rev,
10877 .dig_out_nid = ALC883_DIGOUT_NID,
10878 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10879 .channel_mode = alc888_4ST_8ch_intel_modes,
10880 .num_mux_defs =
10881 ARRAY_SIZE(alc888_2_capture_sources),
10882 .input_mux = alc888_2_capture_sources,
d922b51d 10883 .unsol_event = alc_sku_unsol_event,
4f5d1706 10884 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10885 .init_hook = alc_hp_automute,
ef8ef5fb 10886 },
e2757d5e
KY
10887 [ALC888_LENOVO_SKY] = {
10888 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10889 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10890 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10891 .dac_nids = alc883_dac_nids,
10892 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10893 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10894 .channel_mode = alc883_sixstack_modes,
10895 .need_dac_fix = 1,
10896 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10897 .unsol_event = alc_sku_unsol_event,
4f5d1706 10898 .setup = alc888_lenovo_sky_setup,
d922b51d 10899 .init_hook = alc_hp_automute,
e2757d5e
KY
10900 },
10901 [ALC888_ASUS_M90V] = {
10902 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10903 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10904 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10905 .dac_nids = alc883_dac_nids,
10906 .dig_out_nid = ALC883_DIGOUT_NID,
10907 .dig_in_nid = ALC883_DIGIN_NID,
10908 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10909 .channel_mode = alc883_3ST_6ch_modes,
10910 .need_dac_fix = 1,
10911 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10912 .unsol_event = alc_sku_unsol_event,
10913 .setup = alc883_mode2_setup,
10914 .init_hook = alc_inithook,
e2757d5e
KY
10915 },
10916 [ALC888_ASUS_EEE1601] = {
10917 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10918 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10919 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10921 .dac_nids = alc883_dac_nids,
10922 .dig_out_nid = ALC883_DIGOUT_NID,
10923 .dig_in_nid = ALC883_DIGIN_NID,
10924 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10925 .channel_mode = alc883_3ST_2ch_modes,
10926 .need_dac_fix = 1,
10927 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10928 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10929 .init_hook = alc883_eee1601_inithook,
10930 },
3ab90935
WF
10931 [ALC1200_ASUS_P5Q] = {
10932 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10933 .init_verbs = { alc883_init_verbs },
10934 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10935 .dac_nids = alc883_dac_nids,
10936 .dig_out_nid = ALC1200_DIGOUT_NID,
10937 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10938 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10939 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10940 .channel_mode = alc883_sixstack_modes,
10941 .input_mux = &alc883_capture_source,
10942 },
eb4c41d3
TS
10943 [ALC889A_MB31] = {
10944 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10945 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10946 alc880_gpio1_init_verbs },
10947 .adc_nids = alc883_adc_nids,
10948 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10949 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10950 .dac_nids = alc883_dac_nids,
10951 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10952 .channel_mode = alc889A_mb31_6ch_modes,
10953 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10954 .input_mux = &alc889A_mb31_capture_source,
10955 .dig_out_nid = ALC883_DIGOUT_NID,
10956 .unsol_event = alc889A_mb31_unsol_event,
10957 .init_hook = alc889A_mb31_automute,
10958 },
3e1647c5
GG
10959 [ALC883_SONY_VAIO_TT] = {
10960 .mixers = { alc883_vaiott_mixer },
10961 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10962 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10963 .dac_nids = alc883_dac_nids,
10964 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10965 .channel_mode = alc883_3ST_2ch_modes,
10966 .input_mux = &alc883_capture_source,
d922b51d 10967 .unsol_event = alc_sku_unsol_event,
4f5d1706 10968 .setup = alc883_vaiott_setup,
d922b51d 10969 .init_hook = alc_hp_automute,
3e1647c5 10970 },
9c7f852e
TI
10971};
10972
10973
4953550a
TI
10974/*
10975 * Pin config fixes
10976 */
10977enum {
954a29c8 10978 PINFIX_ABIT_AW9D_MAX,
32eea388 10979 PINFIX_LENOVO_Y530,
954a29c8 10980 PINFIX_PB_M5210,
c3d226ab 10981 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10982};
10983
f8f25ba3
TI
10984static const struct alc_fixup alc882_fixups[] = {
10985 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10986 .type = ALC_FIXUP_PINS,
10987 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10988 { 0x15, 0x01080104 }, /* side */
10989 { 0x16, 0x01011012 }, /* rear */
10990 { 0x17, 0x01016011 }, /* clfe */
10991 { }
10992 }
f8f25ba3 10993 },
32eea388
DH
10994 [PINFIX_LENOVO_Y530] = {
10995 .type = ALC_FIXUP_PINS,
10996 .v.pins = (const struct alc_pincfg[]) {
10997 { 0x15, 0x99130112 }, /* rear int speakers */
10998 { 0x16, 0x99130111 }, /* subwoofer */
10999 { }
11000 }
11001 },
954a29c8 11002 [PINFIX_PB_M5210] = {
b5bfbc67
TI
11003 .type = ALC_FIXUP_VERBS,
11004 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
11005 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11006 {}
11007 }
954a29c8 11008 },
c3d226ab 11009 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
11010 .type = ALC_FIXUP_SKU,
11011 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 11012 },
4953550a
TI
11013};
11014
a9111321 11015static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 11016 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 11017 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 11018 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 11019 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
11020 {}
11021};
11022
9c7f852e
TI
11023/*
11024 * BIOS auto configuration
11025 */
05f5f477
TI
11026static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11027 const struct auto_pin_cfg *cfg)
11028{
11029 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11030}
11031
4953550a 11032static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 11033 hda_nid_t nid, int pin_type,
489008cd 11034 hda_nid_t dac)
9c7f852e 11035{
f12ab1e0
TI
11036 int idx;
11037
489008cd 11038 /* set as output */
f6c7e546 11039 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
11040
11041 if (dac == 0x25)
9c7f852e 11042 idx = 4;
489008cd
TI
11043 else if (dac >= 0x02 && dac <= 0x05)
11044 idx = dac - 2;
f9700d5a 11045 else
489008cd 11046 return;
9c7f852e 11047 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11048}
11049
4953550a 11050static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11051{
11052 struct alc_spec *spec = codec->spec;
11053 int i;
11054
11055 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11056 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11057 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11058 if (nid)
4953550a 11059 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11060 spec->multiout.dac_nids[i]);
9c7f852e
TI
11061 }
11062}
11063
4953550a 11064static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11065{
11066 struct alc_spec *spec = codec->spec;
489008cd 11067 hda_nid_t pin, dac;
5855fb80 11068 int i;
9c7f852e 11069
0a3fabe3
DH
11070 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11071 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11072 pin = spec->autocfg.hp_pins[i];
11073 if (!pin)
11074 break;
11075 dac = spec->multiout.hp_nid;
11076 if (!dac)
11077 dac = spec->multiout.dac_nids[0]; /* to front */
11078 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11079 }
489008cd 11080 }
0a3fabe3
DH
11081
11082 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11083 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11084 pin = spec->autocfg.speaker_pins[i];
11085 if (!pin)
11086 break;
11087 dac = spec->multiout.extra_out_nid[0];
11088 if (!dac)
11089 dac = spec->multiout.dac_nids[0]; /* to front */
11090 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11091 }
489008cd 11092 }
9c7f852e
TI
11093}
11094
4953550a 11095static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11096{
11097 struct alc_spec *spec = codec->spec;
66ceeb6b 11098 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11099 int i;
11100
66ceeb6b
TI
11101 for (i = 0; i < cfg->num_inputs; i++) {
11102 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11103 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11104 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11105 snd_hda_codec_write(codec, nid, 0,
11106 AC_VERB_SET_AMP_GAIN_MUTE,
11107 AMP_OUT_MUTE);
11108 }
11109}
11110
11111static void alc882_auto_init_input_src(struct hda_codec *codec)
11112{
11113 struct alc_spec *spec = codec->spec;
11114 int c;
11115
11116 for (c = 0; c < spec->num_adc_nids; c++) {
11117 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11118 hda_nid_t nid = spec->capsrc_nids[c];
11119 unsigned int mux_idx;
11120 const struct hda_input_mux *imux;
11121 int conns, mute, idx, item;
11122
10696aa0
TI
11123 /* mute ADC */
11124 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11125 AC_VERB_SET_AMP_GAIN_MUTE,
11126 AMP_IN_MUTE(0));
11127
4953550a
TI
11128 conns = snd_hda_get_connections(codec, nid, conn_list,
11129 ARRAY_SIZE(conn_list));
11130 if (conns < 0)
11131 continue;
11132 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11133 imux = &spec->input_mux[mux_idx];
5311114d
TI
11134 if (!imux->num_items && mux_idx > 0)
11135 imux = &spec->input_mux[0];
4953550a
TI
11136 for (idx = 0; idx < conns; idx++) {
11137 /* if the current connection is the selected one,
11138 * unmute it as default - otherwise mute it
11139 */
11140 mute = AMP_IN_MUTE(idx);
11141 for (item = 0; item < imux->num_items; item++) {
11142 if (imux->items[item].index == idx) {
11143 if (spec->cur_mux[c] == item)
11144 mute = AMP_IN_UNMUTE(idx);
11145 break;
11146 }
11147 }
11148 /* check if we have a selector or mixer
11149 * we could check for the widget type instead, but
11150 * just check for Amp-In presence (in case of mixer
11151 * without amp-in there is something wrong, this
11152 * function shouldn't be used or capsrc nid is wrong)
11153 */
11154 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11155 snd_hda_codec_write(codec, nid, 0,
11156 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11157 mute);
11158 else if (mute != AMP_IN_MUTE(idx))
11159 snd_hda_codec_write(codec, nid, 0,
11160 AC_VERB_SET_CONNECT_SEL,
11161 idx);
9c7f852e
TI
11162 }
11163 }
11164}
11165
4953550a
TI
11166/* add mic boosts if needed */
11167static int alc_auto_add_mic_boost(struct hda_codec *codec)
11168{
11169 struct alc_spec *spec = codec->spec;
66ceeb6b 11170 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11171 int i, err;
53e8c323 11172 int type_idx = 0;
4953550a 11173 hda_nid_t nid;
5322bf27 11174 const char *prev_label = NULL;
4953550a 11175
66ceeb6b 11176 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11177 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11178 break;
11179 nid = cfg->inputs[i].pin;
11180 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11181 const char *label;
11182 char boost_label[32];
11183
11184 label = hda_get_autocfg_input_label(codec, cfg, i);
11185 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11186 type_idx++;
11187 else
11188 type_idx = 0;
5322bf27
DH
11189 prev_label = label;
11190
11191 snprintf(boost_label, sizeof(boost_label),
11192 "%s Boost Volume", label);
11193 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11194 boost_label, type_idx,
4953550a 11195 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11196 if (err < 0)
11197 return err;
11198 }
4953550a
TI
11199 }
11200 return 0;
11201}
f511b01c 11202
9c7f852e 11203/* almost identical with ALC880 parser... */
4953550a 11204static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11205{
11206 struct alc_spec *spec = codec->spec;
4c6d72d1 11207 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11208 int err;
9c7f852e 11209
05f5f477
TI
11210 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11211 alc882_ignore);
9c7f852e
TI
11212 if (err < 0)
11213 return err;
05f5f477
TI
11214 if (!spec->autocfg.line_outs)
11215 return 0; /* can't find valid BIOS pin config */
776e184e 11216
05f5f477 11217 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11218 if (err < 0)
11219 return err;
11220 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11221 if (err < 0)
11222 return err;
569ed348 11223 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11224 if (err < 0)
11225 return err;
11226 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11227 "Headphone");
05f5f477
TI
11228 if (err < 0)
11229 return err;
11230 err = alc880_auto_create_extra_out(spec,
11231 spec->autocfg.speaker_pins[0],
11232 "Speaker");
11233 if (err < 0)
11234 return err;
05f5f477 11235 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11236 if (err < 0)
11237 return err;
11238
05f5f477
TI
11239 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11240
757899ac 11241 alc_auto_parse_digital(codec);
05f5f477
TI
11242
11243 if (spec->kctls.list)
11244 add_mixer(spec, spec->kctls.list);
11245
11246 add_verb(spec, alc883_auto_init_verbs);
4953550a 11247 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11248 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11249 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11250
05f5f477
TI
11251 spec->num_mux_defs = 1;
11252 spec->input_mux = &spec->private_imux[0];
11253
6227cdce 11254 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11255
11256 err = alc_auto_add_mic_boost(codec);
11257 if (err < 0)
11258 return err;
61b9b9b1 11259
776e184e 11260 return 1; /* config found */
9c7f852e
TI
11261}
11262
11263/* additional initialization for auto-configuration model */
4953550a 11264static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11265{
f6c7e546 11266 struct alc_spec *spec = codec->spec;
4953550a
TI
11267 alc882_auto_init_multi_out(codec);
11268 alc882_auto_init_hp_out(codec);
11269 alc882_auto_init_analog_input(codec);
11270 alc882_auto_init_input_src(codec);
757899ac 11271 alc_auto_init_digital(codec);
f6c7e546 11272 if (spec->unsol_event)
7fb0d78f 11273 alc_inithook(codec);
9c7f852e
TI
11274}
11275
4953550a 11276static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11277{
11278 struct alc_spec *spec;
11279 int err, board_config;
11280
11281 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11282 if (spec == NULL)
11283 return -ENOMEM;
11284
11285 codec->spec = spec;
11286
4953550a
TI
11287 switch (codec->vendor_id) {
11288 case 0x10ec0882:
11289 case 0x10ec0885:
11290 break;
11291 default:
11292 /* ALC883 and variants */
11293 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11294 break;
11295 }
2c3bf9ab 11296
4953550a
TI
11297 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11298 alc882_models,
11299 alc882_cfg_tbl);
11300
11301 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11302 board_config = snd_hda_check_board_codec_sid_config(codec,
11303 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11304
11305 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11306 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11307 codec->chip_name);
11308 board_config = ALC882_AUTO;
9c7f852e
TI
11309 }
11310
b5bfbc67
TI
11311 if (board_config == ALC882_AUTO) {
11312 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11313 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11314 }
4953550a 11315
90622917
DH
11316 alc_auto_parse_customize_define(codec);
11317
4953550a 11318 if (board_config == ALC882_AUTO) {
9c7f852e 11319 /* automatic parse from the BIOS config */
4953550a 11320 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11321 if (err < 0) {
11322 alc_free(codec);
11323 return err;
f12ab1e0 11324 } else if (!err) {
9c7f852e
TI
11325 printk(KERN_INFO
11326 "hda_codec: Cannot set up configuration "
11327 "from BIOS. Using base mode...\n");
4953550a 11328 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11329 }
11330 }
11331
dc1eae25 11332 if (has_cdefine_beep(codec)) {
8af2591d
TI
11333 err = snd_hda_attach_beep_device(codec, 0x1);
11334 if (err < 0) {
11335 alc_free(codec);
11336 return err;
11337 }
680cd536
KK
11338 }
11339
4953550a 11340 if (board_config != ALC882_AUTO)
e9c364c0 11341 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11342
4953550a
TI
11343 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11344 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11345 /* FIXME: setup DAC5 */
11346 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11347 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11348
11349 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11350 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11351
4953550a 11352 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11353 int i, j;
4953550a
TI
11354 spec->num_adc_nids = 0;
11355 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11356 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11357 hda_nid_t cap;
d11f74c6 11358 hda_nid_t items[16];
4953550a
TI
11359 hda_nid_t nid = alc882_adc_nids[i];
11360 unsigned int wcap = get_wcaps(codec, nid);
11361 /* get type */
a22d543a 11362 wcap = get_wcaps_type(wcap);
4953550a
TI
11363 if (wcap != AC_WID_AUD_IN)
11364 continue;
11365 spec->private_adc_nids[spec->num_adc_nids] = nid;
11366 err = snd_hda_get_connections(codec, nid, &cap, 1);
11367 if (err < 0)
11368 continue;
d11f74c6
TI
11369 err = snd_hda_get_connections(codec, cap, items,
11370 ARRAY_SIZE(items));
11371 if (err < 0)
11372 continue;
11373 for (j = 0; j < imux->num_items; j++)
11374 if (imux->items[j].index >= err)
11375 break;
11376 if (j < imux->num_items)
11377 continue;
4953550a
TI
11378 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11379 spec->num_adc_nids++;
61b9b9b1 11380 }
4953550a
TI
11381 spec->adc_nids = spec->private_adc_nids;
11382 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11383 }
11384
b59bdf3b 11385 set_capture_mixer(codec);
da00c244 11386
dc1eae25 11387 if (has_cdefine_beep(codec))
da00c244 11388 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11389
b5bfbc67 11390 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11391
2134ea4f
TI
11392 spec->vmaster_nid = 0x0c;
11393
9c7f852e 11394 codec->patch_ops = alc_patch_ops;
4953550a
TI
11395 if (board_config == ALC882_AUTO)
11396 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11397
11398 alc_init_jacks(codec);
cb53c626
TI
11399#ifdef CONFIG_SND_HDA_POWER_SAVE
11400 if (!spec->loopback.amplist)
4953550a 11401 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11402#endif
9c7f852e
TI
11403
11404 return 0;
11405}
11406
4953550a 11407
9c7f852e
TI
11408/*
11409 * ALC262 support
11410 */
11411
11412#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11413#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11414
11415#define alc262_dac_nids alc260_dac_nids
11416#define alc262_adc_nids alc882_adc_nids
11417#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11418#define alc262_capsrc_nids alc882_capsrc_nids
11419#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11420
11421#define alc262_modes alc260_modes
11422#define alc262_capture_source alc882_capture_source
11423
4c6d72d1 11424static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11425 /* ADC0 */
11426 0x09
11427};
11428
4c6d72d1 11429static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11430
a9111321 11431static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11437 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11443 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11448 { } /* end */
11449};
11450
ce875f07 11451/* update HP, line and mono-out pins according to the master switch */
e9427969 11452#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11453
e9427969 11454static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11455{
11456 struct alc_spec *spec = codec->spec;
864f92be 11457
e9427969
TI
11458 spec->autocfg.hp_pins[0] = 0x1b;
11459 spec->autocfg.speaker_pins[0] = 0x16;
11460 spec->automute = 1;
11461 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11462}
11463
e9427969 11464static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11465{
11466 struct alc_spec *spec = codec->spec;
864f92be 11467
e9427969
TI
11468 spec->autocfg.hp_pins[0] = 0x15;
11469 spec->autocfg.speaker_pins[0] = 0x16;
11470 spec->automute = 1;
11471 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11472}
11473
b72519b5 11474#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11475#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11476
b72519b5
TI
11477#define ALC262_HP_MASTER_SWITCH \
11478 { \
11479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11480 .name = "Master Playback Switch", \
11481 .info = snd_ctl_boolean_mono_info, \
11482 .get = alc262_hp_master_sw_get, \
11483 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11484 }, \
11485 { \
11486 .iface = NID_MAPPING, \
11487 .name = "Master Playback Switch", \
11488 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11489 }
11490
5b0cb1d8 11491
a9111321 11492static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11493 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11494 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11497 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11498 HDA_OUTPUT),
11499 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11500 HDA_OUTPUT),
9c7f852e
TI
11501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11503 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11504 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11505 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11506 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11511 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11512 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11513 { } /* end */
11514};
11515
a9111321 11516static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11517 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11518 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11519 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11520 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11522 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11523 HDA_OUTPUT),
11524 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11525 HDA_OUTPUT),
cd7509a4
KY
11526 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11527 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11528 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11532 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11533 { } /* end */
11534};
11535
a9111321 11536static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11537 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11538 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11539 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11540 { } /* end */
11541};
11542
66d2a9d6 11543/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11544static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11545{
11546 struct alc_spec *spec = codec->spec;
66d2a9d6 11547
a9fd4f3f 11548 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11549 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11550 spec->automute = 1;
11551 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11552}
11553
a9111321 11554static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11555 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11556 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11560 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11561 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11562 { } /* end */
11563};
11564
a9111321 11565static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11568
11569 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11570 { }
11571};
11572
a9111321 11573static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11577 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11578 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11579 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11580 { } /* end */
11581};
11582
a9111321 11583static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11585 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11586 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11588 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11589 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11593 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11594 {}
11595};
11596
a9111321 11597static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11598 .num_items = 1,
11599 .items = {
11600 { "Line", 0x1 },
11601 },
11602};
11603
42171c17 11604/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11605#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11606#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11607#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11608
11609#define ALC262_HIPPO_MASTER_SWITCH \
11610 { \
11611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11612 .name = "Master Playback Switch", \
11613 .info = snd_ctl_boolean_mono_info, \
11614 .get = alc262_hippo_master_sw_get, \
11615 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11616 }, \
11617 { \
11618 .iface = NID_MAPPING, \
11619 .name = "Master Playback Switch", \
11620 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11621 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11622 }
42171c17 11623
a9111321 11624static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11625 ALC262_HIPPO_MASTER_SWITCH,
11626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11636 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11638 { } /* end */
11639};
11640
a9111321 11641static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11642 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11643 ALC262_HIPPO_MASTER_SWITCH,
11644 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11645 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11646 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11647 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11650 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11651 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11652 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11653 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11654 { } /* end */
11655};
11656
11657/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11658static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11659{
11660 struct alc_spec *spec = codec->spec;
11661
11662 spec->autocfg.hp_pins[0] = 0x15;
11663 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11664 spec->automute = 1;
11665 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11666}
11667
4f5d1706 11668static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11669{
11670 struct alc_spec *spec = codec->spec;
11671
11672 spec->autocfg.hp_pins[0] = 0x1b;
11673 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11674 spec->automute = 1;
11675 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11676}
11677
11678
a9111321 11679static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11680 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11681 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11684 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11685 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11686 { } /* end */
11687};
11688
a9111321 11689static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11690 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11691 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11697 { } /* end */
11698};
272a527c 11699
a9111321 11700static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11701 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11702 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11703 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11704 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11709 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11711 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11712 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11713 { } /* end */
11714};
11715
a9111321 11716static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11717 /* Headphone automute */
11718 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11719 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11720 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11721
11722 /* P11 AUX_IN, white 4-pin connector */
11723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11724 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11725 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11726 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11727
11728 {}
11729};
11730
11731/* unsolicited event for HP jack sensing */
4f5d1706 11732static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11733{
a9fd4f3f 11734 struct alc_spec *spec = codec->spec;
ba340e82 11735
a9fd4f3f
TI
11736 spec->autocfg.hp_pins[0] = 0x1b;
11737 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11738 spec->automute = 1;
11739 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11740}
11741
ba340e82 11742
9c7f852e
TI
11743#define alc262_capture_mixer alc882_capture_mixer
11744#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11745
11746/*
11747 * generic initialization of ADC, input mixers and output mixers
11748 */
a9111321 11749static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11750 /*
11751 * Unmute ADC0-2 and set the default input to mic-in
11752 */
11753 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11755 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11756 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11757 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11759
cb53c626 11760 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11761 * mixer widget
f12ab1e0
TI
11762 * Note: PASD motherboards uses the Line In 2 as the input for
11763 * front panel mic (mic 2)
9c7f852e
TI
11764 */
11765 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11771
11772 /*
df694daa
KY
11773 * Set up output mixers (0x0c - 0x0e)
11774 */
11775 /* set vol=0 to output mixers */
11776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11777 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11779 /* set up input amps for analog loopback */
11780 /* Amp Indices: DAC = 0, mixer = 1 */
11781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11786 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11787
11788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11793 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11794
11795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11797 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11800
df694daa
KY
11801 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11803
df694daa
KY
11804 /* FIXME: use matrix-type input source selection */
11805 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11811 /* Input mixer2 */
11812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11815 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11816 /* Input mixer3 */
11817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11821
11822 { }
11823};
1da177e4 11824
a9111321 11825static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11826 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11827 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11828 { }
11829};
11830
a9111321 11831static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11832 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11835
11836 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11838 {}
11839};
11840
a9111321 11841static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11843 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11844 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11845
11846 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11848 {}
272a527c
KY
11849};
11850
a9111321 11851static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11852 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11857 { } /* end */
11858};
11859
a9111321 11860static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11861 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11864 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11865 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11867 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11869 {}
11870};
11871
4f5d1706 11872static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11873{
a9fd4f3f
TI
11874 struct alc_spec *spec = codec->spec;
11875
11876 spec->autocfg.hp_pins[0] = 0x15;
11877 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11878 spec->ext_mic.pin = 0x18;
11879 spec->ext_mic.mux_idx = 0;
11880 spec->int_mic.pin = 0x12;
11881 spec->int_mic.mux_idx = 9;
11882 spec->auto_mic = 1;
d922b51d
TI
11883 spec->automute = 1;
11884 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11885}
11886
e8f9ae2a
PT
11887/*
11888 * nec model
11889 * 0x15 = headphone
11890 * 0x16 = internal speaker
11891 * 0x18 = external mic
11892 */
11893
a9111321 11894static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11895 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11896 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11897
11898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11900 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11901
11902 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11904 { } /* end */
11905};
11906
a9111321 11907static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11908 /* Unmute Speaker */
11909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11910
11911 /* Headphone */
11912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11914
11915 /* External mic to headphone */
11916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11917 /* External mic to speaker */
11918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11919 {}
11920};
11921
834be88d
TI
11922/*
11923 * fujitsu model
5d9fab2d
TV
11924 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11925 * 0x1b = port replicator headphone out
834be88d
TI
11926 */
11927
20f5e0b3 11928#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11929
a9111321 11930static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11931 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11933 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11934 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11935 {}
11936};
11937
a9111321 11938static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11939 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11941 {}
11942};
11943
a9111321 11944static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11945 /* Front Mic pin: input vref at 50% */
11946 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11948 {}
11949};
11950
a9111321 11951static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11952 .num_items = 3,
834be88d
TI
11953 .items = {
11954 { "Mic", 0x0 },
28c4edb7 11955 { "Internal Mic", 0x1 },
834be88d
TI
11956 { "CD", 0x4 },
11957 },
11958};
11959
a9111321 11960static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11961 .num_items = 5,
11962 .items = {
11963 { "Mic", 0x0 },
accbe498 11964 { "Front Mic", 0x1 },
9c7f852e
TI
11965 { "Line", 0x2 },
11966 { "CD", 0x4 },
11967 { "AUX IN", 0x6 },
11968 },
11969};
11970
a9111321 11971static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11972 .num_items = 4,
11973 .items = {
11974 { "Mic", 0x0 },
11975 { "Front Mic", 0x2 },
11976 { "Line", 0x1 },
11977 { "CD", 0x4 },
11978 },
11979};
11980
0f0f391c 11981static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11982{
11983 struct alc_spec *spec = codec->spec;
834be88d 11984
0f0f391c
TI
11985 spec->autocfg.hp_pins[0] = 0x14;
11986 spec->autocfg.hp_pins[1] = 0x1b;
11987 spec->autocfg.speaker_pins[0] = 0x15;
11988 spec->automute = 1;
11989 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11990}
11991
834be88d 11992/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11993static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11994 .ops = &snd_hda_bind_vol,
11995 .values = {
11996 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11997 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11998 0
11999 },
12000};
834be88d 12001
a9111321 12002static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 12003 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
12004 {
12005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12006 .name = "Master Playback Switch",
0f0f391c
TI
12007 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12008 .info = snd_ctl_boolean_mono_info,
12009 .get = alc262_hp_master_sw_get,
12010 .put = alc262_hp_master_sw_put,
834be88d 12011 },
5b0cb1d8
JK
12012 {
12013 .iface = NID_MAPPING,
12014 .name = "Master Playback Switch",
12015 .private_value = 0x1b,
12016 },
834be88d
TI
12017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
12020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12022 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12023 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12024 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
12025 { } /* end */
12026};
12027
0f0f391c 12028static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 12029{
0f0f391c 12030 struct alc_spec *spec = codec->spec;
0e31daf7 12031
0f0f391c
TI
12032 spec->autocfg.hp_pins[0] = 0x1b;
12033 spec->autocfg.speaker_pins[0] = 0x14;
12034 spec->autocfg.speaker_pins[1] = 0x16;
12035 spec->automute = 1;
12036 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
12037}
12038
a9111321 12039static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
12040 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12041 {
12042 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12043 .name = "Master Playback Switch",
0f0f391c
TI
12044 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12045 .info = snd_ctl_boolean_mono_info,
12046 .get = alc262_hp_master_sw_get,
12047 .put = alc262_hp_master_sw_put,
0e31daf7
J
12048 },
12049 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12050 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12051 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12054 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12055 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12056 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12057 { } /* end */
12058};
12059
a9111321 12060static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12061 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12062 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12066 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12067 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12068 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12069 { } /* end */
12070};
12071
304dcaac 12072/* additional init verbs for Benq laptops */
a9111321 12073static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12074 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12075 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12076 {}
12077};
12078
a9111321 12079static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12081 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12082
12083 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12084 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12085 {}
12086};
12087
f651b50b 12088/* Samsung Q1 Ultra Vista model setup */
a9111321 12089static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12090 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12091 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12093 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12095 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12096 { } /* end */
12097};
12098
a9111321 12099static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12100 /* output mixer */
12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12104 /* speaker */
12105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12109 /* HP */
f651b50b 12110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12115 /* internal mic */
12116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12118 /* ADC, choose mic */
12119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12129 {}
12130};
12131
f651b50b
TD
12132/* mute/unmute internal speaker according to the hp jack and mute state */
12133static void alc262_ultra_automute(struct hda_codec *codec)
12134{
12135 struct alc_spec *spec = codec->spec;
12136 unsigned int mute;
f651b50b 12137
bb9f76cd
TI
12138 mute = 0;
12139 /* auto-mute only when HP is used as HP */
12140 if (!spec->cur_mux[0]) {
864f92be 12141 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12142 if (spec->jack_present)
12143 mute = HDA_AMP_MUTE;
f651b50b 12144 }
bb9f76cd
TI
12145 /* mute/unmute internal speaker */
12146 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12147 HDA_AMP_MUTE, mute);
12148 /* mute/unmute HP */
12149 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12150 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12151}
12152
12153/* unsolicited event for HP jack sensing */
12154static void alc262_ultra_unsol_event(struct hda_codec *codec,
12155 unsigned int res)
12156{
12157 if ((res >> 26) != ALC880_HP_EVENT)
12158 return;
12159 alc262_ultra_automute(codec);
12160}
12161
a9111321 12162static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12163 .num_items = 2,
12164 .items = {
12165 { "Mic", 0x1 },
12166 { "Headphone", 0x7 },
12167 },
12168};
12169
12170static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12171 struct snd_ctl_elem_value *ucontrol)
12172{
12173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12174 struct alc_spec *spec = codec->spec;
12175 int ret;
12176
54cbc9ab 12177 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12178 if (!ret)
12179 return 0;
12180 /* reprogram the HP pin as mic or HP according to the input source */
12181 snd_hda_codec_write_cache(codec, 0x15, 0,
12182 AC_VERB_SET_PIN_WIDGET_CONTROL,
12183 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12184 alc262_ultra_automute(codec); /* mute/unmute HP */
12185 return ret;
12186}
12187
a9111321 12188static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12189 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12190 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12191 {
12192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12193 .name = "Capture Source",
54cbc9ab
TI
12194 .info = alc_mux_enum_info,
12195 .get = alc_mux_enum_get,
bb9f76cd
TI
12196 .put = alc262_ultra_mux_enum_put,
12197 },
5b0cb1d8
JK
12198 {
12199 .iface = NID_MAPPING,
12200 .name = "Capture Source",
12201 .private_value = 0x15,
12202 },
bb9f76cd
TI
12203 { } /* end */
12204};
12205
c3fc1f50
TI
12206/* We use two mixers depending on the output pin; 0x16 is a mono output
12207 * and thus it's bound with a different mixer.
12208 * This function returns which mixer amp should be used.
12209 */
12210static int alc262_check_volbit(hda_nid_t nid)
12211{
12212 if (!nid)
12213 return 0;
12214 else if (nid == 0x16)
12215 return 2;
12216 else
12217 return 1;
12218}
12219
12220static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12221 const char *pfx, int *vbits, int idx)
c3fc1f50 12222{
c3fc1f50
TI
12223 unsigned long val;
12224 int vbit;
12225
12226 vbit = alc262_check_volbit(nid);
12227 if (!vbit)
12228 return 0;
12229 if (*vbits & vbit) /* a volume control for this mixer already there */
12230 return 0;
12231 *vbits |= vbit;
c3fc1f50
TI
12232 if (vbit == 2)
12233 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12234 else
12235 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12236 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12237}
12238
12239static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12240 const char *pfx, int idx)
c3fc1f50 12241{
c3fc1f50
TI
12242 unsigned long val;
12243
12244 if (!nid)
12245 return 0;
c3fc1f50
TI
12246 if (nid == 0x16)
12247 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12248 else
12249 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12250 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12251}
12252
df694daa 12253/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12254static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12255 const struct auto_pin_cfg *cfg)
df694daa 12256{
c3fc1f50
TI
12257 const char *pfx;
12258 int vbits;
033688a5 12259 int i, err;
df694daa
KY
12260
12261 spec->multiout.num_dacs = 1; /* only use one dac */
12262 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12263 spec->private_dac_nids[0] = 2;
df694daa 12264
ce764ab2 12265 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12266 if (!pfx)
c3fc1f50 12267 pfx = "Front";
033688a5
TI
12268 for (i = 0; i < 2; i++) {
12269 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12270 if (err < 0)
12271 return err;
12272 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12273 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12274 "Speaker", i);
12275 if (err < 0)
12276 return err;
12277 }
12278 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12279 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12280 "Headphone", i);
12281 if (err < 0)
12282 return err;
12283 }
12284 }
df694daa 12285
c3fc1f50
TI
12286 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12287 alc262_check_volbit(cfg->speaker_pins[0]) |
12288 alc262_check_volbit(cfg->hp_pins[0]);
12289 if (vbits == 1 || vbits == 2)
12290 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12291 vbits = 0;
033688a5
TI
12292 for (i = 0; i < 2; i++) {
12293 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12294 &vbits, i);
12295 if (err < 0)
12296 return err;
12297 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12298 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12299 "Speaker", &vbits, i);
12300 if (err < 0)
12301 return err;
12302 }
12303 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12304 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12305 "Headphone", &vbits, i);
12306 if (err < 0)
12307 return err;
12308 }
12309 }
f12ab1e0 12310 return 0;
df694daa
KY
12311}
12312
05f5f477 12313#define alc262_auto_create_input_ctls \
eaa9b3a7 12314 alc882_auto_create_input_ctls
df694daa
KY
12315
12316/*
12317 * generic initialization of ADC, input mixers and output mixers
12318 */
a9111321 12319static const struct hda_verb alc262_volume_init_verbs[] = {
df694daa
KY
12320 /*
12321 * Unmute ADC0-2 and set the default input to mic-in
12322 */
12323 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12325 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12327 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12329
cb53c626 12330 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12331 * mixer widget
f12ab1e0
TI
12332 * Note: PASD motherboards uses the Line In 2 as the input for
12333 * front panel mic (mic 2)
df694daa
KY
12334 */
12335 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12341
12342 /*
12343 * Set up output mixers (0x0c - 0x0f)
12344 */
12345 /* set vol=0 to output mixers */
12346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12349
df694daa
KY
12350 /* set up input amps for analog loopback */
12351 /* Amp Indices: DAC = 0, mixer = 1 */
12352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12358
12359 /* FIXME: use matrix-type input source selection */
12360 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12361 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12365 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12366 /* Input mixer2 */
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12371 /* Input mixer3 */
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12376
12377 { }
12378};
12379
a9111321 12380static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12381 /*
12382 * Unmute ADC0-2 and set the default input to mic-in
12383 */
12384 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12386 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12387 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12388 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12389 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12390
cb53c626 12391 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12392 * mixer widget
f12ab1e0
TI
12393 * Note: PASD motherboards uses the Line In 2 as the input for
12394 * front panel mic (mic 2)
9c7f852e
TI
12395 */
12396 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12404
9c7f852e
TI
12405 /*
12406 * Set up output mixers (0x0c - 0x0e)
12407 */
12408 /* set vol=0 to output mixers */
12409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12412
12413 /* set up input amps for analog loopback */
12414 /* Amp Indices: DAC = 0, mixer = 1 */
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12421
ce875f07 12422 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12425
12426 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12428
12429 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12431
12432 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12433 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12437
0e4835c1 12438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12442 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12444
12445
12446 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12447 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12448 /* Input mixer1: only unmute Mic */
9c7f852e 12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12458 /* Input mixer2 */
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12468 /* Input mixer3 */
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12478
ce875f07
TI
12479 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12480
9c7f852e
TI
12481 { }
12482};
12483
a9111321 12484static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12485 /*
12486 * Unmute ADC0-2 and set the default input to mic-in
12487 */
12488 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12490 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12492 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12493 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12494
cb53c626 12495 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12496 * mixer widget
12497 * Note: PASD motherboards uses the Line In 2 as the input for front
12498 * panel mic (mic 2)
12499 */
12500 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12508 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12509 /*
12510 * Set up output mixers (0x0c - 0x0e)
12511 */
12512 /* set vol=0 to output mixers */
12513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12516
12517 /* set up input amps for analog loopback */
12518 /* Amp Indices: DAC = 0, mixer = 1 */
12519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12522 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12524 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12525
12526
12527 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12529 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12531 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12534
12535 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12537
12538 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12539 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12540
12541 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12543 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12545 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12546 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12547
12548 /* FIXME: use matrix-type input source selection */
12549 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12550 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12556 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12557 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12558 /* Input mixer2 */
12559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12564 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12566 /* Input mixer3 */
12567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12572 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12574
ce875f07
TI
12575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12576
cd7509a4
KY
12577 { }
12578};
12579
a9111321 12580static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12581
12582 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12583 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12584 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12585
12586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12588 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12589 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12590
12591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12592 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12593 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12594 {}
12595};
12596
18675e42
TI
12597/*
12598 * Pin config fixes
12599 */
12600enum {
12601 PINFIX_FSC_H270,
12602};
12603
12604static const struct alc_fixup alc262_fixups[] = {
12605 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12606 .type = ALC_FIXUP_PINS,
12607 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12608 { 0x14, 0x99130110 }, /* speaker */
12609 { 0x15, 0x0221142f }, /* front HP */
12610 { 0x1b, 0x0121141f }, /* rear HP */
12611 { }
12612 }
12613 },
18675e42
TI
12614};
12615
a9111321 12616static const struct snd_pci_quirk alc262_fixup_tbl[] = {
18675e42
TI
12617 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12618 {}
12619};
12620
9f99a638 12621
cb53c626
TI
12622#ifdef CONFIG_SND_HDA_POWER_SAVE
12623#define alc262_loopbacks alc880_loopbacks
12624#endif
12625
def319f9 12626/* pcm configuration: identical with ALC880 */
df694daa
KY
12627#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12628#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12629#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12630#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12631
12632/*
12633 * BIOS auto configuration
12634 */
12635static int alc262_parse_auto_config(struct hda_codec *codec)
12636{
12637 struct alc_spec *spec = codec->spec;
12638 int err;
4c6d72d1 12639 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12640
f12ab1e0
TI
12641 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12642 alc262_ignore);
12643 if (err < 0)
df694daa 12644 return err;
e64f14f4 12645 if (!spec->autocfg.line_outs) {
0852d7a6 12646 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12647 spec->multiout.max_channels = 2;
12648 spec->no_analog = 1;
12649 goto dig_only;
12650 }
df694daa 12651 return 0; /* can't find valid BIOS pin config */
e64f14f4 12652 }
f12ab1e0
TI
12653 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12654 if (err < 0)
12655 return err;
05f5f477 12656 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12657 if (err < 0)
df694daa
KY
12658 return err;
12659
12660 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12661
e64f14f4 12662 dig_only:
757899ac 12663 alc_auto_parse_digital(codec);
df694daa 12664
603c4019 12665 if (spec->kctls.list)
d88897ea 12666 add_mixer(spec, spec->kctls.list);
df694daa 12667
d88897ea 12668 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12669 spec->num_mux_defs = 1;
61b9b9b1 12670 spec->input_mux = &spec->private_imux[0];
df694daa 12671
776e184e
TI
12672 err = alc_auto_add_mic_boost(codec);
12673 if (err < 0)
12674 return err;
12675
6227cdce 12676 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12677
df694daa
KY
12678 return 1;
12679}
12680
12681#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12682#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12683#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12684#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12685
12686
12687/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12688static void alc262_auto_init(struct hda_codec *codec)
df694daa 12689{
f6c7e546 12690 struct alc_spec *spec = codec->spec;
df694daa
KY
12691 alc262_auto_init_multi_out(codec);
12692 alc262_auto_init_hp_out(codec);
12693 alc262_auto_init_analog_input(codec);
f511b01c 12694 alc262_auto_init_input_src(codec);
757899ac 12695 alc_auto_init_digital(codec);
f6c7e546 12696 if (spec->unsol_event)
7fb0d78f 12697 alc_inithook(codec);
df694daa
KY
12698}
12699
12700/*
12701 * configuration and preset
12702 */
ea734963 12703static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12704 [ALC262_BASIC] = "basic",
12705 [ALC262_HIPPO] = "hippo",
12706 [ALC262_HIPPO_1] = "hippo_1",
12707 [ALC262_FUJITSU] = "fujitsu",
12708 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12709 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12710 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12711 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12712 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12713 [ALC262_BENQ_T31] = "benq-t31",
12714 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12715 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12716 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12717 [ALC262_ULTRA] = "ultra",
0e31daf7 12718 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12719 [ALC262_NEC] = "nec",
ba340e82 12720 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12721 [ALC262_AUTO] = "auto",
12722};
12723
a9111321 12724static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12725 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12726 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12727 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12728 ALC262_HP_BPC),
12729 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12730 ALC262_HP_BPC),
5734a07c
TI
12731 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12732 ALC262_HP_BPC),
53eff7e1
TI
12733 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12734 ALC262_HP_BPC),
cd7509a4 12735 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12736 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12737 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12738 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12739 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12740 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12741 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12742 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12743 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12744 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12745 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12746 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12747 ALC262_HP_TC_T5735),
8c427226 12748 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12749 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12750 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12751 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12752 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12753 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12754 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12755 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12756#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12757 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12758 ALC262_SONY_ASSAMD),
c5b5165c 12759#endif
36ca6e13 12760 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12761 ALC262_TOSHIBA_RX1),
80ffe869 12762 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12763 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12764 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12765 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12766 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12767 ALC262_ULTRA),
3e420e78 12768 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12769 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12770 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12771 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12772 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12773 {}
12774};
12775
a9111321 12776static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12777 [ALC262_BASIC] = {
12778 .mixers = { alc262_base_mixer },
12779 .init_verbs = { alc262_init_verbs },
12780 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12781 .dac_nids = alc262_dac_nids,
12782 .hp_nid = 0x03,
12783 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784 .channel_mode = alc262_modes,
a3bcba38 12785 .input_mux = &alc262_capture_source,
df694daa 12786 },
ccc656ce 12787 [ALC262_HIPPO] = {
42171c17 12788 .mixers = { alc262_hippo_mixer },
6732bd0d 12789 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12790 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12791 .dac_nids = alc262_dac_nids,
12792 .hp_nid = 0x03,
12793 .dig_out_nid = ALC262_DIGOUT_NID,
12794 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12795 .channel_mode = alc262_modes,
12796 .input_mux = &alc262_capture_source,
e9427969 12797 .unsol_event = alc_sku_unsol_event,
4f5d1706 12798 .setup = alc262_hippo_setup,
e9427969 12799 .init_hook = alc_inithook,
ccc656ce
KY
12800 },
12801 [ALC262_HIPPO_1] = {
12802 .mixers = { alc262_hippo1_mixer },
12803 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805 .dac_nids = alc262_dac_nids,
12806 .hp_nid = 0x02,
12807 .dig_out_nid = ALC262_DIGOUT_NID,
12808 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12809 .channel_mode = alc262_modes,
12810 .input_mux = &alc262_capture_source,
e9427969 12811 .unsol_event = alc_sku_unsol_event,
4f5d1706 12812 .setup = alc262_hippo1_setup,
e9427969 12813 .init_hook = alc_inithook,
ccc656ce 12814 },
834be88d
TI
12815 [ALC262_FUJITSU] = {
12816 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12817 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12818 alc262_fujitsu_unsol_verbs },
834be88d
TI
12819 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12820 .dac_nids = alc262_dac_nids,
12821 .hp_nid = 0x03,
12822 .dig_out_nid = ALC262_DIGOUT_NID,
12823 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12824 .channel_mode = alc262_modes,
12825 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12826 .unsol_event = alc_sku_unsol_event,
12827 .setup = alc262_fujitsu_setup,
12828 .init_hook = alc_inithook,
834be88d 12829 },
9c7f852e
TI
12830 [ALC262_HP_BPC] = {
12831 .mixers = { alc262_HP_BPC_mixer },
12832 .init_verbs = { alc262_HP_BPC_init_verbs },
12833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12834 .dac_nids = alc262_dac_nids,
12835 .hp_nid = 0x03,
12836 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12837 .channel_mode = alc262_modes,
12838 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12839 .unsol_event = alc_sku_unsol_event,
12840 .setup = alc262_hp_bpc_setup,
12841 .init_hook = alc_inithook,
f12ab1e0 12842 },
cd7509a4
KY
12843 [ALC262_HP_BPC_D7000_WF] = {
12844 .mixers = { alc262_HP_BPC_WildWest_mixer },
12845 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12846 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12847 .dac_nids = alc262_dac_nids,
12848 .hp_nid = 0x03,
12849 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12850 .channel_mode = alc262_modes,
accbe498 12851 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12852 .unsol_event = alc_sku_unsol_event,
12853 .setup = alc262_hp_wildwest_setup,
12854 .init_hook = alc_inithook,
f12ab1e0 12855 },
cd7509a4
KY
12856 [ALC262_HP_BPC_D7000_WL] = {
12857 .mixers = { alc262_HP_BPC_WildWest_mixer,
12858 alc262_HP_BPC_WildWest_option_mixer },
12859 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12861 .dac_nids = alc262_dac_nids,
12862 .hp_nid = 0x03,
12863 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12864 .channel_mode = alc262_modes,
accbe498 12865 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12866 .unsol_event = alc_sku_unsol_event,
12867 .setup = alc262_hp_wildwest_setup,
12868 .init_hook = alc_inithook,
f12ab1e0 12869 },
66d2a9d6
KY
12870 [ALC262_HP_TC_T5735] = {
12871 .mixers = { alc262_hp_t5735_mixer },
12872 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12873 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12874 .dac_nids = alc262_dac_nids,
12875 .hp_nid = 0x03,
12876 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12877 .channel_mode = alc262_modes,
12878 .input_mux = &alc262_capture_source,
dc99be47 12879 .unsol_event = alc_sku_unsol_event,
4f5d1706 12880 .setup = alc262_hp_t5735_setup,
dc99be47 12881 .init_hook = alc_inithook,
8c427226
KY
12882 },
12883 [ALC262_HP_RP5700] = {
12884 .mixers = { alc262_hp_rp5700_mixer },
12885 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12886 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12887 .dac_nids = alc262_dac_nids,
12888 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12889 .channel_mode = alc262_modes,
12890 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12891 },
304dcaac
TI
12892 [ALC262_BENQ_ED8] = {
12893 .mixers = { alc262_base_mixer },
12894 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12895 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12896 .dac_nids = alc262_dac_nids,
12897 .hp_nid = 0x03,
12898 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12899 .channel_mode = alc262_modes,
12900 .input_mux = &alc262_capture_source,
f12ab1e0 12901 },
272a527c
KY
12902 [ALC262_SONY_ASSAMD] = {
12903 .mixers = { alc262_sony_mixer },
12904 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12905 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12906 .dac_nids = alc262_dac_nids,
12907 .hp_nid = 0x02,
12908 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12909 .channel_mode = alc262_modes,
12910 .input_mux = &alc262_capture_source,
e9427969 12911 .unsol_event = alc_sku_unsol_event,
4f5d1706 12912 .setup = alc262_hippo_setup,
e9427969 12913 .init_hook = alc_inithook,
83c34218
KY
12914 },
12915 [ALC262_BENQ_T31] = {
12916 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12917 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12918 alc_hp15_unsol_verbs },
83c34218
KY
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,
e9427969 12925 .unsol_event = alc_sku_unsol_event,
4f5d1706 12926 .setup = alc262_hippo_setup,
e9427969 12927 .init_hook = alc_inithook,
ea1fb29a 12928 },
f651b50b 12929 [ALC262_ULTRA] = {
f9e336f6
TI
12930 .mixers = { alc262_ultra_mixer },
12931 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12932 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12933 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12934 .dac_nids = alc262_dac_nids,
f651b50b
TD
12935 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12936 .channel_mode = alc262_modes,
12937 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12938 .adc_nids = alc262_adc_nids, /* ADC0 */
12939 .capsrc_nids = alc262_capsrc_nids,
12940 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12941 .unsol_event = alc262_ultra_unsol_event,
12942 .init_hook = alc262_ultra_automute,
12943 },
0e31daf7
J
12944 [ALC262_LENOVO_3000] = {
12945 .mixers = { alc262_lenovo_3000_mixer },
12946 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12947 alc262_lenovo_3000_unsol_verbs,
12948 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12949 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12950 .dac_nids = alc262_dac_nids,
12951 .hp_nid = 0x03,
12952 .dig_out_nid = ALC262_DIGOUT_NID,
12953 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12954 .channel_mode = alc262_modes,
12955 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12956 .unsol_event = alc_sku_unsol_event,
12957 .setup = alc262_lenovo_3000_setup,
12958 .init_hook = alc_inithook,
0e31daf7 12959 },
e8f9ae2a
PT
12960 [ALC262_NEC] = {
12961 .mixers = { alc262_nec_mixer },
12962 .init_verbs = { alc262_nec_verbs },
12963 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12964 .dac_nids = alc262_dac_nids,
12965 .hp_nid = 0x03,
12966 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12967 .channel_mode = alc262_modes,
12968 .input_mux = &alc262_capture_source,
12969 },
4e555fe5
KY
12970 [ALC262_TOSHIBA_S06] = {
12971 .mixers = { alc262_toshiba_s06_mixer },
12972 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12973 alc262_eapd_verbs },
12974 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12975 .capsrc_nids = alc262_dmic_capsrc_nids,
12976 .dac_nids = alc262_dac_nids,
12977 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12978 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12979 .dig_out_nid = ALC262_DIGOUT_NID,
12980 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12981 .channel_mode = alc262_modes,
4f5d1706
TI
12982 .unsol_event = alc_sku_unsol_event,
12983 .setup = alc262_toshiba_s06_setup,
12984 .init_hook = alc_inithook,
4e555fe5 12985 },
9f99a638
HM
12986 [ALC262_TOSHIBA_RX1] = {
12987 .mixers = { alc262_toshiba_rx1_mixer },
12988 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12989 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12990 .dac_nids = alc262_dac_nids,
12991 .hp_nid = 0x03,
12992 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12993 .channel_mode = alc262_modes,
12994 .input_mux = &alc262_capture_source,
e9427969 12995 .unsol_event = alc_sku_unsol_event,
4f5d1706 12996 .setup = alc262_hippo_setup,
e9427969 12997 .init_hook = alc_inithook,
9f99a638 12998 },
ba340e82
TV
12999 [ALC262_TYAN] = {
13000 .mixers = { alc262_tyan_mixer },
13001 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13002 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13003 .dac_nids = alc262_dac_nids,
13004 .hp_nid = 0x02,
13005 .dig_out_nid = ALC262_DIGOUT_NID,
13006 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13007 .channel_mode = alc262_modes,
13008 .input_mux = &alc262_capture_source,
d922b51d 13009 .unsol_event = alc_sku_unsol_event,
4f5d1706 13010 .setup = alc262_tyan_setup,
d922b51d 13011 .init_hook = alc_hp_automute,
ba340e82 13012 },
df694daa
KY
13013};
13014
13015static int patch_alc262(struct hda_codec *codec)
13016{
13017 struct alc_spec *spec;
13018 int board_config;
13019 int err;
13020
dc041e0b 13021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13022 if (spec == NULL)
13023 return -ENOMEM;
13024
13025 codec->spec = spec;
13026#if 0
f12ab1e0
TI
13027 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13028 * under-run
13029 */
df694daa
KY
13030 {
13031 int tmp;
13032 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13033 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13034 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13035 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13036 }
13037#endif
da00c244 13038 alc_auto_parse_customize_define(codec);
df694daa 13039
2c3bf9ab
TI
13040 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13041
f5fcc13c
TI
13042 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13043 alc262_models,
13044 alc262_cfg_tbl);
cd7509a4 13045
f5fcc13c 13046 if (board_config < 0) {
9a11f1aa
TI
13047 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13048 codec->chip_name);
df694daa
KY
13049 board_config = ALC262_AUTO;
13050 }
13051
b5bfbc67
TI
13052 if (board_config == ALC262_AUTO) {
13053 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13054 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13055 }
18675e42 13056
df694daa
KY
13057 if (board_config == ALC262_AUTO) {
13058 /* automatic parse from the BIOS config */
13059 err = alc262_parse_auto_config(codec);
13060 if (err < 0) {
13061 alc_free(codec);
13062 return err;
f12ab1e0 13063 } else if (!err) {
9c7f852e
TI
13064 printk(KERN_INFO
13065 "hda_codec: Cannot set up configuration "
13066 "from BIOS. Using base mode...\n");
df694daa
KY
13067 board_config = ALC262_BASIC;
13068 }
13069 }
13070
dc1eae25 13071 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13072 err = snd_hda_attach_beep_device(codec, 0x1);
13073 if (err < 0) {
13074 alc_free(codec);
13075 return err;
13076 }
680cd536
KK
13077 }
13078
df694daa 13079 if (board_config != ALC262_AUTO)
e9c364c0 13080 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13081
df694daa
KY
13082 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13083 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13084
df694daa
KY
13085 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13086 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13087
f12ab1e0 13088 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13089 int i;
13090 /* check whether the digital-mic has to be supported */
13091 for (i = 0; i < spec->input_mux->num_items; i++) {
13092 if (spec->input_mux->items[i].index >= 9)
13093 break;
13094 }
13095 if (i < spec->input_mux->num_items) {
13096 /* use only ADC0 */
13097 spec->adc_nids = alc262_dmic_adc_nids;
13098 spec->num_adc_nids = 1;
13099 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13100 } else {
8c927b4a
TI
13101 /* all analog inputs */
13102 /* check whether NID 0x07 is valid */
13103 unsigned int wcap = get_wcaps(codec, 0x07);
13104
13105 /* get type */
a22d543a 13106 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13107 if (wcap != AC_WID_AUD_IN) {
13108 spec->adc_nids = alc262_adc_nids_alt;
13109 spec->num_adc_nids =
13110 ARRAY_SIZE(alc262_adc_nids_alt);
13111 spec->capsrc_nids = alc262_capsrc_nids_alt;
13112 } else {
13113 spec->adc_nids = alc262_adc_nids;
13114 spec->num_adc_nids =
13115 ARRAY_SIZE(alc262_adc_nids);
13116 spec->capsrc_nids = alc262_capsrc_nids;
13117 }
df694daa
KY
13118 }
13119 }
e64f14f4 13120 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13121 set_capture_mixer(codec);
dc1eae25 13122 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13123 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13124
b5bfbc67 13125 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13126
2134ea4f
TI
13127 spec->vmaster_nid = 0x0c;
13128
df694daa
KY
13129 codec->patch_ops = alc_patch_ops;
13130 if (board_config == ALC262_AUTO)
ae6b813a 13131 spec->init_hook = alc262_auto_init;
1c716153 13132 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13133
13134 alc_init_jacks(codec);
cb53c626
TI
13135#ifdef CONFIG_SND_HDA_POWER_SAVE
13136 if (!spec->loopback.amplist)
13137 spec->loopback.amplist = alc262_loopbacks;
13138#endif
ea1fb29a 13139
df694daa
KY
13140 return 0;
13141}
13142
a361d84b
KY
13143/*
13144 * ALC268 channel source setting (2 channel)
13145 */
13146#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13147#define alc268_modes alc260_modes
ea1fb29a 13148
4c6d72d1 13149static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13150 /* front, hp */
13151 0x02, 0x03
13152};
13153
4c6d72d1 13154static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13155 /* ADC0-1 */
13156 0x08, 0x07
13157};
13158
4c6d72d1 13159static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13160 /* ADC0 */
13161 0x08
13162};
13163
4c6d72d1 13164static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13165
a9111321 13166static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13167 /* output mixer control */
13168 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13172 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13174 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13175 { }
13176};
13177
a9111321 13178static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13179 /* output mixer control */
13180 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13182 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13184 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13185 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13186 { }
13187};
13188
aef9d318 13189/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13190static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13191 .ops = &snd_hda_bind_sw,
13192 .values = {
13193 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13194 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13195 0
13196 },
13197};
13198
a9111321 13199static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13200 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13201 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13202 { }
13203};
13204
a9111321 13205static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13207 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13208 { }
13209};
13210
d273809e 13211/* Toshiba specific */
a9111321 13212static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13213 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13214 { } /* end */
13215};
13216
13217/* Acer specific */
889c4395 13218/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13219static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13220 .ops = &snd_hda_bind_vol,
13221 .values = {
13222 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13223 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13224 0
13225 },
13226};
13227
0f0f391c 13228static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13229{
13230 struct alc_spec *spec = codec->spec;
889c4395 13231
0f0f391c
TI
13232 spec->autocfg.hp_pins[0] = 0x14;
13233 spec->autocfg.speaker_pins[0] = 0x15;
13234 spec->automute = 1;
13235 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13236}
13237
0f0f391c
TI
13238#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13239#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13240
a9111321 13241static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13242 /* output mixer control */
13243 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13244 {
13245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13246 .name = "Master Playback Switch",
0f0f391c
TI
13247 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13248 .info = snd_ctl_boolean_mono_info,
13249 .get = alc268_acer_master_sw_get,
8ef355da 13250 .put = alc268_acer_master_sw_put,
8ef355da
KY
13251 },
13252 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13253 { }
13254};
13255
a9111321 13256static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13257 /* output mixer control */
13258 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13259 {
13260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13261 .name = "Master Playback Switch",
0f0f391c
TI
13262 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13263 .info = snd_ctl_boolean_mono_info,
13264 .get = alc268_acer_master_sw_get,
d273809e 13265 .put = alc268_acer_master_sw_put,
d273809e 13266 },
5f99f86a
DH
13267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13269 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13270 { }
13271};
13272
a9111321 13273static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13274 /* output mixer control */
13275 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13276 {
13277 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13278 .name = "Master Playback Switch",
0f0f391c
TI
13279 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13280 .info = snd_ctl_boolean_mono_info,
13281 .get = alc268_acer_master_sw_get,
c238b4f4 13282 .put = alc268_acer_master_sw_put,
c238b4f4 13283 },
5f99f86a
DH
13284 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13285 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13286 { }
13287};
13288
a9111321 13289static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13290 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13292 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13294 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13295 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13296 { }
13297};
13298
a9111321 13299static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13300 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13301 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13303 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13304 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13306 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13307 { }
13308};
13309
13310/* unsolicited event for HP jack sensing */
4f5d1706 13311#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13312
4f5d1706
TI
13313static void alc268_acer_lc_setup(struct hda_codec *codec)
13314{
13315 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13316 spec->autocfg.hp_pins[0] = 0x15;
13317 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce 13318 spec->automute = 1;
54463a66 13319 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
13320 spec->ext_mic.pin = 0x18;
13321 spec->ext_mic.mux_idx = 0;
13322 spec->int_mic.pin = 0x12;
13323 spec->int_mic.mux_idx = 6;
13324 spec->auto_mic = 1;
8ef355da
KY
13325}
13326
a9111321 13327static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13328 /* output mixer control */
13329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13333 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13334 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13335 { }
13336};
13337
a9111321 13338static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13343 { }
13344};
13345
13346/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13347static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13348{
a9fd4f3f 13349 struct alc_spec *spec = codec->spec;
3866f0b0 13350
a9fd4f3f
TI
13351 spec->autocfg.hp_pins[0] = 0x15;
13352 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13353 spec->ext_mic.pin = 0x18;
13354 spec->ext_mic.mux_idx = 0;
13355 spec->int_mic.pin = 0x19;
13356 spec->int_mic.mux_idx = 1;
13357 spec->auto_mic = 1;
d922b51d
TI
13358 spec->automute = 1;
13359 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13360}
13361
a9111321 13362static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13368 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13369 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13370 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13371 { }
13372};
13373
a9111321 13374static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13377 { }
13378};
13379
4f5d1706 13380static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13381{
a9fd4f3f 13382 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13383 spec->autocfg.hp_pins[0] = 0x15;
13384 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13385 spec->ext_mic.pin = 0x18;
13386 spec->ext_mic.mux_idx = 0;
13387 spec->int_mic.pin = 0x19;
13388 spec->int_mic.mux_idx = 1;
13389 spec->auto_mic = 1;
d922b51d
TI
13390 spec->automute = 1;
13391 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13392}
13393
a361d84b
KY
13394/*
13395 * generic initialization of ADC, input mixers and output mixers
13396 */
a9111321 13397static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13398 /* Unmute DAC0-1 and set vol = 0 */
13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13401
13402 /*
13403 * Set up output mixers (0x0c - 0x0e)
13404 */
13405 /* set vol=0 to output mixers */
13406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13407 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13408
13409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13411
13412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13419 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13420
13421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13424 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13426
13427 /* set PCBEEP vol = 0, mute connections */
13428 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13430 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13431
a9b3aa8a 13432 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13433
a9b3aa8a
JZ
13434 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13436 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13438
a361d84b
KY
13439 { }
13440};
13441
13442/*
13443 * generic initialization of ADC, input mixers and output mixers
13444 */
a9111321 13445static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13446 /* set output DAC */
4cfb91c6
TI
13447 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13449
13450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13454 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13455
a361d84b 13456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13458 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13462
aef9d318
TI
13463 /* set PCBEEP vol = 0, mute connections */
13464 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13466 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13467
13468 { }
13469};
13470
a9111321 13471static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13472 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13473 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13474 { } /* end */
13475};
13476
a9111321 13477static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13478 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13479 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13480 _DEFINE_CAPSRC(1),
a361d84b
KY
13481 { } /* end */
13482};
13483
a9111321 13484static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13485 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13486 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13488 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13489 _DEFINE_CAPSRC(2),
a361d84b
KY
13490 { } /* end */
13491};
13492
a9111321 13493static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13494 .num_items = 4,
13495 .items = {
13496 { "Mic", 0x0 },
13497 { "Front Mic", 0x1 },
13498 { "Line", 0x2 },
13499 { "CD", 0x3 },
13500 },
13501};
13502
a9111321 13503static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13504 .num_items = 3,
13505 .items = {
13506 { "Mic", 0x0 },
13507 { "Internal Mic", 0x1 },
13508 { "Line", 0x2 },
13509 },
13510};
13511
a9111321 13512static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13513 .num_items = 3,
13514 .items = {
13515 { "Mic", 0x0 },
13516 { "Internal Mic", 0x6 },
13517 { "Line", 0x2 },
13518 },
13519};
13520
86c53bd2 13521#ifdef CONFIG_SND_DEBUG
a9111321 13522static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13523 /* Volume widgets */
13524 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13525 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13526 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13527 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13528 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13529 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13530 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13531 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13532 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13533 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13534 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13535 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13536 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13537 /* The below appears problematic on some hardwares */
13538 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13539 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13540 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13541 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13542 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13543
13544 /* Modes for retasking pin widgets */
13545 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13546 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13547 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13548 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13549
13550 /* Controls for GPIO pins, assuming they are configured as outputs */
13551 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13552 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13553 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13554 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13555
13556 /* Switches to allow the digital SPDIF output pin to be enabled.
13557 * The ALC268 does not have an SPDIF input.
13558 */
13559 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13560
13561 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13562 * this output to turn on an external amplifier.
13563 */
13564 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13565 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13566
13567 { } /* end */
13568};
13569#endif
13570
a361d84b
KY
13571/* create input playback/capture controls for the given pin */
13572static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13573 const char *ctlname, int idx)
13574{
3f3b7c1a 13575 hda_nid_t dac;
a361d84b
KY
13576 int err;
13577
3f3b7c1a
TI
13578 switch (nid) {
13579 case 0x14:
13580 case 0x16:
13581 dac = 0x02;
13582 break;
13583 case 0x15:
b08b1637
TI
13584 case 0x1a: /* ALC259/269 only */
13585 case 0x1b: /* ALC259/269 only */
531d8791 13586 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13587 dac = 0x03;
13588 break;
13589 default:
c7a9434d
TI
13590 snd_printd(KERN_WARNING "hda_codec: "
13591 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13592 return 0;
13593 }
13594 if (spec->multiout.dac_nids[0] != dac &&
13595 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13596 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13597 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13598 HDA_OUTPUT));
13599 if (err < 0)
13600 return err;
dda14410 13601 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13602 }
13603
3f3b7c1a 13604 if (nid != 0x16)
0afe5f89 13605 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13606 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13607 else /* mono */
0afe5f89 13608 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13609 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13610 if (err < 0)
13611 return err;
13612 return 0;
13613}
13614
13615/* add playback controls from the parsed DAC table */
13616static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13617 const struct auto_pin_cfg *cfg)
13618{
13619 hda_nid_t nid;
13620 int err;
13621
a361d84b 13622 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13623
13624 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13625 if (nid) {
13626 const char *name;
13627 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13628 name = "Speaker";
13629 else
13630 name = "Front";
13631 err = alc268_new_analog_output(spec, nid, name, 0);
13632 if (err < 0)
13633 return err;
13634 }
a361d84b
KY
13635
13636 nid = cfg->speaker_pins[0];
13637 if (nid == 0x1d) {
0afe5f89 13638 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13639 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13640 if (err < 0)
13641 return err;
7bfb9c03 13642 } else if (nid) {
3f3b7c1a
TI
13643 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13644 if (err < 0)
13645 return err;
a361d84b
KY
13646 }
13647 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13648 if (nid) {
13649 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13650 if (err < 0)
13651 return err;
13652 }
a361d84b
KY
13653
13654 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13655 if (nid == 0x16) {
0afe5f89 13656 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13657 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13658 if (err < 0)
13659 return err;
13660 }
ea1fb29a 13661 return 0;
a361d84b
KY
13662}
13663
13664/* create playback/capture controls for input pins */
05f5f477 13665static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13666 const struct auto_pin_cfg *cfg)
13667{
05f5f477 13668 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13669}
13670
e9af4f36
TI
13671static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13672 hda_nid_t nid, int pin_type)
13673{
13674 int idx;
13675
13676 alc_set_pin_output(codec, nid, pin_type);
13677 if (nid == 0x14 || nid == 0x16)
13678 idx = 0;
13679 else
13680 idx = 1;
13681 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13682}
13683
13684static void alc268_auto_init_multi_out(struct hda_codec *codec)
13685{
13686 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13687 int i;
13688
13689 for (i = 0; i < spec->autocfg.line_outs; i++) {
13690 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13691 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13692 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13693 }
13694}
13695
13696static void alc268_auto_init_hp_out(struct hda_codec *codec)
13697{
13698 struct alc_spec *spec = codec->spec;
13699 hda_nid_t pin;
e1ca7b4e 13700 int i;
e9af4f36 13701
e1ca7b4e
TI
13702 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13703 pin = spec->autocfg.hp_pins[i];
e9af4f36 13704 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13705 }
13706 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13707 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13708 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13709 }
13710 if (spec->autocfg.mono_out_pin)
13711 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13712 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13713}
13714
a361d84b
KY
13715static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13716{
13717 struct alc_spec *spec = codec->spec;
13718 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13719 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13720 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13721 unsigned int dac_vol1, dac_vol2;
13722
e9af4f36 13723 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13724 snd_hda_codec_write(codec, speaker_nid, 0,
13725 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13726 /* mute mixer inputs from 0x1d */
a361d84b
KY
13727 snd_hda_codec_write(codec, 0x0f, 0,
13728 AC_VERB_SET_AMP_GAIN_MUTE,
13729 AMP_IN_UNMUTE(1));
13730 snd_hda_codec_write(codec, 0x10, 0,
13731 AC_VERB_SET_AMP_GAIN_MUTE,
13732 AMP_IN_UNMUTE(1));
13733 } else {
e9af4f36 13734 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13735 snd_hda_codec_write(codec, 0x0f, 0,
13736 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13737 snd_hda_codec_write(codec, 0x10, 0,
13738 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13739 }
13740
13741 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13742 if (line_nid == 0x14)
a361d84b
KY
13743 dac_vol2 = AMP_OUT_ZERO;
13744 else if (line_nid == 0x15)
13745 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13746 if (hp_nid == 0x14)
a361d84b
KY
13747 dac_vol2 = AMP_OUT_ZERO;
13748 else if (hp_nid == 0x15)
13749 dac_vol1 = AMP_OUT_ZERO;
13750 if (line_nid != 0x16 || hp_nid != 0x16 ||
13751 spec->autocfg.line_out_pins[1] != 0x16 ||
13752 spec->autocfg.line_out_pins[2] != 0x16)
13753 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13754
13755 snd_hda_codec_write(codec, 0x02, 0,
13756 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13757 snd_hda_codec_write(codec, 0x03, 0,
13758 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13759}
13760
def319f9 13761/* pcm configuration: identical with ALC880 */
a361d84b
KY
13762#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13763#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13764#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13765#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13766
13767/*
13768 * BIOS auto configuration
13769 */
13770static int alc268_parse_auto_config(struct hda_codec *codec)
13771{
13772 struct alc_spec *spec = codec->spec;
13773 int err;
4c6d72d1 13774 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13775
13776 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13777 alc268_ignore);
13778 if (err < 0)
13779 return err;
7e0e44d4
TI
13780 if (!spec->autocfg.line_outs) {
13781 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13782 spec->multiout.max_channels = 2;
13783 spec->no_analog = 1;
13784 goto dig_only;
13785 }
a361d84b 13786 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13787 }
a361d84b
KY
13788 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13789 if (err < 0)
13790 return err;
05f5f477 13791 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13792 if (err < 0)
13793 return err;
13794
13795 spec->multiout.max_channels = 2;
13796
7e0e44d4 13797 dig_only:
a361d84b 13798 /* digital only support output */
757899ac 13799 alc_auto_parse_digital(codec);
603c4019 13800 if (spec->kctls.list)
d88897ea 13801 add_mixer(spec, spec->kctls.list);
a361d84b 13802
892981ff 13803 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13804 add_mixer(spec, alc268_beep_mixer);
aef9d318 13805
d88897ea 13806 add_verb(spec, alc268_volume_init_verbs);
5908589f 13807 spec->num_mux_defs = 2;
61b9b9b1 13808 spec->input_mux = &spec->private_imux[0];
a361d84b 13809
776e184e
TI
13810 err = alc_auto_add_mic_boost(codec);
13811 if (err < 0)
13812 return err;
13813
6227cdce 13814 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13815
a361d84b
KY
13816 return 1;
13817}
13818
a361d84b 13819#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13820#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13821
13822/* init callback for auto-configuration model -- overriding the default init */
13823static void alc268_auto_init(struct hda_codec *codec)
13824{
f6c7e546 13825 struct alc_spec *spec = codec->spec;
a361d84b
KY
13826 alc268_auto_init_multi_out(codec);
13827 alc268_auto_init_hp_out(codec);
13828 alc268_auto_init_mono_speaker_out(codec);
13829 alc268_auto_init_analog_input(codec);
ae0ebbf7 13830 alc268_auto_init_input_src(codec);
757899ac 13831 alc_auto_init_digital(codec);
f6c7e546 13832 if (spec->unsol_event)
7fb0d78f 13833 alc_inithook(codec);
a361d84b
KY
13834}
13835
13836/*
13837 * configuration and preset
13838 */
ea734963 13839static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13840 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13841 [ALC268_3ST] = "3stack",
983f8ae4 13842 [ALC268_TOSHIBA] = "toshiba",
d273809e 13843 [ALC268_ACER] = "acer",
c238b4f4 13844 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13845 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13846 [ALC268_DELL] = "dell",
f12462c5 13847 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13848#ifdef CONFIG_SND_DEBUG
13849 [ALC268_TEST] = "test",
13850#endif
a361d84b
KY
13851 [ALC268_AUTO] = "auto",
13852};
13853
a9111321 13854static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13855 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13856 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13857 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13858 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13859 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13860 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13861 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13862 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
0a1896b2 13863 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
a1bf8088
DC
13864 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13865 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13866 /* almost compatible with toshiba but with optional digital outs;
13867 * auto-probing seems working fine
13868 */
8871e5b9 13869 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13870 ALC268_AUTO),
a361d84b 13871 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13872 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13873 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
eb5a6621 13874 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13875 {}
13876};
13877
3abf2f36 13878/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13879static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13880 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13881 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13882 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13883 ALC268_TOSHIBA),
13884 {}
13885};
13886
a9111321 13887static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13888 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13889 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13890 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc267_quanta_il1_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
13897 .hp_nid = 0x03,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
4f5d1706
TI
13900 .unsol_event = alc_sku_unsol_event,
13901 .setup = alc267_quanta_il1_setup,
13902 .init_hook = alc_inithook,
eb5a6621 13903 },
a361d84b 13904 [ALC268_3ST] = {
aef9d318
TI
13905 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
a361d84b
KY
13907 .init_verbs = { alc268_base_init_verbs },
13908 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13909 .dac_nids = alc268_dac_nids,
13910 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13911 .adc_nids = alc268_adc_nids_alt,
e1406348 13912 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13913 .hp_nid = 0x03,
13914 .dig_out_nid = ALC268_DIGOUT_NID,
13915 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13916 .channel_mode = alc268_modes,
13917 .input_mux = &alc268_capture_source,
13918 },
d1a991a6 13919 [ALC268_TOSHIBA] = {
42171c17 13920 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13921 alc268_beep_mixer },
d273809e
TI
13922 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13923 alc268_toshiba_verbs },
d1a991a6
KY
13924 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13925 .dac_nids = alc268_dac_nids,
13926 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13927 .adc_nids = alc268_adc_nids_alt,
e1406348 13928 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13929 .hp_nid = 0x03,
13930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13931 .channel_mode = alc268_modes,
13932 .input_mux = &alc268_capture_source,
e9427969 13933 .unsol_event = alc_sku_unsol_event,
4f5d1706 13934 .setup = alc268_toshiba_setup,
e9427969 13935 .init_hook = alc_inithook,
d273809e
TI
13936 },
13937 [ALC268_ACER] = {
432fd133 13938 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13939 alc268_beep_mixer },
d273809e
TI
13940 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13941 alc268_acer_verbs },
13942 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13943 .dac_nids = alc268_dac_nids,
13944 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13945 .adc_nids = alc268_adc_nids_alt,
e1406348 13946 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13947 .hp_nid = 0x02,
13948 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13949 .channel_mode = alc268_modes,
0ccb541c 13950 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13951 .unsol_event = alc_sku_unsol_event,
13952 .setup = alc268_acer_setup,
13953 .init_hook = alc_inithook,
d1a991a6 13954 },
c238b4f4
TI
13955 [ALC268_ACER_DMIC] = {
13956 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13957 alc268_beep_mixer },
13958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13959 alc268_acer_verbs },
13960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13961 .dac_nids = alc268_dac_nids,
13962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13963 .adc_nids = alc268_adc_nids_alt,
13964 .capsrc_nids = alc268_capsrc_nids,
13965 .hp_nid = 0x02,
13966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13967 .channel_mode = alc268_modes,
13968 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13969 .unsol_event = alc_sku_unsol_event,
13970 .setup = alc268_acer_setup,
13971 .init_hook = alc_inithook,
c238b4f4 13972 },
8ef355da
KY
13973 [ALC268_ACER_ASPIRE_ONE] = {
13974 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13975 alc268_beep_mixer,
fdbc6626 13976 alc268_capture_nosrc_mixer },
8ef355da
KY
13977 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13978 alc268_acer_aspire_one_verbs },
13979 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13980 .dac_nids = alc268_dac_nids,
13981 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13982 .adc_nids = alc268_adc_nids_alt,
13983 .capsrc_nids = alc268_capsrc_nids,
13984 .hp_nid = 0x03,
13985 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13986 .channel_mode = alc268_modes,
3b8510ce 13987 .unsol_event = alc_sku_unsol_event,
4f5d1706 13988 .setup = alc268_acer_lc_setup,
3b8510ce 13989 .init_hook = alc_inithook,
8ef355da 13990 },
3866f0b0 13991 [ALC268_DELL] = {
fdbc6626
TI
13992 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13993 alc268_capture_nosrc_mixer },
3866f0b0
TI
13994 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13995 alc268_dell_verbs },
13996 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13997 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13998 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13999 .adc_nids = alc268_adc_nids_alt,
14000 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
14001 .hp_nid = 0x02,
14002 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14003 .channel_mode = alc268_modes,
a9fd4f3f 14004 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
14005 .setup = alc268_dell_setup,
14006 .init_hook = alc_inithook,
3866f0b0 14007 },
f12462c5 14008 [ALC268_ZEPTO] = {
aef9d318
TI
14009 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14010 alc268_beep_mixer },
f12462c5
MT
14011 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14012 alc268_toshiba_verbs },
14013 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14014 .dac_nids = alc268_dac_nids,
14015 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14016 .adc_nids = alc268_adc_nids_alt,
e1406348 14017 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
14018 .hp_nid = 0x03,
14019 .dig_out_nid = ALC268_DIGOUT_NID,
14020 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14021 .channel_mode = alc268_modes,
14022 .input_mux = &alc268_capture_source,
e9427969 14023 .unsol_event = alc_sku_unsol_event,
4f5d1706 14024 .setup = alc268_toshiba_setup,
e9427969 14025 .init_hook = alc_inithook,
f12462c5 14026 },
86c53bd2
JW
14027#ifdef CONFIG_SND_DEBUG
14028 [ALC268_TEST] = {
14029 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14030 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14031 alc268_volume_init_verbs },
14032 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14033 .dac_nids = alc268_dac_nids,
14034 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14035 .adc_nids = alc268_adc_nids_alt,
e1406348 14036 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
14037 .hp_nid = 0x03,
14038 .dig_out_nid = ALC268_DIGOUT_NID,
14039 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14040 .channel_mode = alc268_modes,
14041 .input_mux = &alc268_capture_source,
14042 },
14043#endif
a361d84b
KY
14044};
14045
14046static int patch_alc268(struct hda_codec *codec)
14047{
14048 struct alc_spec *spec;
14049 int board_config;
22971e3a 14050 int i, has_beep, err;
a361d84b 14051
ef86f581 14052 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14053 if (spec == NULL)
14054 return -ENOMEM;
14055
14056 codec->spec = spec;
14057
14058 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14059 alc268_models,
14060 alc268_cfg_tbl);
14061
3abf2f36
TI
14062 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14063 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14064 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14065
a361d84b 14066 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14067 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14068 codec->chip_name);
a361d84b
KY
14069 board_config = ALC268_AUTO;
14070 }
14071
14072 if (board_config == ALC268_AUTO) {
14073 /* automatic parse from the BIOS config */
14074 err = alc268_parse_auto_config(codec);
14075 if (err < 0) {
14076 alc_free(codec);
14077 return err;
14078 } else if (!err) {
14079 printk(KERN_INFO
14080 "hda_codec: Cannot set up configuration "
14081 "from BIOS. Using base mode...\n");
14082 board_config = ALC268_3ST;
14083 }
14084 }
14085
14086 if (board_config != ALC268_AUTO)
e9c364c0 14087 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14088
a361d84b
KY
14089 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14090 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14091 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14092
a361d84b
KY
14093 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14094
22971e3a
TI
14095 has_beep = 0;
14096 for (i = 0; i < spec->num_mixers; i++) {
14097 if (spec->mixers[i] == alc268_beep_mixer) {
14098 has_beep = 1;
14099 break;
14100 }
14101 }
14102
14103 if (has_beep) {
14104 err = snd_hda_attach_beep_device(codec, 0x1);
14105 if (err < 0) {
14106 alc_free(codec);
14107 return err;
14108 }
14109 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14110 /* override the amp caps for beep generator */
14111 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14112 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14113 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14114 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14115 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14116 }
aef9d318 14117
7e0e44d4 14118 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14119 /* check whether NID 0x07 is valid */
14120 unsigned int wcap = get_wcaps(codec, 0x07);
14121
defb5ab2 14122 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14123 /* get type */
a22d543a 14124 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14125 if (spec->auto_mic ||
14126 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14127 spec->adc_nids = alc268_adc_nids_alt;
14128 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14129 if (spec->auto_mic)
14130 fixup_automic_adc(codec);
fdbc6626
TI
14131 if (spec->auto_mic || spec->input_mux->num_items == 1)
14132 add_mixer(spec, alc268_capture_nosrc_mixer);
14133 else
14134 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14135 } else {
14136 spec->adc_nids = alc268_adc_nids;
14137 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14138 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14139 }
14140 }
2134ea4f
TI
14141
14142 spec->vmaster_nid = 0x02;
14143
a361d84b
KY
14144 codec->patch_ops = alc_patch_ops;
14145 if (board_config == ALC268_AUTO)
14146 spec->init_hook = alc268_auto_init;
1c716153 14147 spec->shutup = alc_eapd_shutup;
ea1fb29a 14148
bf1b0225
KY
14149 alc_init_jacks(codec);
14150
a361d84b
KY
14151 return 0;
14152}
14153
f6a92248
KY
14154/*
14155 * ALC269 channel source setting (2 channel)
14156 */
14157#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14158
14159#define alc269_dac_nids alc260_dac_nids
14160
4c6d72d1 14161static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14162 /* ADC1 */
f53281e6
KY
14163 0x08,
14164};
14165
4c6d72d1 14166static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14167 0x23,
14168};
14169
4c6d72d1 14170static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14171 /* ADC1 */
14172 0x09,
14173};
14174
4c6d72d1 14175static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14176 0x22,
14177};
14178
4c6d72d1 14179static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14180 0x08, 0x09, 0x07, 0x11,
6694635d 14181};
e01bf509 14182
f6a92248
KY
14183#define alc269_modes alc260_modes
14184#define alc269_capture_source alc880_lg_lw_capture_source
14185
a9111321 14186static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14188 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14199 { } /* end */
14200};
14201
a9111321 14202static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14203 /* output mixer control */
14204 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14205 {
14206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14207 .name = "Master Playback Switch",
5e26dfd0 14208 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14209 .info = snd_hda_mixer_amp_switch_info,
14210 .get = snd_hda_mixer_amp_switch_get,
14211 .put = alc268_acer_master_sw_put,
14212 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14213 },
14214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14217 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14218 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14219 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14220 { }
14221};
14222
a9111321 14223static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14224 /* output mixer control */
14225 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14226 {
14227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14228 .name = "Master Playback Switch",
5e26dfd0 14229 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14230 .info = snd_hda_mixer_amp_switch_info,
14231 .get = snd_hda_mixer_amp_switch_get,
14232 .put = alc268_acer_master_sw_put,
14233 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14234 },
14235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14238 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14239 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14240 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14241 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14242 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14243 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14244 { }
14245};
14246
a9111321 14247static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14249 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14252 { } /* end */
14253};
14254
a9111321 14255static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14256 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14260 { } /* end */
14261};
14262
a9111321 14263static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14264 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14265 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14266 { } /* end */
14267};
14268
f53281e6 14269/* capture mixer elements */
a9111321 14270static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14271 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14272 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14275 { } /* end */
14276};
14277
a9111321 14278static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14279 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14280 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14282 { } /* end */
14283};
14284
a9111321 14285static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14286 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14287 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14290 { } /* end */
14291};
14292
a9111321 14293static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14297 { } /* end */
14298};
14299
26f5df26 14300/* FSC amilo */
84898e87 14301#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14302
a9111321 14303static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14304 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14309 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14310 { }
14311};
f6a92248 14312
a9111321 14313static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14315 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14316 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14321 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14322 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14323 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14324 { }
14325};
14326
60db6b53
KY
14327/* toggle speaker-output according to the hp-jack state */
14328static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14329{
3b8510ce 14330 alc_hp_automute(codec);
f6a92248 14331
60db6b53
KY
14332 snd_hda_codec_write(codec, 0x20, 0,
14333 AC_VERB_SET_COEF_INDEX, 0x0c);
14334 snd_hda_codec_write(codec, 0x20, 0,
14335 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14336
60db6b53
KY
14337 snd_hda_codec_write(codec, 0x20, 0,
14338 AC_VERB_SET_COEF_INDEX, 0x0c);
14339 snd_hda_codec_write(codec, 0x20, 0,
14340 AC_VERB_SET_PROC_COEF, 0x480);
14341}
f6a92248 14342
3b8510ce
TI
14343#define alc269_lifebook_speaker_automute \
14344 alc269_quanta_fl1_speaker_automute
64154835 14345
64154835
TV
14346static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14347{
14348 unsigned int present_laptop;
14349 unsigned int present_dock;
14350
864f92be
WF
14351 present_laptop = snd_hda_jack_detect(codec, 0x18);
14352 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14353
14354 /* Laptop mic port overrides dock mic port, design decision */
14355 if (present_dock)
14356 snd_hda_codec_write(codec, 0x23, 0,
14357 AC_VERB_SET_CONNECT_SEL, 0x3);
14358 if (present_laptop)
14359 snd_hda_codec_write(codec, 0x23, 0,
14360 AC_VERB_SET_CONNECT_SEL, 0x0);
14361 if (!present_dock && !present_laptop)
14362 snd_hda_codec_write(codec, 0x23, 0,
14363 AC_VERB_SET_CONNECT_SEL, 0x1);
14364}
14365
60db6b53
KY
14366static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14367 unsigned int res)
14368{
4f5d1706
TI
14369 switch (res >> 26) {
14370 case ALC880_HP_EVENT:
60db6b53 14371 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14372 break;
14373 case ALC880_MIC_EVENT:
14374 alc_mic_automute(codec);
14375 break;
14376 }
60db6b53 14377}
f6a92248 14378
64154835
TV
14379static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14380 unsigned int res)
14381{
14382 if ((res >> 26) == ALC880_HP_EVENT)
14383 alc269_lifebook_speaker_automute(codec);
14384 if ((res >> 26) == ALC880_MIC_EVENT)
14385 alc269_lifebook_mic_autoswitch(codec);
14386}
14387
4f5d1706
TI
14388static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14389{
14390 struct alc_spec *spec = codec->spec;
20645d70
TI
14391 spec->autocfg.hp_pins[0] = 0x15;
14392 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14393 spec->automute_mixer_nid[0] = 0x0c;
14394 spec->automute = 1;
14395 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14396 spec->ext_mic.pin = 0x18;
14397 spec->ext_mic.mux_idx = 0;
14398 spec->int_mic.pin = 0x19;
14399 spec->int_mic.mux_idx = 1;
14400 spec->auto_mic = 1;
14401}
14402
60db6b53
KY
14403static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14404{
14405 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14406 alc_mic_automute(codec);
60db6b53 14407}
f6a92248 14408
3b8510ce
TI
14409static void alc269_lifebook_setup(struct hda_codec *codec)
14410{
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.hp_pins[1] = 0x1a;
14414 spec->autocfg.speaker_pins[0] = 0x14;
14415 spec->automute_mixer_nid[0] = 0x0c;
14416 spec->automute = 1;
14417 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14418}
14419
64154835
TV
14420static void alc269_lifebook_init_hook(struct hda_codec *codec)
14421{
14422 alc269_lifebook_speaker_automute(codec);
14423 alc269_lifebook_mic_autoswitch(codec);
14424}
14425
a9111321 14426static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14428 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14433 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14434 {}
14435};
14436
a9111321 14437static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14439 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14442 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14444 {}
14445};
14446
a9111321 14447static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14449 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14450 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14453 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14455 {}
14456};
14457
a9111321 14458static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14460 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14463 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14466 {}
14467};
14468
a9111321 14469static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14470 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14471 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14475 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14476 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14478 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14479 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14480 { }
14481};
14482
226b1ec8 14483static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14484{
4f5d1706 14485 struct alc_spec *spec = codec->spec;
20645d70
TI
14486 spec->autocfg.hp_pins[0] = 0x15;
14487 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14491 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14493 spec->int_mic.pin = 0x19;
14494 spec->int_mic.mux_idx = 1;
4f5d1706 14495 spec->auto_mic = 1;
f53281e6
KY
14496}
14497
226b1ec8 14498static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14499{
14500 struct alc_spec *spec = codec->spec;
20645d70
TI
14501 spec->autocfg.hp_pins[0] = 0x15;
14502 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14503 spec->automute_mixer_nid[0] = 0x0c;
14504 spec->automute = 1;
14505 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14506 spec->ext_mic.pin = 0x18;
14507 spec->ext_mic.mux_idx = 0;
14508 spec->int_mic.pin = 0x12;
226b1ec8 14509 spec->int_mic.mux_idx = 5;
84898e87
KY
14510 spec->auto_mic = 1;
14511}
14512
226b1ec8 14513static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14514{
4f5d1706 14515 struct alc_spec *spec = codec->spec;
226b1ec8 14516 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14517 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14518 spec->automute_mixer_nid[0] = 0x0c;
14519 spec->automute = 1;
14520 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14521 spec->ext_mic.pin = 0x18;
14522 spec->ext_mic.mux_idx = 0;
14523 spec->int_mic.pin = 0x19;
14524 spec->int_mic.mux_idx = 1;
14525 spec->auto_mic = 1;
f53281e6
KY
14526}
14527
226b1ec8
KY
14528static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14529{
14530 struct alc_spec *spec = codec->spec;
14531 spec->autocfg.hp_pins[0] = 0x21;
14532 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14533 spec->automute_mixer_nid[0] = 0x0c;
14534 spec->automute = 1;
14535 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14536 spec->ext_mic.pin = 0x18;
14537 spec->ext_mic.mux_idx = 0;
14538 spec->int_mic.pin = 0x12;
14539 spec->int_mic.mux_idx = 6;
14540 spec->auto_mic = 1;
14541}
14542
60db6b53
KY
14543/*
14544 * generic initialization of ADC, input mixers and output mixers
14545 */
a9111321 14546static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14547 /*
14548 * Unmute ADC0 and set the default input to mic-in
14549 */
84898e87 14550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14551
14552 /*
84898e87 14553 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14554 */
14555 /* set vol=0 to output mixers */
14556 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14557 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558
14559 /* set up input amps for analog loopback */
14560 /* Amp Indices: DAC = 0, mixer = 1 */
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567
14568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14572 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575
14576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14578
84898e87
KY
14579 /* FIXME: use Mux-type input source selection */
14580 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14581 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14582 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14583
84898e87
KY
14584 /* set EAPD */
14585 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14586 { }
14587};
14588
a9111321 14589static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14590 /*
14591 * Unmute ADC0 and set the default input to mic-in
14592 */
14593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14594
14595 /*
14596 * Set up output mixers (0x02 - 0x03)
14597 */
14598 /* set vol=0 to output mixers */
14599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14600 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601
14602 /* set up input amps for analog loopback */
14603 /* Amp Indices: DAC = 0, mixer = 1 */
14604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610
14611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14612 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14613 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618
14619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14620 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621
14622 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14623 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14624 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14625 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14626
14627 /* set EAPD */
14628 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14629 { }
14630};
14631
9d0b71b1
TI
14632#define alc269_auto_create_multi_out_ctls \
14633 alc268_auto_create_multi_out_ctls
05f5f477
TI
14634#define alc269_auto_create_input_ctls \
14635 alc268_auto_create_input_ctls
f6a92248
KY
14636
14637#ifdef CONFIG_SND_HDA_POWER_SAVE
14638#define alc269_loopbacks alc880_loopbacks
14639#endif
14640
def319f9 14641/* pcm configuration: identical with ALC880 */
f6a92248
KY
14642#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14643#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14644#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14645#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14646
a9111321 14647static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14648 .substreams = 1,
14649 .channels_min = 2,
14650 .channels_max = 8,
14651 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14652 /* NID is set in alc_build_pcms */
14653 .ops = {
14654 .open = alc880_playback_pcm_open,
14655 .prepare = alc880_playback_pcm_prepare,
14656 .cleanup = alc880_playback_pcm_cleanup
14657 },
14658};
14659
a9111321 14660static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14661 .substreams = 1,
14662 .channels_min = 2,
14663 .channels_max = 2,
14664 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14665 /* NID is set in alc_build_pcms */
14666};
14667
ad35879a
TI
14668#ifdef CONFIG_SND_HDA_POWER_SAVE
14669static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14670{
14671 switch (codec->subsystem_id) {
14672 case 0x103c1586:
14673 return 1;
14674 }
14675 return 0;
14676}
14677
14678static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14679{
14680 /* update mute-LED according to the speaker mute state */
14681 if (nid == 0x01 || nid == 0x14) {
14682 int pinval;
14683 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14684 HDA_AMP_MUTE)
14685 pinval = 0x24;
14686 else
14687 pinval = 0x20;
14688 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14689 snd_hda_codec_update_cache(codec, 0x19, 0,
14690 AC_VERB_SET_PIN_WIDGET_CONTROL,
14691 pinval);
ad35879a
TI
14692 }
14693 return alc_check_power_status(codec, nid);
14694}
14695#endif /* CONFIG_SND_HDA_POWER_SAVE */
14696
840b64c0
TI
14697static int alc275_setup_dual_adc(struct hda_codec *codec)
14698{
14699 struct alc_spec *spec = codec->spec;
14700
14701 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14702 return 0;
14703 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14704 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14705 if (spec->ext_mic.pin <= 0x12) {
14706 spec->private_adc_nids[0] = 0x08;
14707 spec->private_adc_nids[1] = 0x11;
14708 spec->private_capsrc_nids[0] = 0x23;
14709 spec->private_capsrc_nids[1] = 0x22;
14710 } else {
14711 spec->private_adc_nids[0] = 0x11;
14712 spec->private_adc_nids[1] = 0x08;
14713 spec->private_capsrc_nids[0] = 0x22;
14714 spec->private_capsrc_nids[1] = 0x23;
14715 }
14716 spec->adc_nids = spec->private_adc_nids;
14717 spec->capsrc_nids = spec->private_capsrc_nids;
14718 spec->num_adc_nids = 2;
14719 spec->dual_adc_switch = 1;
14720 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14721 spec->adc_nids[0], spec->adc_nids[1]);
14722 return 1;
14723 }
14724 return 0;
14725}
14726
d433a678
TI
14727/* different alc269-variants */
14728enum {
14729 ALC269_TYPE_NORMAL,
48c88e82 14730 ALC269_TYPE_ALC258,
d433a678 14731 ALC269_TYPE_ALC259,
48c88e82
KY
14732 ALC269_TYPE_ALC269VB,
14733 ALC269_TYPE_ALC270,
d433a678
TI
14734 ALC269_TYPE_ALC271X,
14735};
14736
f6a92248
KY
14737/*
14738 * BIOS auto configuration
14739 */
14740static int alc269_parse_auto_config(struct hda_codec *codec)
14741{
14742 struct alc_spec *spec = codec->spec;
cfb9fb55 14743 int err;
4c6d72d1 14744 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14745
14746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14747 alc269_ignore);
14748 if (err < 0)
14749 return err;
14750
14751 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14752 if (err < 0)
14753 return err;
f3550d1b
TI
14754 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14755 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14756 else
14757 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14758 0x22, 0);
f6a92248
KY
14759 if (err < 0)
14760 return err;
14761
14762 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14763
757899ac 14764 alc_auto_parse_digital(codec);
f6a92248 14765
603c4019 14766 if (spec->kctls.list)
d88897ea 14767 add_mixer(spec, spec->kctls.list);
f6a92248 14768
d433a678 14769 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14770 add_verb(spec, alc269vb_init_verbs);
6227cdce 14771 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14772 } else {
14773 add_verb(spec, alc269_init_verbs);
6227cdce 14774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14775 }
14776
f6a92248 14777 spec->num_mux_defs = 1;
61b9b9b1 14778 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14779
14780 if (!alc275_setup_dual_adc(codec))
14781 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14782 sizeof(alc269_adc_candidates));
6694635d 14783
f6a92248
KY
14784 err = alc_auto_add_mic_boost(codec);
14785 if (err < 0)
14786 return err;
14787
7e0e44d4 14788 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14789 set_capture_mixer(codec);
f53281e6 14790
f6a92248
KY
14791 return 1;
14792}
14793
e9af4f36
TI
14794#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14795#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14796#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14797#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14798
14799
14800/* init callback for auto-configuration model -- overriding the default init */
14801static void alc269_auto_init(struct hda_codec *codec)
14802{
f6c7e546 14803 struct alc_spec *spec = codec->spec;
f6a92248
KY
14804 alc269_auto_init_multi_out(codec);
14805 alc269_auto_init_hp_out(codec);
14806 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14807 if (!spec->dual_adc_switch)
14808 alc269_auto_init_input_src(codec);
757899ac 14809 alc_auto_init_digital(codec);
f6c7e546 14810 if (spec->unsol_event)
7fb0d78f 14811 alc_inithook(codec);
f6a92248
KY
14812}
14813
0ec33d1f
TI
14814static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14815{
14816 int val = alc_read_coef_idx(codec, 0x04);
14817 if (power_up)
14818 val |= 1 << 11;
14819 else
14820 val &= ~(1 << 11);
14821 alc_write_coef_idx(codec, 0x04, val);
14822}
14823
5402e4cb 14824static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14825{
0ec33d1f
TI
14826 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14827 alc269_toggle_power_output(codec, 0);
977ddd6b 14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14829 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14830 msleep(150);
14831 }
977ddd6b 14832}
0ec33d1f 14833
5402e4cb 14834#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14835static int alc269_resume(struct hda_codec *codec)
14836{
977ddd6b 14837 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14838 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14839 msleep(150);
14840 }
14841
14842 codec->patch_ops.init(codec);
14843
14844 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14845 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14846 msleep(200);
14847 }
14848
0ec33d1f
TI
14849 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14850 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14851
14852 snd_hda_codec_resume_amp(codec);
14853 snd_hda_codec_resume_cache(codec);
9e5341b9 14854 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14855 return 0;
14856}
0ec33d1f 14857#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14858
1a99d4a4 14859static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14860 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14861{
14862 int coef;
14863
58701120 14864 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14865 return;
1a99d4a4
KY
14866 coef = alc_read_coef_idx(codec, 0x1e);
14867 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14868}
14869
6981d184
TI
14870static void alc271_fixup_dmic(struct hda_codec *codec,
14871 const struct alc_fixup *fix, int action)
14872{
a9111321 14873 static const struct hda_verb verbs[] = {
6981d184
TI
14874 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14875 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14876 {}
14877 };
14878 unsigned int cfg;
14879
14880 if (strcmp(codec->chip_name, "ALC271X"))
14881 return;
14882 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14883 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14884 snd_hda_sequence_write(codec, verbs);
14885}
14886
ff818c24
TI
14887enum {
14888 ALC269_FIXUP_SONY_VAIO,
74dc8909 14889 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14890 ALC269_FIXUP_DELL_M101Z,
022c92be 14891 ALC269_FIXUP_SKU_IGNORE,
ac612407 14892 ALC269_FIXUP_ASUS_G73JW,
357f915e 14893 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14894 ALC275_FIXUP_SONY_HWEQ,
6981d184 14895 ALC271_FIXUP_DMIC,
ff818c24
TI
14896};
14897
ff818c24
TI
14898static const struct alc_fixup alc269_fixups[] = {
14899 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14900 .type = ALC_FIXUP_VERBS,
14901 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14903 {}
14904 }
ff818c24 14905 },
74dc8909 14906 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14907 .type = ALC_FIXUP_VERBS,
14908 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14909 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14911 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14912 { }
b5bfbc67
TI
14913 },
14914 .chained = true,
14915 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14916 },
145a902b 14917 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14918 .type = ALC_FIXUP_VERBS,
14919 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14920 /* Enables internal speaker */
14921 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14922 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14923 {}
14924 }
14925 },
022c92be 14926 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14927 .type = ALC_FIXUP_SKU,
14928 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14929 },
ac612407 14930 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14931 .type = ALC_FIXUP_PINS,
14932 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14933 { 0x17, 0x99130111 }, /* subwoofer */
14934 { }
14935 }
14936 },
357f915e 14937 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14938 .type = ALC_FIXUP_VERBS,
14939 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14940 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14941 {}
14942 }
14943 },
1a99d4a4 14944 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14945 .type = ALC_FIXUP_FUNC,
14946 .v.func = alc269_fixup_hweq,
14947 .chained = true,
14948 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14949 },
14950 [ALC271_FIXUP_DMIC] = {
14951 .type = ALC_FIXUP_FUNC,
14952 .v.func = alc271_fixup_dmic,
14953 },
ff818c24
TI
14954};
14955
a9111321 14956static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14957 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14958 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14959 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14960 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14961 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14962 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14963 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14964 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14965 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14968 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14969 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14970 {}
14971};
14972
14973
f6a92248
KY
14974/*
14975 * configuration and preset
14976 */
ea734963 14977static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14978 [ALC269_BASIC] = "basic",
2922c9af 14979 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14980 [ALC269_AMIC] = "laptop-amic",
14981 [ALC269_DMIC] = "laptop-dmic",
64154835 14982 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14983 [ALC269_LIFEBOOK] = "lifebook",
14984 [ALC269_AUTO] = "auto",
f6a92248
KY
14985};
14986
a9111321 14987static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14988 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14989 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14990 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14991 ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 15001 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
15002 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15028 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15029 ALC269_DMIC),
60db6b53 15030 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15031 ALC269_DMIC),
15032 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15033 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15034 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15035 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15036 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15037 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15038 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15041 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15042 {}
15043};
15044
a9111321 15045static const struct alc_config_preset alc269_presets[] = {
f6a92248 15046 [ALC269_BASIC] = {
f9e336f6 15047 .mixers = { alc269_base_mixer },
f6a92248
KY
15048 .init_verbs = { alc269_init_verbs },
15049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15050 .dac_nids = alc269_dac_nids,
15051 .hp_nid = 0x03,
15052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15053 .channel_mode = alc269_modes,
15054 .input_mux = &alc269_capture_source,
15055 },
60db6b53
KY
15056 [ALC269_QUANTA_FL1] = {
15057 .mixers = { alc269_quanta_fl1_mixer },
15058 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15060 .dac_nids = alc269_dac_nids,
15061 .hp_nid = 0x03,
15062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15063 .channel_mode = alc269_modes,
15064 .input_mux = &alc269_capture_source,
15065 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15066 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15067 .init_hook = alc269_quanta_fl1_init_hook,
15068 },
84898e87
KY
15069 [ALC269_AMIC] = {
15070 .mixers = { alc269_laptop_mixer },
15071 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15072 .init_verbs = { alc269_init_verbs,
84898e87 15073 alc269_laptop_amic_init_verbs },
f53281e6
KY
15074 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15075 .dac_nids = alc269_dac_nids,
15076 .hp_nid = 0x03,
15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15078 .channel_mode = alc269_modes,
3b8510ce 15079 .unsol_event = alc_sku_unsol_event,
84898e87 15080 .setup = alc269_laptop_amic_setup,
3b8510ce 15081 .init_hook = alc_inithook,
f53281e6 15082 },
84898e87
KY
15083 [ALC269_DMIC] = {
15084 .mixers = { alc269_laptop_mixer },
15085 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15086 .init_verbs = { alc269_init_verbs,
84898e87
KY
15087 alc269_laptop_dmic_init_verbs },
15088 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089 .dac_nids = alc269_dac_nids,
15090 .hp_nid = 0x03,
15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092 .channel_mode = alc269_modes,
3b8510ce 15093 .unsol_event = alc_sku_unsol_event,
84898e87 15094 .setup = alc269_laptop_dmic_setup,
3b8510ce 15095 .init_hook = alc_inithook,
84898e87
KY
15096 },
15097 [ALC269VB_AMIC] = {
15098 .mixers = { alc269vb_laptop_mixer },
15099 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15100 .init_verbs = { alc269vb_init_verbs,
15101 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15102 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103 .dac_nids = alc269_dac_nids,
15104 .hp_nid = 0x03,
15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106 .channel_mode = alc269_modes,
3b8510ce 15107 .unsol_event = alc_sku_unsol_event,
226b1ec8 15108 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15109 .init_hook = alc_inithook,
84898e87
KY
15110 },
15111 [ALC269VB_DMIC] = {
15112 .mixers = { alc269vb_laptop_mixer },
15113 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15114 .init_verbs = { alc269vb_init_verbs,
15115 alc269vb_laptop_dmic_init_verbs },
15116 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117 .dac_nids = alc269_dac_nids,
15118 .hp_nid = 0x03,
15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120 .channel_mode = alc269_modes,
3b8510ce 15121 .unsol_event = alc_sku_unsol_event,
84898e87 15122 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15123 .init_hook = alc_inithook,
f53281e6 15124 },
26f5df26 15125 [ALC269_FUJITSU] = {
45bdd1c1 15126 .mixers = { alc269_fujitsu_mixer },
84898e87 15127 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15128 .init_verbs = { alc269_init_verbs,
84898e87 15129 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15130 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131 .dac_nids = alc269_dac_nids,
15132 .hp_nid = 0x03,
15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134 .channel_mode = alc269_modes,
3b8510ce 15135 .unsol_event = alc_sku_unsol_event,
84898e87 15136 .setup = alc269_laptop_dmic_setup,
3b8510ce 15137 .init_hook = alc_inithook,
26f5df26 15138 },
64154835
TV
15139 [ALC269_LIFEBOOK] = {
15140 .mixers = { alc269_lifebook_mixer },
15141 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15142 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15143 .dac_nids = alc269_dac_nids,
15144 .hp_nid = 0x03,
15145 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15146 .channel_mode = alc269_modes,
15147 .input_mux = &alc269_capture_source,
15148 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15149 .setup = alc269_lifebook_setup,
64154835
TV
15150 .init_hook = alc269_lifebook_init_hook,
15151 },
fe3eb0a7
KY
15152 [ALC271_ACER] = {
15153 .mixers = { alc269_asus_mixer },
15154 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15155 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157 .dac_nids = alc269_dac_nids,
15158 .adc_nids = alc262_dmic_adc_nids,
15159 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15160 .capsrc_nids = alc262_dmic_capsrc_nids,
15161 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15162 .channel_mode = alc269_modes,
15163 .input_mux = &alc269_capture_source,
15164 .dig_out_nid = ALC880_DIGOUT_NID,
15165 .unsol_event = alc_sku_unsol_event,
15166 .setup = alc269vb_laptop_dmic_setup,
15167 .init_hook = alc_inithook,
15168 },
f6a92248
KY
15169};
15170
977ddd6b
KY
15171static int alc269_fill_coef(struct hda_codec *codec)
15172{
15173 int val;
15174
15175 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15176 alc_write_coef_idx(codec, 0xf, 0x960b);
15177 alc_write_coef_idx(codec, 0xe, 0x8817);
15178 }
15179
15180 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15181 alc_write_coef_idx(codec, 0xf, 0x960b);
15182 alc_write_coef_idx(codec, 0xe, 0x8814);
15183 }
15184
15185 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15186 val = alc_read_coef_idx(codec, 0x04);
15187 /* Power up output pin */
15188 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15189 }
15190
15191 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15192 val = alc_read_coef_idx(codec, 0xd);
15193 if ((val & 0x0c00) >> 10 != 0x1) {
15194 /* Capless ramp up clock control */
b896b4eb 15195 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
15196 }
15197 val = alc_read_coef_idx(codec, 0x17);
15198 if ((val & 0x01c0) >> 6 != 0x4) {
15199 /* Class D power on reset */
b896b4eb 15200 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
15201 }
15202 }
b896b4eb
KY
15203
15204 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15205 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15206
15207 val = alc_read_coef_idx(codec, 0x4); /* HP */
15208 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15209
977ddd6b
KY
15210 return 0;
15211}
15212
f6a92248
KY
15213static int patch_alc269(struct hda_codec *codec)
15214{
15215 struct alc_spec *spec;
48c88e82 15216 int board_config, coef;
f6a92248
KY
15217 int err;
15218
15219 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15220 if (spec == NULL)
15221 return -ENOMEM;
15222
15223 codec->spec = spec;
15224
da00c244
KY
15225 alc_auto_parse_customize_define(codec);
15226
c793bec5
KY
15227 if (codec->vendor_id == 0x10ec0269) {
15228 coef = alc_read_coef_idx(codec, 0);
15229 if ((coef & 0x00f0) == 0x0010) {
15230 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15231 spec->cdefine.platform_type == 1) {
15232 alc_codec_rename(codec, "ALC271X");
15233 spec->codec_variant = ALC269_TYPE_ALC271X;
15234 } else if ((coef & 0xf000) == 0x1000) {
15235 spec->codec_variant = ALC269_TYPE_ALC270;
15236 } else if ((coef & 0xf000) == 0x2000) {
15237 alc_codec_rename(codec, "ALC259");
15238 spec->codec_variant = ALC269_TYPE_ALC259;
15239 } else if ((coef & 0xf000) == 0x3000) {
15240 alc_codec_rename(codec, "ALC258");
15241 spec->codec_variant = ALC269_TYPE_ALC258;
15242 } else {
15243 alc_codec_rename(codec, "ALC269VB");
15244 spec->codec_variant = ALC269_TYPE_ALC269VB;
15245 }
15246 } else
15247 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15248 alc269_fill_coef(codec);
15249 }
977ddd6b 15250
f6a92248
KY
15251 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15252 alc269_models,
15253 alc269_cfg_tbl);
15254
15255 if (board_config < 0) {
9a11f1aa
TI
15256 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15257 codec->chip_name);
f6a92248
KY
15258 board_config = ALC269_AUTO;
15259 }
15260
b5bfbc67
TI
15261 if (board_config == ALC269_AUTO) {
15262 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15263 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15264 }
ff818c24 15265
f6a92248
KY
15266 if (board_config == ALC269_AUTO) {
15267 /* automatic parse from the BIOS config */
15268 err = alc269_parse_auto_config(codec);
15269 if (err < 0) {
15270 alc_free(codec);
15271 return err;
15272 } else if (!err) {
15273 printk(KERN_INFO
15274 "hda_codec: Cannot set up configuration "
15275 "from BIOS. Using base mode...\n");
15276 board_config = ALC269_BASIC;
15277 }
15278 }
15279
dc1eae25 15280 if (has_cdefine_beep(codec)) {
8af2591d
TI
15281 err = snd_hda_attach_beep_device(codec, 0x1);
15282 if (err < 0) {
15283 alc_free(codec);
15284 return err;
15285 }
680cd536
KK
15286 }
15287
f6a92248 15288 if (board_config != ALC269_AUTO)
e9c364c0 15289 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15290
84898e87 15291 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15292 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15293 * fix the sample rate of analog I/O to 44.1kHz
15294 */
15295 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15296 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15297 } else if (spec->dual_adc_switch) {
15298 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15299 /* switch ADC dynamically */
15300 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15301 } else {
15302 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15303 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15304 }
f6a92248
KY
15305 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15306 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15307
6694635d 15308 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15309 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15310 spec->adc_nids = alc269_adc_nids;
15311 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15312 spec->capsrc_nids = alc269_capsrc_nids;
15313 } else {
15314 spec->adc_nids = alc269vb_adc_nids;
15315 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15316 spec->capsrc_nids = alc269vb_capsrc_nids;
15317 }
84898e87
KY
15318 }
15319
f9e336f6 15320 if (!spec->cap_mixer)
b59bdf3b 15321 set_capture_mixer(codec);
dc1eae25 15322 if (has_cdefine_beep(codec))
da00c244 15323 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15324
b5bfbc67 15325 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15326
100d5eb3
TI
15327 spec->vmaster_nid = 0x02;
15328
f6a92248 15329 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15330#ifdef SND_HDA_NEEDS_RESUME
15331 codec->patch_ops.resume = alc269_resume;
15332#endif
f6a92248
KY
15333 if (board_config == ALC269_AUTO)
15334 spec->init_hook = alc269_auto_init;
5402e4cb 15335 spec->shutup = alc269_shutup;
bf1b0225
KY
15336
15337 alc_init_jacks(codec);
f6a92248
KY
15338#ifdef CONFIG_SND_HDA_POWER_SAVE
15339 if (!spec->loopback.amplist)
15340 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15341 if (alc269_mic2_for_mute_led(codec))
15342 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15343#endif
15344
15345 return 0;
15346}
15347
df694daa
KY
15348/*
15349 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15350 */
15351
15352/*
15353 * set the path ways for 2 channel output
15354 * need to set the codec line out and mic 1 pin widgets to inputs
15355 */
a9111321 15356static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15357 /* set pin widget 1Ah (line in) for input */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15359 /* set pin widget 18h (mic1/2) for input, for mic also enable
15360 * the vref
15361 */
df694daa
KY
15362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15363
9c7f852e
TI
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15365#if 0
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15368#endif
df694daa
KY
15369 { } /* end */
15370};
15371/*
15372 * 6ch mode
15373 * need to set the codec line out and mic 1 pin widgets to outputs
15374 */
a9111321 15375static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15376 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15377 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15378 /* set pin widget 18h (mic1) for output (CLFE)*/
15379 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15380
15381 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15382 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15383
9c7f852e
TI
15384 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15385#if 0
15386 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15388#endif
df694daa
KY
15389 { } /* end */
15390};
15391
a9111321 15392static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15393 { 2, alc861_threestack_ch2_init },
15394 { 6, alc861_threestack_ch6_init },
15395};
22309c3e 15396/* Set mic1 as input and unmute the mixer */
a9111321 15397static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15400 { } /* end */
15401};
15402/* Set mic1 as output and mute mixer */
a9111321 15403static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15405 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15406 { } /* end */
15407};
15408
a9111321 15409static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15410 { 2, alc861_uniwill_m31_ch2_init },
15411 { 4, alc861_uniwill_m31_ch4_init },
15412};
df694daa 15413
7cdbff94 15414/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15415static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15416 /* set pin widget 1Ah (line in) for input */
15417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15418 /* set pin widget 18h (mic1/2) for input, for mic also enable
15419 * the vref
15420 */
7cdbff94
MD
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422
15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15424#if 0
15425 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15427#endif
15428 { } /* end */
15429};
15430/* Set mic1 nad line-in as output and mute mixer */
a9111321 15431static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15432 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15433 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15434 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15435 /* set pin widget 18h (mic1) for output (CLFE)*/
15436 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15437 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15438 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15439 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15440
15441 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15442#if 0
15443 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15444 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15445#endif
15446 { } /* end */
15447};
15448
a9111321 15449static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15450 { 2, alc861_asus_ch2_init },
15451 { 6, alc861_asus_ch6_init },
15452};
15453
df694daa
KY
15454/* patch-ALC861 */
15455
a9111321 15456static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15463
15464 /*Input mixer control */
15465 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15466 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15467 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15468 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15470 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15475
df694daa
KY
15476 { } /* end */
15477};
15478
a9111321 15479static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15480 /* output mixer control */
15481 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15485 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15486
15487 /* Input mixer control */
15488 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15490 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15491 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15493 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15495 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15498
df694daa
KY
15499 {
15500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15501 .name = "Channel Mode",
15502 .info = alc_ch_mode_info,
15503 .get = alc_ch_mode_get,
15504 .put = alc_ch_mode_put,
15505 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15506 },
15507 { } /* end */
a53d1aec
TD
15508};
15509
a9111321 15510static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15511 /* output mixer control */
15512 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15515
a53d1aec 15516 { } /* end */
f12ab1e0 15517};
a53d1aec 15518
a9111321 15519static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15520 /* output mixer control */
15521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15525 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15526
15527 /* Input mixer control */
15528 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15529 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15530 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15531 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15533 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15535 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15538
22309c3e
TI
15539 {
15540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15541 .name = "Channel Mode",
15542 .info = alc_ch_mode_info,
15543 .get = alc_ch_mode_get,
15544 .put = alc_ch_mode_put,
15545 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15546 },
15547 { } /* end */
f12ab1e0 15548};
7cdbff94 15549
a9111321 15550static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15551 /* output mixer control */
15552 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15557
15558 /* Input mixer control */
15559 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15560 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15562 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15563 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15564 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15566 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15569
7cdbff94
MD
15570 {
15571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15572 .name = "Channel Mode",
15573 .info = alc_ch_mode_info,
15574 .get = alc_ch_mode_get,
15575 .put = alc_ch_mode_put,
15576 .private_value = ARRAY_SIZE(alc861_asus_modes),
15577 },
15578 { }
56bb0cab
TI
15579};
15580
15581/* additional mixer */
a9111321 15582static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15583 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15585 { }
15586};
7cdbff94 15587
df694daa
KY
15588/*
15589 * generic initialization of ADC, input mixers and output mixers
15590 */
a9111321 15591static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15592 /*
15593 * Unmute ADC0 and set the default input to mic-in
15594 */
15595 /* port-A for surround (rear panel) */
15596 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15597 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15598 /* port-B for mic-in (rear panel) with vref */
15599 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15600 /* port-C for line-in (rear panel) */
15601 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15602 /* port-D for Front */
15603 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15604 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15605 /* port-E for HP out (front panel) */
15606 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15607 /* route front PCM to HP */
9dece1d7 15608 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15609 /* port-F for mic-in (front panel) with vref */
15610 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15611 /* port-G for CLFE (rear panel) */
15612 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15613 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15614 /* port-H for side (rear panel) */
15615 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15616 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15617 /* CD-in */
15618 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* route front mic to ADC1*/
15620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15622
df694daa
KY
15623 /* Unmute DAC0~3 & spdif out*/
15624 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15628 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15629
df694daa
KY
15630 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15631 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15635
df694daa
KY
15636 /* Unmute Stereo Mixer 15 */
15637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15641
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15647 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15650 /* hp used DAC 3 (Front) */
15651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15653
15654 { }
15655};
15656
a9111321 15657static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15658 /*
15659 * Unmute ADC0 and set the default input to mic-in
15660 */
15661 /* port-A for surround (rear panel) */
15662 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15663 /* port-B for mic-in (rear panel) with vref */
15664 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15665 /* port-C for line-in (rear panel) */
15666 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15667 /* port-D for Front */
15668 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15669 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15670 /* port-E for HP out (front panel) */
15671 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15672 /* route front PCM to HP */
9dece1d7 15673 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15674 /* port-F for mic-in (front panel) with vref */
15675 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15676 /* port-G for CLFE (rear panel) */
15677 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15678 /* port-H for side (rear panel) */
15679 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15680 /* CD-in */
15681 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15682 /* route front mic to ADC1*/
15683 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 /* Unmute DAC0~3 & spdif out*/
15686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15691
df694daa
KY
15692 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15693 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15697
df694daa
KY
15698 /* Unmute Stereo Mixer 15 */
15699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15703
15704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15711 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15712 /* hp used DAC 3 (Front) */
15713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15715 { }
15716};
22309c3e 15717
a9111321 15718static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15719 /*
15720 * Unmute ADC0 and set the default input to mic-in
15721 */
15722 /* port-A for surround (rear panel) */
15723 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15724 /* port-B for mic-in (rear panel) with vref */
15725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15726 /* port-C for line-in (rear panel) */
15727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15728 /* port-D for Front */
15729 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15730 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15731 /* port-E for HP out (front panel) */
f12ab1e0
TI
15732 /* this has to be set to VREF80 */
15733 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15734 /* route front PCM to HP */
9dece1d7 15735 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15736 /* port-F for mic-in (front panel) with vref */
15737 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15738 /* port-G for CLFE (rear panel) */
15739 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15740 /* port-H for side (rear panel) */
15741 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15742 /* CD-in */
15743 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15744 /* route front mic to ADC1*/
15745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 /* Unmute DAC0~3 & spdif out*/
15748 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15753
22309c3e
TI
15754 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15755 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15758 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15759
22309c3e
TI
15760 /* Unmute Stereo Mixer 15 */
15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15765
15766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15774 /* hp used DAC 3 (Front) */
15775 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15777 { }
15778};
15779
a9111321 15780static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15781 /*
15782 * Unmute ADC0 and set the default input to mic-in
15783 */
f12ab1e0
TI
15784 /* port-A for surround (rear panel)
15785 * according to codec#0 this is the HP jack
15786 */
7cdbff94
MD
15787 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15788 /* route front PCM to HP */
15789 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15790 /* port-B for mic-in (rear panel) with vref */
15791 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15792 /* port-C for line-in (rear panel) */
15793 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15794 /* port-D for Front */
15795 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15796 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15797 /* port-E for HP out (front panel) */
f12ab1e0
TI
15798 /* this has to be set to VREF80 */
15799 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15800 /* route front PCM to HP */
9dece1d7 15801 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15802 /* port-F for mic-in (front panel) with vref */
15803 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15804 /* port-G for CLFE (rear panel) */
15805 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15806 /* port-H for side (rear panel) */
15807 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15808 /* CD-in */
15809 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15810 /* route front mic to ADC1*/
15811 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15812 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15813 /* Unmute DAC0~3 & spdif out*/
15814 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15816 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15824
7cdbff94
MD
15825 /* Unmute Stereo Mixer 15 */
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15830
15831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15839 /* hp used DAC 3 (Front) */
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15842 { }
15843};
15844
56bb0cab 15845/* additional init verbs for ASUS laptops */
a9111321 15846static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15847 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15848 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15849 { }
15850};
7cdbff94 15851
df694daa
KY
15852/*
15853 * generic initialization of ADC, input mixers and output mixers
15854 */
a9111321 15855static const struct hda_verb alc861_auto_init_verbs[] = {
df694daa
KY
15856 /*
15857 * Unmute ADC0 and set the default input to mic-in
15858 */
f12ab1e0 15859 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15861
df694daa
KY
15862 /* Unmute DAC0~3 & spdif out*/
15863 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15864 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15866 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15868
df694daa
KY
15869 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15870 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15871 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15872 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15873 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15874
df694daa
KY
15875 /* Unmute Stereo Mixer 15 */
15876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15880
1c20930a
TI
15881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15883 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15889
15890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15896 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15897 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15898
f12ab1e0 15899 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15900
15901 { }
15902};
15903
a9111321 15904static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15905 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15906
a53d1aec
TD
15907 { }
15908};
15909
15910/* toggle speaker-output according to the hp-jack state */
15911static void alc861_toshiba_automute(struct hda_codec *codec)
15912{
864f92be 15913 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15914
47fd830a
TI
15915 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15917 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15918 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15919}
15920
15921static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15922 unsigned int res)
15923{
a53d1aec
TD
15924 if ((res >> 26) == ALC880_HP_EVENT)
15925 alc861_toshiba_automute(codec);
15926}
15927
def319f9 15928/* pcm configuration: identical with ALC880 */
df694daa
KY
15929#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15930#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15931#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15932#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15933
15934
15935#define ALC861_DIGOUT_NID 0x07
15936
a9111321 15937static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15938 { 8, NULL }
15939};
15940
4c6d72d1 15941static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15942 /* front, surround, clfe, side */
15943 0x03, 0x06, 0x05, 0x04
15944};
15945
4c6d72d1 15946static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15947 /* front, clfe, surround */
15948 0x03, 0x05, 0x06
15949};
15950
4c6d72d1 15951static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15952 /* ADC0-2 */
15953 0x08,
15954};
15955
a9111321 15956static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15957 .num_items = 5,
15958 .items = {
15959 { "Mic", 0x0 },
15960 { "Front Mic", 0x3 },
15961 { "Line", 0x1 },
15962 { "CD", 0x4 },
15963 { "Mixer", 0x5 },
15964 },
15965};
15966
1c20930a
TI
15967static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15968{
15969 struct alc_spec *spec = codec->spec;
15970 hda_nid_t mix, srcs[5];
15971 int i, j, num;
15972
15973 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15974 return 0;
15975 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15976 if (num < 0)
15977 return 0;
15978 for (i = 0; i < num; i++) {
15979 unsigned int type;
a22d543a 15980 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15981 if (type != AC_WID_AUD_OUT)
15982 continue;
15983 for (j = 0; j < spec->multiout.num_dacs; j++)
15984 if (spec->multiout.dac_nids[j] == srcs[i])
15985 break;
15986 if (j >= spec->multiout.num_dacs)
15987 return srcs[i];
15988 }
15989 return 0;
15990}
15991
df694daa 15992/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15993static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15994 const struct auto_pin_cfg *cfg)
df694daa 15995{
1c20930a 15996 struct alc_spec *spec = codec->spec;
df694daa 15997 int i;
1c20930a 15998 hda_nid_t nid, dac;
df694daa
KY
15999
16000 spec->multiout.dac_nids = spec->private_dac_nids;
16001 for (i = 0; i < cfg->line_outs; i++) {
16002 nid = cfg->line_out_pins[i];
1c20930a
TI
16003 dac = alc861_look_for_dac(codec, nid);
16004 if (!dac)
16005 continue;
dda14410 16006 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 16007 }
df694daa
KY
16008 return 0;
16009}
16010
bcb2f0f5
TI
16011static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16012 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 16013{
bcb2f0f5 16014 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
16015 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16016}
16017
bcb2f0f5
TI
16018#define alc861_create_out_sw(codec, pfx, nid, chs) \
16019 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16020
df694daa 16021/* add playback controls from the parsed DAC table */
1c20930a 16022static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
16023 const struct auto_pin_cfg *cfg)
16024{
1c20930a 16025 struct alc_spec *spec = codec->spec;
ea734963 16026 static const char * const chname[4] = {
f12ab1e0
TI
16027 "Front", "Surround", NULL /*CLFE*/, "Side"
16028 };
ce764ab2 16029 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 16030 hda_nid_t nid;
ce764ab2 16031 int i, err, noutputs;
1c20930a 16032
ce764ab2
TI
16033 noutputs = cfg->line_outs;
16034 if (spec->multi_ios > 0)
16035 noutputs += spec->multi_ios;
16036
16037 for (i = 0; i < noutputs; i++) {
df694daa 16038 nid = spec->multiout.dac_nids[i];
f12ab1e0 16039 if (!nid)
df694daa 16040 continue;
bcb2f0f5 16041 if (!pfx && i == 2) {
df694daa 16042 /* Center/LFE */
1c20930a 16043 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16044 if (err < 0)
df694daa 16045 return err;
1c20930a 16046 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16047 if (err < 0)
df694daa
KY
16048 return err;
16049 } else {
bcb2f0f5 16050 const char *name = pfx;
5a882646
DH
16051 int index = i;
16052 if (!name) {
bcb2f0f5 16053 name = chname[i];
5a882646
DH
16054 index = 0;
16055 }
16056 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16057 if (err < 0)
df694daa
KY
16058 return err;
16059 }
16060 }
16061 return 0;
16062}
16063
1c20930a 16064static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16065{
1c20930a 16066 struct alc_spec *spec = codec->spec;
df694daa
KY
16067 int err;
16068 hda_nid_t nid;
16069
f12ab1e0 16070 if (!pin)
df694daa
KY
16071 return 0;
16072
16073 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16074 nid = alc861_look_for_dac(codec, pin);
16075 if (nid) {
16076 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16077 if (err < 0)
16078 return err;
16079 spec->multiout.hp_nid = nid;
16080 }
df694daa
KY
16081 }
16082 return 0;
16083}
16084
16085/* create playback/capture controls for input pins */
05f5f477 16086static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16087 const struct auto_pin_cfg *cfg)
df694daa 16088{
05f5f477 16089 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16090}
16091
f12ab1e0
TI
16092static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16093 hda_nid_t nid,
1c20930a 16094 int pin_type, hda_nid_t dac)
df694daa 16095{
1c20930a
TI
16096 hda_nid_t mix, srcs[5];
16097 int i, num;
16098
564c5bea
JL
16099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16100 pin_type);
1c20930a 16101 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16102 AMP_OUT_UNMUTE);
1c20930a
TI
16103 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16104 return;
16105 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16106 if (num < 0)
16107 return;
16108 for (i = 0; i < num; i++) {
16109 unsigned int mute;
16110 if (srcs[i] == dac || srcs[i] == 0x15)
16111 mute = AMP_IN_UNMUTE(i);
16112 else
16113 mute = AMP_IN_MUTE(i);
16114 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16115 mute);
16116 }
df694daa
KY
16117}
16118
16119static void alc861_auto_init_multi_out(struct hda_codec *codec)
16120{
16121 struct alc_spec *spec = codec->spec;
16122 int i;
16123
16124 for (i = 0; i < spec->autocfg.line_outs; i++) {
16125 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16126 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16127 if (nid)
baba8ee9 16128 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16129 spec->multiout.dac_nids[i]);
df694daa
KY
16130 }
16131}
16132
16133static void alc861_auto_init_hp_out(struct hda_codec *codec)
16134{
16135 struct alc_spec *spec = codec->spec;
df694daa 16136
15870f05
TI
16137 if (spec->autocfg.hp_outs)
16138 alc861_auto_set_output_and_unmute(codec,
16139 spec->autocfg.hp_pins[0],
16140 PIN_HP,
1c20930a 16141 spec->multiout.hp_nid);
15870f05
TI
16142 if (spec->autocfg.speaker_outs)
16143 alc861_auto_set_output_and_unmute(codec,
16144 spec->autocfg.speaker_pins[0],
16145 PIN_OUT,
1c20930a 16146 spec->multiout.dac_nids[0]);
df694daa
KY
16147}
16148
16149static void alc861_auto_init_analog_input(struct hda_codec *codec)
16150{
16151 struct alc_spec *spec = codec->spec;
66ceeb6b 16152 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16153 int i;
16154
66ceeb6b
TI
16155 for (i = 0; i < cfg->num_inputs; i++) {
16156 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16157 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16158 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16159 }
16160}
16161
16162/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16163/* return 1 if successful, 0 if the proper config is not found,
16164 * or a negative error code
16165 */
df694daa
KY
16166static int alc861_parse_auto_config(struct hda_codec *codec)
16167{
16168 struct alc_spec *spec = codec->spec;
16169 int err;
4c6d72d1 16170 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16171
f12ab1e0
TI
16172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16173 alc861_ignore);
16174 if (err < 0)
df694daa 16175 return err;
f12ab1e0 16176 if (!spec->autocfg.line_outs)
df694daa
KY
16177 return 0; /* can't find valid BIOS pin config */
16178
1c20930a 16179 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16180 if (err < 0)
16181 return err;
16182 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16183 if (err < 0)
16184 return err;
1c20930a 16185 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16186 if (err < 0)
16187 return err;
1c20930a 16188 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16189 if (err < 0)
16190 return err;
05f5f477 16191 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16192 if (err < 0)
df694daa
KY
16193 return err;
16194
16195 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16196
757899ac 16197 alc_auto_parse_digital(codec);
df694daa 16198
603c4019 16199 if (spec->kctls.list)
d88897ea 16200 add_mixer(spec, spec->kctls.list);
df694daa 16201
d88897ea 16202 add_verb(spec, alc861_auto_init_verbs);
df694daa 16203
a1e8d2da 16204 spec->num_mux_defs = 1;
61b9b9b1 16205 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16206
16207 spec->adc_nids = alc861_adc_nids;
16208 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16209 set_capture_mixer(codec);
df694daa 16210
6227cdce 16211 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16212
df694daa
KY
16213 return 1;
16214}
16215
ae6b813a
TI
16216/* additional initialization for auto-configuration model */
16217static void alc861_auto_init(struct hda_codec *codec)
df694daa 16218{
f6c7e546 16219 struct alc_spec *spec = codec->spec;
df694daa
KY
16220 alc861_auto_init_multi_out(codec);
16221 alc861_auto_init_hp_out(codec);
16222 alc861_auto_init_analog_input(codec);
757899ac 16223 alc_auto_init_digital(codec);
f6c7e546 16224 if (spec->unsol_event)
7fb0d78f 16225 alc_inithook(codec);
df694daa
KY
16226}
16227
cb53c626 16228#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16229static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16230 { 0x15, HDA_INPUT, 0 },
16231 { 0x15, HDA_INPUT, 1 },
16232 { 0x15, HDA_INPUT, 2 },
16233 { 0x15, HDA_INPUT, 3 },
16234 { } /* end */
16235};
16236#endif
16237
df694daa
KY
16238
16239/*
16240 * configuration and preset
16241 */
ea734963 16242static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16243 [ALC861_3ST] = "3stack",
16244 [ALC660_3ST] = "3stack-660",
16245 [ALC861_3ST_DIG] = "3stack-dig",
16246 [ALC861_6ST_DIG] = "6stack-dig",
16247 [ALC861_UNIWILL_M31] = "uniwill-m31",
16248 [ALC861_TOSHIBA] = "toshiba",
16249 [ALC861_ASUS] = "asus",
16250 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16251 [ALC861_AUTO] = "auto",
16252};
16253
a9111321 16254static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16255 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16256 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16257 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16258 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16259 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16260 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16261 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16262 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16263 * Any other models that need this preset?
16264 */
16265 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16266 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16267 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16268 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16269 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16270 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16271 /* FIXME: the below seems conflict */
16272 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16273 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16274 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16275 {}
16276};
16277
a9111321 16278static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16279 [ALC861_3ST] = {
16280 .mixers = { alc861_3ST_mixer },
16281 .init_verbs = { alc861_threestack_init_verbs },
16282 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16283 .dac_nids = alc861_dac_nids,
16284 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16285 .channel_mode = alc861_threestack_modes,
4e195a7b 16286 .need_dac_fix = 1,
df694daa
KY
16287 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16288 .adc_nids = alc861_adc_nids,
16289 .input_mux = &alc861_capture_source,
16290 },
16291 [ALC861_3ST_DIG] = {
16292 .mixers = { alc861_base_mixer },
16293 .init_verbs = { alc861_threestack_init_verbs },
16294 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16295 .dac_nids = alc861_dac_nids,
16296 .dig_out_nid = ALC861_DIGOUT_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16298 .channel_mode = alc861_threestack_modes,
4e195a7b 16299 .need_dac_fix = 1,
df694daa
KY
16300 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16301 .adc_nids = alc861_adc_nids,
16302 .input_mux = &alc861_capture_source,
16303 },
16304 [ALC861_6ST_DIG] = {
16305 .mixers = { alc861_base_mixer },
16306 .init_verbs = { alc861_base_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16308 .dac_nids = alc861_dac_nids,
16309 .dig_out_nid = ALC861_DIGOUT_NID,
16310 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16311 .channel_mode = alc861_8ch_modes,
16312 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16313 .adc_nids = alc861_adc_nids,
16314 .input_mux = &alc861_capture_source,
16315 },
9c7f852e
TI
16316 [ALC660_3ST] = {
16317 .mixers = { alc861_3ST_mixer },
16318 .init_verbs = { alc861_threestack_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16320 .dac_nids = alc660_dac_nids,
16321 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16322 .channel_mode = alc861_threestack_modes,
4e195a7b 16323 .need_dac_fix = 1,
9c7f852e
TI
16324 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325 .adc_nids = alc861_adc_nids,
16326 .input_mux = &alc861_capture_source,
16327 },
22309c3e
TI
16328 [ALC861_UNIWILL_M31] = {
16329 .mixers = { alc861_uniwill_m31_mixer },
16330 .init_verbs = { alc861_uniwill_m31_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16332 .dac_nids = alc861_dac_nids,
16333 .dig_out_nid = ALC861_DIGOUT_NID,
16334 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16335 .channel_mode = alc861_uniwill_m31_modes,
16336 .need_dac_fix = 1,
16337 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16338 .adc_nids = alc861_adc_nids,
16339 .input_mux = &alc861_capture_source,
16340 },
a53d1aec
TD
16341 [ALC861_TOSHIBA] = {
16342 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16343 .init_verbs = { alc861_base_init_verbs,
16344 alc861_toshiba_init_verbs },
a53d1aec
TD
16345 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16346 .dac_nids = alc861_dac_nids,
16347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16348 .channel_mode = alc883_3ST_2ch_modes,
16349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16350 .adc_nids = alc861_adc_nids,
16351 .input_mux = &alc861_capture_source,
16352 .unsol_event = alc861_toshiba_unsol_event,
16353 .init_hook = alc861_toshiba_automute,
16354 },
7cdbff94
MD
16355 [ALC861_ASUS] = {
16356 .mixers = { alc861_asus_mixer },
16357 .init_verbs = { alc861_asus_init_verbs },
16358 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16359 .dac_nids = alc861_dac_nids,
16360 .dig_out_nid = ALC861_DIGOUT_NID,
16361 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16362 .channel_mode = alc861_asus_modes,
16363 .need_dac_fix = 1,
16364 .hp_nid = 0x06,
16365 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16366 .adc_nids = alc861_adc_nids,
16367 .input_mux = &alc861_capture_source,
16368 },
56bb0cab
TI
16369 [ALC861_ASUS_LAPTOP] = {
16370 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16371 .init_verbs = { alc861_asus_init_verbs,
16372 alc861_asus_laptop_init_verbs },
16373 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16374 .dac_nids = alc861_dac_nids,
16375 .dig_out_nid = ALC861_DIGOUT_NID,
16376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16377 .channel_mode = alc883_3ST_2ch_modes,
16378 .need_dac_fix = 1,
16379 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16380 .adc_nids = alc861_adc_nids,
16381 .input_mux = &alc861_capture_source,
16382 },
16383};
df694daa 16384
cfc9b06f
TI
16385/* Pin config fixes */
16386enum {
16387 PINFIX_FSC_AMILO_PI1505,
16388};
16389
cfc9b06f
TI
16390static const struct alc_fixup alc861_fixups[] = {
16391 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16392 .type = ALC_FIXUP_PINS,
16393 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16394 { 0x0b, 0x0221101f }, /* HP */
16395 { 0x0f, 0x90170310 }, /* speaker */
16396 { }
16397 }
cfc9b06f
TI
16398 },
16399};
16400
a9111321 16401static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16402 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16403 {}
16404};
df694daa
KY
16405
16406static int patch_alc861(struct hda_codec *codec)
16407{
16408 struct alc_spec *spec;
16409 int board_config;
16410 int err;
16411
dc041e0b 16412 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16413 if (spec == NULL)
16414 return -ENOMEM;
16415
f12ab1e0 16416 codec->spec = spec;
df694daa 16417
f5fcc13c
TI
16418 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16419 alc861_models,
16420 alc861_cfg_tbl);
9c7f852e 16421
f5fcc13c 16422 if (board_config < 0) {
9a11f1aa
TI
16423 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16424 codec->chip_name);
df694daa
KY
16425 board_config = ALC861_AUTO;
16426 }
16427
b5bfbc67
TI
16428 if (board_config == ALC861_AUTO) {
16429 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16430 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16431 }
cfc9b06f 16432
df694daa
KY
16433 if (board_config == ALC861_AUTO) {
16434 /* automatic parse from the BIOS config */
16435 err = alc861_parse_auto_config(codec);
16436 if (err < 0) {
16437 alc_free(codec);
16438 return err;
f12ab1e0 16439 } else if (!err) {
9c7f852e
TI
16440 printk(KERN_INFO
16441 "hda_codec: Cannot set up configuration "
16442 "from BIOS. Using base mode...\n");
df694daa
KY
16443 board_config = ALC861_3ST_DIG;
16444 }
16445 }
16446
680cd536
KK
16447 err = snd_hda_attach_beep_device(codec, 0x23);
16448 if (err < 0) {
16449 alc_free(codec);
16450 return err;
16451 }
16452
df694daa 16453 if (board_config != ALC861_AUTO)
e9c364c0 16454 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16455
df694daa
KY
16456 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16457 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16458
df694daa
KY
16459 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16460 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16461
c7a8eb10
TI
16462 if (!spec->cap_mixer)
16463 set_capture_mixer(codec);
45bdd1c1
TI
16464 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16465
2134ea4f
TI
16466 spec->vmaster_nid = 0x03;
16467
b5bfbc67 16468 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16469
df694daa 16470 codec->patch_ops = alc_patch_ops;
c97259df 16471 if (board_config == ALC861_AUTO) {
ae6b813a 16472 spec->init_hook = alc861_auto_init;
c97259df
DC
16473#ifdef CONFIG_SND_HDA_POWER_SAVE
16474 spec->power_hook = alc_power_eapd;
16475#endif
16476 }
cb53c626
TI
16477#ifdef CONFIG_SND_HDA_POWER_SAVE
16478 if (!spec->loopback.amplist)
16479 spec->loopback.amplist = alc861_loopbacks;
16480#endif
ea1fb29a 16481
1da177e4
LT
16482 return 0;
16483}
16484
f32610ed
JS
16485/*
16486 * ALC861-VD support
16487 *
16488 * Based on ALC882
16489 *
16490 * In addition, an independent DAC
16491 */
16492#define ALC861VD_DIGOUT_NID 0x06
16493
4c6d72d1 16494static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16495 /* front, surr, clfe, side surr */
16496 0x02, 0x03, 0x04, 0x05
16497};
16498
16499/* dac_nids for ALC660vd are in a different order - according to
16500 * Realtek's driver.
def319f9 16501 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16502 * of ALC660vd codecs, but for now there is only 3stack mixer
16503 * - and it is the same as in 861vd.
16504 * adc_nids in ALC660vd are (is) the same as in 861vd
16505 */
4c6d72d1 16506static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16507 /* front, rear, clfe, rear_surr */
16508 0x02, 0x04, 0x03
16509};
16510
4c6d72d1 16511static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16512 /* ADC0 */
16513 0x09,
16514};
16515
4c6d72d1 16516static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16517
f32610ed
JS
16518/* input MUX */
16519/* FIXME: should be a matrix-type input source selection */
a9111321 16520static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16521 .num_items = 4,
16522 .items = {
16523 { "Mic", 0x0 },
16524 { "Front Mic", 0x1 },
16525 { "Line", 0x2 },
16526 { "CD", 0x4 },
16527 },
16528};
16529
a9111321 16530static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16531 .num_items = 2,
272a527c 16532 .items = {
8607f7c4 16533 { "Mic", 0x0 },
28c4edb7 16534 { "Internal Mic", 0x1 },
272a527c
KY
16535 },
16536};
16537
a9111321 16538static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16539 .num_items = 2,
16540 .items = {
16541 { "Front Mic", 0x0 },
16542 { "ATAPI Mic", 0x1 },
16543 },
16544};
16545
f32610ed
JS
16546/*
16547 * 2ch mode
16548 */
a9111321 16549static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16550 { 2, NULL }
16551};
16552
16553/*
16554 * 6ch mode
16555 */
a9111321 16556static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16557 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16558 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16560 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16561 { } /* end */
16562};
16563
16564/*
16565 * 8ch mode
16566 */
a9111321 16567static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16572 { } /* end */
16573};
16574
a9111321 16575static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16576 { 6, alc861vd_6stack_ch6_init },
16577 { 8, alc861vd_6stack_ch8_init },
16578};
16579
a9111321 16580static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16581 {
16582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16583 .name = "Channel Mode",
16584 .info = alc_ch_mode_info,
16585 .get = alc_ch_mode_get,
16586 .put = alc_ch_mode_put,
16587 },
16588 { } /* end */
16589};
16590
f32610ed
JS
16591/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16592 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16593 */
a9111321 16594static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16597
16598 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16599 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16600
16601 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16602 HDA_OUTPUT),
16603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16604 HDA_OUTPUT),
16605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16607
16608 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16609 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16610
16611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16612
5f99f86a 16613 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16616
5f99f86a 16617 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16620
16621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16623
16624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16626
f32610ed
JS
16627 { } /* end */
16628};
16629
a9111321 16630static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16633
16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16635
5f99f86a 16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16639
5f99f86a 16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16643
16644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16646
16647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16649
f32610ed
JS
16650 { } /* end */
16651};
16652
a9111321 16653static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16656 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16657
16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16659
5f99f86a 16660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16663
5f99f86a 16664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16667
16668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16670
16671 { } /* end */
16672};
16673
b419f346 16674/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16675 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16676 */
a9111321 16677static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16682 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16685 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16686 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16687 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16688 { } /* end */
16689};
16690
d1a991a6
KY
16691/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16692 * Front Mic=0x18, ATAPI Mic = 0x19,
16693 */
a9111321 16694static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16698 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16701 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16702 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16703
d1a991a6
KY
16704 { } /* end */
16705};
16706
f32610ed
JS
16707/*
16708 * generic initialization of ADC, input mixers and output mixers
16709 */
a9111321 16710static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16711 /*
16712 * Unmute ADC0 and set the default input to mic-in
16713 */
16714 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16716
16717 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16718 * the analog-loopback mixer widget
16719 */
16720 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16726
16727 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16732
16733 /*
16734 * Set up output mixers (0x02 - 0x05)
16735 */
16736 /* set vol=0 to output mixers */
16737 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16741
16742 /* set up input amps for analog loopback */
16743 /* Amp Indices: DAC = 0, mixer = 1 */
16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16752
16753 { }
16754};
16755
16756/*
16757 * 3-stack pin configuration:
16758 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16759 */
a9111321 16760static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16761 /*
16762 * Set pin mode and muting
16763 */
16764 /* set front pin widgets 0x14 for output */
16765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16768
16769 /* Mic (rear) pin: input vref at 80% */
16770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16772 /* Front Mic pin: input vref at 80% */
16773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16775 /* Line In pin: input */
16776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16782 /* CD pin widget for input */
16783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16784
16785 { }
16786};
16787
16788/*
16789 * 6-stack pin configuration:
16790 */
a9111321 16791static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16792 /*
16793 * Set pin mode and muting
16794 */
16795 /* set front pin widgets 0x14 for output */
16796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16799
16800 /* Rear Pin: output 1 (0x0d) */
16801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16804 /* CLFE Pin: output 2 (0x0e) */
16805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16807 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16808 /* Side Pin: output 3 (0x0f) */
16809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16812
16813 /* Mic (rear) pin: input vref at 80% */
16814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16816 /* Front Mic pin: input vref at 80% */
16817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16819 /* Line In pin: input */
16820 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16821 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16822 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16826 /* CD pin widget for input */
16827 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16828
16829 { }
16830};
16831
a9111321 16832static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16834 { }
16835};
16836
a9111321 16837static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16838 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16839 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16840 { }
16841};
16842
a9111321 16843static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16849 {}
16850};
16851
4f5d1706 16852static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16853{
a9fd4f3f 16854 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16855 spec->autocfg.hp_pins[0] = 0x1b;
16856 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16857 spec->automute = 1;
16858 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16859}
16860
16861static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16862{
d922b51d 16863 alc_hp_automute(codec);
eeb43387 16864 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16865}
16866
16867static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16868 unsigned int res)
16869{
16870 switch (res >> 26) {
bdd148a3 16871 case ALC880_MIC_EVENT:
eeb43387 16872 alc88x_simple_mic_automute(codec);
bdd148a3 16873 break;
a9fd4f3f 16874 default:
d922b51d 16875 alc_sku_unsol_event(codec, res);
a9fd4f3f 16876 break;
bdd148a3
KY
16877 }
16878}
16879
a9111321 16880static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16882 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16885
16886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16892 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16894
272a527c
KY
16895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16901 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16903
16904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16911 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16912
16913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16917
16918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16921
16922 { } /* end */
16923};
16924
16925/* toggle speaker-output according to the hp-jack state */
4f5d1706 16926static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16927{
a9fd4f3f 16928 struct alc_spec *spec = codec->spec;
272a527c 16929
a9fd4f3f
TI
16930 spec->autocfg.hp_pins[0] = 0x15;
16931 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16932 spec->automute = 1;
16933 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16934}
16935
cb53c626
TI
16936#ifdef CONFIG_SND_HDA_POWER_SAVE
16937#define alc861vd_loopbacks alc880_loopbacks
16938#endif
16939
def319f9 16940/* pcm configuration: identical with ALC880 */
f32610ed
JS
16941#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16942#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16943#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16944#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16945
16946/*
16947 * configuration and preset
16948 */
ea734963 16949static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16950 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16951 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16952 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16953 [ALC861VD_3ST] = "3stack",
16954 [ALC861VD_3ST_DIG] = "3stack-digout",
16955 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16956 [ALC861VD_LENOVO] = "lenovo",
272a527c 16957 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16958 [ALC861VD_HP] = "hp",
f32610ed
JS
16959 [ALC861VD_AUTO] = "auto",
16960};
16961
a9111321 16962static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16963 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16964 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16965 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16966 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16967 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16968 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16969 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16970 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16971 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16972 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16973 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16974 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16975 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16976 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16977 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16978 {}
16979};
16980
a9111321 16981static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16982 [ALC660VD_3ST] = {
16983 .mixers = { alc861vd_3st_mixer },
16984 .init_verbs = { alc861vd_volume_init_verbs,
16985 alc861vd_3stack_init_verbs },
16986 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16987 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16988 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16989 .channel_mode = alc861vd_3stack_2ch_modes,
16990 .input_mux = &alc861vd_capture_source,
16991 },
6963f84c
MC
16992 [ALC660VD_3ST_DIG] = {
16993 .mixers = { alc861vd_3st_mixer },
16994 .init_verbs = { alc861vd_volume_init_verbs,
16995 alc861vd_3stack_init_verbs },
16996 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16997 .dac_nids = alc660vd_dac_nids,
16998 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16999 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17000 .channel_mode = alc861vd_3stack_2ch_modes,
17001 .input_mux = &alc861vd_capture_source,
17002 },
f32610ed
JS
17003 [ALC861VD_3ST] = {
17004 .mixers = { alc861vd_3st_mixer },
17005 .init_verbs = { alc861vd_volume_init_verbs,
17006 alc861vd_3stack_init_verbs },
17007 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17008 .dac_nids = alc861vd_dac_nids,
17009 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17010 .channel_mode = alc861vd_3stack_2ch_modes,
17011 .input_mux = &alc861vd_capture_source,
17012 },
17013 [ALC861VD_3ST_DIG] = {
17014 .mixers = { alc861vd_3st_mixer },
17015 .init_verbs = { alc861vd_volume_init_verbs,
17016 alc861vd_3stack_init_verbs },
17017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17018 .dac_nids = alc861vd_dac_nids,
17019 .dig_out_nid = ALC861VD_DIGOUT_NID,
17020 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17021 .channel_mode = alc861vd_3stack_2ch_modes,
17022 .input_mux = &alc861vd_capture_source,
17023 },
17024 [ALC861VD_6ST_DIG] = {
17025 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17026 .init_verbs = { alc861vd_volume_init_verbs,
17027 alc861vd_6stack_init_verbs },
17028 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17029 .dac_nids = alc861vd_dac_nids,
17030 .dig_out_nid = ALC861VD_DIGOUT_NID,
17031 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17032 .channel_mode = alc861vd_6stack_modes,
17033 .input_mux = &alc861vd_capture_source,
17034 },
bdd148a3
KY
17035 [ALC861VD_LENOVO] = {
17036 .mixers = { alc861vd_lenovo_mixer },
17037 .init_verbs = { alc861vd_volume_init_verbs,
17038 alc861vd_3stack_init_verbs,
17039 alc861vd_eapd_verbs,
17040 alc861vd_lenovo_unsol_verbs },
17041 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17042 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
17043 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17044 .channel_mode = alc861vd_3stack_2ch_modes,
17045 .input_mux = &alc861vd_capture_source,
17046 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17047 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17048 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17049 },
272a527c
KY
17050 [ALC861VD_DALLAS] = {
17051 .mixers = { alc861vd_dallas_mixer },
17052 .init_verbs = { alc861vd_dallas_verbs },
17053 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17054 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17055 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17056 .channel_mode = alc861vd_3stack_2ch_modes,
17057 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 17058 .unsol_event = alc_sku_unsol_event,
4f5d1706 17059 .setup = alc861vd_dallas_setup,
d922b51d 17060 .init_hook = alc_hp_automute,
d1a991a6
KY
17061 },
17062 [ALC861VD_HP] = {
17063 .mixers = { alc861vd_hp_mixer },
17064 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17065 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17066 .dac_nids = alc861vd_dac_nids,
d1a991a6 17067 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17069 .channel_mode = alc861vd_3stack_2ch_modes,
17070 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17071 .unsol_event = alc_sku_unsol_event,
4f5d1706 17072 .setup = alc861vd_dallas_setup,
d922b51d 17073 .init_hook = alc_hp_automute,
ea1fb29a 17074 },
13c94744
TI
17075 [ALC660VD_ASUS_V1S] = {
17076 .mixers = { alc861vd_lenovo_mixer },
17077 .init_verbs = { alc861vd_volume_init_verbs,
17078 alc861vd_3stack_init_verbs,
17079 alc861vd_eapd_verbs,
17080 alc861vd_lenovo_unsol_verbs },
17081 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17082 .dac_nids = alc660vd_dac_nids,
17083 .dig_out_nid = ALC861VD_DIGOUT_NID,
17084 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17085 .channel_mode = alc861vd_3stack_2ch_modes,
17086 .input_mux = &alc861vd_capture_source,
17087 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17088 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17089 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17090 },
f32610ed
JS
17091};
17092
17093/*
17094 * BIOS auto configuration
17095 */
05f5f477
TI
17096static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17097 const struct auto_pin_cfg *cfg)
17098{
7167594a 17099 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17100}
17101
17102
f32610ed
JS
17103static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17104 hda_nid_t nid, int pin_type, int dac_idx)
17105{
f6c7e546 17106 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17107}
17108
17109static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17110{
17111 struct alc_spec *spec = codec->spec;
17112 int i;
17113
17114 for (i = 0; i <= HDA_SIDE; i++) {
17115 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17116 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17117 if (nid)
17118 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17119 pin_type, i);
f32610ed
JS
17120 }
17121}
17122
17123
17124static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17125{
17126 struct alc_spec *spec = codec->spec;
17127 hda_nid_t pin;
17128
17129 pin = spec->autocfg.hp_pins[0];
def319f9 17130 if (pin) /* connect to front and use dac 0 */
f32610ed 17131 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17132 pin = spec->autocfg.speaker_pins[0];
17133 if (pin)
17134 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17135}
17136
f32610ed
JS
17137#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17138
17139static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17140{
17141 struct alc_spec *spec = codec->spec;
66ceeb6b 17142 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17143 int i;
17144
66ceeb6b
TI
17145 for (i = 0; i < cfg->num_inputs; i++) {
17146 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17147 if (alc_is_input_pin(codec, nid)) {
30ea098f 17148 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17149 if (nid != ALC861VD_PIN_CD_NID &&
17150 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17151 snd_hda_codec_write(codec, nid, 0,
17152 AC_VERB_SET_AMP_GAIN_MUTE,
17153 AMP_OUT_MUTE);
17154 }
17155 }
17156}
17157
f511b01c
TI
17158#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17159
f32610ed
JS
17160#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17161#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17162
17163/* add playback controls from the parsed DAC table */
569ed348 17164/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17165 * different NIDs for mute/unmute switch and volume control */
17166static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17167 const struct auto_pin_cfg *cfg)
17168{
ea734963
TI
17169 static const char * const chname[4] = {
17170 "Front", "Surround", "CLFE", "Side"
17171 };
ce764ab2 17172 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17173 hda_nid_t nid_v, nid_s;
ce764ab2 17174 int i, err, noutputs;
f32610ed 17175
ce764ab2
TI
17176 noutputs = cfg->line_outs;
17177 if (spec->multi_ios > 0)
17178 noutputs += spec->multi_ios;
17179
17180 for (i = 0; i < noutputs; i++) {
f12ab1e0 17181 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17182 continue;
17183 nid_v = alc861vd_idx_to_mixer_vol(
17184 alc880_dac_to_idx(
17185 spec->multiout.dac_nids[i]));
17186 nid_s = alc861vd_idx_to_mixer_switch(
17187 alc880_dac_to_idx(
17188 spec->multiout.dac_nids[i]));
17189
bcb2f0f5 17190 if (!pfx && i == 2) {
f32610ed 17191 /* Center/LFE */
0afe5f89
TI
17192 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17193 "Center",
f12ab1e0
TI
17194 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17195 HDA_OUTPUT));
17196 if (err < 0)
f32610ed 17197 return err;
0afe5f89
TI
17198 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17199 "LFE",
f12ab1e0
TI
17200 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17201 HDA_OUTPUT));
17202 if (err < 0)
f32610ed 17203 return err;
0afe5f89
TI
17204 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17205 "Center",
f12ab1e0
TI
17206 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17207 HDA_INPUT));
17208 if (err < 0)
f32610ed 17209 return err;
0afe5f89
TI
17210 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17211 "LFE",
f12ab1e0
TI
17212 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17213 HDA_INPUT));
17214 if (err < 0)
f32610ed
JS
17215 return err;
17216 } else {
bcb2f0f5 17217 const char *name = pfx;
5a882646
DH
17218 int index = i;
17219 if (!name) {
bcb2f0f5 17220 name = chname[i];
5a882646
DH
17221 index = 0;
17222 }
bcb2f0f5 17223 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17224 name, index,
f12ab1e0
TI
17225 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17226 HDA_OUTPUT));
17227 if (err < 0)
f32610ed 17228 return err;
bcb2f0f5 17229 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17230 name, index,
bdd148a3 17231 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17232 HDA_INPUT));
17233 if (err < 0)
f32610ed
JS
17234 return err;
17235 }
17236 }
17237 return 0;
17238}
17239
17240/* add playback controls for speaker and HP outputs */
17241/* Based on ALC880 version. But ALC861VD has separate,
17242 * different NIDs for mute/unmute switch and volume control */
17243static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17244 hda_nid_t pin, const char *pfx)
17245{
17246 hda_nid_t nid_v, nid_s;
17247 int err;
f32610ed 17248
f12ab1e0 17249 if (!pin)
f32610ed
JS
17250 return 0;
17251
17252 if (alc880_is_fixed_pin(pin)) {
17253 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17254 /* specify the DAC as the extra output */
f12ab1e0 17255 if (!spec->multiout.hp_nid)
f32610ed
JS
17256 spec->multiout.hp_nid = nid_v;
17257 else
17258 spec->multiout.extra_out_nid[0] = nid_v;
17259 /* control HP volume/switch on the output mixer amp */
17260 nid_v = alc861vd_idx_to_mixer_vol(
17261 alc880_fixed_pin_idx(pin));
17262 nid_s = alc861vd_idx_to_mixer_switch(
17263 alc880_fixed_pin_idx(pin));
17264
0afe5f89 17265 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17266 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17267 if (err < 0)
f32610ed 17268 return err;
0afe5f89 17269 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17270 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17271 if (err < 0)
f32610ed
JS
17272 return err;
17273 } else if (alc880_is_multi_pin(pin)) {
17274 /* set manual connection */
17275 /* we have only a switch on HP-out PIN */
0afe5f89 17276 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17277 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17278 if (err < 0)
f32610ed
JS
17279 return err;
17280 }
17281 return 0;
17282}
17283
17284/* parse the BIOS configuration and set up the alc_spec
17285 * return 1 if successful, 0 if the proper config is not found,
17286 * or a negative error code
17287 * Based on ALC880 version - had to change it to override
17288 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17289static int alc861vd_parse_auto_config(struct hda_codec *codec)
17290{
17291 struct alc_spec *spec = codec->spec;
17292 int err;
4c6d72d1 17293 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17294
f12ab1e0
TI
17295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17296 alc861vd_ignore);
17297 if (err < 0)
f32610ed 17298 return err;
f12ab1e0 17299 if (!spec->autocfg.line_outs)
f32610ed
JS
17300 return 0; /* can't find valid BIOS pin config */
17301
f12ab1e0 17302 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17303 if (err < 0)
17304 return err;
17305 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17306 if (err < 0)
17307 return err;
17308 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17309 if (err < 0)
17310 return err;
17311 err = alc861vd_auto_create_extra_out(spec,
17312 spec->autocfg.speaker_pins[0],
17313 "Speaker");
17314 if (err < 0)
17315 return err;
17316 err = alc861vd_auto_create_extra_out(spec,
17317 spec->autocfg.hp_pins[0],
17318 "Headphone");
17319 if (err < 0)
17320 return err;
05f5f477 17321 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17322 if (err < 0)
f32610ed
JS
17323 return err;
17324
17325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17326
757899ac 17327 alc_auto_parse_digital(codec);
f32610ed 17328
603c4019 17329 if (spec->kctls.list)
d88897ea 17330 add_mixer(spec, spec->kctls.list);
f32610ed 17331
d88897ea 17332 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17333
17334 spec->num_mux_defs = 1;
61b9b9b1 17335 spec->input_mux = &spec->private_imux[0];
f32610ed 17336
776e184e
TI
17337 err = alc_auto_add_mic_boost(codec);
17338 if (err < 0)
17339 return err;
17340
6227cdce 17341 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17342
f32610ed
JS
17343 return 1;
17344}
17345
17346/* additional initialization for auto-configuration model */
17347static void alc861vd_auto_init(struct hda_codec *codec)
17348{
f6c7e546 17349 struct alc_spec *spec = codec->spec;
f32610ed
JS
17350 alc861vd_auto_init_multi_out(codec);
17351 alc861vd_auto_init_hp_out(codec);
17352 alc861vd_auto_init_analog_input(codec);
f511b01c 17353 alc861vd_auto_init_input_src(codec);
757899ac 17354 alc_auto_init_digital(codec);
f6c7e546 17355 if (spec->unsol_event)
7fb0d78f 17356 alc_inithook(codec);
f32610ed
JS
17357}
17358
f8f25ba3
TI
17359enum {
17360 ALC660VD_FIX_ASUS_GPIO1
17361};
17362
17363/* reset GPIO1 */
f8f25ba3
TI
17364static const struct alc_fixup alc861vd_fixups[] = {
17365 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17366 .type = ALC_FIXUP_VERBS,
17367 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17368 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17369 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17370 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17371 { }
17372 }
f8f25ba3
TI
17373 },
17374};
17375
a9111321 17376static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17377 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17378 {}
17379};
17380
f32610ed
JS
17381static int patch_alc861vd(struct hda_codec *codec)
17382{
17383 struct alc_spec *spec;
17384 int err, board_config;
17385
17386 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17387 if (spec == NULL)
17388 return -ENOMEM;
17389
17390 codec->spec = spec;
17391
17392 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17393 alc861vd_models,
17394 alc861vd_cfg_tbl);
17395
17396 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17397 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17398 codec->chip_name);
f32610ed
JS
17399 board_config = ALC861VD_AUTO;
17400 }
17401
b5bfbc67
TI
17402 if (board_config == ALC861VD_AUTO) {
17403 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17404 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17405 }
f8f25ba3 17406
f32610ed
JS
17407 if (board_config == ALC861VD_AUTO) {
17408 /* automatic parse from the BIOS config */
17409 err = alc861vd_parse_auto_config(codec);
17410 if (err < 0) {
17411 alc_free(codec);
17412 return err;
f12ab1e0 17413 } else if (!err) {
f32610ed
JS
17414 printk(KERN_INFO
17415 "hda_codec: Cannot set up configuration "
17416 "from BIOS. Using base mode...\n");
17417 board_config = ALC861VD_3ST;
17418 }
17419 }
17420
680cd536
KK
17421 err = snd_hda_attach_beep_device(codec, 0x23);
17422 if (err < 0) {
17423 alc_free(codec);
17424 return err;
17425 }
17426
f32610ed 17427 if (board_config != ALC861VD_AUTO)
e9c364c0 17428 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17429
2f893286 17430 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17431 /* always turn on EAPD */
d88897ea 17432 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17433 }
17434
f32610ed
JS
17435 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17436 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17437
f32610ed
JS
17438 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17439 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17440
dd704698
TI
17441 if (!spec->adc_nids) {
17442 spec->adc_nids = alc861vd_adc_nids;
17443 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17444 }
17445 if (!spec->capsrc_nids)
17446 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17447
b59bdf3b 17448 set_capture_mixer(codec);
45bdd1c1 17449 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17450
2134ea4f
TI
17451 spec->vmaster_nid = 0x02;
17452
b5bfbc67 17453 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17454
f32610ed
JS
17455 codec->patch_ops = alc_patch_ops;
17456
17457 if (board_config == ALC861VD_AUTO)
17458 spec->init_hook = alc861vd_auto_init;
1c716153 17459 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17460#ifdef CONFIG_SND_HDA_POWER_SAVE
17461 if (!spec->loopback.amplist)
17462 spec->loopback.amplist = alc861vd_loopbacks;
17463#endif
f32610ed
JS
17464
17465 return 0;
17466}
17467
bc9f98a9
KY
17468/*
17469 * ALC662 support
17470 *
17471 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17472 * configuration. Each pin widget can choose any input DACs and a mixer.
17473 * Each ADC is connected from a mixer of all inputs. This makes possible
17474 * 6-channel independent captures.
17475 *
17476 * In addition, an independent DAC for the multi-playback (not used in this
17477 * driver yet).
17478 */
17479#define ALC662_DIGOUT_NID 0x06
17480#define ALC662_DIGIN_NID 0x0a
17481
4c6d72d1 17482static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17483 /* front, rear, clfe */
bc9f98a9
KY
17484 0x02, 0x03, 0x04
17485};
17486
4c6d72d1 17487static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17488 0x02, 0x03
17489};
17490
4c6d72d1 17491static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17492 /* ADC1-2 */
b59bdf3b 17493 0x09, 0x08
bc9f98a9 17494};
e1406348 17495
4c6d72d1 17496static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17497 /* ADC1-2 */
17498 0x08,
17499};
17500
4c6d72d1
TI
17501static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17502static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17503
e1406348 17504
bc9f98a9
KY
17505/* input MUX */
17506/* FIXME: should be a matrix-type input source selection */
a9111321 17507static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17508 .num_items = 4,
17509 .items = {
17510 { "Mic", 0x0 },
17511 { "Front Mic", 0x1 },
17512 { "Line", 0x2 },
17513 { "CD", 0x4 },
17514 },
17515};
17516
a9111321 17517static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17518 .num_items = 2,
17519 .items = {
17520 { "Mic", 0x1 },
17521 { "Line", 0x2 },
17522 },
17523};
291702f0 17524
a9111321 17525static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17526 .num_items = 3,
17527 .items = {
17528 { "Mic", 0x0 },
17529 { "Front Mic", 0x1 },
17530 { "Line", 0x2 },
17531 },
17532};
17533
4f5d1706 17534#if 0 /* set to 1 for testing other input sources below */
a9111321 17535static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17536 .num_items = 16,
17537 .items = {
17538 { "Autoselect Mic", 0x0 },
17539 { "Internal Mic", 0x1 },
17540 { "In-0x02", 0x2 },
17541 { "In-0x03", 0x3 },
17542 { "In-0x04", 0x4 },
17543 { "In-0x05", 0x5 },
17544 { "In-0x06", 0x6 },
17545 { "In-0x07", 0x7 },
17546 { "In-0x08", 0x8 },
17547 { "In-0x09", 0x9 },
17548 { "In-0x0a", 0x0a },
17549 { "In-0x0b", 0x0b },
17550 { "In-0x0c", 0x0c },
17551 { "In-0x0d", 0x0d },
17552 { "In-0x0e", 0x0e },
17553 { "In-0x0f", 0x0f },
17554 },
17555};
17556#endif
17557
bc9f98a9
KY
17558/*
17559 * 2ch mode
17560 */
a9111321 17561static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17562 { 2, NULL }
17563};
17564
17565/*
17566 * 2ch mode
17567 */
a9111321 17568static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17573 { } /* end */
17574};
17575
17576/*
17577 * 6ch mode
17578 */
a9111321 17579static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17580 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17581 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17582 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17583 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17585 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17586 { } /* end */
17587};
17588
a9111321 17589static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17590 { 2, alc662_3ST_ch2_init },
17591 { 6, alc662_3ST_ch6_init },
17592};
17593
17594/*
17595 * 2ch mode
17596 */
a9111321 17597static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17598 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17599 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17600 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17601 { } /* end */
17602};
17603
17604/*
17605 * 6ch mode
17606 */
a9111321 17607static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17608 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17611 { } /* end */
17612};
17613
a9111321 17614static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17615 { 2, alc662_sixstack_ch6_init },
17616 { 6, alc662_sixstack_ch8_init },
17617};
17618
17619/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17620 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17621 */
17622
a9111321 17623static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17624 /* output mixer control */
17625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17626 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17628 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17631 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634
17635 /*Input mixer control */
17636 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17637 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17639 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17644 { } /* end */
17645};
17646
a9111321 17647static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17648 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17649 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17659 { } /* end */
17660};
17661
a9111321 17662static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17666 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17669 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17680 { } /* end */
17681};
17682
a9111321 17683static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17685 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17686 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17687 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17693 { } /* end */
17694};
17695
a9111321 17696static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17697 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17698 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17699
5f99f86a 17700 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17703
5f99f86a 17704 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17707 { } /* end */
17708};
17709
a9111321 17710static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17711 ALC262_HIPPO_MASTER_SWITCH,
17712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17716 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17721 { } /* end */
17722};
17723
a9111321 17724static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17725 .ops = &snd_hda_bind_vol,
17726 .values = {
17727 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17728 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17729 0
17730 },
17731};
17732
a9111321 17733static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17734 .ops = &snd_hda_bind_sw,
17735 .values = {
17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17738 0
17739 },
17740};
17741
a9111321 17742static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17747 { } /* end */
17748};
17749
a9111321 17750static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17751 .ops = &snd_hda_bind_sw,
17752 .values = {
17753 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17754 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17755 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17756 0
17757 },
17758};
17759
a9111321 17760static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17761 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17762 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17765 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17766 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17767
17768 { } /* end */
17769};
17770
a9111321 17771static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17772 .ops = &snd_hda_bind_sw,
17773 .values = {
17774 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17775 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17777 0
17778 },
17779};
17780
a9111321 17781static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17782 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17783 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17786 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17787 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17788 { } /* end */
17789};
17790
a9111321 17791static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17798 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17799 { } /* end */
17800};
17801
a9111321 17802static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17803 .ops = &snd_hda_bind_vol,
17804 .values = {
17805 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17807 0
17808 },
17809};
17810
a9111321 17811static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17812 .ops = &snd_hda_bind_sw,
17813 .values = {
17814 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17815 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17816 0
17817 },
17818};
17819
a9111321 17820static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17821 HDA_BIND_VOL("Master Playback Volume",
17822 &alc663_asus_two_bind_master_vol),
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17828 { } /* end */
17829};
17830
a9111321 17831static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17832 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17833 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17838 { } /* end */
17839};
17840
a9111321 17841static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17843 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17845 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17847
17848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17850 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17852 { } /* end */
17853};
17854
a9111321 17855static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17859
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17866 { } /* end */
17867};
17868
a9111321 17869static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17870 .ops = &snd_hda_bind_sw,
17871 .values = {
17872 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17873 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17874 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17875 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17876 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17877 0
17878 },
17879};
17880
a9111321 17881static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17882 .ops = &snd_hda_bind_sw,
17883 .values = {
17884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17885 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17886 0
17887 },
17888};
17889
a9111321 17890static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17891 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17892 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17893 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17894 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17895 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17896 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17897 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17900 { } /* end */
17901};
17902
a9111321 17903static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17904 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17905 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17906 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17907 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17908 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17911 { } /* end */
17912};
17913
17914
a9111321 17915static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17916 {
17917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17918 .name = "Channel Mode",
17919 .info = alc_ch_mode_info,
17920 .get = alc_ch_mode_get,
17921 .put = alc_ch_mode_put,
17922 },
17923 { } /* end */
17924};
17925
a9111321 17926static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17927 /* ADC: mute amp left and right */
17928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17930
b60dd394
KY
17931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17937
17938 /* Front Pin: output 0 (0x0c) */
17939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941
17942 /* Rear Pin: output 1 (0x0d) */
17943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945
17946 /* CLFE Pin: output 2 (0x0e) */
17947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949
17950 /* Mic (rear) pin: input vref at 80% */
17951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17953 /* Front Mic pin: input vref at 80% */
17954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17956 /* Line In pin: input */
17957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17963 /* CD pin widget for input */
17964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17965
17966 /* FIXME: use matrix-type input source selection */
17967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17968 /* Input mixer */
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17971
a7f2371f
TI
17972 { }
17973};
17974
a9111321 17975static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17976 /* always trun on EAPD */
17977 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17978 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17979 { }
17980};
17981
a9111321 17982static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17985 {}
17986};
17987
a9111321 17988static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
bc9f98a9
KY
17992};
17993
8c427226 17994/* Set Unsolicited Event*/
a9111321 17995static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17998 {}
17999};
18000
a9111321 18001static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
18004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
18006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18010 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18011 {}
18012};
18013
a9111321 18014static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
18015 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {}
18023};
18024
a9111321 18025static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18032 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18033 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 {}
18035};
6dda9f4a 18036
a9111321 18037static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
18038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18045 {}
18046};
6dda9f4a 18047
a9111321 18048static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18055 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18059 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18060 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {}
18062};
18063
a9111321 18064static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18076 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18077 {}
18078};
18079
a9111321 18080static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
18081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18083 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18084
18085 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18086 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18087 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18088
18089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18090 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18091 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18092 {}
18093};
18094
a9111321 18095static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
18096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18099
18100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18102 {}
18103};
18104
a9111321 18105static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
18106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111};
18112
a9111321 18113static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18119 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126};
18127
a9111321 18128static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
18129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18134 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18135 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18138 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18139 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18140 {}
18141};
18142
a9111321 18143static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18156 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18159 {}
18160};
18161
a9111321 18162static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
18163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18168 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18170 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18171 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18172 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18173 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18177 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18178 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179 {}
18180};
18181
a9111321 18182static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
18183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18185 { } /* end */
18186};
18187
a9111321 18188static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
18189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18191 { } /* end */
18192};
18193
e6a5e1b7 18194static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18195{
e6a5e1b7 18196 struct alc_spec *spec = codec->spec;
bc9f98a9 18197
e6a5e1b7
TI
18198 spec->autocfg.hp_pins[0] = 0x1b;
18199 spec->autocfg.line_out_pins[0] = 0x14;
18200 spec->autocfg.speaker_pins[0] = 0x15;
18201 spec->automute = 1;
18202 spec->detect_line = 1;
18203 spec->automute_lines = 1;
18204 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18205}
18206
4f5d1706
TI
18207static void alc662_eeepc_setup(struct hda_codec *codec)
18208{
18209 struct alc_spec *spec = codec->spec;
18210
18211 alc262_hippo1_setup(codec);
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217}
18218
4f5d1706 18219static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18220{
42171c17
TI
18221 struct alc_spec *spec = codec->spec;
18222
18223 spec->autocfg.hp_pins[0] = 0x14;
18224 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18225 spec->automute = 1;
18226 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18227}
18228
4f5d1706
TI
18229static void alc663_m51va_setup(struct hda_codec *codec)
18230{
18231 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18232 spec->autocfg.hp_pins[0] = 0x21;
18233 spec->autocfg.speaker_pins[0] = 0x14;
18234 spec->automute_mixer_nid[0] = 0x0c;
18235 spec->automute = 1;
18236 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18237 spec->ext_mic.pin = 0x18;
18238 spec->ext_mic.mux_idx = 0;
18239 spec->int_mic.pin = 0x12;
ebb83eeb 18240 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18241 spec->auto_mic = 1;
18242}
18243
f1d4e28b 18244/* ***************** Mode1 ******************************/
ebb83eeb
KY
18245static void alc663_mode1_setup(struct hda_codec *codec)
18246{
18247 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18248 spec->autocfg.hp_pins[0] = 0x21;
18249 spec->autocfg.speaker_pins[0] = 0x14;
18250 spec->automute_mixer_nid[0] = 0x0c;
18251 spec->automute = 1;
18252 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18253 spec->ext_mic.pin = 0x18;
18254 spec->ext_mic.mux_idx = 0;
18255 spec->int_mic.pin = 0x19;
18256 spec->int_mic.mux_idx = 1;
18257 spec->auto_mic = 1;
18258}
18259
f1d4e28b 18260/* ***************** Mode2 ******************************/
3b8510ce 18261static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18262{
3b8510ce
TI
18263 struct alc_spec *spec = codec->spec;
18264 spec->autocfg.hp_pins[0] = 0x1b;
18265 spec->autocfg.speaker_pins[0] = 0x14;
18266 spec->automute = 1;
18267 spec->automute_mode = ALC_AUTOMUTE_PIN;
18268 spec->ext_mic.pin = 0x18;
18269 spec->ext_mic.mux_idx = 0;
18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
f1d4e28b
KY
18273}
18274
f1d4e28b 18275/* ***************** Mode3 ******************************/
3b8510ce 18276static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18277{
3b8510ce
TI
18278 struct alc_spec *spec = codec->spec;
18279 spec->autocfg.hp_pins[0] = 0x21;
18280 spec->autocfg.hp_pins[0] = 0x15;
18281 spec->autocfg.speaker_pins[0] = 0x14;
18282 spec->automute = 1;
18283 spec->automute_mode = ALC_AUTOMUTE_PIN;
18284 spec->ext_mic.pin = 0x18;
18285 spec->ext_mic.mux_idx = 0;
18286 spec->int_mic.pin = 0x19;
18287 spec->int_mic.mux_idx = 1;
18288 spec->auto_mic = 1;
f1d4e28b
KY
18289}
18290
f1d4e28b 18291/* ***************** Mode4 ******************************/
3b8510ce 18292static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18293{
3b8510ce
TI
18294 struct alc_spec *spec = codec->spec;
18295 spec->autocfg.hp_pins[0] = 0x21;
18296 spec->autocfg.speaker_pins[0] = 0x14;
18297 spec->autocfg.speaker_pins[1] = 0x16;
18298 spec->automute_mixer_nid[0] = 0x0c;
18299 spec->automute_mixer_nid[1] = 0x0e;
18300 spec->automute = 1;
18301 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
f1d4e28b
KY
18307}
18308
f1d4e28b 18309/* ***************** Mode5 ******************************/
3b8510ce 18310static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18311{
3b8510ce
TI
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x15;
18314 spec->autocfg.speaker_pins[0] = 0x14;
18315 spec->autocfg.speaker_pins[1] = 0x16;
18316 spec->automute_mixer_nid[0] = 0x0c;
18317 spec->automute_mixer_nid[1] = 0x0e;
18318 spec->automute = 1;
18319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x19;
18323 spec->int_mic.mux_idx = 1;
18324 spec->auto_mic = 1;
f1d4e28b
KY
18325}
18326
f1d4e28b 18327/* ***************** Mode6 ******************************/
3b8510ce 18328static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18329{
3b8510ce
TI
18330 struct alc_spec *spec = codec->spec;
18331 spec->autocfg.hp_pins[0] = 0x1b;
18332 spec->autocfg.hp_pins[0] = 0x15;
18333 spec->autocfg.speaker_pins[0] = 0x14;
18334 spec->automute_mixer_nid[0] = 0x0c;
18335 spec->automute = 1;
18336 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18337 spec->ext_mic.pin = 0x18;
18338 spec->ext_mic.mux_idx = 0;
18339 spec->int_mic.pin = 0x19;
18340 spec->int_mic.mux_idx = 1;
18341 spec->auto_mic = 1;
f1d4e28b
KY
18342}
18343
ebb83eeb 18344/* ***************** Mode7 ******************************/
3b8510ce 18345static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18346{
3b8510ce
TI
18347 struct alc_spec *spec = codec->spec;
18348 spec->autocfg.hp_pins[0] = 0x1b;
18349 spec->autocfg.hp_pins[0] = 0x21;
18350 spec->autocfg.speaker_pins[0] = 0x14;
18351 spec->autocfg.speaker_pins[0] = 0x17;
18352 spec->automute = 1;
18353 spec->automute_mode = ALC_AUTOMUTE_PIN;
18354 spec->ext_mic.pin = 0x18;
18355 spec->ext_mic.mux_idx = 0;
18356 spec->int_mic.pin = 0x19;
18357 spec->int_mic.mux_idx = 1;
18358 spec->auto_mic = 1;
ebb83eeb
KY
18359}
18360
18361/* ***************** Mode8 ******************************/
3b8510ce 18362static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18363{
3b8510ce
TI
18364 struct alc_spec *spec = codec->spec;
18365 spec->autocfg.hp_pins[0] = 0x21;
18366 spec->autocfg.hp_pins[1] = 0x15;
18367 spec->autocfg.speaker_pins[0] = 0x14;
18368 spec->autocfg.speaker_pins[0] = 0x17;
18369 spec->automute = 1;
18370 spec->automute_mode = ALC_AUTOMUTE_PIN;
18371 spec->ext_mic.pin = 0x18;
18372 spec->ext_mic.mux_idx = 0;
18373 spec->int_mic.pin = 0x12;
18374 spec->int_mic.mux_idx = 9;
18375 spec->auto_mic = 1;
ebb83eeb
KY
18376}
18377
e6a5e1b7 18378static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18379{
e6a5e1b7
TI
18380 struct alc_spec *spec = codec->spec;
18381 spec->autocfg.hp_pins[0] = 0x21;
18382 spec->autocfg.line_out_pins[0] = 0x15;
18383 spec->autocfg.speaker_pins[0] = 0x14;
18384 spec->automute = 1;
18385 spec->automute_mode = ALC_AUTOMUTE_AMP;
18386 spec->detect_line = 1;
18387 spec->automute_lines = 1;
18388 spec->ext_mic.pin = 0x18;
18389 spec->ext_mic.mux_idx = 0;
18390 spec->int_mic.pin = 0x12;
18391 spec->int_mic.mux_idx = 9;
18392 spec->auto_mic = 1;
6dda9f4a
KY
18393}
18394
4f5d1706
TI
18395#define alc663_g50v_setup alc663_m51va_setup
18396
a9111321 18397static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18398 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18399 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18400
5f99f86a 18401 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18402 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18403 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18404
5f99f86a 18405 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18408 { } /* end */
18409};
18410
a9111321 18411static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18412 /* Master Playback automatically created from Speaker and Headphone */
18413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18416 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18417
8607f7c4
DH
18418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18420 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18421
28c4edb7
DH
18422 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18423 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18424 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18425 { } /* end */
18426};
18427
cb53c626
TI
18428#ifdef CONFIG_SND_HDA_POWER_SAVE
18429#define alc662_loopbacks alc880_loopbacks
18430#endif
18431
bc9f98a9 18432
def319f9 18433/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18434#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18435#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18436#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18437#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18438
18439/*
18440 * configuration and preset
18441 */
ea734963 18442static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18443 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18444 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18445 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18446 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18447 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18448 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18449 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18450 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18451 [ALC663_ASUS_M51VA] = "m51va",
18452 [ALC663_ASUS_G71V] = "g71v",
18453 [ALC663_ASUS_H13] = "h13",
18454 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18455 [ALC663_ASUS_MODE1] = "asus-mode1",
18456 [ALC662_ASUS_MODE2] = "asus-mode2",
18457 [ALC663_ASUS_MODE3] = "asus-mode3",
18458 [ALC663_ASUS_MODE4] = "asus-mode4",
18459 [ALC663_ASUS_MODE5] = "asus-mode5",
18460 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18461 [ALC663_ASUS_MODE7] = "asus-mode7",
18462 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18463 [ALC272_DELL] = "dell",
18464 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18465 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18466 [ALC662_AUTO] = "auto",
18467};
18468
a9111321 18469static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18470 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18471 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18472 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18473 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18474 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18475 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18476 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18477 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18478 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18479 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18480 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18481 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18482 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18483 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18484 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18485 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18486 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18487 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18488 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18489 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18490 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18491 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18492 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18493 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18494 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18495 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18496 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18497 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18498 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18499 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18500 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18501 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18502 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18503 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18504 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18505 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18506 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18507 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18508 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18509 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18510 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18511 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18512 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18513 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18514 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18515 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18516 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18517 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18518 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18519 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18520 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18521 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18522 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18523 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18524 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18526 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18527 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18528 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18529 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18530 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18531 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18532 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18533 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18534 ALC662_3ST_6ch_DIG),
4dee8baa 18535 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18536 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18537 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18538 ALC662_3ST_6ch_DIG),
6227cdce 18539 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18540 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18541 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18542 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18543 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18544 ALC662_3ST_6ch_DIG),
dea0a509
TI
18545 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18546 ALC663_ASUS_H13),
965b76d2 18547 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18548 {}
18549};
18550
a9111321 18551static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18552 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18553 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18554 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18556 .dac_nids = alc662_dac_nids,
18557 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18558 .dig_in_nid = ALC662_DIGIN_NID,
18559 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18560 .channel_mode = alc662_3ST_2ch_modes,
18561 .input_mux = &alc662_capture_source,
18562 },
18563 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18564 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18565 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18567 .dac_nids = alc662_dac_nids,
18568 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18569 .dig_in_nid = ALC662_DIGIN_NID,
18570 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18571 .channel_mode = alc662_3ST_6ch_modes,
18572 .need_dac_fix = 1,
18573 .input_mux = &alc662_capture_source,
f12ab1e0 18574 },
bc9f98a9 18575 [ALC662_3ST_6ch] = {
f9e336f6 18576 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18577 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18579 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18581 .channel_mode = alc662_3ST_6ch_modes,
18582 .need_dac_fix = 1,
18583 .input_mux = &alc662_capture_source,
f12ab1e0 18584 },
bc9f98a9 18585 [ALC662_5ST_DIG] = {
f9e336f6 18586 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18587 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18589 .dac_nids = alc662_dac_nids,
18590 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18591 .dig_in_nid = ALC662_DIGIN_NID,
18592 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18593 .channel_mode = alc662_5stack_modes,
18594 .input_mux = &alc662_capture_source,
18595 },
18596 [ALC662_LENOVO_101E] = {
f9e336f6 18597 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18598 .init_verbs = { alc662_init_verbs,
18599 alc662_eapd_init_verbs,
18600 alc662_sue_init_verbs },
bc9f98a9
KY
18601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18602 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18604 .channel_mode = alc662_3ST_2ch_modes,
18605 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18606 .unsol_event = alc_sku_unsol_event,
18607 .setup = alc662_lenovo_101e_setup,
18608 .init_hook = alc_inithook,
bc9f98a9 18609 },
291702f0 18610 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18611 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18612 .init_verbs = { alc662_init_verbs,
a7f2371f 18613 alc662_eapd_init_verbs,
291702f0
KY
18614 alc662_eeepc_sue_init_verbs },
18615 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18616 .dac_nids = alc662_dac_nids,
291702f0
KY
18617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18618 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18619 .unsol_event = alc_sku_unsol_event,
4f5d1706 18620 .setup = alc662_eeepc_setup,
e9427969 18621 .init_hook = alc_inithook,
291702f0 18622 },
8c427226 18623 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18624 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18625 alc662_chmode_mixer },
18626 .init_verbs = { alc662_init_verbs,
a7f2371f 18627 alc662_eapd_init_verbs,
8c427226
KY
18628 alc662_eeepc_ep20_sue_init_verbs },
18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630 .dac_nids = alc662_dac_nids,
8c427226
KY
18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18632 .channel_mode = alc662_3ST_6ch_modes,
18633 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18634 .unsol_event = alc_sku_unsol_event,
4f5d1706 18635 .setup = alc662_eeepc_ep20_setup,
e9427969 18636 .init_hook = alc_inithook,
8c427226 18637 },
f1d4e28b 18638 [ALC662_ECS] = {
f9e336f6 18639 .mixers = { alc662_ecs_mixer },
f1d4e28b 18640 .init_verbs = { alc662_init_verbs,
a7f2371f 18641 alc662_eapd_init_verbs,
f1d4e28b
KY
18642 alc662_ecs_init_verbs },
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .dac_nids = alc662_dac_nids,
18645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18646 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18647 .unsol_event = alc_sku_unsol_event,
4f5d1706 18648 .setup = alc662_eeepc_setup,
e9427969 18649 .init_hook = alc_inithook,
f1d4e28b 18650 },
6dda9f4a 18651 [ALC663_ASUS_M51VA] = {
f9e336f6 18652 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18653 .init_verbs = { alc662_init_verbs,
18654 alc662_eapd_init_verbs,
18655 alc663_m51va_init_verbs },
6dda9f4a
KY
18656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18657 .dac_nids = alc662_dac_nids,
18658 .dig_out_nid = ALC662_DIGOUT_NID,
18659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18660 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18661 .unsol_event = alc_sku_unsol_event,
4f5d1706 18662 .setup = alc663_m51va_setup,
3b8510ce 18663 .init_hook = alc_inithook,
6dda9f4a
KY
18664 },
18665 [ALC663_ASUS_G71V] = {
f9e336f6 18666 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18667 .init_verbs = { alc662_init_verbs,
18668 alc662_eapd_init_verbs,
18669 alc663_g71v_init_verbs },
6dda9f4a
KY
18670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18671 .dac_nids = alc662_dac_nids,
18672 .dig_out_nid = ALC662_DIGOUT_NID,
18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18675 .unsol_event = alc_sku_unsol_event,
4f5d1706 18676 .setup = alc663_g71v_setup,
e6a5e1b7 18677 .init_hook = alc_inithook,
6dda9f4a
KY
18678 },
18679 [ALC663_ASUS_H13] = {
f9e336f6 18680 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18681 .init_verbs = { alc662_init_verbs,
18682 alc662_eapd_init_verbs,
18683 alc663_m51va_init_verbs },
6dda9f4a
KY
18684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18685 .dac_nids = alc662_dac_nids,
18686 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18687 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18688 .setup = alc663_m51va_setup,
18689 .unsol_event = alc_sku_unsol_event,
18690 .init_hook = alc_inithook,
6dda9f4a
KY
18691 },
18692 [ALC663_ASUS_G50V] = {
f9e336f6 18693 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18694 .init_verbs = { alc662_init_verbs,
18695 alc662_eapd_init_verbs,
18696 alc663_g50v_init_verbs },
6dda9f4a
KY
18697 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18698 .dac_nids = alc662_dac_nids,
18699 .dig_out_nid = ALC662_DIGOUT_NID,
18700 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18701 .channel_mode = alc662_3ST_6ch_modes,
18702 .input_mux = &alc663_capture_source,
3b8510ce 18703 .unsol_event = alc_sku_unsol_event,
4f5d1706 18704 .setup = alc663_g50v_setup,
3b8510ce 18705 .init_hook = alc_inithook,
6dda9f4a 18706 },
f1d4e28b 18707 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18708 .mixers = { alc663_m51va_mixer },
18709 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18710 .init_verbs = { alc662_init_verbs,
a7f2371f 18711 alc662_eapd_init_verbs,
f1d4e28b
KY
18712 alc663_21jd_amic_init_verbs },
18713 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18714 .hp_nid = 0x03,
18715 .dac_nids = alc662_dac_nids,
18716 .dig_out_nid = ALC662_DIGOUT_NID,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18719 .unsol_event = alc_sku_unsol_event,
4f5d1706 18720 .setup = alc663_mode1_setup,
3b8510ce 18721 .init_hook = alc_inithook,
f1d4e28b
KY
18722 },
18723 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18724 .mixers = { alc662_1bjd_mixer },
18725 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18726 .init_verbs = { alc662_init_verbs,
a7f2371f 18727 alc662_eapd_init_verbs,
f1d4e28b
KY
18728 alc662_1bjd_amic_init_verbs },
18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18730 .dac_nids = alc662_dac_nids,
18731 .dig_out_nid = ALC662_DIGOUT_NID,
18732 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18733 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18734 .unsol_event = alc_sku_unsol_event,
4f5d1706 18735 .setup = alc662_mode2_setup,
3b8510ce 18736 .init_hook = alc_inithook,
f1d4e28b
KY
18737 },
18738 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18739 .mixers = { alc663_two_hp_m1_mixer },
18740 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18741 .init_verbs = { alc662_init_verbs,
a7f2371f 18742 alc662_eapd_init_verbs,
f1d4e28b
KY
18743 alc663_two_hp_amic_m1_init_verbs },
18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18745 .hp_nid = 0x03,
18746 .dac_nids = alc662_dac_nids,
18747 .dig_out_nid = ALC662_DIGOUT_NID,
18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18749 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18750 .unsol_event = alc_sku_unsol_event,
4f5d1706 18751 .setup = alc663_mode3_setup,
3b8510ce 18752 .init_hook = alc_inithook,
f1d4e28b
KY
18753 },
18754 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18755 .mixers = { alc663_asus_21jd_clfe_mixer },
18756 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18757 .init_verbs = { alc662_init_verbs,
a7f2371f 18758 alc662_eapd_init_verbs,
f1d4e28b
KY
18759 alc663_21jd_amic_init_verbs},
18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18761 .hp_nid = 0x03,
18762 .dac_nids = alc662_dac_nids,
18763 .dig_out_nid = ALC662_DIGOUT_NID,
18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18765 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18766 .unsol_event = alc_sku_unsol_event,
4f5d1706 18767 .setup = alc663_mode4_setup,
3b8510ce 18768 .init_hook = alc_inithook,
f1d4e28b
KY
18769 },
18770 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18771 .mixers = { alc663_asus_15jd_clfe_mixer },
18772 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18773 .init_verbs = { alc662_init_verbs,
a7f2371f 18774 alc662_eapd_init_verbs,
f1d4e28b
KY
18775 alc663_15jd_amic_init_verbs },
18776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18777 .hp_nid = 0x03,
18778 .dac_nids = alc662_dac_nids,
18779 .dig_out_nid = ALC662_DIGOUT_NID,
18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18781 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18782 .unsol_event = alc_sku_unsol_event,
4f5d1706 18783 .setup = alc663_mode5_setup,
3b8510ce 18784 .init_hook = alc_inithook,
f1d4e28b
KY
18785 },
18786 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18787 .mixers = { alc663_two_hp_m2_mixer },
18788 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18789 .init_verbs = { alc662_init_verbs,
a7f2371f 18790 alc662_eapd_init_verbs,
f1d4e28b
KY
18791 alc663_two_hp_amic_m2_init_verbs },
18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18793 .hp_nid = 0x03,
18794 .dac_nids = alc662_dac_nids,
18795 .dig_out_nid = ALC662_DIGOUT_NID,
18796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18797 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18798 .unsol_event = alc_sku_unsol_event,
4f5d1706 18799 .setup = alc663_mode6_setup,
3b8510ce 18800 .init_hook = alc_inithook,
f1d4e28b 18801 },
ebb83eeb
KY
18802 [ALC663_ASUS_MODE7] = {
18803 .mixers = { alc663_mode7_mixer },
18804 .cap_mixer = alc662_auto_capture_mixer,
18805 .init_verbs = { alc662_init_verbs,
a7f2371f 18806 alc662_eapd_init_verbs,
ebb83eeb
KY
18807 alc663_mode7_init_verbs },
18808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18809 .hp_nid = 0x03,
18810 .dac_nids = alc662_dac_nids,
18811 .dig_out_nid = ALC662_DIGOUT_NID,
18812 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18813 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18814 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18815 .setup = alc663_mode7_setup,
3b8510ce 18816 .init_hook = alc_inithook,
ebb83eeb
KY
18817 },
18818 [ALC663_ASUS_MODE8] = {
18819 .mixers = { alc663_mode8_mixer },
18820 .cap_mixer = alc662_auto_capture_mixer,
18821 .init_verbs = { alc662_init_verbs,
a7f2371f 18822 alc662_eapd_init_verbs,
ebb83eeb
KY
18823 alc663_mode8_init_verbs },
18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18825 .hp_nid = 0x03,
18826 .dac_nids = alc662_dac_nids,
18827 .dig_out_nid = ALC662_DIGOUT_NID,
18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18830 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18831 .setup = alc663_mode8_setup,
3b8510ce 18832 .init_hook = alc_inithook,
ebb83eeb 18833 },
622e84cd
KY
18834 [ALC272_DELL] = {
18835 .mixers = { alc663_m51va_mixer },
18836 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18837 .init_verbs = { alc662_init_verbs,
18838 alc662_eapd_init_verbs,
18839 alc272_dell_init_verbs },
622e84cd 18840 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18841 .dac_nids = alc272_dac_nids,
622e84cd
KY
18842 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18843 .adc_nids = alc272_adc_nids,
18844 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18845 .capsrc_nids = alc272_capsrc_nids,
18846 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18847 .unsol_event = alc_sku_unsol_event,
4f5d1706 18848 .setup = alc663_m51va_setup,
3b8510ce 18849 .init_hook = alc_inithook,
622e84cd
KY
18850 },
18851 [ALC272_DELL_ZM1] = {
18852 .mixers = { alc663_m51va_mixer },
18853 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eapd_init_verbs,
18856 alc272_dell_zm1_init_verbs },
622e84cd 18857 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18858 .dac_nids = alc272_dac_nids,
622e84cd
KY
18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18860 .adc_nids = alc662_adc_nids,
b59bdf3b 18861 .num_adc_nids = 1,
622e84cd
KY
18862 .capsrc_nids = alc662_capsrc_nids,
18863 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18864 .unsol_event = alc_sku_unsol_event,
4f5d1706 18865 .setup = alc663_m51va_setup,
3b8510ce 18866 .init_hook = alc_inithook,
622e84cd 18867 },
9541ba1d
CP
18868 [ALC272_SAMSUNG_NC10] = {
18869 .mixers = { alc272_nc10_mixer },
18870 .init_verbs = { alc662_init_verbs,
a7f2371f 18871 alc662_eapd_init_verbs,
9541ba1d
CP
18872 alc663_21jd_amic_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc272_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18877 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18878 .unsol_event = alc_sku_unsol_event,
4f5d1706 18879 .setup = alc663_mode4_setup,
3b8510ce 18880 .init_hook = alc_inithook,
9541ba1d 18881 },
bc9f98a9
KY
18882};
18883
18884
18885/*
18886 * BIOS auto configuration
18887 */
18888
7085ec12 18889/* convert from MIX nid to DAC */
604401a9 18890static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18891{
604401a9 18892 hda_nid_t list[5];
1304ac89
TI
18893 int i, num;
18894
18895 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18896 for (i = 0; i < num; i++) {
18897 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18898 return list[i];
18899 }
18900 return 0;
7085ec12
TI
18901}
18902
604401a9
TI
18903/* go down to the selector widget before the mixer */
18904static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18905{
18906 hda_nid_t srcs[5];
18907 int num = snd_hda_get_connections(codec, pin, srcs,
18908 ARRAY_SIZE(srcs));
18909 if (num != 1 ||
18910 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18911 return pin;
18912 return srcs[0];
18913}
18914
7085ec12 18915/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18916static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18917 hda_nid_t dac)
18918{
cc1c452e 18919 hda_nid_t mix[5];
7085ec12
TI
18920 int i, num;
18921
604401a9 18922 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18923 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18924 for (i = 0; i < num; i++) {
604401a9 18925 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18926 return mix[i];
18927 }
18928 return 0;
18929}
18930
ce764ab2
TI
18931/* select the connection from pin to DAC if needed */
18932static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18933 hda_nid_t dac)
18934{
18935 hda_nid_t mix[5];
18936 int i, num;
18937
18938 pin = alc_go_down_to_selector(codec, pin);
18939 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18940 if (num < 2)
18941 return 0;
18942 for (i = 0; i < num; i++) {
18943 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18944 snd_hda_codec_update_cache(codec, pin, 0,
18945 AC_VERB_SET_CONNECT_SEL, i);
18946 return 0;
18947 }
18948 }
18949 return 0;
18950}
18951
7085ec12 18952/* look for an empty DAC slot */
604401a9 18953static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18954{
18955 struct alc_spec *spec = codec->spec;
18956 hda_nid_t srcs[5];
18957 int i, j, num;
18958
604401a9 18959 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18960 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18961 for (i = 0; i < num; i++) {
604401a9 18962 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18963 if (!nid)
18964 continue;
18965 for (j = 0; j < spec->multiout.num_dacs; j++)
18966 if (spec->multiout.dac_nids[j] == nid)
18967 break;
18968 if (j >= spec->multiout.num_dacs)
18969 return nid;
18970 }
18971 return 0;
18972}
18973
18974/* fill in the dac_nids table from the parsed pin configuration */
18975static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18976 const struct auto_pin_cfg *cfg)
18977{
18978 struct alc_spec *spec = codec->spec;
18979 int i;
18980 hda_nid_t dac;
18981
18982 spec->multiout.dac_nids = spec->private_dac_nids;
18983 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18984 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18985 if (!dac)
18986 continue;
dda14410 18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
7085ec12
TI
18988 }
18989 return 0;
18990}
18991
bcb2f0f5
TI
18992static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18993 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18994{
bcb2f0f5 18995 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18996 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18997}
18998
bcb2f0f5
TI
18999static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19000 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19001{
bcb2f0f5 19002 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19003 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19004}
19005
bcb2f0f5
TI
19006#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19007 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19008#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19009 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19010#define alc662_add_stereo_vol(spec, pfx, nid) \
19011 alc662_add_vol_ctl(spec, pfx, nid, 3)
19012#define alc662_add_stereo_sw(spec, pfx, nid) \
19013 alc662_add_sw_ctl(spec, pfx, nid, 3)
19014
bc9f98a9 19015/* add playback controls from the parsed DAC table */
7085ec12 19016static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19017 const struct auto_pin_cfg *cfg)
19018{
7085ec12 19019 struct alc_spec *spec = codec->spec;
ea734963 19020 static const char * const chname[4] = {
bc9f98a9
KY
19021 "Front", "Surround", NULL /*CLFE*/, "Side"
19022 };
ce764ab2
TI
19023 const char *pfx = alc_get_line_out_pfx(spec, true);
19024 hda_nid_t nid, mix, pin;
19025 int i, err, noutputs;
bc9f98a9 19026
ce764ab2
TI
19027 noutputs = cfg->line_outs;
19028 if (spec->multi_ios > 0)
19029 noutputs += spec->multi_ios;
19030
19031 for (i = 0; i < noutputs; i++) {
7085ec12
TI
19032 nid = spec->multiout.dac_nids[i];
19033 if (!nid)
19034 continue;
ce764ab2
TI
19035 if (i >= cfg->line_outs)
19036 pin = spec->multi_io[i - 1].pin;
19037 else
19038 pin = cfg->line_out_pins[i];
19039 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 19040 if (!mix)
bc9f98a9 19041 continue;
bcb2f0f5 19042 if (!pfx && i == 2) {
bc9f98a9 19043 /* Center/LFE */
7085ec12 19044 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19045 if (err < 0)
19046 return err;
7085ec12 19047 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19048 if (err < 0)
19049 return err;
7085ec12 19050 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19051 if (err < 0)
19052 return err;
7085ec12 19053 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19054 if (err < 0)
19055 return err;
19056 } else {
bcb2f0f5 19057 const char *name = pfx;
5a882646
DH
19058 int index = i;
19059 if (!name) {
bcb2f0f5 19060 name = chname[i];
5a882646
DH
19061 index = 0;
19062 }
19063 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19064 if (err < 0)
19065 return err;
5a882646 19066 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19067 if (err < 0)
19068 return err;
19069 }
19070 }
19071 return 0;
19072}
19073
19074/* add playback controls for speaker and HP outputs */
7085ec12
TI
19075/* return DAC nid if any new DAC is assigned */
19076static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19077 const char *pfx)
19078{
7085ec12
TI
19079 struct alc_spec *spec = codec->spec;
19080 hda_nid_t nid, mix;
bc9f98a9 19081 int err;
bc9f98a9
KY
19082
19083 if (!pin)
19084 return 0;
604401a9 19085 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19086 if (!nid) {
7085ec12
TI
19087 /* the corresponding DAC is already occupied */
19088 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19089 return 0; /* no way */
19090 /* create a switch only */
0afe5f89 19091 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19093 }
19094
604401a9 19095 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19096 if (!mix)
19097 return 0;
19098 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19099 if (err < 0)
19100 return err;
19101 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19102 if (err < 0)
19103 return err;
19104 return nid;
bc9f98a9
KY
19105}
19106
19107/* create playback/capture controls for input pins */
05f5f477 19108#define alc662_auto_create_input_ctls \
4b7348a1 19109 alc882_auto_create_input_ctls
bc9f98a9
KY
19110
19111static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19112 hda_nid_t nid, int pin_type,
7085ec12 19113 hda_nid_t dac)
bc9f98a9 19114{
7085ec12 19115 int i, num;
ce503f38 19116 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19117
f6c7e546 19118 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19119 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19120 for (i = 0; i < num; i++) {
604401a9 19121 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19122 continue;
0e53f344
TI
19123 /* need the manual connection? */
19124 if (num > 1)
19125 snd_hda_codec_write(codec, nid, 0,
19126 AC_VERB_SET_CONNECT_SEL, i);
19127 /* unmute mixer widget inputs */
19128 snd_hda_codec_write(codec, srcs[i], 0,
19129 AC_VERB_SET_AMP_GAIN_MUTE,
19130 AMP_IN_UNMUTE(0));
19131 snd_hda_codec_write(codec, srcs[i], 0,
19132 AC_VERB_SET_AMP_GAIN_MUTE,
19133 AMP_IN_UNMUTE(1));
7085ec12 19134 return;
bc9f98a9
KY
19135 }
19136}
19137
19138static void alc662_auto_init_multi_out(struct hda_codec *codec)
19139{
19140 struct alc_spec *spec = codec->spec;
7085ec12 19141 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19142 int i;
19143
19144 for (i = 0; i <= HDA_SIDE; i++) {
19145 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19146 if (nid)
baba8ee9 19147 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19148 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19149 }
19150}
19151
19152static void alc662_auto_init_hp_out(struct hda_codec *codec)
19153{
19154 struct alc_spec *spec = codec->spec;
19155 hda_nid_t pin;
19156
19157 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19158 if (pin)
19159 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19160 spec->multiout.hp_nid);
f6c7e546
TI
19161 pin = spec->autocfg.speaker_pins[0];
19162 if (pin)
7085ec12
TI
19163 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19164 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19165}
19166
bc9f98a9
KY
19167#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19168
19169static void alc662_auto_init_analog_input(struct hda_codec *codec)
19170{
19171 struct alc_spec *spec = codec->spec;
66ceeb6b 19172 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19173 int i;
19174
66ceeb6b
TI
19175 for (i = 0; i < cfg->num_inputs; i++) {
19176 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19177 if (alc_is_input_pin(codec, nid)) {
30ea098f 19178 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19179 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19180 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19181 snd_hda_codec_write(codec, nid, 0,
19182 AC_VERB_SET_AMP_GAIN_MUTE,
19183 AMP_OUT_MUTE);
19184 }
19185 }
19186}
19187
f511b01c
TI
19188#define alc662_auto_init_input_src alc882_auto_init_input_src
19189
ce764ab2
TI
19190/*
19191 * multi-io helper
19192 */
19193static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19194 unsigned int location)
19195{
19196 struct alc_spec *spec = codec->spec;
19197 struct auto_pin_cfg *cfg = &spec->autocfg;
19198 int type, i, num_pins = 0;
19199
19200 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19201 for (i = 0; i < cfg->num_inputs; i++) {
19202 hda_nid_t nid = cfg->inputs[i].pin;
19203 hda_nid_t dac;
19204 unsigned int defcfg, caps;
19205 if (cfg->inputs[i].type != type)
19206 continue;
19207 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19208 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19209 continue;
19210 if (location && get_defcfg_location(defcfg) != location)
19211 continue;
19212 caps = snd_hda_query_pin_caps(codec, nid);
19213 if (!(caps & AC_PINCAP_OUT))
19214 continue;
19215 dac = alc_auto_look_for_dac(codec, nid);
19216 if (!dac)
19217 continue;
19218 spec->multi_io[num_pins].pin = nid;
19219 spec->multi_io[num_pins].dac = dac;
19220 num_pins++;
dda14410 19221 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19222 }
19223 }
19224 spec->multiout.num_dacs = 1;
19225 if (num_pins < 2)
19226 return 0;
19227 return num_pins;
19228}
19229
19230static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19231 struct snd_ctl_elem_info *uinfo)
19232{
19233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19234 struct alc_spec *spec = codec->spec;
19235
19236 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19237 uinfo->count = 1;
19238 uinfo->value.enumerated.items = spec->multi_ios + 1;
19239 if (uinfo->value.enumerated.item > spec->multi_ios)
19240 uinfo->value.enumerated.item = spec->multi_ios;
19241 sprintf(uinfo->value.enumerated.name, "%dch",
19242 (uinfo->value.enumerated.item + 1) * 2);
19243 return 0;
19244}
19245
19246static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19247 struct snd_ctl_elem_value *ucontrol)
19248{
19249 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19250 struct alc_spec *spec = codec->spec;
19251 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19252 return 0;
19253}
19254
19255static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19256{
19257 struct alc_spec *spec = codec->spec;
19258 hda_nid_t nid = spec->multi_io[idx].pin;
19259
19260 if (!spec->multi_io[idx].ctl_in)
19261 spec->multi_io[idx].ctl_in =
19262 snd_hda_codec_read(codec, nid, 0,
19263 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19264 if (output) {
19265 snd_hda_codec_update_cache(codec, nid, 0,
19266 AC_VERB_SET_PIN_WIDGET_CONTROL,
19267 PIN_OUT);
19268 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19269 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19270 HDA_AMP_MUTE, 0);
19271 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19272 } else {
19273 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19274 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19275 HDA_AMP_MUTE, HDA_AMP_MUTE);
19276 snd_hda_codec_update_cache(codec, nid, 0,
19277 AC_VERB_SET_PIN_WIDGET_CONTROL,
19278 spec->multi_io[idx].ctl_in);
19279 }
19280 return 0;
19281}
19282
19283static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19284 struct snd_ctl_elem_value *ucontrol)
19285{
19286 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19287 struct alc_spec *spec = codec->spec;
19288 int i, ch;
19289
19290 ch = ucontrol->value.enumerated.item[0];
19291 if (ch < 0 || ch > spec->multi_ios)
19292 return -EINVAL;
19293 if (ch == (spec->ext_channel_count - 1) / 2)
19294 return 0;
19295 spec->ext_channel_count = (ch + 1) * 2;
19296 for (i = 0; i < spec->multi_ios; i++)
19297 alc_set_multi_io(codec, i, i < ch);
19298 spec->multiout.max_channels = spec->ext_channel_count;
19299 return 1;
19300}
19301
a9111321 19302static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19304 .name = "Channel Mode",
19305 .info = alc_auto_ch_mode_info,
19306 .get = alc_auto_ch_mode_get,
19307 .put = alc_auto_ch_mode_put,
19308};
19309
19310static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19311{
19312 struct alc_spec *spec = codec->spec;
19313 struct auto_pin_cfg *cfg = &spec->autocfg;
19314 unsigned int location, defcfg;
19315 int num_pins;
19316
19317 if (cfg->line_outs != 1 ||
19318 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19319 return 0;
19320
19321 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19322 location = get_defcfg_location(defcfg);
19323
19324 num_pins = alc_auto_fill_multi_ios(codec, location);
19325 if (num_pins > 0) {
19326 struct snd_kcontrol_new *knew;
19327
19328 knew = alc_kcontrol_new(spec);
19329 if (!knew)
19330 return -ENOMEM;
19331 *knew = alc_auto_channel_mode_enum;
19332 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19333 if (!knew->name)
19334 return -ENOMEM;
19335
19336 spec->multi_ios = num_pins;
19337 spec->ext_channel_count = 2;
19338 spec->multiout.num_dacs = num_pins + 1;
19339 }
19340 return 0;
19341}
19342
bc9f98a9
KY
19343static int alc662_parse_auto_config(struct hda_codec *codec)
19344{
19345 struct alc_spec *spec = codec->spec;
19346 int err;
4c6d72d1 19347 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19348
19349 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19350 alc662_ignore);
19351 if (err < 0)
19352 return err;
19353 if (!spec->autocfg.line_outs)
19354 return 0; /* can't find valid BIOS pin config */
19355
7085ec12 19356 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19357 if (err < 0)
19358 return err;
19359 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19360 if (err < 0)
19361 return err;
7085ec12 19362 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19363 if (err < 0)
19364 return err;
7085ec12 19365 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19366 spec->autocfg.speaker_pins[0],
19367 "Speaker");
19368 if (err < 0)
19369 return err;
7085ec12
TI
19370 if (err)
19371 spec->multiout.extra_out_nid[0] = err;
19372 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19373 "Headphone");
19374 if (err < 0)
19375 return err;
7085ec12
TI
19376 if (err)
19377 spec->multiout.hp_nid = err;
05f5f477 19378 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19379 if (err < 0)
bc9f98a9
KY
19380 return err;
19381
19382 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19383
757899ac 19384 alc_auto_parse_digital(codec);
bc9f98a9 19385
603c4019 19386 if (spec->kctls.list)
d88897ea 19387 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19388
19389 spec->num_mux_defs = 1;
61b9b9b1 19390 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19391
ee979a14
TI
19392 err = alc_auto_add_mic_boost(codec);
19393 if (err < 0)
19394 return err;
19395
6227cdce
KY
19396 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19397 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19398 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19399 else
19400 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19401
8c87286f 19402 return 1;
bc9f98a9
KY
19403}
19404
19405/* additional initialization for auto-configuration model */
19406static void alc662_auto_init(struct hda_codec *codec)
19407{
f6c7e546 19408 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19409 alc662_auto_init_multi_out(codec);
19410 alc662_auto_init_hp_out(codec);
19411 alc662_auto_init_analog_input(codec);
f511b01c 19412 alc662_auto_init_input_src(codec);
757899ac 19413 alc_auto_init_digital(codec);
f6c7e546 19414 if (spec->unsol_event)
7fb0d78f 19415 alc_inithook(codec);
bc9f98a9
KY
19416}
19417
6be7948f 19418static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19419 const struct alc_fixup *fix, int action)
6fc398cb 19420{
b5bfbc67 19421 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19422 return;
6be7948f
TB
19423 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19424 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19425 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19426 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19427 (0 << AC_AMPCAP_MUTE_SHIFT)))
19428 printk(KERN_WARNING
19429 "hda_codec: failed to override amp caps for NID 0x2\n");
19430}
19431
6cb3b707 19432enum {
2df03514 19433 ALC662_FIXUP_ASPIRE,
6cb3b707 19434 ALC662_FIXUP_IDEAPAD,
6be7948f 19435 ALC272_FIXUP_MARIO,
d2ebd479 19436 ALC662_FIXUP_CZC_P10T,
94024cd1 19437 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19438};
19439
19440static const struct alc_fixup alc662_fixups[] = {
2df03514 19441 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19442 .type = ALC_FIXUP_PINS,
19443 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19444 { 0x15, 0x99130112 }, /* subwoofer */
19445 { }
19446 }
19447 },
6cb3b707 19448 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19449 .type = ALC_FIXUP_PINS,
19450 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19451 { 0x17, 0x99130112 }, /* subwoofer */
19452 { }
19453 }
19454 },
6be7948f 19455 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19456 .type = ALC_FIXUP_FUNC,
19457 .v.func = alc272_fixup_mario,
d2ebd479
AA
19458 },
19459 [ALC662_FIXUP_CZC_P10T] = {
19460 .type = ALC_FIXUP_VERBS,
19461 .v.verbs = (const struct hda_verb[]) {
19462 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19463 {}
19464 }
19465 },
94024cd1
DH
19466 [ALC662_FIXUP_SKU_IGNORE] = {
19467 .type = ALC_FIXUP_SKU,
19468 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19469 },
6cb3b707
DH
19470};
19471
a9111321 19472static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19473 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19474 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19475 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19476 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19477 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19478 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19479 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19480 {}
19481};
19482
6be7948f
TB
19483static const struct alc_model_fixup alc662_fixup_models[] = {
19484 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19485 {}
19486};
6cb3b707
DH
19487
19488
bc9f98a9
KY
19489static int patch_alc662(struct hda_codec *codec)
19490{
19491 struct alc_spec *spec;
19492 int err, board_config;
693194f3 19493 int coef;
bc9f98a9
KY
19494
19495 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19496 if (!spec)
19497 return -ENOMEM;
19498
19499 codec->spec = spec;
19500
da00c244
KY
19501 alc_auto_parse_customize_define(codec);
19502
2c3bf9ab
TI
19503 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19504
693194f3
KY
19505 coef = alc_read_coef_idx(codec, 0);
19506 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19507 alc_codec_rename(codec, "ALC661");
693194f3
KY
19508 else if (coef & (1 << 14) &&
19509 codec->bus->pci->subsystem_vendor == 0x1025 &&
19510 spec->cdefine.platform_type == 1)
c027ddcd 19511 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19512 else if (coef == 0x4011)
19513 alc_codec_rename(codec, "ALC656");
274693f3 19514
bc9f98a9
KY
19515 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19516 alc662_models,
19517 alc662_cfg_tbl);
19518 if (board_config < 0) {
9a11f1aa
TI
19519 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19520 codec->chip_name);
bc9f98a9
KY
19521 board_config = ALC662_AUTO;
19522 }
19523
19524 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19525 alc_pick_fixup(codec, alc662_fixup_models,
19526 alc662_fixup_tbl, alc662_fixups);
19527 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19528 /* automatic parse from the BIOS config */
19529 err = alc662_parse_auto_config(codec);
19530 if (err < 0) {
19531 alc_free(codec);
19532 return err;
8c87286f 19533 } else if (!err) {
bc9f98a9
KY
19534 printk(KERN_INFO
19535 "hda_codec: Cannot set up configuration "
19536 "from BIOS. Using base mode...\n");
19537 board_config = ALC662_3ST_2ch_DIG;
19538 }
19539 }
19540
dc1eae25 19541 if (has_cdefine_beep(codec)) {
8af2591d
TI
19542 err = snd_hda_attach_beep_device(codec, 0x1);
19543 if (err < 0) {
19544 alc_free(codec);
19545 return err;
19546 }
680cd536
KK
19547 }
19548
bc9f98a9 19549 if (board_config != ALC662_AUTO)
e9c364c0 19550 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19551
bc9f98a9
KY
19552 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19553 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19554
bc9f98a9
KY
19555 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19556 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19557
dd704698
TI
19558 if (!spec->adc_nids) {
19559 spec->adc_nids = alc662_adc_nids;
19560 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19561 }
19562 if (!spec->capsrc_nids)
19563 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19564
f9e336f6 19565 if (!spec->cap_mixer)
b59bdf3b 19566 set_capture_mixer(codec);
cec27c89 19567
dc1eae25 19568 if (has_cdefine_beep(codec)) {
da00c244
KY
19569 switch (codec->vendor_id) {
19570 case 0x10ec0662:
19571 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19572 break;
19573 case 0x10ec0272:
19574 case 0x10ec0663:
19575 case 0x10ec0665:
19576 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19577 break;
19578 case 0x10ec0273:
19579 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19580 break;
19581 }
cec27c89 19582 }
2134ea4f
TI
19583 spec->vmaster_nid = 0x02;
19584
b5bfbc67
TI
19585 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19586
bc9f98a9 19587 codec->patch_ops = alc_patch_ops;
b5bfbc67 19588 if (board_config == ALC662_AUTO)
bc9f98a9 19589 spec->init_hook = alc662_auto_init;
1c716153 19590 spec->shutup = alc_eapd_shutup;
6cb3b707 19591
bf1b0225
KY
19592 alc_init_jacks(codec);
19593
cb53c626
TI
19594#ifdef CONFIG_SND_HDA_POWER_SAVE
19595 if (!spec->loopback.amplist)
19596 spec->loopback.amplist = alc662_loopbacks;
19597#endif
bc9f98a9
KY
19598
19599 return 0;
19600}
19601
274693f3
KY
19602static int patch_alc888(struct hda_codec *codec)
19603{
19604 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19605 kfree(codec->chip_name);
01e0f137
KY
19606 if (codec->vendor_id == 0x10ec0887)
19607 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19608 else
19609 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19610 if (!codec->chip_name) {
19611 alc_free(codec);
274693f3 19612 return -ENOMEM;
ac2c92e0
TI
19613 }
19614 return patch_alc662(codec);
274693f3 19615 }
ac2c92e0 19616 return patch_alc882(codec);
274693f3
KY
19617}
19618
b478b998
KY
19619static int patch_alc899(struct hda_codec *codec)
19620{
19621 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19622 kfree(codec->chip_name);
19623 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19624 }
19625 return patch_alc882(codec);
19626}
19627
d1eb57f4
KY
19628/*
19629 * ALC680 support
19630 */
c69aefab 19631#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19632#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19633#define alc680_modes alc260_modes
19634
4c6d72d1 19635static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19636 /* Lout1, Lout2, hp */
19637 0x02, 0x03, 0x04
19638};
19639
4c6d72d1 19640static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19641 /* ADC0-2 */
19642 /* DMIC, MIC, Line-in*/
19643 0x07, 0x08, 0x09
19644};
19645
c69aefab
KY
19646/*
19647 * Analog capture ADC cgange
19648 */
66ceeb6b
TI
19649static void alc680_rec_autoswitch(struct hda_codec *codec)
19650{
19651 struct alc_spec *spec = codec->spec;
19652 struct auto_pin_cfg *cfg = &spec->autocfg;
19653 int pin_found = 0;
19654 int type_found = AUTO_PIN_LAST;
19655 hda_nid_t nid;
19656 int i;
19657
19658 for (i = 0; i < cfg->num_inputs; i++) {
19659 nid = cfg->inputs[i].pin;
06dec228 19660 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19661 continue;
19662 if (snd_hda_jack_detect(codec, nid)) {
19663 if (cfg->inputs[i].type < type_found) {
19664 type_found = cfg->inputs[i].type;
19665 pin_found = nid;
19666 }
19667 }
19668 }
19669
19670 nid = 0x07;
19671 if (pin_found)
19672 snd_hda_get_connections(codec, pin_found, &nid, 1);
19673
19674 if (nid != spec->cur_adc)
19675 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19676 spec->cur_adc = nid;
19677 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19678 spec->cur_adc_format);
19679}
19680
c69aefab
KY
19681static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19682 struct hda_codec *codec,
19683 unsigned int stream_tag,
19684 unsigned int format,
19685 struct snd_pcm_substream *substream)
19686{
19687 struct alc_spec *spec = codec->spec;
c69aefab 19688
66ceeb6b 19689 spec->cur_adc = 0x07;
c69aefab
KY
19690 spec->cur_adc_stream_tag = stream_tag;
19691 spec->cur_adc_format = format;
19692
66ceeb6b 19693 alc680_rec_autoswitch(codec);
c69aefab
KY
19694 return 0;
19695}
19696
19697static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19698 struct hda_codec *codec,
19699 struct snd_pcm_substream *substream)
19700{
19701 snd_hda_codec_cleanup_stream(codec, 0x07);
19702 snd_hda_codec_cleanup_stream(codec, 0x08);
19703 snd_hda_codec_cleanup_stream(codec, 0x09);
19704 return 0;
19705}
19706
a9111321 19707static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19708 .substreams = 1, /* can be overridden */
19709 .channels_min = 2,
19710 .channels_max = 2,
19711 /* NID is set in alc_build_pcms */
19712 .ops = {
19713 .prepare = alc680_capture_pcm_prepare,
19714 .cleanup = alc680_capture_pcm_cleanup
19715 },
19716};
19717
a9111321 19718static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19719 /* output mixer control */
19720 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19721 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19724 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19726 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19727 { }
19728};
19729
a9111321 19730static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19731 .ops = &snd_hda_bind_vol,
19732 .values = {
19733 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19734 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19735 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19736 0
19737 },
19738};
19739
a9111321 19740static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19741 .ops = &snd_hda_bind_sw,
19742 .values = {
19743 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19744 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19746 0
19747 },
19748};
19749
a9111321 19750static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19751 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19752 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19753 { } /* end */
19754};
19755
19756/*
19757 * generic initialization of ADC, input mixers and output mixers
19758 */
a9111321 19759static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19763
c69aefab
KY
19764 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19768 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19769 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19770
19771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19776
19777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19778 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19779 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19780
d1eb57f4
KY
19781 { }
19782};
19783
c69aefab
KY
19784/* toggle speaker-output according to the hp-jack state */
19785static void alc680_base_setup(struct hda_codec *codec)
19786{
19787 struct alc_spec *spec = codec->spec;
19788
19789 spec->autocfg.hp_pins[0] = 0x16;
19790 spec->autocfg.speaker_pins[0] = 0x14;
19791 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19792 spec->autocfg.num_inputs = 2;
19793 spec->autocfg.inputs[0].pin = 0x18;
19794 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19795 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19796 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19797 spec->automute = 1;
19798 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19799}
19800
19801static void alc680_unsol_event(struct hda_codec *codec,
19802 unsigned int res)
19803{
19804 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19805 alc_hp_automute(codec);
c69aefab
KY
19806 if ((res >> 26) == ALC880_MIC_EVENT)
19807 alc680_rec_autoswitch(codec);
19808}
19809
19810static void alc680_inithook(struct hda_codec *codec)
19811{
d922b51d 19812 alc_hp_automute(codec);
c69aefab
KY
19813 alc680_rec_autoswitch(codec);
19814}
19815
d1eb57f4
KY
19816/* create input playback/capture controls for the given pin */
19817static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19818 const char *ctlname, int idx)
19819{
19820 hda_nid_t dac;
19821 int err;
19822
19823 switch (nid) {
19824 case 0x14:
19825 dac = 0x02;
19826 break;
19827 case 0x15:
19828 dac = 0x03;
19829 break;
19830 case 0x16:
19831 dac = 0x04;
19832 break;
19833 default:
19834 return 0;
19835 }
19836 if (spec->multiout.dac_nids[0] != dac &&
19837 spec->multiout.dac_nids[1] != dac) {
19838 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19839 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19840 HDA_OUTPUT));
19841 if (err < 0)
19842 return err;
19843
19844 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19845 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19846
19847 if (err < 0)
19848 return err;
dda14410 19849 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19850 }
19851
19852 return 0;
19853}
19854
19855/* add playback controls from the parsed DAC table */
19856static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19857 const struct auto_pin_cfg *cfg)
19858{
19859 hda_nid_t nid;
19860 int err;
19861
19862 spec->multiout.dac_nids = spec->private_dac_nids;
19863
19864 nid = cfg->line_out_pins[0];
19865 if (nid) {
19866 const char *name;
19867 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19868 name = "Speaker";
19869 else
19870 name = "Front";
19871 err = alc680_new_analog_output(spec, nid, name, 0);
19872 if (err < 0)
19873 return err;
19874 }
19875
19876 nid = cfg->speaker_pins[0];
19877 if (nid) {
19878 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19879 if (err < 0)
19880 return err;
19881 }
19882 nid = cfg->hp_pins[0];
19883 if (nid) {
19884 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19885 if (err < 0)
19886 return err;
19887 }
19888
19889 return 0;
19890}
19891
19892static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19893 hda_nid_t nid, int pin_type)
19894{
19895 alc_set_pin_output(codec, nid, pin_type);
19896}
19897
19898static void alc680_auto_init_multi_out(struct hda_codec *codec)
19899{
19900 struct alc_spec *spec = codec->spec;
19901 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19902 if (nid) {
19903 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19904 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19905 }
19906}
19907
19908static void alc680_auto_init_hp_out(struct hda_codec *codec)
19909{
19910 struct alc_spec *spec = codec->spec;
19911 hda_nid_t pin;
19912
19913 pin = spec->autocfg.hp_pins[0];
19914 if (pin)
19915 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19916 pin = spec->autocfg.speaker_pins[0];
19917 if (pin)
19918 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19919}
19920
19921/* pcm configuration: identical with ALC880 */
19922#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19923#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19924#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19925#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19926#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19927
19928/*
19929 * BIOS auto configuration
19930 */
19931static int alc680_parse_auto_config(struct hda_codec *codec)
19932{
19933 struct alc_spec *spec = codec->spec;
19934 int err;
4c6d72d1 19935 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19936
19937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19938 alc680_ignore);
19939 if (err < 0)
19940 return err;
c69aefab 19941
d1eb57f4
KY
19942 if (!spec->autocfg.line_outs) {
19943 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19944 spec->multiout.max_channels = 2;
19945 spec->no_analog = 1;
19946 goto dig_only;
19947 }
19948 return 0; /* can't find valid BIOS pin config */
19949 }
19950 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19951 if (err < 0)
19952 return err;
19953
19954 spec->multiout.max_channels = 2;
19955
19956 dig_only:
19957 /* digital only support output */
757899ac 19958 alc_auto_parse_digital(codec);
d1eb57f4
KY
19959 if (spec->kctls.list)
19960 add_mixer(spec, spec->kctls.list);
19961
19962 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19963
19964 err = alc_auto_add_mic_boost(codec);
19965 if (err < 0)
19966 return err;
19967
19968 return 1;
19969}
19970
19971#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19972
19973/* init callback for auto-configuration model -- overriding the default init */
19974static void alc680_auto_init(struct hda_codec *codec)
19975{
19976 struct alc_spec *spec = codec->spec;
19977 alc680_auto_init_multi_out(codec);
19978 alc680_auto_init_hp_out(codec);
19979 alc680_auto_init_analog_input(codec);
757899ac 19980 alc_auto_init_digital(codec);
d1eb57f4
KY
19981 if (spec->unsol_event)
19982 alc_inithook(codec);
19983}
19984
19985/*
19986 * configuration and preset
19987 */
ea734963 19988static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19989 [ALC680_BASE] = "base",
19990 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19991};
19992
a9111321 19993static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19994 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19995 {}
19996};
19997
a9111321 19998static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19999 [ALC680_BASE] = {
20000 .mixers = { alc680_base_mixer },
c69aefab 20001 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
20002 .init_verbs = { alc680_init_verbs },
20003 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20004 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20005 .dig_out_nid = ALC680_DIGOUT_NID,
20006 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20007 .channel_mode = alc680_modes,
c69aefab
KY
20008 .unsol_event = alc680_unsol_event,
20009 .setup = alc680_base_setup,
20010 .init_hook = alc680_inithook,
20011
d1eb57f4
KY
20012 },
20013};
20014
20015static int patch_alc680(struct hda_codec *codec)
20016{
20017 struct alc_spec *spec;
20018 int board_config;
20019 int err;
20020
20021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20022 if (spec == NULL)
20023 return -ENOMEM;
20024
20025 codec->spec = spec;
20026
20027 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20028 alc680_models,
20029 alc680_cfg_tbl);
20030
20031 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20032 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20033 codec->chip_name);
20034 board_config = ALC680_AUTO;
20035 }
20036
20037 if (board_config == ALC680_AUTO) {
20038 /* automatic parse from the BIOS config */
20039 err = alc680_parse_auto_config(codec);
20040 if (err < 0) {
20041 alc_free(codec);
20042 return err;
20043 } else if (!err) {
20044 printk(KERN_INFO
20045 "hda_codec: Cannot set up configuration "
20046 "from BIOS. Using base mode...\n");
20047 board_config = ALC680_BASE;
20048 }
20049 }
20050
20051 if (board_config != ALC680_AUTO)
20052 setup_preset(codec, &alc680_presets[board_config]);
20053
20054 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20055 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20056 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20057 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20058
20059 if (!spec->adc_nids) {
20060 spec->adc_nids = alc680_adc_nids;
20061 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20062 }
20063
20064 if (!spec->cap_mixer)
20065 set_capture_mixer(codec);
20066
20067 spec->vmaster_nid = 0x02;
20068
20069 codec->patch_ops = alc_patch_ops;
20070 if (board_config == ALC680_AUTO)
20071 spec->init_hook = alc680_auto_init;
20072
20073 return 0;
20074}
20075
1da177e4
LT
20076/*
20077 * patch entries
20078 */
a9111321 20079static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 20080 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 20081 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20082 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20083 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20084 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20085 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20086 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20088 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 20089 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 20090 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20091 .patch = patch_alc861 },
f32610ed
JS
20092 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20093 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20094 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20095 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20096 .patch = patch_alc882 },
bc9f98a9
KY
20097 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20098 .patch = patch_alc662 },
6dda9f4a 20099 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20100 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20101 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20102 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20103 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20104 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20105 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20106 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20107 .patch = patch_alc882 },
cb308f97 20108 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20109 .patch = patch_alc882 },
df694daa 20110 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20111 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20112 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20113 .patch = patch_alc882 },
274693f3 20114 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20115 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20116 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 20117 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
20118 {} /* terminator */
20119};
1289e9e8
TI
20120
20121MODULE_ALIAS("snd-hda-codec-id:10ec*");
20122
20123MODULE_LICENSE("GPL");
20124MODULE_DESCRIPTION("Realtek HD-audio codec");
20125
20126static struct hda_codec_preset_list realtek_list = {
20127 .preset = snd_hda_preset_realtek,
20128 .owner = THIS_MODULE,
20129};
20130
20131static int __init patch_realtek_init(void)
20132{
20133 return snd_hda_add_codec_preset(&realtek_list);
20134}
20135
20136static void __exit patch_realtek_exit(void)
20137{
20138 snd_hda_delete_codec_preset(&realtek_list);
20139}
20140
20141module_init(patch_realtek_init)
20142module_exit(patch_realtek_exit)