]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix invalid unsol tag for some alc262 model quirks
[mirror_ubuntu-bionic-kernel.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
1a1455de
TI
1144 if (!spec->automute)
1145 on = 0;
1146 else
1147 on = spec->jack_present | spec->line_jack_present;
1148 on |= spec->master_mute;
e6a5e1b7 1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1150 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1151
1152 /* toggle line-out mutes if needed, too */
1a1455de
TI
1153 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1154 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1155 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1156 return;
1a1455de
TI
1157 if (!spec->automute_lines || !spec->automute)
1158 on = 0;
1159 else
1160 on = spec->jack_present;
1161 on |= spec->master_mute;
e6a5e1b7 1162 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1163 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1164}
1165
1166static void alc_hp_automute(struct hda_codec *codec)
1167{
1168 struct alc_spec *spec = codec->spec;
1169
1170 if (!spec->automute)
1171 return;
1172 spec->jack_present =
1173 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1174 spec->autocfg.hp_pins);
1175 update_speakers(codec);
1176}
1177
1178static void alc_line_automute(struct hda_codec *codec)
1179{
1180 struct alc_spec *spec = codec->spec;
1181
1182 if (!spec->automute || !spec->detect_line)
1183 return;
1184 spec->line_jack_present =
1185 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1186 spec->autocfg.line_out_pins);
1187 update_speakers(codec);
1188}
1189
6c819492
TI
1190static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1191 hda_nid_t nid)
1192{
1193 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1194 int i, nums;
1195
1196 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1197 for (i = 0; i < nums; i++)
1198 if (conn[i] == nid)
1199 return i;
1200 return -1;
1201}
1202
840b64c0
TI
1203/* switch the current ADC according to the jack state */
1204static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1205{
1206 struct alc_spec *spec = codec->spec;
1207 unsigned int present;
1208 hda_nid_t new_adc;
1209
1210 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1211 if (present)
1212 spec->cur_adc_idx = 1;
1213 else
1214 spec->cur_adc_idx = 0;
1215 new_adc = spec->adc_nids[spec->cur_adc_idx];
1216 if (spec->cur_adc && spec->cur_adc != new_adc) {
1217 /* stream is running, let's swap the current ADC */
f0cea797 1218 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1219 spec->cur_adc = new_adc;
1220 snd_hda_codec_setup_stream(codec, new_adc,
1221 spec->cur_adc_stream_tag, 0,
1222 spec->cur_adc_format);
1223 }
1224}
1225
7fb0d78f
KY
1226static void alc_mic_automute(struct hda_codec *codec)
1227{
1228 struct alc_spec *spec = codec->spec;
8ed99d97 1229 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1230 unsigned int present, type;
1231 hda_nid_t cap_nid;
1232
b59bdf3b
TI
1233 if (!spec->auto_mic)
1234 return;
6c819492
TI
1235 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1236 return;
1237 if (snd_BUG_ON(!spec->adc_nids))
1238 return;
1239
840b64c0
TI
1240 if (spec->dual_adc_switch) {
1241 alc_dual_mic_adc_auto_switch(codec);
1242 return;
1243 }
1244
6c819492
TI
1245 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1246
8ed99d97
TI
1247 alive = &spec->int_mic;
1248 dead1 = &spec->ext_mic;
1249 dead2 = &spec->dock_mic;
1250
864f92be 1251 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1252 if (present) {
1253 alive = &spec->ext_mic;
8ed99d97
TI
1254 dead1 = &spec->int_mic;
1255 dead2 = &spec->dock_mic;
1256 }
1257 if (!present && spec->dock_mic.pin > 0) {
1258 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 if (present) {
1260 alive = &spec->dock_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->ext_mic;
1263 }
1264 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
6c819492
TI
1265 }
1266
6c819492
TI
1267 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1268 if (type == AC_WID_AUD_MIX) {
1269 /* Matrix-mixer style (e.g. ALC882) */
1270 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1271 alive->mux_idx,
1272 HDA_AMP_MUTE, 0);
8ed99d97
TI
1273 if (dead1->pin > 0)
1274 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1275 dead1->mux_idx,
1276 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 if (dead2->pin > 0)
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 dead2->mux_idx,
1280 HDA_AMP_MUTE, HDA_AMP_MUTE);
6c819492
TI
1281 } else {
1282 /* MUX style (e.g. ALC880) */
1283 snd_hda_codec_write_cache(codec, cap_nid, 0,
1284 AC_VERB_SET_CONNECT_SEL,
1285 alive->mux_idx);
1286 }
cd372fb3 1287 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1288
1289 /* FIXME: analog mixer */
7fb0d78f
KY
1290}
1291
c9b58006
KY
1292/* unsolicited event for HP jack sensing */
1293static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1294{
1295 if (codec->vendor_id == 0x10ec0880)
1296 res >>= 28;
1297 else
1298 res >>= 26;
a9fd4f3f
TI
1299 switch (res) {
1300 case ALC880_HP_EVENT:
d922b51d 1301 alc_hp_automute(codec);
a9fd4f3f 1302 break;
e6a5e1b7
TI
1303 case ALC880_FRONT_EVENT:
1304 alc_line_automute(codec);
1305 break;
a9fd4f3f 1306 case ALC880_MIC_EVENT:
7fb0d78f 1307 alc_mic_automute(codec);
a9fd4f3f
TI
1308 break;
1309 }
7fb0d78f
KY
1310}
1311
1312static void alc_inithook(struct hda_codec *codec)
1313{
d922b51d 1314 alc_hp_automute(codec);
e6a5e1b7 1315 alc_line_automute(codec);
7fb0d78f 1316 alc_mic_automute(codec);
c9b58006
KY
1317}
1318
f9423e7a
KY
1319/* additional initialization for ALC888 variants */
1320static void alc888_coef_init(struct hda_codec *codec)
1321{
1322 unsigned int tmp;
1323
1324 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1325 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1326 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1327 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1328 /* alc888S-VC */
1329 snd_hda_codec_read(codec, 0x20, 0,
1330 AC_VERB_SET_PROC_COEF, 0x830);
1331 else
1332 /* alc888-VB */
1333 snd_hda_codec_read(codec, 0x20, 0,
1334 AC_VERB_SET_PROC_COEF, 0x3030);
1335}
1336
87a8c370
JK
1337static void alc889_coef_init(struct hda_codec *codec)
1338{
1339 unsigned int tmp;
1340
1341 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1342 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1343 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1344 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1345}
1346
3fb4a508
TI
1347/* turn on/off EAPD control (only if available) */
1348static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1349{
1350 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1351 return;
1352 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1353 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1354 on ? 2 : 0);
1355}
1356
691f1fcc
TI
1357/* turn on/off EAPD controls of the codec */
1358static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359{
1360 /* We currently only handle front, HP */
1361 switch (codec->vendor_id) {
1362 case 0x10ec0260:
1363 set_eapd(codec, 0x0f, on);
1364 set_eapd(codec, 0x10, on);
1365 break;
1366 case 0x10ec0262:
1367 case 0x10ec0267:
1368 case 0x10ec0268:
1369 case 0x10ec0269:
1370 case 0x10ec0270:
1371 case 0x10ec0272:
1372 case 0x10ec0660:
1373 case 0x10ec0662:
1374 case 0x10ec0663:
1375 case 0x10ec0665:
1376 case 0x10ec0862:
1377 case 0x10ec0889:
1378 case 0x10ec0892:
1379 set_eapd(codec, 0x14, on);
1380 set_eapd(codec, 0x15, on);
1381 break;
1382 }
1383}
1384
1c716153
TI
1385/* generic shutup callback;
1386 * just turning off EPAD and a little pause for avoiding pop-noise
1387 */
1388static void alc_eapd_shutup(struct hda_codec *codec)
1389{
1390 alc_auto_setup_eapd(codec, false);
1391 msleep(200);
1392}
1393
4a79ba34 1394static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1395{
4a79ba34 1396 unsigned int tmp;
bc9f98a9 1397
4a79ba34
TI
1398 switch (type) {
1399 case ALC_INIT_GPIO1:
bc9f98a9
KY
1400 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1401 break;
4a79ba34 1402 case ALC_INIT_GPIO2:
bc9f98a9
KY
1403 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1404 break;
4a79ba34 1405 case ALC_INIT_GPIO3:
bdd148a3
KY
1406 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1407 break;
4a79ba34 1408 case ALC_INIT_DEFAULT:
691f1fcc 1409 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1410 switch (codec->vendor_id) {
1411 case 0x10ec0260:
1412 snd_hda_codec_write(codec, 0x1a, 0,
1413 AC_VERB_SET_COEF_INDEX, 7);
1414 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1415 AC_VERB_GET_PROC_COEF, 0);
1416 snd_hda_codec_write(codec, 0x1a, 0,
1417 AC_VERB_SET_COEF_INDEX, 7);
1418 snd_hda_codec_write(codec, 0x1a, 0,
1419 AC_VERB_SET_PROC_COEF,
1420 tmp | 0x2010);
1421 break;
1422 case 0x10ec0262:
1423 case 0x10ec0880:
1424 case 0x10ec0882:
1425 case 0x10ec0883:
1426 case 0x10ec0885:
4a5a4c56 1427 case 0x10ec0887:
20b67ddd 1428 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1429 alc889_coef_init(codec);
c9b58006 1430 break;
f9423e7a 1431 case 0x10ec0888:
4a79ba34 1432 alc888_coef_init(codec);
f9423e7a 1433 break;
0aea778e 1434#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1435 case 0x10ec0267:
1436 case 0x10ec0268:
1437 snd_hda_codec_write(codec, 0x20, 0,
1438 AC_VERB_SET_COEF_INDEX, 7);
1439 tmp = snd_hda_codec_read(codec, 0x20, 0,
1440 AC_VERB_GET_PROC_COEF, 0);
1441 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1442 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1443 snd_hda_codec_write(codec, 0x20, 0,
1444 AC_VERB_SET_PROC_COEF,
1445 tmp | 0x3000);
1446 break;
0aea778e 1447#endif /* XXX */
bc9f98a9 1448 }
4a79ba34
TI
1449 break;
1450 }
1451}
1452
1a1455de
TI
1453static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1454 struct snd_ctl_elem_info *uinfo)
1455{
ae8a60a5
TI
1456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1457 struct alc_spec *spec = codec->spec;
1458 static const char * const texts2[] = {
1459 "Disabled", "Enabled"
1460 };
1461 static const char * const texts3[] = {
1a1455de
TI
1462 "Disabled", "Speaker Only", "Line-Out+Speaker"
1463 };
ae8a60a5 1464 const char * const *texts;
1a1455de
TI
1465
1466 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1467 uinfo->count = 1;
ae8a60a5
TI
1468 if (spec->automute_hp_lo) {
1469 uinfo->value.enumerated.items = 3;
1470 texts = texts3;
1471 } else {
1472 uinfo->value.enumerated.items = 2;
1473 texts = texts2;
1474 }
1475 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1476 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1477 strcpy(uinfo->value.enumerated.name,
1478 texts[uinfo->value.enumerated.item]);
1479 return 0;
1480}
1481
1482static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1483 struct snd_ctl_elem_value *ucontrol)
1484{
1485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1486 struct alc_spec *spec = codec->spec;
1487 unsigned int val;
1488 if (!spec->automute)
1489 val = 0;
1490 else if (!spec->automute_lines)
1491 val = 1;
1492 else
1493 val = 2;
1494 ucontrol->value.enumerated.item[0] = val;
1495 return 0;
1496}
1497
1498static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1499 struct snd_ctl_elem_value *ucontrol)
1500{
1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1502 struct alc_spec *spec = codec->spec;
1503
1504 switch (ucontrol->value.enumerated.item[0]) {
1505 case 0:
1506 if (!spec->automute)
1507 return 0;
1508 spec->automute = 0;
1509 break;
1510 case 1:
1511 if (spec->automute && !spec->automute_lines)
1512 return 0;
1513 spec->automute = 1;
1514 spec->automute_lines = 0;
1515 break;
1516 case 2:
ae8a60a5
TI
1517 if (!spec->automute_hp_lo)
1518 return -EINVAL;
1a1455de
TI
1519 if (spec->automute && spec->automute_lines)
1520 return 0;
1521 spec->automute = 1;
1522 spec->automute_lines = 1;
1523 break;
1524 default:
1525 return -EINVAL;
1526 }
1527 update_speakers(codec);
1528 return 1;
1529}
1530
a9111321 1531static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 .name = "Auto-Mute Mode",
1534 .info = alc_automute_mode_info,
1535 .get = alc_automute_mode_get,
1536 .put = alc_automute_mode_put,
1537};
1538
1539static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1540
1541static int alc_add_automute_mode_enum(struct hda_codec *codec)
1542{
1543 struct alc_spec *spec = codec->spec;
1544 struct snd_kcontrol_new *knew;
1545
1546 knew = alc_kcontrol_new(spec);
1547 if (!knew)
1548 return -ENOMEM;
1549 *knew = alc_automute_mode_enum;
1550 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1551 if (!knew->name)
1552 return -ENOMEM;
1553 return 0;
1554}
1555
4a79ba34
TI
1556static void alc_init_auto_hp(struct hda_codec *codec)
1557{
1558 struct alc_spec *spec = codec->spec;
bb35febd 1559 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1560 int present = 0;
bb35febd 1561 int i;
4a79ba34 1562
1daf5f46
TI
1563 if (cfg->hp_pins[0])
1564 present++;
1565 if (cfg->line_out_pins[0])
1566 present++;
1567 if (cfg->speaker_pins[0])
1568 present++;
1569 if (present < 2) /* need two different output types */
1570 return;
ae8a60a5
TI
1571 if (present == 3)
1572 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1573
bb35febd 1574 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1575 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1576 sizeof(cfg->speaker_pins));
1577 cfg->speaker_outs = cfg->line_outs;
1578 }
1579
1580 if (!cfg->hp_pins[0]) {
1581 memcpy(cfg->hp_pins, cfg->line_out_pins,
1582 sizeof(cfg->hp_pins));
1583 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1584 }
1585
bb35febd 1586 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1587 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1588 if (!is_jack_detectable(codec, nid))
1a1455de 1589 continue;
bb35febd 1590 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1591 nid);
1592 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1593 AC_VERB_SET_UNSOLICITED_ENABLE,
1594 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1595 spec->automute = 1;
1596 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1597 }
1a1455de
TI
1598 if (spec->automute && cfg->line_out_pins[0] &&
1599 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1600 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1601 for (i = 0; i < cfg->line_outs; i++) {
1602 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1603 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1604 continue;
1605 snd_printdd("realtek: Enable Line-Out auto-muting "
1606 "on NID 0x%x\n", nid);
1607 snd_hda_codec_write_cache(codec, nid, 0,
1608 AC_VERB_SET_UNSOLICITED_ENABLE,
1609 AC_USRSP_EN | ALC880_FRONT_EVENT);
1610 spec->detect_line = 1;
1611 }
52d3cb88 1612 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1613 }
1614
1615 if (spec->automute) {
1a1455de
TI
1616 /* create a control for automute mode */
1617 alc_add_automute_mode_enum(codec);
ae8a60a5 1618 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1619 }
4a79ba34
TI
1620}
1621
6c819492
TI
1622static void alc_init_auto_mic(struct hda_codec *codec)
1623{
1624 struct alc_spec *spec = codec->spec;
1625 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1626 hda_nid_t fixed, ext, dock;
6c819492
TI
1627 int i;
1628
8ed99d97 1629 fixed = ext = dock = 0;
66ceeb6b
TI
1630 for (i = 0; i < cfg->num_inputs; i++) {
1631 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1632 unsigned int defcfg;
6c819492 1633 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1634 switch (snd_hda_get_input_pin_attr(defcfg)) {
1635 case INPUT_PIN_ATTR_INT:
6c819492
TI
1636 if (fixed)
1637 return; /* already occupied */
8ed99d97
TI
1638 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1639 return; /* invalid type */
6c819492
TI
1640 fixed = nid;
1641 break;
99ae28be
TI
1642 case INPUT_PIN_ATTR_UNUSED:
1643 return; /* invalid entry */
8ed99d97
TI
1644 case INPUT_PIN_ATTR_DOCK:
1645 if (dock)
1646 return; /* already occupied */
1647 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1648 return; /* invalid type */
1649 dock = nid;
1650 break;
99ae28be 1651 default:
6c819492
TI
1652 if (ext)
1653 return; /* already occupied */
8ed99d97
TI
1654 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1655 return; /* invalid type */
6c819492
TI
1656 ext = nid;
1657 break;
6c819492
TI
1658 }
1659 }
8ed99d97
TI
1660 if (!ext && dock) {
1661 ext = dock;
1662 dock = 0;
1663 }
eaa9b3a7
TI
1664 if (!ext || !fixed)
1665 return;
e35d9d6a 1666 if (!is_jack_detectable(codec, ext))
6c819492 1667 return; /* no unsol support */
8ed99d97
TI
1668 if (dock && !is_jack_detectable(codec, dock))
1669 return; /* no unsol support */
1670 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1671 ext, fixed, dock);
6c819492 1672 spec->ext_mic.pin = ext;
8ed99d97 1673 spec->dock_mic.pin = dock;
6c819492
TI
1674 spec->int_mic.pin = fixed;
1675 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1676 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1677 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1678 spec->auto_mic = 1;
1679 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1680 AC_VERB_SET_UNSOLICITED_ENABLE,
1681 AC_USRSP_EN | ALC880_MIC_EVENT);
1682 spec->unsol_event = alc_sku_unsol_event;
1683}
1684
90622917
DH
1685/* Could be any non-zero and even value. When used as fixup, tells
1686 * the driver to ignore any present sku defines.
1687 */
1688#define ALC_FIXUP_SKU_IGNORE (2)
1689
da00c244
KY
1690static int alc_auto_parse_customize_define(struct hda_codec *codec)
1691{
1692 unsigned int ass, tmp, i;
7fb56223 1693 unsigned nid = 0;
da00c244
KY
1694 struct alc_spec *spec = codec->spec;
1695
b6cbe517
TI
1696 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1697
90622917
DH
1698 if (spec->cdefine.fixup) {
1699 ass = spec->cdefine.sku_cfg;
1700 if (ass == ALC_FIXUP_SKU_IGNORE)
1701 return -1;
1702 goto do_sku;
1703 }
1704
da00c244 1705 ass = codec->subsystem_id & 0xffff;
b6cbe517 1706 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1707 goto do_sku;
1708
1709 nid = 0x1d;
1710 if (codec->vendor_id == 0x10ec0260)
1711 nid = 0x17;
1712 ass = snd_hda_codec_get_pincfg(codec, nid);
1713
1714 if (!(ass & 1)) {
1715 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1716 codec->chip_name, ass);
1717 return -1;
1718 }
1719
1720 /* check sum */
1721 tmp = 0;
1722 for (i = 1; i < 16; i++) {
1723 if ((ass >> i) & 1)
1724 tmp++;
1725 }
1726 if (((ass >> 16) & 0xf) != tmp)
1727 return -1;
1728
1729 spec->cdefine.port_connectivity = ass >> 30;
1730 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1731 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1732 spec->cdefine.customization = ass >> 8;
1733do_sku:
1734 spec->cdefine.sku_cfg = ass;
1735 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1736 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1737 spec->cdefine.swap = (ass & 0x2) >> 1;
1738 spec->cdefine.override = ass & 0x1;
1739
1740 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1741 nid, spec->cdefine.sku_cfg);
1742 snd_printd("SKU: port_connectivity=0x%x\n",
1743 spec->cdefine.port_connectivity);
1744 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1745 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1746 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1747 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1748 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1749 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1750 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1751
1752 return 0;
1753}
1754
4a79ba34
TI
1755/* check subsystem ID and set up device-specific initialization;
1756 * return 1 if initialized, 0 if invalid SSID
1757 */
1758/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1759 * 31 ~ 16 : Manufacture ID
1760 * 15 ~ 8 : SKU ID
1761 * 7 ~ 0 : Assembly ID
1762 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1763 */
1764static int alc_subsystem_id(struct hda_codec *codec,
1765 hda_nid_t porta, hda_nid_t porte,
6227cdce 1766 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1767{
1768 unsigned int ass, tmp, i;
1769 unsigned nid;
1770 struct alc_spec *spec = codec->spec;
1771
90622917
DH
1772 if (spec->cdefine.fixup) {
1773 ass = spec->cdefine.sku_cfg;
1774 if (ass == ALC_FIXUP_SKU_IGNORE)
1775 return 0;
1776 goto do_sku;
1777 }
1778
4a79ba34
TI
1779 ass = codec->subsystem_id & 0xffff;
1780 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1781 goto do_sku;
1782
1783 /* invalid SSID, check the special NID pin defcfg instead */
1784 /*
def319f9 1785 * 31~30 : port connectivity
4a79ba34
TI
1786 * 29~21 : reserve
1787 * 20 : PCBEEP input
1788 * 19~16 : Check sum (15:1)
1789 * 15~1 : Custom
1790 * 0 : override
1791 */
1792 nid = 0x1d;
1793 if (codec->vendor_id == 0x10ec0260)
1794 nid = 0x17;
1795 ass = snd_hda_codec_get_pincfg(codec, nid);
1796 snd_printd("realtek: No valid SSID, "
1797 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1798 ass, nid);
6227cdce 1799 if (!(ass & 1))
4a79ba34
TI
1800 return 0;
1801 if ((ass >> 30) != 1) /* no physical connection */
1802 return 0;
1803
1804 /* check sum */
1805 tmp = 0;
1806 for (i = 1; i < 16; i++) {
1807 if ((ass >> i) & 1)
1808 tmp++;
1809 }
1810 if (((ass >> 16) & 0xf) != tmp)
1811 return 0;
1812do_sku:
1813 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1814 ass & 0xffff, codec->vendor_id);
1815 /*
1816 * 0 : override
1817 * 1 : Swap Jack
1818 * 2 : 0 --> Desktop, 1 --> Laptop
1819 * 3~5 : External Amplifier control
1820 * 7~6 : Reserved
1821 */
1822 tmp = (ass & 0x38) >> 3; /* external Amp control */
1823 switch (tmp) {
1824 case 1:
1825 spec->init_amp = ALC_INIT_GPIO1;
1826 break;
1827 case 3:
1828 spec->init_amp = ALC_INIT_GPIO2;
1829 break;
1830 case 7:
1831 spec->init_amp = ALC_INIT_GPIO3;
1832 break;
1833 case 5:
5a8cfb4e 1834 default:
4a79ba34 1835 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1836 break;
1837 }
ea1fb29a 1838
8c427226 1839 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1840 * when the external headphone out jack is plugged"
1841 */
8c427226 1842 if (!(ass & 0x8000))
4a79ba34 1843 return 1;
c9b58006
KY
1844 /*
1845 * 10~8 : Jack location
1846 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1847 * 14~13: Resvered
1848 * 15 : 1 --> enable the function "Mute internal speaker
1849 * when the external headphone out jack is plugged"
1850 */
c9b58006 1851 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1852 hda_nid_t nid;
c9b58006
KY
1853 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1854 if (tmp == 0)
01d4825d 1855 nid = porta;
c9b58006 1856 else if (tmp == 1)
01d4825d 1857 nid = porte;
c9b58006 1858 else if (tmp == 2)
01d4825d 1859 nid = portd;
6227cdce
KY
1860 else if (tmp == 3)
1861 nid = porti;
c9b58006 1862 else
4a79ba34 1863 return 1;
01d4825d
TI
1864 for (i = 0; i < spec->autocfg.line_outs; i++)
1865 if (spec->autocfg.line_out_pins[i] == nid)
1866 return 1;
1867 spec->autocfg.hp_pins[0] = nid;
c9b58006 1868 }
4a79ba34
TI
1869 return 1;
1870}
ea1fb29a 1871
4a79ba34 1872static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1873 hda_nid_t porta, hda_nid_t porte,
1874 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1875{
6227cdce 1876 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1877 struct alc_spec *spec = codec->spec;
1878 snd_printd("realtek: "
1879 "Enable default setup for auto mode as fallback\n");
1880 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1881 }
1a1455de
TI
1882
1883 alc_init_auto_hp(codec);
1884 alc_init_auto_mic(codec);
bc9f98a9
KY
1885}
1886
f95474ec 1887/*
f8f25ba3 1888 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1889 */
1890
1891struct alc_pincfg {
1892 hda_nid_t nid;
1893 u32 val;
1894};
1895
e1eb5f10
TB
1896struct alc_model_fixup {
1897 const int id;
1898 const char *name;
1899};
1900
f8f25ba3 1901struct alc_fixup {
b5bfbc67 1902 int type;
361fe6e9
TI
1903 bool chained;
1904 int chain_id;
b5bfbc67
TI
1905 union {
1906 unsigned int sku;
1907 const struct alc_pincfg *pins;
1908 const struct hda_verb *verbs;
1909 void (*func)(struct hda_codec *codec,
1910 const struct alc_fixup *fix,
1911 int action);
1912 } v;
f8f25ba3
TI
1913};
1914
b5bfbc67
TI
1915enum {
1916 ALC_FIXUP_INVALID,
1917 ALC_FIXUP_SKU,
1918 ALC_FIXUP_PINS,
1919 ALC_FIXUP_VERBS,
1920 ALC_FIXUP_FUNC,
1921};
1922
1923enum {
1924 ALC_FIXUP_ACT_PRE_PROBE,
1925 ALC_FIXUP_ACT_PROBE,
58701120 1926 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1927};
1928
1929static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1930{
b5bfbc67
TI
1931 struct alc_spec *spec = codec->spec;
1932 int id = spec->fixup_id;
aa1d0c52 1933#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1934 const char *modelname = spec->fixup_name;
aa1d0c52 1935#endif
b5bfbc67 1936 int depth = 0;
f95474ec 1937
b5bfbc67
TI
1938 if (!spec->fixup_list)
1939 return;
1940
1941 while (id >= 0) {
1942 const struct alc_fixup *fix = spec->fixup_list + id;
1943 const struct alc_pincfg *cfg;
1944
1945 switch (fix->type) {
1946 case ALC_FIXUP_SKU:
1947 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1948 break;;
1949 snd_printdd(KERN_INFO "hda_codec: %s: "
1950 "Apply sku override for %s\n",
1951 codec->chip_name, modelname);
1952 spec->cdefine.sku_cfg = fix->v.sku;
1953 spec->cdefine.fixup = 1;
1954 break;
1955 case ALC_FIXUP_PINS:
1956 cfg = fix->v.pins;
1957 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1958 break;
1959 snd_printdd(KERN_INFO "hda_codec: %s: "
1960 "Apply pincfg for %s\n",
1961 codec->chip_name, modelname);
1962 for (; cfg->nid; cfg++)
1963 snd_hda_codec_set_pincfg(codec, cfg->nid,
1964 cfg->val);
1965 break;
1966 case ALC_FIXUP_VERBS:
1967 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1968 break;
1969 snd_printdd(KERN_INFO "hda_codec: %s: "
1970 "Apply fix-verbs for %s\n",
1971 codec->chip_name, modelname);
1972 add_verb(codec->spec, fix->v.verbs);
1973 break;
1974 case ALC_FIXUP_FUNC:
1975 if (!fix->v.func)
1976 break;
1977 snd_printdd(KERN_INFO "hda_codec: %s: "
1978 "Apply fix-func for %s\n",
1979 codec->chip_name, modelname);
1980 fix->v.func(codec, fix, action);
1981 break;
1982 default:
1983 snd_printk(KERN_ERR "hda_codec: %s: "
1984 "Invalid fixup type %d\n",
1985 codec->chip_name, fix->type);
1986 break;
1987 }
24af2b1c 1988 if (!fix->chained)
b5bfbc67
TI
1989 break;
1990 if (++depth > 10)
1991 break;
24af2b1c 1992 id = fix->chain_id;
9d57883f 1993 }
f95474ec
TI
1994}
1995
e1eb5f10 1996static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1997 const struct alc_model_fixup *models,
1998 const struct snd_pci_quirk *quirk,
1999 const struct alc_fixup *fixlist)
e1eb5f10 2000{
b5bfbc67
TI
2001 struct alc_spec *spec = codec->spec;
2002 int id = -1;
2003 const char *name = NULL;
e1eb5f10 2004
e1eb5f10
TB
2005 if (codec->modelname && models) {
2006 while (models->name) {
2007 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2008 id = models->id;
2009 name = models->name;
e1eb5f10
TB
2010 break;
2011 }
2012 models++;
2013 }
b5bfbc67
TI
2014 }
2015 if (id < 0) {
2016 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2017 if (quirk) {
2018 id = quirk->value;
2019#ifdef CONFIG_SND_DEBUG_VERBOSE
2020 name = quirk->name;
2021#endif
2022 }
2023 }
2024
2025 spec->fixup_id = id;
2026 if (id >= 0) {
2027 spec->fixup_list = fixlist;
2028 spec->fixup_name = name;
e1eb5f10 2029 }
f95474ec
TI
2030}
2031
274693f3
KY
2032static int alc_read_coef_idx(struct hda_codec *codec,
2033 unsigned int coef_idx)
2034{
2035 unsigned int val;
2036 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2037 coef_idx);
2038 val = snd_hda_codec_read(codec, 0x20, 0,
2039 AC_VERB_GET_PROC_COEF, 0);
2040 return val;
2041}
2042
977ddd6b
KY
2043static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2044 unsigned int coef_val)
2045{
2046 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2047 coef_idx);
2048 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2049 coef_val);
2050}
2051
757899ac
TI
2052/* set right pin controls for digital I/O */
2053static void alc_auto_init_digital(struct hda_codec *codec)
2054{
2055 struct alc_spec *spec = codec->spec;
2056 int i;
2057 hda_nid_t pin;
2058
2059 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2060 pin = spec->autocfg.dig_out_pins[i];
2061 if (pin) {
2062 snd_hda_codec_write(codec, pin, 0,
2063 AC_VERB_SET_PIN_WIDGET_CONTROL,
2064 PIN_OUT);
2065 }
2066 }
2067 pin = spec->autocfg.dig_in_pin;
2068 if (pin)
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2071 PIN_IN);
2072}
2073
2074/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2075static void alc_auto_parse_digital(struct hda_codec *codec)
2076{
2077 struct alc_spec *spec = codec->spec;
2078 int i, err;
2079 hda_nid_t dig_nid;
2080
2081 /* support multiple SPDIFs; the secondary is set up as a slave */
2082 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2083 err = snd_hda_get_connections(codec,
2084 spec->autocfg.dig_out_pins[i],
2085 &dig_nid, 1);
2086 if (err < 0)
2087 continue;
2088 if (!i) {
2089 spec->multiout.dig_out_nid = dig_nid;
2090 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2091 } else {
2092 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2093 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2094 break;
2095 spec->slave_dig_outs[i - 1] = dig_nid;
2096 }
2097 }
2098
2099 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2100 dig_nid = codec->start_nid;
2101 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2102 unsigned int wcaps = get_wcaps(codec, dig_nid);
2103 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2104 continue;
2105 if (!(wcaps & AC_WCAP_DIGITAL))
2106 continue;
2107 if (!(wcaps & AC_WCAP_CONN_LIST))
2108 continue;
2109 err = get_connection_index(codec, dig_nid,
2110 spec->autocfg.dig_in_pin);
2111 if (err >= 0) {
2112 spec->dig_in_nid = dig_nid;
2113 break;
2114 }
2115 }
757899ac
TI
2116 }
2117}
2118
ef8ef5fb
VP
2119/*
2120 * ALC888
2121 */
2122
2123/*
2124 * 2ch mode
2125 */
a9111321 2126static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2127/* Mic-in jack as mic in */
2128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2130/* Line-in jack as Line in */
2131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2133/* Line-Out as Front */
2134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2135 { } /* end */
2136};
2137
2138/*
2139 * 4ch mode
2140 */
a9111321 2141static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2142/* Mic-in jack as mic in */
2143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2145/* Line-in jack as Surround */
2146 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2147 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2148/* Line-Out as Front */
2149 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2150 { } /* end */
2151};
2152
2153/*
2154 * 6ch mode
2155 */
a9111321 2156static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2157/* Mic-in jack as CLFE */
2158 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2159 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2160/* Line-in jack as Surround */
2161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2163/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2164 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2165 { } /* end */
2166};
2167
2168/*
2169 * 8ch mode
2170 */
a9111321 2171static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2172/* Mic-in jack as CLFE */
2173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2175/* Line-in jack as Surround */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178/* Line-Out as Side */
2179 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2180 { } /* end */
2181};
2182
a9111321 2183static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2184 { 2, alc888_4ST_ch2_intel_init },
2185 { 4, alc888_4ST_ch4_intel_init },
2186 { 6, alc888_4ST_ch6_intel_init },
2187 { 8, alc888_4ST_ch8_intel_init },
2188};
2189
2190/*
2191 * ALC888 Fujitsu Siemens Amillo xa3530
2192 */
2193
a9111321 2194static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2195/* Front Mic: set to PIN_IN (empty by default) */
2196 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197/* Connect Internal HP to Front */
2198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2200 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2201/* Connect Bass HP to Front */
2202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2205/* Connect Line-Out side jack (SPDIF) to Side */
2206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2207 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2208 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2209/* Connect Mic jack to CLFE */
2210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2212 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2213/* Connect Line-in jack to Surround */
2214 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2217/* Connect HP out jack to Front */
2218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2221/* Enable unsolicited event for HP jack and Line-out jack */
2222 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2223 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2224 {}
2225};
2226
4f5d1706 2227static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2228{
2229 struct alc_spec *spec = codec->spec;
2230
2231 spec->autocfg.hp_pins[0] = 0x15;
2232 spec->autocfg.speaker_pins[0] = 0x14;
2233 spec->autocfg.speaker_pins[1] = 0x16;
2234 spec->autocfg.speaker_pins[2] = 0x17;
2235 spec->autocfg.speaker_pins[3] = 0x19;
2236 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2237 spec->automute = 1;
2238 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2239}
2240
2241static void alc889_intel_init_hook(struct hda_codec *codec)
2242{
2243 alc889_coef_init(codec);
d922b51d 2244 alc_hp_automute(codec);
6732bd0d
WF
2245}
2246
4f5d1706 2247static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2248{
2249 struct alc_spec *spec = codec->spec;
2250
2251 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2252 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2253 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2254 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2255 spec->automute = 1;
2256 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2257}
ef8ef5fb 2258
5b2d1eca
VP
2259/*
2260 * ALC888 Acer Aspire 4930G model
2261 */
2262
a9111321 2263static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2264/* Front Mic: set to PIN_IN (empty by default) */
2265 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2266/* Unselect Front Mic by default in input mixer 3 */
2267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2268/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2270/* Connect Internal HP to front */
2271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2274/* Connect HP out to front */
2275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2278 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2279 { }
2280};
2281
d2fd4b09
TV
2282/*
2283 * ALC888 Acer Aspire 6530G model
2284 */
2285
a9111321 2286static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2287/* Route to built-in subwoofer as well as speakers */
2288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2290 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2291 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2292/* Bias voltage on for external mic port */
2293 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2294/* Front Mic: set to PIN_IN (empty by default) */
2295 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2296/* Unselect Front Mic by default in input mixer 3 */
2297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2298/* Enable unsolicited event for HP jack */
2299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2300/* Enable speaker output */
2301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2303 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2304/* Enable headphone output */
2305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2309 { }
2310};
2311
d9477207
DK
2312/*
2313 *ALC888 Acer Aspire 7730G model
2314 */
2315
a9111321 2316static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2317/* Bias voltage on for external mic port */
2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2319/* Front Mic: set to PIN_IN (empty by default) */
2320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2321/* Unselect Front Mic by default in input mixer 3 */
2322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2323/* Enable unsolicited event for HP jack */
2324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2325/* Enable speaker output */
2326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329/* Enable headphone output */
2330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2333 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2334/*Enable internal subwoofer */
2335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2338 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2339 { }
2340};
2341
3b315d70 2342/*
018df418 2343 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2344 */
2345
a9111321 2346static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2347/* Front Mic: set to PIN_IN (empty by default) */
2348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2349/* Unselect Front Mic by default in input mixer 3 */
2350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2351/* Enable unsolicited event for HP jack */
2352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2353/* Connect Internal Front to Front */
2354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2357/* Connect Internal Rear to Rear */
2358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2359 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2360 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2361/* Connect Internal CLFE to CLFE */
2362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2363 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2365/* Connect HP out to Front */
018df418 2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2369/* Enable all DACs */
2370/* DAC DISABLE/MUTE 1? */
2371/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2372 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2373 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2374/* DAC DISABLE/MUTE 2? */
2375/* some bit here disables the other DACs. Init=0x4900 */
2376 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2377 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2378/* DMIC fix
2379 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2380 * which makes the stereo useless. However, either the mic or the ALC889
2381 * makes the signal become a difference/sum signal instead of standard
2382 * stereo, which is annoying. So instead we flip this bit which makes the
2383 * codec replicate the sum signal to both channels, turning it into a
2384 * normal mono mic.
2385 */
2386/* DMIC_CONTROL? Init value = 0x0001 */
2387 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2388 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2389 { }
2390};
2391
a9111321 2392static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2393 /* Front mic only available on one ADC */
2394 {
2395 .num_items = 4,
2396 .items = {
2397 { "Mic", 0x0 },
2398 { "Line", 0x2 },
2399 { "CD", 0x4 },
2400 { "Front Mic", 0xb },
2401 },
2402 },
2403 {
2404 .num_items = 3,
2405 .items = {
2406 { "Mic", 0x0 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 },
2410 }
2411};
2412
a9111321 2413static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2414 /* Interal mic only available on one ADC */
2415 {
684a8842 2416 .num_items = 5,
d2fd4b09 2417 .items = {
8607f7c4 2418 { "Mic", 0x0 },
684a8842 2419 { "Line In", 0x2 },
d2fd4b09 2420 { "CD", 0x4 },
684a8842 2421 { "Input Mix", 0xa },
28c4edb7 2422 { "Internal Mic", 0xb },
d2fd4b09
TV
2423 },
2424 },
2425 {
684a8842 2426 .num_items = 4,
d2fd4b09 2427 .items = {
8607f7c4 2428 { "Mic", 0x0 },
684a8842 2429 { "Line In", 0x2 },
d2fd4b09 2430 { "CD", 0x4 },
684a8842 2431 { "Input Mix", 0xa },
d2fd4b09
TV
2432 },
2433 }
2434};
2435
a9111321 2436static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2437 /* Digital mic only available on first "ADC" */
2438 {
2439 .num_items = 5,
2440 .items = {
2441 { "Mic", 0x0 },
2442 { "Line", 0x2 },
2443 { "CD", 0x4 },
2444 { "Front Mic", 0xb },
2445 { "Input Mix", 0xa },
2446 },
2447 },
2448 {
2449 .num_items = 4,
2450 .items = {
2451 { "Mic", 0x0 },
2452 { "Line", 0x2 },
2453 { "CD", 0x4 },
2454 { "Input Mix", 0xa },
2455 },
2456 },
2457 {
2458 .num_items = 4,
2459 .items = {
2460 { "Mic", 0x0 },
2461 { "Line", 0x2 },
2462 { "CD", 0x4 },
2463 { "Input Mix", 0xa },
2464 },
2465 }
2466};
2467
a9111321 2468static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2471 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2472 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2473 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2474 HDA_OUTPUT),
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2485 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2487 { } /* end */
2488};
2489
a9111321 2490static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2494 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2496 HDA_OUTPUT),
786c51f9
ŁW
2497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2502 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2503 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2505 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2507 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2509 { } /* end */
2510};
2511
a9111321 2512static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2516 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2518 HDA_OUTPUT),
2519 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2521 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2525 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2527 { } /* end */
2528};
2529
2530
4f5d1706 2531static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2532{
a9fd4f3f 2533 struct alc_spec *spec = codec->spec;
5b2d1eca 2534
a9fd4f3f
TI
2535 spec->autocfg.hp_pins[0] = 0x15;
2536 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2537 spec->autocfg.speaker_pins[1] = 0x16;
2538 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2539 spec->automute = 1;
2540 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2541}
2542
4f5d1706 2543static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2544{
2545 struct alc_spec *spec = codec->spec;
2546
2547 spec->autocfg.hp_pins[0] = 0x15;
2548 spec->autocfg.speaker_pins[0] = 0x14;
2549 spec->autocfg.speaker_pins[1] = 0x16;
2550 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2551 spec->automute = 1;
2552 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2553}
2554
d9477207
DK
2555static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2556{
2557 struct alc_spec *spec = codec->spec;
2558
2559 spec->autocfg.hp_pins[0] = 0x15;
2560 spec->autocfg.speaker_pins[0] = 0x14;
2561 spec->autocfg.speaker_pins[1] = 0x16;
2562 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2563 spec->automute = 1;
2564 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2565}
2566
4f5d1706 2567static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2568{
2569 struct alc_spec *spec = codec->spec;
2570
2571 spec->autocfg.hp_pins[0] = 0x15;
2572 spec->autocfg.speaker_pins[0] = 0x14;
2573 spec->autocfg.speaker_pins[1] = 0x16;
2574 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2575 spec->automute = 1;
2576 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2577}
2578
1da177e4 2579/*
e9edcee0
TI
2580 * ALC880 3-stack model
2581 *
2582 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2583 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2584 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2585 */
2586
4c6d72d1 2587static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2588 /* front, rear, clfe, rear_surr */
2589 0x02, 0x05, 0x04, 0x03
2590};
2591
4c6d72d1 2592static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2593 /* ADC0-2 */
2594 0x07, 0x08, 0x09,
2595};
2596
2597/* The datasheet says the node 0x07 is connected from inputs,
2598 * but it shows zero connection in the real implementation on some devices.
df694daa 2599 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2600 */
4c6d72d1 2601static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2602 /* ADC1-2 */
2603 0x08, 0x09,
2604};
2605
2606#define ALC880_DIGOUT_NID 0x06
2607#define ALC880_DIGIN_NID 0x0a
2608
a9111321 2609static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2610 .num_items = 4,
2611 .items = {
2612 { "Mic", 0x0 },
2613 { "Front Mic", 0x3 },
2614 { "Line", 0x2 },
2615 { "CD", 0x4 },
2616 },
2617};
2618
2619/* channel source setting (2/6 channel selection for 3-stack) */
2620/* 2ch mode */
a9111321 2621static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2622 /* set line-in to input, mute it */
2623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2625 /* set mic-in to input vref 80%, mute it */
2626 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2627 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2628 { } /* end */
2629};
2630
2631/* 6ch mode */
a9111321 2632static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2633 /* set line-in to output, unmute it */
2634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2635 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2636 /* set mic-in to output, unmute it */
2637 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2638 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2639 { } /* end */
2640};
2641
a9111321 2642static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2643 { 2, alc880_threestack_ch2_init },
2644 { 6, alc880_threestack_ch6_init },
2645};
2646
a9111321 2647static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2651 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2656 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2657 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2659 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2665 {
2666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2667 .name = "Channel Mode",
df694daa
KY
2668 .info = alc_ch_mode_info,
2669 .get = alc_ch_mode_get,
2670 .put = alc_ch_mode_put,
e9edcee0
TI
2671 },
2672 { } /* end */
2673};
2674
2675/* capture mixer elements */
f9e336f6
TI
2676static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2677 struct snd_ctl_elem_info *uinfo)
2678{
2679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2680 struct alc_spec *spec = codec->spec;
2681 int err;
1da177e4 2682
5a9e02e9 2683 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2684 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2685 HDA_INPUT);
2686 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2687 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2688 return err;
2689}
2690
2691static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2692 unsigned int size, unsigned int __user *tlv)
2693{
2694 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2695 struct alc_spec *spec = codec->spec;
2696 int err;
1da177e4 2697
5a9e02e9 2698 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2699 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2700 HDA_INPUT);
2701 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2702 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2703 return err;
2704}
2705
2706typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2707 struct snd_ctl_elem_value *ucontrol);
2708
2709static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2710 struct snd_ctl_elem_value *ucontrol,
2711 getput_call_t func)
2712{
2713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2714 struct alc_spec *spec = codec->spec;
2715 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2716 int err;
2717
5a9e02e9 2718 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2719 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2720 3, 0, HDA_INPUT);
2721 err = func(kcontrol, ucontrol);
5a9e02e9 2722 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2723 return err;
2724}
2725
2726static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_value *ucontrol)
2728{
2729 return alc_cap_getput_caller(kcontrol, ucontrol,
2730 snd_hda_mixer_amp_volume_get);
2731}
2732
2733static int alc_cap_vol_put(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_put);
2738}
2739
2740/* capture mixer elements */
2741#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2742
2743static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2744 struct snd_ctl_elem_value *ucontrol)
2745{
2746 return alc_cap_getput_caller(kcontrol, ucontrol,
2747 snd_hda_mixer_amp_switch_get);
2748}
2749
2750static int alc_cap_sw_put(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_put);
2755}
2756
a23b688f 2757#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2758 { \
2759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2760 .name = "Capture Switch", \
2761 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2762 .count = num, \
2763 .info = alc_cap_sw_info, \
2764 .get = alc_cap_sw_get, \
2765 .put = alc_cap_sw_put, \
2766 }, \
2767 { \
2768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2769 .name = "Capture Volume", \
2770 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2771 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2772 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2773 .count = num, \
2774 .info = alc_cap_vol_info, \
2775 .get = alc_cap_vol_get, \
2776 .put = alc_cap_vol_put, \
2777 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2778 }
2779
2780#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2781 { \
2782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2783 /* .name = "Capture Source", */ \
2784 .name = "Input Source", \
2785 .count = num, \
2786 .info = alc_mux_enum_info, \
2787 .get = alc_mux_enum_get, \
2788 .put = alc_mux_enum_put, \
a23b688f
TI
2789 }
2790
2791#define DEFINE_CAPMIX(num) \
a9111321 2792static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2793 _DEFINE_CAPMIX(num), \
2794 _DEFINE_CAPSRC(num), \
2795 { } /* end */ \
2796}
2797
2798#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2799static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2800 _DEFINE_CAPMIX(num), \
2801 { } /* end */ \
f9e336f6
TI
2802}
2803
2804/* up to three ADCs */
2805DEFINE_CAPMIX(1);
2806DEFINE_CAPMIX(2);
2807DEFINE_CAPMIX(3);
a23b688f
TI
2808DEFINE_CAPMIX_NOSRC(1);
2809DEFINE_CAPMIX_NOSRC(2);
2810DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2811
2812/*
2813 * ALC880 5-stack model
2814 *
9c7f852e
TI
2815 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2816 * Side = 0x02 (0xd)
e9edcee0
TI
2817 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2818 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2819 */
2820
2821/* additional mixers to alc880_three_stack_mixer */
a9111321 2822static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2823 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2824 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2825 { } /* end */
2826};
2827
e9edcee0
TI
2828/* channel source setting (6/8 channel selection for 5-stack) */
2829/* 6ch mode */
a9111321 2830static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2831 /* set line-in to input, mute it */
2832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2834 { } /* end */
2835};
2836
e9edcee0 2837/* 8ch mode */
a9111321 2838static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2839 /* set line-in to output, unmute it */
2840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2842 { } /* end */
2843};
2844
a9111321 2845static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2846 { 6, alc880_fivestack_ch6_init },
2847 { 8, alc880_fivestack_ch8_init },
2848};
2849
2850
2851/*
2852 * ALC880 6-stack model
2853 *
9c7f852e
TI
2854 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2855 * Side = 0x05 (0x0f)
e9edcee0
TI
2856 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2857 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2858 */
2859
4c6d72d1 2860static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2861 /* front, rear, clfe, rear_surr */
2862 0x02, 0x03, 0x04, 0x05
f12ab1e0 2863};
e9edcee0 2864
a9111321 2865static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2866 .num_items = 4,
2867 .items = {
2868 { "Mic", 0x0 },
2869 { "Front Mic", 0x1 },
2870 { "Line", 0x2 },
2871 { "CD", 0x4 },
2872 },
2873};
2874
2875/* fixed 8-channels */
a9111321 2876static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2877 { 8, NULL },
2878};
2879
a9111321 2880static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2883 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2884 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2885 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2886 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2887 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2888 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2889 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2890 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2897 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2899 {
2900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2901 .name = "Channel Mode",
df694daa
KY
2902 .info = alc_ch_mode_info,
2903 .get = alc_ch_mode_get,
2904 .put = alc_ch_mode_put,
16ded525
TI
2905 },
2906 { } /* end */
2907};
2908
e9edcee0
TI
2909
2910/*
2911 * ALC880 W810 model
2912 *
2913 * W810 has rear IO for:
2914 * Front (DAC 02)
2915 * Surround (DAC 03)
2916 * Center/LFE (DAC 04)
2917 * Digital out (06)
2918 *
2919 * The system also has a pair of internal speakers, and a headphone jack.
2920 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2921 *
e9edcee0
TI
2922 * There is a variable resistor to control the speaker or headphone
2923 * volume. This is a hardware-only device without a software API.
2924 *
2925 * Plugging headphones in will disable the internal speakers. This is
2926 * implemented in hardware, not via the driver using jack sense. In
2927 * a similar fashion, plugging into the rear socket marked "front" will
2928 * disable both the speakers and headphones.
2929 *
2930 * For input, there's a microphone jack, and an "audio in" jack.
2931 * These may not do anything useful with this driver yet, because I
2932 * haven't setup any initialization verbs for these yet...
2933 */
2934
4c6d72d1 2935static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2936 /* front, rear/surround, clfe */
2937 0x02, 0x03, 0x04
16ded525
TI
2938};
2939
e9edcee0 2940/* fixed 6 channels */
a9111321 2941static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2942 { 6, NULL }
2943};
2944
2945/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2946static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2948 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2949 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2950 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2951 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2952 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2953 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2954 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2956 { } /* end */
2957};
2958
2959
2960/*
2961 * Z710V model
2962 *
2963 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2964 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2965 * Line = 0x1a
e9edcee0
TI
2966 */
2967
4c6d72d1 2968static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2969 0x02
2970};
2971#define ALC880_Z71V_HP_DAC 0x03
2972
2973/* fixed 2 channels */
a9111321 2974static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2975 { 2, NULL }
2976};
2977
a9111321 2978static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2982 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2983 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2984 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2987 { } /* end */
2988};
2989
e9edcee0 2990
e9edcee0
TI
2991/*
2992 * ALC880 F1734 model
2993 *
2994 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2995 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2996 */
2997
4c6d72d1 2998static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
2999 0x03
3000};
3001#define ALC880_F1734_HP_DAC 0x02
3002
a9111321 3003static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3005 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3007 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3012 { } /* end */
3013};
3014
a9111321 3015static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3016 .num_items = 2,
3017 .items = {
3018 { "Mic", 0x1 },
3019 { "CD", 0x4 },
3020 },
3021};
3022
e9edcee0 3023
e9edcee0
TI
3024/*
3025 * ALC880 ASUS model
3026 *
3027 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3028 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3029 * Mic = 0x18, Line = 0x1a
3030 */
3031
3032#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3033#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3034
a9111321 3035static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3039 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3040 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3041 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3042 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3043 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3050 {
3051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3052 .name = "Channel Mode",
df694daa
KY
3053 .info = alc_ch_mode_info,
3054 .get = alc_ch_mode_get,
3055 .put = alc_ch_mode_put,
16ded525
TI
3056 },
3057 { } /* end */
3058};
e9edcee0 3059
e9edcee0
TI
3060/*
3061 * ALC880 ASUS W1V model
3062 *
3063 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3064 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3065 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3066 */
3067
3068/* additional mixers to alc880_asus_mixer */
a9111321 3069static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3070 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3071 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3072 { } /* end */
3073};
3074
df694daa 3075/* TCL S700 */
a9111321 3076static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3078 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3080 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3081 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3084 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3085 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3086 { } /* end */
3087};
3088
ccc656ce 3089/* Uniwill */
a9111321 3090static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3092 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3094 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3106 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3107 {
3108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3109 .name = "Channel Mode",
3110 .info = alc_ch_mode_info,
3111 .get = alc_ch_mode_get,
3112 .put = alc_ch_mode_put,
3113 },
3114 { } /* end */
3115};
3116
a9111321 3117static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3119 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3121 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3126 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3128 { } /* end */
3129};
3130
a9111321 3131static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3133 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3138 { } /* end */
3139};
3140
2134ea4f
TI
3141/*
3142 * virtual master controls
3143 */
3144
3145/*
3146 * slave controls for virtual master
3147 */
ea734963 3148static const char * const alc_slave_vols[] = {
2134ea4f
TI
3149 "Front Playback Volume",
3150 "Surround Playback Volume",
3151 "Center Playback Volume",
3152 "LFE Playback Volume",
3153 "Side Playback Volume",
3154 "Headphone Playback Volume",
3155 "Speaker Playback Volume",
3156 "Mono Playback Volume",
2134ea4f
TI
3157 "Line-Out Playback Volume",
3158 NULL,
3159};
3160
ea734963 3161static const char * const alc_slave_sws[] = {
2134ea4f
TI
3162 "Front Playback Switch",
3163 "Surround Playback Switch",
3164 "Center Playback Switch",
3165 "LFE Playback Switch",
3166 "Side Playback Switch",
3167 "Headphone Playback Switch",
3168 "Speaker Playback Switch",
3169 "Mono Playback Switch",
edb54a55 3170 "IEC958 Playback Switch",
23033b2b 3171 "Line-Out Playback Switch",
2134ea4f
TI
3172 NULL,
3173};
3174
1da177e4 3175/*
e9edcee0 3176 * build control elements
1da177e4 3177 */
603c4019 3178
5b0cb1d8
JK
3179#define NID_MAPPING (-1)
3180
3181#define SUBDEV_SPEAKER_ (0 << 6)
3182#define SUBDEV_HP_ (1 << 6)
3183#define SUBDEV_LINE_ (2 << 6)
3184#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3185#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3186#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3187
603c4019
TI
3188static void alc_free_kctls(struct hda_codec *codec);
3189
67d634c0 3190#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3191/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3192static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3193 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3194 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3195 { } /* end */
3196};
67d634c0 3197#endif
45bdd1c1 3198
1da177e4
LT
3199static int alc_build_controls(struct hda_codec *codec)
3200{
3201 struct alc_spec *spec = codec->spec;
2f44f847 3202 struct snd_kcontrol *kctl = NULL;
a9111321 3203 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3204 int i, j, err;
3205 unsigned int u;
3206 hda_nid_t nid;
1da177e4
LT
3207
3208 for (i = 0; i < spec->num_mixers; i++) {
3209 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3210 if (err < 0)
3211 return err;
3212 }
f9e336f6
TI
3213 if (spec->cap_mixer) {
3214 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3215 if (err < 0)
3216 return err;
3217 }
1da177e4 3218 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3219 err = snd_hda_create_spdif_out_ctls(codec,
3220 spec->multiout.dig_out_nid);
1da177e4
LT
3221 if (err < 0)
3222 return err;
e64f14f4
TI
3223 if (!spec->no_analog) {
3224 err = snd_hda_create_spdif_share_sw(codec,
3225 &spec->multiout);
3226 if (err < 0)
3227 return err;
3228 spec->multiout.share_spdif = 1;
3229 }
1da177e4
LT
3230 }
3231 if (spec->dig_in_nid) {
3232 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3233 if (err < 0)
3234 return err;
3235 }
2134ea4f 3236
67d634c0 3237#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3238 /* create beep controls if needed */
3239 if (spec->beep_amp) {
a9111321 3240 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3241 for (knew = alc_beep_mixer; knew->name; knew++) {
3242 struct snd_kcontrol *kctl;
3243 kctl = snd_ctl_new1(knew, codec);
3244 if (!kctl)
3245 return -ENOMEM;
3246 kctl->private_value = spec->beep_amp;
5e26dfd0 3247 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3248 if (err < 0)
3249 return err;
3250 }
3251 }
67d634c0 3252#endif
45bdd1c1 3253
2134ea4f 3254 /* if we have no master control, let's create it */
e64f14f4
TI
3255 if (!spec->no_analog &&
3256 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3257 unsigned int vmaster_tlv[4];
2134ea4f 3258 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3259 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3260 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3261 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3262 if (err < 0)
3263 return err;
3264 }
e64f14f4
TI
3265 if (!spec->no_analog &&
3266 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3267 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3268 NULL, alc_slave_sws);
3269 if (err < 0)
3270 return err;
3271 }
3272
5b0cb1d8 3273 /* assign Capture Source enums to NID */
fbe618f2
TI
3274 if (spec->capsrc_nids || spec->adc_nids) {
3275 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3276 if (!kctl)
3277 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3278 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3279 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3280 if (!nids)
3281 nids = spec->adc_nids;
3282 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3283 if (err < 0)
3284 return err;
3285 }
5b0cb1d8
JK
3286 }
3287 if (spec->cap_mixer) {
3288 const char *kname = kctl ? kctl->id.name : NULL;
3289 for (knew = spec->cap_mixer; knew->name; knew++) {
3290 if (kname && strcmp(knew->name, kname) == 0)
3291 continue;
3292 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3293 for (i = 0; kctl && i < kctl->count; i++) {
3294 err = snd_hda_add_nid(codec, kctl, i,
3295 spec->adc_nids[i]);
3296 if (err < 0)
3297 return err;
3298 }
3299 }
3300 }
3301
3302 /* other nid->control mapping */
3303 for (i = 0; i < spec->num_mixers; i++) {
3304 for (knew = spec->mixers[i]; knew->name; knew++) {
3305 if (knew->iface != NID_MAPPING)
3306 continue;
3307 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3308 if (kctl == NULL)
3309 continue;
3310 u = knew->subdevice;
3311 for (j = 0; j < 4; j++, u >>= 8) {
3312 nid = u & 0x3f;
3313 if (nid == 0)
3314 continue;
3315 switch (u & 0xc0) {
3316 case SUBDEV_SPEAKER_:
3317 nid = spec->autocfg.speaker_pins[nid];
3318 break;
3319 case SUBDEV_LINE_:
3320 nid = spec->autocfg.line_out_pins[nid];
3321 break;
3322 case SUBDEV_HP_:
3323 nid = spec->autocfg.hp_pins[nid];
3324 break;
3325 default:
3326 continue;
3327 }
3328 err = snd_hda_add_nid(codec, kctl, 0, nid);
3329 if (err < 0)
3330 return err;
3331 }
3332 u = knew->private_value;
3333 for (j = 0; j < 4; j++, u >>= 8) {
3334 nid = u & 0xff;
3335 if (nid == 0)
3336 continue;
3337 err = snd_hda_add_nid(codec, kctl, 0, nid);
3338 if (err < 0)
3339 return err;
3340 }
3341 }
3342 }
bae84e70
TI
3343
3344 alc_free_kctls(codec); /* no longer needed */
3345
1da177e4
LT
3346 return 0;
3347}
3348
e9edcee0 3349
1da177e4
LT
3350/*
3351 * initialize the codec volumes, etc
3352 */
3353
e9edcee0
TI
3354/*
3355 * generic initialization of ADC, input mixers and output mixers
3356 */
a9111321 3357static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3358 /*
3359 * Unmute ADC0-2 and set the default input to mic-in
3360 */
71fe7b82 3361 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3363 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3365 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3367
e9edcee0
TI
3368 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3369 * mixer widget
9c7f852e
TI
3370 * Note: PASD motherboards uses the Line In 2 as the input for front
3371 * panel mic (mic 2)
1da177e4 3372 */
e9edcee0 3373 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3381
e9edcee0
TI
3382 /*
3383 * Set up output mixers (0x0c - 0x0f)
1da177e4 3384 */
e9edcee0
TI
3385 /* set vol=0 to output mixers */
3386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3390 /* set up input amps for analog loopback */
3391 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3400
3401 { }
3402};
3403
e9edcee0
TI
3404/*
3405 * 3-stack pin configuration:
3406 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3407 */
a9111321 3408static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3409 /*
3410 * preset connection lists of input pins
3411 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3412 */
3413 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3414 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3415 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3416
3417 /*
3418 * Set pin mode and muting
3419 */
3420 /* set front pin widgets 0x14 for output */
05acb863 3421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3422 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3423 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3425 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3426 /* Mic2 (as headphone out) for HP output */
3427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3429 /* Line In pin widget for input */
05acb863 3430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3432 /* Line2 (as front mic) pin widget for input and vref at 80% */
3433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3435 /* CD pin widget for input */
05acb863 3436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3437
e9edcee0
TI
3438 { }
3439};
1da177e4 3440
e9edcee0
TI
3441/*
3442 * 5-stack pin configuration:
3443 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3444 * line-in/side = 0x1a, f-mic = 0x1b
3445 */
a9111321 3446static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3447 /*
3448 * preset connection lists of input pins
3449 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3450 */
e9edcee0
TI
3451 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3452 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3453
e9edcee0
TI
3454 /*
3455 * Set pin mode and muting
1da177e4 3456 */
e9edcee0
TI
3457 /* set pin widgets 0x14-0x17 for output */
3458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3459 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3461 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3462 /* unmute pins for output (no gain on this amp) */
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3465 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3466 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467
3468 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3471 /* Mic2 (as headphone out) for HP output */
3472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 /* Line In pin widget for input */
3475 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3477 /* Line2 (as front mic) pin widget for input and vref at 80% */
3478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3480 /* CD pin widget for input */
3481 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3482
3483 { }
3484};
3485
e9edcee0
TI
3486/*
3487 * W810 pin configuration:
3488 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3489 */
a9111321 3490static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3491 /* hphone/speaker input selector: front DAC */
3492 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3493
05acb863 3494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3500
e9edcee0 3501 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3502 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3503
1da177e4
LT
3504 { }
3505};
3506
e9edcee0
TI
3507/*
3508 * Z71V pin configuration:
3509 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3510 */
a9111321 3511static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3513 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3516
16ded525 3517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3518 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3521
3522 { }
3523};
3524
e9edcee0
TI
3525/*
3526 * 6-stack pin configuration:
9c7f852e
TI
3527 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3528 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3529 */
a9111321 3530static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3531 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3532
16ded525 3533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3538 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3539 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3540 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541
16ded525 3542 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3543 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3549 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3551
e9edcee0
TI
3552 { }
3553};
3554
ccc656ce
KY
3555/*
3556 * Uniwill pin configuration:
3557 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3558 * line = 0x1a
3559 */
a9111321 3560static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3561 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3562
3563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3569 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3577
3578 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3582 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3584 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3585 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3587
3588 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3590
3591 { }
3592};
3593
3594/*
3595* Uniwill P53
ea1fb29a 3596* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3597 */
a9111321 3598static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3599 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3600
3601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3612 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3613
3614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3615 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3616 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3619 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3620
3621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3623
3624 { }
3625};
3626
a9111321 3627static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3628 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3629 { }
3630};
3631
458a4fab 3632/* auto-toggle front mic */
eeb43387 3633static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3634{
3635 unsigned int present;
3636 unsigned char bits;
ccc656ce 3637
864f92be 3638 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3639 bits = present ? HDA_AMP_MUTE : 0;
3640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3641}
3642
4f5d1706 3643static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3644{
a9fd4f3f
TI
3645 struct alc_spec *spec = codec->spec;
3646
3647 spec->autocfg.hp_pins[0] = 0x14;
3648 spec->autocfg.speaker_pins[0] = 0x15;
3649 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3650 spec->automute = 1;
3651 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3652}
3653
3654static void alc880_uniwill_init_hook(struct hda_codec *codec)
3655{
d922b51d 3656 alc_hp_automute(codec);
eeb43387 3657 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3658}
3659
3660static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3661 unsigned int res)
3662{
3663 /* Looks like the unsol event is incompatible with the standard
3664 * definition. 4bit tag is placed at 28 bit!
3665 */
458a4fab 3666 switch (res >> 28) {
458a4fab 3667 case ALC880_MIC_EVENT:
eeb43387 3668 alc88x_simple_mic_automute(codec);
458a4fab 3669 break;
a9fd4f3f 3670 default:
d922b51d 3671 alc_sku_unsol_event(codec, res);
a9fd4f3f 3672 break;
458a4fab 3673 }
ccc656ce
KY
3674}
3675
4f5d1706 3676static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3677{
a9fd4f3f 3678 struct alc_spec *spec = codec->spec;
ccc656ce 3679
a9fd4f3f
TI
3680 spec->autocfg.hp_pins[0] = 0x14;
3681 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3682 spec->automute = 1;
3683 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3684}
3685
3686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3687{
3688 unsigned int present;
ea1fb29a 3689
ccc656ce 3690 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3691 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3692 present &= HDA_AMP_VOLMASK;
3693 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3694 HDA_AMP_VOLMASK, present);
3695 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3696 HDA_AMP_VOLMASK, present);
ccc656ce 3697}
47fd830a 3698
ccc656ce
KY
3699static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3700 unsigned int res)
3701{
3702 /* Looks like the unsol event is incompatible with the standard
3703 * definition. 4bit tag is placed at 28 bit!
3704 */
f12ab1e0 3705 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3706 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3707 else
d922b51d 3708 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3709}
3710
e9edcee0
TI
3711/*
3712 * F1734 pin configuration:
3713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3714 */
a9111321 3715static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3719 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3720 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3721
e9edcee0 3722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3726
e9edcee0
TI
3727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3736
937b4160
TI
3737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3738 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3739
dfc0ff62
TI
3740 { }
3741};
3742
e9edcee0
TI
3743/*
3744 * ASUS pin configuration:
3745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3746 */
a9111321 3747static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3751 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3752
3753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3761
3762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3771
e9edcee0
TI
3772 { }
3773};
16ded525 3774
e9edcee0 3775/* Enable GPIO mask and set output */
bc9f98a9
KY
3776#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3777#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3778#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3779
3780/* Clevo m520g init */
a9111321 3781static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3782 /* headphone output */
3783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3784 /* line-out */
3785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3787 /* Line-in */
3788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790 /* CD */
3791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3792 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3793 /* Mic1 (rear panel) */
3794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3796 /* Mic2 (front panel) */
3797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3799 /* headphone */
3800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3802 /* change to EAPD mode */
3803 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3804 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3805
3806 { }
16ded525
TI
3807};
3808
a9111321 3809static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3810 /* change to EAPD mode */
3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3813
df694daa
KY
3814 /* Headphone output */
3815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3816 /* Front output*/
3817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3819
3820 /* Line In pin widget for input */
3821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3822 /* CD pin widget for input */
3823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3824 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3826
3827 /* change to EAPD mode */
3828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3829 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3830
3831 { }
3832};
16ded525 3833
e9edcee0 3834/*
ae6b813a
TI
3835 * LG m1 express dual
3836 *
3837 * Pin assignment:
3838 * Rear Line-In/Out (blue): 0x14
3839 * Build-in Mic-In: 0x15
3840 * Speaker-out: 0x17
3841 * HP-Out (green): 0x1b
3842 * Mic-In/Out (red): 0x19
3843 * SPDIF-Out: 0x1e
3844 */
3845
3846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3847static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3848 0x05, 0x02, 0x03
3849};
3850
3851/* seems analog CD is not working */
a9111321 3852static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3853 .num_items = 3,
3854 .items = {
3855 { "Mic", 0x1 },
3856 { "Line", 0x5 },
3857 { "Internal Mic", 0x6 },
3858 },
3859};
3860
3861/* 2,4,6 channel modes */
a9111321 3862static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3863 /* set line-in and mic-in to input */
3864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3866 { }
3867};
3868
a9111321 3869static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3870 /* set line-in to out and mic-in to input */
3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3873 { }
3874};
3875
a9111321 3876static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3877 /* set line-in and mic-in to output */
3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3880 { }
3881};
3882
a9111321 3883static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3884 { 2, alc880_lg_ch2_init },
3885 { 4, alc880_lg_ch4_init },
3886 { 6, alc880_lg_ch6_init },
3887};
3888
a9111321 3889static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3893 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3902 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3903 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3904 {
3905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3906 .name = "Channel Mode",
3907 .info = alc_ch_mode_info,
3908 .get = alc_ch_mode_get,
3909 .put = alc_ch_mode_put,
3910 },
3911 { } /* end */
3912};
3913
a9111321 3914static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3915 /* set capture source to mic-in */
3916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3919 /* mute all amp mixer inputs */
3920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3923 /* line-in to input */
3924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3926 /* built-in mic */
3927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3929 /* speaker-out */
3930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3932 /* mic-in to input */
3933 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* HP-out */
3937 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3940 /* jack sense */
a9fd4f3f 3941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3942 { }
3943};
3944
3945/* toggle speaker-output according to the hp-jack state */
4f5d1706 3946static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3947{
a9fd4f3f 3948 struct alc_spec *spec = codec->spec;
ae6b813a 3949
a9fd4f3f
TI
3950 spec->autocfg.hp_pins[0] = 0x1b;
3951 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3952 spec->automute = 1;
3953 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3954}
3955
d681518a
TI
3956/*
3957 * LG LW20
3958 *
3959 * Pin assignment:
3960 * Speaker-out: 0x14
3961 * Mic-In: 0x18
e4f41da9
CM
3962 * Built-in Mic-In: 0x19
3963 * Line-In: 0x1b
3964 * HP-Out: 0x1a
d681518a
TI
3965 * SPDIF-Out: 0x1e
3966 */
3967
a9111321 3968static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3969 .num_items = 3,
d681518a
TI
3970 .items = {
3971 { "Mic", 0x0 },
3972 { "Internal Mic", 0x1 },
e4f41da9 3973 { "Line In", 0x2 },
d681518a
TI
3974 },
3975};
3976
0a8c5da3
CM
3977#define alc880_lg_lw_modes alc880_threestack_modes
3978
a9111321 3979static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3983 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3984 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3986 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3987 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3988 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3989 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3993 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3994 {
3995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3996 .name = "Channel Mode",
3997 .info = alc_ch_mode_info,
3998 .get = alc_ch_mode_get,
3999 .put = alc_ch_mode_put,
4000 },
d681518a
TI
4001 { } /* end */
4002};
4003
a9111321 4004static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4005 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4006 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4007 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4008
d681518a
TI
4009 /* set capture source to mic-in */
4010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4012 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4014 /* speaker-out */
4015 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* HP-out */
d681518a
TI
4018 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4020 /* mic-in to input */
4021 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4023 /* built-in mic */
4024 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4026 /* jack sense */
a9fd4f3f 4027 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4028 { }
4029};
4030
4031/* toggle speaker-output according to the hp-jack state */
4f5d1706 4032static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4033{
a9fd4f3f 4034 struct alc_spec *spec = codec->spec;
d681518a 4035
a9fd4f3f
TI
4036 spec->autocfg.hp_pins[0] = 0x1b;
4037 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4038 spec->automute = 1;
4039 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4040}
4041
a9111321 4042static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4043 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4044 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4048 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4049 { } /* end */
4050};
4051
a9111321 4052static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4053 .num_items = 2,
4054 .items = {
4055 { "Mic", 0x0 },
4056 { "Internal Mic", 0x1 },
4057 },
4058};
4059
a9111321 4060static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4061 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4062
4063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4064 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4065
4066 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4069 /* Mic2 (as headphone out) for HP output */
4070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4072 /* Internal Speaker */
4073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4074 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4075
4076 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4077 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4078
4079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4080 { }
4081};
4082
4083/* toggle speaker-output according to the hp-jack state */
4084static void alc880_medion_rim_automute(struct hda_codec *codec)
4085{
a9fd4f3f 4086 struct alc_spec *spec = codec->spec;
d922b51d 4087 alc_hp_automute(codec);
a9fd4f3f
TI
4088 /* toggle EAPD */
4089 if (spec->jack_present)
df99cd33
TI
4090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4091 else
4092 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4093}
4094
4095static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4096 unsigned int res)
4097{
4098 /* Looks like the unsol event is incompatible with the standard
4099 * definition. 4bit tag is placed at 28 bit!
4100 */
4101 if ((res >> 28) == ALC880_HP_EVENT)
4102 alc880_medion_rim_automute(codec);
4103}
4104
4f5d1706 4105static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4106{
4107 struct alc_spec *spec = codec->spec;
4108
4109 spec->autocfg.hp_pins[0] = 0x14;
4110 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4111 spec->automute = 1;
4112 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4113}
4114
cb53c626 4115#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4116static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4117 { 0x0b, HDA_INPUT, 0 },
4118 { 0x0b, HDA_INPUT, 1 },
4119 { 0x0b, HDA_INPUT, 2 },
4120 { 0x0b, HDA_INPUT, 3 },
4121 { 0x0b, HDA_INPUT, 4 },
4122 { } /* end */
4123};
4124
a9111321 4125static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4126 { 0x0b, HDA_INPUT, 1 },
4127 { 0x0b, HDA_INPUT, 6 },
4128 { 0x0b, HDA_INPUT, 7 },
4129 { } /* end */
4130};
4131#endif
4132
ae6b813a
TI
4133/*
4134 * Common callbacks
e9edcee0
TI
4135 */
4136
584c0c4c
TI
4137static void alc_init_special_input_src(struct hda_codec *codec);
4138
1da177e4
LT
4139static int alc_init(struct hda_codec *codec)
4140{
4141 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4142 unsigned int i;
4143
2c3bf9ab 4144 alc_fix_pll(codec);
4a79ba34 4145 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4146
e9edcee0
TI
4147 for (i = 0; i < spec->num_init_verbs; i++)
4148 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4149 alc_init_special_input_src(codec);
ae6b813a
TI
4150
4151 if (spec->init_hook)
4152 spec->init_hook(codec);
4153
58701120
TI
4154 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4155
9e5341b9 4156 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4157 return 0;
4158}
4159
ae6b813a
TI
4160static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4161{
4162 struct alc_spec *spec = codec->spec;
4163
4164 if (spec->unsol_event)
4165 spec->unsol_event(codec, res);
4166}
4167
cb53c626
TI
4168#ifdef CONFIG_SND_HDA_POWER_SAVE
4169static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4170{
4171 struct alc_spec *spec = codec->spec;
4172 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4173}
4174#endif
4175
1da177e4
LT
4176/*
4177 * Analog playback callbacks
4178 */
4179static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4180 struct hda_codec *codec,
c8b6bf9b 4181 struct snd_pcm_substream *substream)
1da177e4
LT
4182{
4183 struct alc_spec *spec = codec->spec;
9a08160b
TI
4184 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4185 hinfo);
1da177e4
LT
4186}
4187
4188static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4189 struct hda_codec *codec,
4190 unsigned int stream_tag,
4191 unsigned int format,
c8b6bf9b 4192 struct snd_pcm_substream *substream)
1da177e4
LT
4193{
4194 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4195 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4196 stream_tag, format, substream);
1da177e4
LT
4197}
4198
4199static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4200 struct hda_codec *codec,
c8b6bf9b 4201 struct snd_pcm_substream *substream)
1da177e4
LT
4202{
4203 struct alc_spec *spec = codec->spec;
4204 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4205}
4206
4207/*
4208 * Digital out
4209 */
4210static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4211 struct hda_codec *codec,
c8b6bf9b 4212 struct snd_pcm_substream *substream)
1da177e4
LT
4213{
4214 struct alc_spec *spec = codec->spec;
4215 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4216}
4217
6b97eb45
TI
4218static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4219 struct hda_codec *codec,
4220 unsigned int stream_tag,
4221 unsigned int format,
4222 struct snd_pcm_substream *substream)
4223{
4224 struct alc_spec *spec = codec->spec;
4225 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4226 stream_tag, format, substream);
4227}
4228
9b5f12e5
TI
4229static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4230 struct hda_codec *codec,
4231 struct snd_pcm_substream *substream)
4232{
4233 struct alc_spec *spec = codec->spec;
4234 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4235}
4236
1da177e4
LT
4237static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4238 struct hda_codec *codec,
c8b6bf9b 4239 struct snd_pcm_substream *substream)
1da177e4
LT
4240{
4241 struct alc_spec *spec = codec->spec;
4242 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4243}
4244
4245/*
4246 * Analog capture
4247 */
6330079f 4248static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4249 struct hda_codec *codec,
4250 unsigned int stream_tag,
4251 unsigned int format,
c8b6bf9b 4252 struct snd_pcm_substream *substream)
1da177e4
LT
4253{
4254 struct alc_spec *spec = codec->spec;
4255
6330079f 4256 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4257 stream_tag, 0, format);
4258 return 0;
4259}
4260
6330079f 4261static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4262 struct hda_codec *codec,
c8b6bf9b 4263 struct snd_pcm_substream *substream)
1da177e4
LT
4264{
4265 struct alc_spec *spec = codec->spec;
4266
888afa15
TI
4267 snd_hda_codec_cleanup_stream(codec,
4268 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4269 return 0;
4270}
4271
840b64c0
TI
4272/* analog capture with dynamic dual-adc changes */
4273static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4274 struct hda_codec *codec,
4275 unsigned int stream_tag,
4276 unsigned int format,
4277 struct snd_pcm_substream *substream)
4278{
4279 struct alc_spec *spec = codec->spec;
4280 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4281 spec->cur_adc_stream_tag = stream_tag;
4282 spec->cur_adc_format = format;
4283 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4284 return 0;
4285}
4286
4287static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4288 struct hda_codec *codec,
4289 struct snd_pcm_substream *substream)
4290{
4291 struct alc_spec *spec = codec->spec;
4292 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4293 spec->cur_adc = 0;
4294 return 0;
4295}
4296
a9111321 4297static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4298 .substreams = 1,
4299 .channels_min = 2,
4300 .channels_max = 2,
4301 .nid = 0, /* fill later */
4302 .ops = {
4303 .prepare = dualmic_capture_pcm_prepare,
4304 .cleanup = dualmic_capture_pcm_cleanup
4305 },
4306};
1da177e4
LT
4307
4308/*
4309 */
a9111321 4310static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4311 .substreams = 1,
4312 .channels_min = 2,
4313 .channels_max = 8,
e9edcee0 4314 /* NID is set in alc_build_pcms */
1da177e4
LT
4315 .ops = {
4316 .open = alc880_playback_pcm_open,
4317 .prepare = alc880_playback_pcm_prepare,
4318 .cleanup = alc880_playback_pcm_cleanup
4319 },
4320};
4321
a9111321 4322static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4323 .substreams = 1,
4324 .channels_min = 2,
4325 .channels_max = 2,
4326 /* NID is set in alc_build_pcms */
4327};
4328
a9111321 4329static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
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_capture = {
6330079f 4337 .substreams = 2, /* can be overridden */
1da177e4
LT
4338 .channels_min = 2,
4339 .channels_max = 2,
e9edcee0 4340 /* NID is set in alc_build_pcms */
1da177e4 4341 .ops = {
6330079f
TI
4342 .prepare = alc880_alt_capture_pcm_prepare,
4343 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4344 },
4345};
4346
a9111321 4347static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4348 .substreams = 1,
4349 .channels_min = 2,
4350 .channels_max = 2,
4351 /* NID is set in alc_build_pcms */
4352 .ops = {
4353 .open = alc880_dig_playback_pcm_open,
6b97eb45 4354 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4355 .prepare = alc880_dig_playback_pcm_prepare,
4356 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4357 },
4358};
4359
a9111321 4360static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4361 .substreams = 1,
4362 .channels_min = 2,
4363 .channels_max = 2,
4364 /* NID is set in alc_build_pcms */
4365};
4366
4c5186ed 4367/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4368static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4369 .substreams = 0,
4370 .channels_min = 0,
4371 .channels_max = 0,
4372};
4373
1da177e4
LT
4374static int alc_build_pcms(struct hda_codec *codec)
4375{
4376 struct alc_spec *spec = codec->spec;
4377 struct hda_pcm *info = spec->pcm_rec;
4378 int i;
4379
4380 codec->num_pcms = 1;
4381 codec->pcm_info = info;
4382
e64f14f4
TI
4383 if (spec->no_analog)
4384 goto skip_analog;
4385
812a2cca
TI
4386 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4387 "%s Analog", codec->chip_name);
1da177e4 4388 info->name = spec->stream_name_analog;
274693f3 4389
4a471b7d 4390 if (spec->stream_analog_playback) {
da3cec35
TI
4391 if (snd_BUG_ON(!spec->multiout.dac_nids))
4392 return -EINVAL;
4a471b7d
TI
4393 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4394 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4395 }
4396 if (spec->stream_analog_capture) {
da3cec35
TI
4397 if (snd_BUG_ON(!spec->adc_nids))
4398 return -EINVAL;
4a471b7d
TI
4399 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4400 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4401 }
4402
4403 if (spec->channel_mode) {
4404 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4405 for (i = 0; i < spec->num_channel_mode; i++) {
4406 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4407 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4408 }
1da177e4
LT
4409 }
4410 }
4411
e64f14f4 4412 skip_analog:
e08a007d 4413 /* SPDIF for stream index #1 */
1da177e4 4414 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4415 snprintf(spec->stream_name_digital,
4416 sizeof(spec->stream_name_digital),
4417 "%s Digital", codec->chip_name);
e08a007d 4418 codec->num_pcms = 2;
b25c9da1 4419 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4420 info = spec->pcm_rec + 1;
1da177e4 4421 info->name = spec->stream_name_digital;
8c441982
TI
4422 if (spec->dig_out_type)
4423 info->pcm_type = spec->dig_out_type;
4424 else
4425 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4426 if (spec->multiout.dig_out_nid &&
4427 spec->stream_digital_playback) {
1da177e4
LT
4428 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4429 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4430 }
4a471b7d
TI
4431 if (spec->dig_in_nid &&
4432 spec->stream_digital_capture) {
1da177e4
LT
4433 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4434 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4435 }
963f803f
TI
4436 /* FIXME: do we need this for all Realtek codec models? */
4437 codec->spdif_status_reset = 1;
1da177e4
LT
4438 }
4439
e64f14f4
TI
4440 if (spec->no_analog)
4441 return 0;
4442
e08a007d
TI
4443 /* If the use of more than one ADC is requested for the current
4444 * model, configure a second analog capture-only PCM.
4445 */
4446 /* Additional Analaog capture for index #2 */
6330079f
TI
4447 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4448 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4449 codec->num_pcms = 3;
c06134d7 4450 info = spec->pcm_rec + 2;
e08a007d 4451 info->name = spec->stream_name_analog;
6330079f
TI
4452 if (spec->alt_dac_nid) {
4453 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4454 *spec->stream_analog_alt_playback;
4455 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4456 spec->alt_dac_nid;
4457 } else {
4458 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4459 alc_pcm_null_stream;
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4461 }
ce85c9ac 4462 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4463 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4464 *spec->stream_analog_alt_capture;
4465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4466 spec->adc_nids[1];
4467 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4468 spec->num_adc_nids - 1;
4469 } else {
4470 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4471 alc_pcm_null_stream;
4472 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4473 }
4474 }
4475
1da177e4
LT
4476 return 0;
4477}
4478
a4e09aa3
TI
4479static inline void alc_shutup(struct hda_codec *codec)
4480{
1c716153
TI
4481 struct alc_spec *spec = codec->spec;
4482
4483 if (spec && spec->shutup)
4484 spec->shutup(codec);
a4e09aa3
TI
4485 snd_hda_shutup_pins(codec);
4486}
4487
603c4019
TI
4488static void alc_free_kctls(struct hda_codec *codec)
4489{
4490 struct alc_spec *spec = codec->spec;
4491
4492 if (spec->kctls.list) {
4493 struct snd_kcontrol_new *kctl = spec->kctls.list;
4494 int i;
4495 for (i = 0; i < spec->kctls.used; i++)
4496 kfree(kctl[i].name);
4497 }
4498 snd_array_free(&spec->kctls);
4499}
4500
1da177e4
LT
4501static void alc_free(struct hda_codec *codec)
4502{
e9edcee0 4503 struct alc_spec *spec = codec->spec;
e9edcee0 4504
f12ab1e0 4505 if (!spec)
e9edcee0
TI
4506 return;
4507
a4e09aa3 4508 alc_shutup(codec);
cd372fb3 4509 snd_hda_input_jack_free(codec);
603c4019 4510 alc_free_kctls(codec);
e9edcee0 4511 kfree(spec);
680cd536 4512 snd_hda_detach_beep_device(codec);
1da177e4
LT
4513}
4514
f5de24b0 4515#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4516static void alc_power_eapd(struct hda_codec *codec)
4517{
691f1fcc 4518 alc_auto_setup_eapd(codec, false);
c97259df
DC
4519}
4520
f5de24b0
HM
4521static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4522{
4523 struct alc_spec *spec = codec->spec;
a4e09aa3 4524 alc_shutup(codec);
f5de24b0 4525 if (spec && spec->power_hook)
c97259df 4526 spec->power_hook(codec);
f5de24b0
HM
4527 return 0;
4528}
4529#endif
4530
e044c39a 4531#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4532static int alc_resume(struct hda_codec *codec)
4533{
1c716153 4534 msleep(150); /* to avoid pop noise */
e044c39a
TI
4535 codec->patch_ops.init(codec);
4536 snd_hda_codec_resume_amp(codec);
4537 snd_hda_codec_resume_cache(codec);
9e5341b9 4538 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4539 return 0;
4540}
e044c39a
TI
4541#endif
4542
1da177e4
LT
4543/*
4544 */
a9111321 4545static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4546 .build_controls = alc_build_controls,
4547 .build_pcms = alc_build_pcms,
4548 .init = alc_init,
4549 .free = alc_free,
ae6b813a 4550 .unsol_event = alc_unsol_event,
e044c39a
TI
4551#ifdef SND_HDA_NEEDS_RESUME
4552 .resume = alc_resume,
4553#endif
cb53c626 4554#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4555 .suspend = alc_suspend,
cb53c626
TI
4556 .check_power_status = alc_check_power_status,
4557#endif
c97259df 4558 .reboot_notify = alc_shutup,
1da177e4
LT
4559};
4560
c027ddcd
KY
4561/* replace the codec chip_name with the given string */
4562static int alc_codec_rename(struct hda_codec *codec, const char *name)
4563{
4564 kfree(codec->chip_name);
4565 codec->chip_name = kstrdup(name, GFP_KERNEL);
4566 if (!codec->chip_name) {
4567 alc_free(codec);
4568 return -ENOMEM;
4569 }
4570 return 0;
4571}
4572
2fa522be
TI
4573/*
4574 * Test configuration for debugging
4575 *
4576 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4577 * enum controls.
4578 */
4579#ifdef CONFIG_SND_DEBUG
4c6d72d1 4580static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4581 0x02, 0x03, 0x04, 0x05
4582};
4583
a9111321 4584static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4585 .num_items = 7,
2fa522be
TI
4586 .items = {
4587 { "In-1", 0x0 },
4588 { "In-2", 0x1 },
4589 { "In-3", 0x2 },
4590 { "In-4", 0x3 },
4591 { "CD", 0x4 },
ae6b813a
TI
4592 { "Front", 0x5 },
4593 { "Surround", 0x6 },
2fa522be
TI
4594 },
4595};
4596
a9111321 4597static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4598 { 2, NULL },
fd2c326d 4599 { 4, NULL },
2fa522be 4600 { 6, NULL },
fd2c326d 4601 { 8, NULL },
2fa522be
TI
4602};
4603
9c7f852e
TI
4604static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4605 struct snd_ctl_elem_info *uinfo)
2fa522be 4606{
4c6d72d1 4607 static const char * const texts[] = {
2fa522be
TI
4608 "N/A", "Line Out", "HP Out",
4609 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4610 };
4611 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4612 uinfo->count = 1;
4613 uinfo->value.enumerated.items = 8;
4614 if (uinfo->value.enumerated.item >= 8)
4615 uinfo->value.enumerated.item = 7;
4616 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4617 return 0;
4618}
4619
9c7f852e
TI
4620static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4621 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4622{
4623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4624 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4625 unsigned int pin_ctl, item = 0;
4626
4627 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4628 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4629 if (pin_ctl & AC_PINCTL_OUT_EN) {
4630 if (pin_ctl & AC_PINCTL_HP_EN)
4631 item = 2;
4632 else
4633 item = 1;
4634 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4635 switch (pin_ctl & AC_PINCTL_VREFEN) {
4636 case AC_PINCTL_VREF_HIZ: item = 3; break;
4637 case AC_PINCTL_VREF_50: item = 4; break;
4638 case AC_PINCTL_VREF_GRD: item = 5; break;
4639 case AC_PINCTL_VREF_80: item = 6; break;
4640 case AC_PINCTL_VREF_100: item = 7; break;
4641 }
4642 }
4643 ucontrol->value.enumerated.item[0] = item;
4644 return 0;
4645}
4646
9c7f852e
TI
4647static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4648 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4649{
4650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4651 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4652 static const unsigned int ctls[] = {
2fa522be
TI
4653 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4654 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4655 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4656 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4657 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4658 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4659 };
4660 unsigned int old_ctl, new_ctl;
4661
4662 old_ctl = snd_hda_codec_read(codec, nid, 0,
4663 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4664 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4665 if (old_ctl != new_ctl) {
82beb8fd
TI
4666 int val;
4667 snd_hda_codec_write_cache(codec, nid, 0,
4668 AC_VERB_SET_PIN_WIDGET_CONTROL,
4669 new_ctl);
47fd830a
TI
4670 val = ucontrol->value.enumerated.item[0] >= 3 ?
4671 HDA_AMP_MUTE : 0;
4672 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4673 HDA_AMP_MUTE, val);
2fa522be
TI
4674 return 1;
4675 }
4676 return 0;
4677}
4678
9c7f852e
TI
4679static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4680 struct snd_ctl_elem_info *uinfo)
2fa522be 4681{
4c6d72d1 4682 static const char * const texts[] = {
2fa522be
TI
4683 "Front", "Surround", "CLFE", "Side"
4684 };
4685 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4686 uinfo->count = 1;
4687 uinfo->value.enumerated.items = 4;
4688 if (uinfo->value.enumerated.item >= 4)
4689 uinfo->value.enumerated.item = 3;
4690 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4691 return 0;
4692}
4693
9c7f852e
TI
4694static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4695 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4696{
4697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4698 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4699 unsigned int sel;
4700
4701 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4702 ucontrol->value.enumerated.item[0] = sel & 3;
4703 return 0;
4704}
4705
9c7f852e
TI
4706static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4707 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4708{
4709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4710 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4711 unsigned int sel;
4712
4713 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4714 if (ucontrol->value.enumerated.item[0] != sel) {
4715 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4716 snd_hda_codec_write_cache(codec, nid, 0,
4717 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4718 return 1;
4719 }
4720 return 0;
4721}
4722
4723#define PIN_CTL_TEST(xname,nid) { \
4724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4725 .name = xname, \
5b0cb1d8 4726 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4727 .info = alc_test_pin_ctl_info, \
4728 .get = alc_test_pin_ctl_get, \
4729 .put = alc_test_pin_ctl_put, \
4730 .private_value = nid \
4731 }
4732
4733#define PIN_SRC_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4735 .name = xname, \
5b0cb1d8 4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4737 .info = alc_test_pin_src_info, \
4738 .get = alc_test_pin_src_get, \
4739 .put = alc_test_pin_src_put, \
4740 .private_value = nid \
4741 }
4742
a9111321 4743static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4744 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4745 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4746 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4747 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4749 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4750 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4751 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4752 PIN_CTL_TEST("Front Pin Mode", 0x14),
4753 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4754 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4755 PIN_CTL_TEST("Side Pin Mode", 0x17),
4756 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4757 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4758 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4759 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4760 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4761 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4762 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4763 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4764 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4765 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4766 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4767 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4768 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4769 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4770 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4771 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4774 {
4775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4776 .name = "Channel Mode",
df694daa
KY
4777 .info = alc_ch_mode_info,
4778 .get = alc_ch_mode_get,
4779 .put = alc_ch_mode_put,
2fa522be
TI
4780 },
4781 { } /* end */
4782};
4783
a9111321 4784static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4785 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4789 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4794 /* Vol output for 0x0c-0x0f */
05acb863
TI
4795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4799 /* Set output pins 0x14-0x17 */
05acb863
TI
4800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4804 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4808 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4809 /* Set input pins 0x18-0x1c */
16ded525
TI
4810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4812 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4814 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4815 /* Mute input pins 0x18-0x1b */
05acb863
TI
4816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4819 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4820 /* ADC set up */
05acb863 4821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4822 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4824 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4826 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4827 /* Analog input/passthru */
4828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4833 { }
4834};
4835#endif
4836
1da177e4
LT
4837/*
4838 */
4839
ea734963 4840static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4841 [ALC880_3ST] = "3stack",
4842 [ALC880_TCL_S700] = "tcl",
4843 [ALC880_3ST_DIG] = "3stack-digout",
4844 [ALC880_CLEVO] = "clevo",
4845 [ALC880_5ST] = "5stack",
4846 [ALC880_5ST_DIG] = "5stack-digout",
4847 [ALC880_W810] = "w810",
4848 [ALC880_Z71V] = "z71v",
4849 [ALC880_6ST] = "6stack",
4850 [ALC880_6ST_DIG] = "6stack-digout",
4851 [ALC880_ASUS] = "asus",
4852 [ALC880_ASUS_W1V] = "asus-w1v",
4853 [ALC880_ASUS_DIG] = "asus-dig",
4854 [ALC880_ASUS_DIG2] = "asus-dig2",
4855 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4856 [ALC880_UNIWILL_P53] = "uniwill-p53",
4857 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4858 [ALC880_F1734] = "F1734",
4859 [ALC880_LG] = "lg",
4860 [ALC880_LG_LW] = "lg-lw",
df99cd33 4861 [ALC880_MEDION_RIM] = "medion",
2fa522be 4862#ifdef CONFIG_SND_DEBUG
f5fcc13c 4863 [ALC880_TEST] = "test",
2fa522be 4864#endif
f5fcc13c
TI
4865 [ALC880_AUTO] = "auto",
4866};
4867
a9111321 4868static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4869 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4870 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4871 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4872 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4873 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4874 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4875 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4876 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4877 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4878 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4879 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4880 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4881 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4882 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4883 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4884 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4885 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4886 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4887 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4888 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4890 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4891 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4893 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4894 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4895 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4896 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4897 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4898 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4899 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4900 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4901 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4902 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4903 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4904 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4905 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4906 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4907 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4908 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4909 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4910 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4911 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4912 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4913 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4914 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4915 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4916 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4917 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4918 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4919 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4920 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4921 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4922 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4923 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4924 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4925 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4926 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4927 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4928 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4929 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4930 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4931 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4932 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4933 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4934 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4935 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4936 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4938 /* default Intel */
4939 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4940 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4941 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4942 {}
4943};
4944
16ded525 4945/*
df694daa 4946 * ALC880 codec presets
16ded525 4947 */
a9111321 4948static const struct alc_config_preset alc880_presets[] = {
16ded525 4949 [ALC880_3ST] = {
e9edcee0 4950 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4951 .init_verbs = { alc880_volume_init_verbs,
4952 alc880_pin_3stack_init_verbs },
16ded525 4953 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4954 .dac_nids = alc880_dac_nids,
16ded525
TI
4955 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4956 .channel_mode = alc880_threestack_modes,
4e195a7b 4957 .need_dac_fix = 1,
16ded525
TI
4958 .input_mux = &alc880_capture_source,
4959 },
4960 [ALC880_3ST_DIG] = {
e9edcee0 4961 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4962 .init_verbs = { alc880_volume_init_verbs,
4963 alc880_pin_3stack_init_verbs },
16ded525 4964 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4965 .dac_nids = alc880_dac_nids,
4966 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4967 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4968 .channel_mode = alc880_threestack_modes,
4e195a7b 4969 .need_dac_fix = 1,
16ded525
TI
4970 .input_mux = &alc880_capture_source,
4971 },
df694daa
KY
4972 [ALC880_TCL_S700] = {
4973 .mixers = { alc880_tcl_s700_mixer },
4974 .init_verbs = { alc880_volume_init_verbs,
4975 alc880_pin_tcl_S700_init_verbs,
4976 alc880_gpio2_init_verbs },
4977 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4978 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4979 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4980 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4981 .hp_nid = 0x03,
4982 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4983 .channel_mode = alc880_2_jack_modes,
4984 .input_mux = &alc880_capture_source,
4985 },
16ded525 4986 [ALC880_5ST] = {
f12ab1e0
TI
4987 .mixers = { alc880_three_stack_mixer,
4988 alc880_five_stack_mixer},
4989 .init_verbs = { alc880_volume_init_verbs,
4990 alc880_pin_5stack_init_verbs },
16ded525
TI
4991 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4992 .dac_nids = alc880_dac_nids,
16ded525
TI
4993 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4994 .channel_mode = alc880_fivestack_modes,
4995 .input_mux = &alc880_capture_source,
4996 },
4997 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4998 .mixers = { alc880_three_stack_mixer,
4999 alc880_five_stack_mixer },
5000 .init_verbs = { alc880_volume_init_verbs,
5001 alc880_pin_5stack_init_verbs },
16ded525
TI
5002 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5003 .dac_nids = alc880_dac_nids,
5004 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5005 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5006 .channel_mode = alc880_fivestack_modes,
5007 .input_mux = &alc880_capture_source,
5008 },
b6482d48
TI
5009 [ALC880_6ST] = {
5010 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5011 .init_verbs = { alc880_volume_init_verbs,
5012 alc880_pin_6stack_init_verbs },
b6482d48
TI
5013 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5014 .dac_nids = alc880_6st_dac_nids,
5015 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5016 .channel_mode = alc880_sixstack_modes,
5017 .input_mux = &alc880_6stack_capture_source,
5018 },
16ded525 5019 [ALC880_6ST_DIG] = {
e9edcee0 5020 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5021 .init_verbs = { alc880_volume_init_verbs,
5022 alc880_pin_6stack_init_verbs },
16ded525
TI
5023 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5024 .dac_nids = alc880_6st_dac_nids,
5025 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5026 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5027 .channel_mode = alc880_sixstack_modes,
5028 .input_mux = &alc880_6stack_capture_source,
5029 },
5030 [ALC880_W810] = {
e9edcee0 5031 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5032 .init_verbs = { alc880_volume_init_verbs,
5033 alc880_pin_w810_init_verbs,
b0af0de5 5034 alc880_gpio2_init_verbs },
16ded525
TI
5035 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5036 .dac_nids = alc880_w810_dac_nids,
5037 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5038 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5039 .channel_mode = alc880_w810_modes,
5040 .input_mux = &alc880_capture_source,
5041 },
5042 [ALC880_Z71V] = {
e9edcee0 5043 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5044 .init_verbs = { alc880_volume_init_verbs,
5045 alc880_pin_z71v_init_verbs },
16ded525
TI
5046 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5047 .dac_nids = alc880_z71v_dac_nids,
5048 .dig_out_nid = ALC880_DIGOUT_NID,
5049 .hp_nid = 0x03,
e9edcee0
TI
5050 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5051 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5052 .input_mux = &alc880_capture_source,
5053 },
5054 [ALC880_F1734] = {
e9edcee0 5055 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5056 .init_verbs = { alc880_volume_init_verbs,
5057 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5058 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5059 .dac_nids = alc880_f1734_dac_nids,
5060 .hp_nid = 0x02,
5061 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5062 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5063 .input_mux = &alc880_f1734_capture_source,
5064 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5065 .setup = alc880_uniwill_p53_setup,
d922b51d 5066 .init_hook = alc_hp_automute,
16ded525
TI
5067 },
5068 [ALC880_ASUS] = {
e9edcee0 5069 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5070 .init_verbs = { alc880_volume_init_verbs,
5071 alc880_pin_asus_init_verbs,
e9edcee0
TI
5072 alc880_gpio1_init_verbs },
5073 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5074 .dac_nids = alc880_asus_dac_nids,
5075 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5076 .channel_mode = alc880_asus_modes,
4e195a7b 5077 .need_dac_fix = 1,
16ded525
TI
5078 .input_mux = &alc880_capture_source,
5079 },
5080 [ALC880_ASUS_DIG] = {
e9edcee0 5081 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5082 .init_verbs = { alc880_volume_init_verbs,
5083 alc880_pin_asus_init_verbs,
e9edcee0
TI
5084 alc880_gpio1_init_verbs },
5085 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5086 .dac_nids = alc880_asus_dac_nids,
16ded525 5087 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5088 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5089 .channel_mode = alc880_asus_modes,
4e195a7b 5090 .need_dac_fix = 1,
16ded525
TI
5091 .input_mux = &alc880_capture_source,
5092 },
df694daa
KY
5093 [ALC880_ASUS_DIG2] = {
5094 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5095 .init_verbs = { alc880_volume_init_verbs,
5096 alc880_pin_asus_init_verbs,
df694daa
KY
5097 alc880_gpio2_init_verbs }, /* use GPIO2 */
5098 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5099 .dac_nids = alc880_asus_dac_nids,
5100 .dig_out_nid = ALC880_DIGOUT_NID,
5101 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5102 .channel_mode = alc880_asus_modes,
4e195a7b 5103 .need_dac_fix = 1,
df694daa
KY
5104 .input_mux = &alc880_capture_source,
5105 },
16ded525 5106 [ALC880_ASUS_W1V] = {
e9edcee0 5107 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5108 .init_verbs = { alc880_volume_init_verbs,
5109 alc880_pin_asus_init_verbs,
e9edcee0
TI
5110 alc880_gpio1_init_verbs },
5111 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5112 .dac_nids = alc880_asus_dac_nids,
16ded525 5113 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5114 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5115 .channel_mode = alc880_asus_modes,
4e195a7b 5116 .need_dac_fix = 1,
16ded525
TI
5117 .input_mux = &alc880_capture_source,
5118 },
5119 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5120 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5121 .init_verbs = { alc880_volume_init_verbs,
5122 alc880_pin_asus_init_verbs },
e9edcee0
TI
5123 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5124 .dac_nids = alc880_asus_dac_nids,
16ded525 5125 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5126 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5127 .channel_mode = alc880_asus_modes,
4e195a7b 5128 .need_dac_fix = 1,
16ded525
TI
5129 .input_mux = &alc880_capture_source,
5130 },
ccc656ce
KY
5131 [ALC880_UNIWILL] = {
5132 .mixers = { alc880_uniwill_mixer },
5133 .init_verbs = { alc880_volume_init_verbs,
5134 alc880_uniwill_init_verbs },
5135 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5136 .dac_nids = alc880_asus_dac_nids,
5137 .dig_out_nid = ALC880_DIGOUT_NID,
5138 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5139 .channel_mode = alc880_threestack_modes,
5140 .need_dac_fix = 1,
5141 .input_mux = &alc880_capture_source,
5142 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5143 .setup = alc880_uniwill_setup,
a9fd4f3f 5144 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5145 },
5146 [ALC880_UNIWILL_P53] = {
5147 .mixers = { alc880_uniwill_p53_mixer },
5148 .init_verbs = { alc880_volume_init_verbs,
5149 alc880_uniwill_p53_init_verbs },
5150 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5151 .dac_nids = alc880_asus_dac_nids,
5152 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5153 .channel_mode = alc880_threestack_modes,
5154 .input_mux = &alc880_capture_source,
5155 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5156 .setup = alc880_uniwill_p53_setup,
d922b51d 5157 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5158 },
5159 [ALC880_FUJITSU] = {
45bdd1c1 5160 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5161 .init_verbs = { alc880_volume_init_verbs,
5162 alc880_uniwill_p53_init_verbs,
5163 alc880_beep_init_verbs },
5164 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5165 .dac_nids = alc880_dac_nids,
d53d7d9e 5166 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5167 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5168 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5169 .input_mux = &alc880_capture_source,
5170 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5171 .setup = alc880_uniwill_p53_setup,
d922b51d 5172 .init_hook = alc_hp_automute,
ccc656ce 5173 },
df694daa
KY
5174 [ALC880_CLEVO] = {
5175 .mixers = { alc880_three_stack_mixer },
5176 .init_verbs = { alc880_volume_init_verbs,
5177 alc880_pin_clevo_init_verbs },
5178 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5179 .dac_nids = alc880_dac_nids,
5180 .hp_nid = 0x03,
5181 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5182 .channel_mode = alc880_threestack_modes,
4e195a7b 5183 .need_dac_fix = 1,
df694daa
KY
5184 .input_mux = &alc880_capture_source,
5185 },
ae6b813a
TI
5186 [ALC880_LG] = {
5187 .mixers = { alc880_lg_mixer },
5188 .init_verbs = { alc880_volume_init_verbs,
5189 alc880_lg_init_verbs },
5190 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5191 .dac_nids = alc880_lg_dac_nids,
5192 .dig_out_nid = ALC880_DIGOUT_NID,
5193 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5194 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5195 .need_dac_fix = 1,
ae6b813a 5196 .input_mux = &alc880_lg_capture_source,
d922b51d 5197 .unsol_event = alc_sku_unsol_event,
4f5d1706 5198 .setup = alc880_lg_setup,
d922b51d 5199 .init_hook = alc_hp_automute,
cb53c626
TI
5200#ifdef CONFIG_SND_HDA_POWER_SAVE
5201 .loopbacks = alc880_lg_loopbacks,
5202#endif
ae6b813a 5203 },
d681518a
TI
5204 [ALC880_LG_LW] = {
5205 .mixers = { alc880_lg_lw_mixer },
5206 .init_verbs = { alc880_volume_init_verbs,
5207 alc880_lg_lw_init_verbs },
0a8c5da3 5208 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5209 .dac_nids = alc880_dac_nids,
5210 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5211 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5212 .channel_mode = alc880_lg_lw_modes,
d681518a 5213 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5214 .unsol_event = alc_sku_unsol_event,
4f5d1706 5215 .setup = alc880_lg_lw_setup,
d922b51d 5216 .init_hook = alc_hp_automute,
d681518a 5217 },
df99cd33
TI
5218 [ALC880_MEDION_RIM] = {
5219 .mixers = { alc880_medion_rim_mixer },
5220 .init_verbs = { alc880_volume_init_verbs,
5221 alc880_medion_rim_init_verbs,
5222 alc_gpio2_init_verbs },
5223 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5224 .dac_nids = alc880_dac_nids,
5225 .dig_out_nid = ALC880_DIGOUT_NID,
5226 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5227 .channel_mode = alc880_2_jack_modes,
5228 .input_mux = &alc880_medion_rim_capture_source,
5229 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5230 .setup = alc880_medion_rim_setup,
5231 .init_hook = alc880_medion_rim_automute,
df99cd33 5232 },
16ded525
TI
5233#ifdef CONFIG_SND_DEBUG
5234 [ALC880_TEST] = {
e9edcee0
TI
5235 .mixers = { alc880_test_mixer },
5236 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5237 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5238 .dac_nids = alc880_test_dac_nids,
5239 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5240 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5241 .channel_mode = alc880_test_modes,
5242 .input_mux = &alc880_test_capture_source,
5243 },
5244#endif
5245};
5246
e9edcee0
TI
5247/*
5248 * Automatic parse of I/O pins from the BIOS configuration
5249 */
5250
e9edcee0
TI
5251enum {
5252 ALC_CTL_WIDGET_VOL,
5253 ALC_CTL_WIDGET_MUTE,
5254 ALC_CTL_BIND_MUTE,
5255};
a9111321 5256static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5257 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5258 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5259 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5260};
5261
ce764ab2
TI
5262static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5263{
5264 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5265 return snd_array_new(&spec->kctls);
5266}
5267
e9edcee0 5268/* add dynamic controls */
f12ab1e0 5269static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5270 int cidx, unsigned long val)
e9edcee0 5271{
c8b6bf9b 5272 struct snd_kcontrol_new *knew;
e9edcee0 5273
ce764ab2 5274 knew = alc_kcontrol_new(spec);
603c4019
TI
5275 if (!knew)
5276 return -ENOMEM;
e9edcee0 5277 *knew = alc880_control_templates[type];
543537bd 5278 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5279 if (!knew->name)
e9edcee0 5280 return -ENOMEM;
66ceeb6b 5281 knew->index = cidx;
4d02d1b6 5282 if (get_amp_nid_(val))
5e26dfd0 5283 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5284 knew->private_value = val;
e9edcee0
TI
5285 return 0;
5286}
5287
0afe5f89
TI
5288static int add_control_with_pfx(struct alc_spec *spec, int type,
5289 const char *pfx, const char *dir,
66ceeb6b 5290 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5291{
5292 char name[32];
5293 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5294 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5295}
5296
66ceeb6b
TI
5297#define add_pb_vol_ctrl(spec, type, pfx, val) \
5298 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5299#define add_pb_sw_ctrl(spec, type, pfx, val) \
5300 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5301#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5302 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5303#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5304 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5305
e9edcee0
TI
5306#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5307#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5308#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5309#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5310#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5311#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5312#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5313#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5314#define ALC880_PIN_CD_NID 0x1c
5315
5316/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5317static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5318 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5319{
5320 hda_nid_t nid;
5321 int assigned[4];
5322 int i, j;
5323
5324 memset(assigned, 0, sizeof(assigned));
b0af0de5 5325 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5326
5327 /* check the pins hardwired to audio widget */
5328 for (i = 0; i < cfg->line_outs; i++) {
5329 nid = cfg->line_out_pins[i];
5330 if (alc880_is_fixed_pin(nid)) {
5331 int idx = alc880_fixed_pin_idx(nid);
dda14410 5332 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5333 assigned[idx] = 1;
5334 }
5335 }
5336 /* left pins can be connect to any audio widget */
5337 for (i = 0; i < cfg->line_outs; i++) {
5338 nid = cfg->line_out_pins[i];
5339 if (alc880_is_fixed_pin(nid))
5340 continue;
5341 /* search for an empty channel */
5342 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5343 if (!assigned[j]) {
dda14410 5344 spec->private_dac_nids[i] =
f12ab1e0 5345 alc880_idx_to_dac(j);
e9edcee0
TI
5346 assigned[j] = 1;
5347 break;
5348 }
5349 }
5350 }
5351 spec->multiout.num_dacs = cfg->line_outs;
5352 return 0;
5353}
5354
ce764ab2 5355static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5356 bool can_be_master)
5357{
ce764ab2
TI
5358 struct auto_pin_cfg *cfg = &spec->autocfg;
5359
5360 if (cfg->line_outs == 1 && !spec->multi_ios &&
5361 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5362 return "Master";
5363
5364 switch (cfg->line_out_type) {
5365 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5366 if (cfg->line_outs == 1)
5367 return "Speaker";
5368 break;
bcb2f0f5
TI
5369 case AUTO_PIN_HP_OUT:
5370 return "Headphone";
5371 default:
ce764ab2 5372 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5373 return "PCM";
5374 break;
5375 }
5376 return NULL;
5377}
5378
e9edcee0 5379/* add playback controls from the parsed DAC table */
df694daa
KY
5380static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5381 const struct auto_pin_cfg *cfg)
e9edcee0 5382{
ea734963 5383 static const char * const chname[4] = {
f12ab1e0
TI
5384 "Front", "Surround", NULL /*CLFE*/, "Side"
5385 };
ce764ab2 5386 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5387 hda_nid_t nid;
ce764ab2 5388 int i, err, noutputs;
e9edcee0 5389
ce764ab2
TI
5390 noutputs = cfg->line_outs;
5391 if (spec->multi_ios > 0)
5392 noutputs += spec->multi_ios;
5393
5394 for (i = 0; i < noutputs; i++) {
f12ab1e0 5395 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5396 continue;
5397 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5398 if (!pfx && i == 2) {
e9edcee0 5399 /* Center/LFE */
0afe5f89
TI
5400 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5401 "Center",
f12ab1e0
TI
5402 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5403 HDA_OUTPUT));
5404 if (err < 0)
e9edcee0 5405 return err;
0afe5f89
TI
5406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5407 "LFE",
f12ab1e0
TI
5408 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5409 HDA_OUTPUT));
5410 if (err < 0)
e9edcee0 5411 return err;
0afe5f89
TI
5412 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5413 "Center",
f12ab1e0
TI
5414 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5415 HDA_INPUT));
5416 if (err < 0)
e9edcee0 5417 return err;
0afe5f89
TI
5418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5419 "LFE",
f12ab1e0
TI
5420 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5421 HDA_INPUT));
5422 if (err < 0)
e9edcee0
TI
5423 return err;
5424 } else {
bcb2f0f5 5425 const char *name = pfx;
7e59e097
DH
5426 int index = i;
5427 if (!name) {
bcb2f0f5 5428 name = chname[i];
7e59e097
DH
5429 index = 0;
5430 }
bcb2f0f5 5431 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5432 name, index,
f12ab1e0
TI
5433 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5434 HDA_OUTPUT));
5435 if (err < 0)
e9edcee0 5436 return err;
bcb2f0f5 5437 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5438 name, index,
f12ab1e0
TI
5439 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5440 HDA_INPUT));
5441 if (err < 0)
e9edcee0
TI
5442 return err;
5443 }
5444 }
e9edcee0
TI
5445 return 0;
5446}
5447
8d88bc3d
TI
5448/* add playback controls for speaker and HP outputs */
5449static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5450 const char *pfx)
e9edcee0
TI
5451{
5452 hda_nid_t nid;
5453 int err;
5454
f12ab1e0 5455 if (!pin)
e9edcee0
TI
5456 return 0;
5457
5458 if (alc880_is_fixed_pin(pin)) {
5459 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5460 /* specify the DAC as the extra output */
f12ab1e0 5461 if (!spec->multiout.hp_nid)
e9edcee0 5462 spec->multiout.hp_nid = nid;
82bc955f
TI
5463 else
5464 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5465 /* control HP volume/switch on the output mixer amp */
5466 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5467 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5468 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5469 if (err < 0)
e9edcee0 5470 return err;
0afe5f89 5471 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5472 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5473 if (err < 0)
e9edcee0
TI
5474 return err;
5475 } else if (alc880_is_multi_pin(pin)) {
5476 /* set manual connection */
e9edcee0 5477 /* we have only a switch on HP-out PIN */
0afe5f89 5478 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5479 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5480 if (err < 0)
e9edcee0
TI
5481 return err;
5482 }
5483 return 0;
5484}
5485
5486/* create input playback/capture controls for the given pin */
f12ab1e0 5487static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5488 const char *ctlname, int ctlidx,
df694daa 5489 int idx, hda_nid_t mix_nid)
e9edcee0 5490{
df694daa 5491 int err;
e9edcee0 5492
66ceeb6b 5493 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5494 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5495 if (err < 0)
e9edcee0 5496 return err;
66ceeb6b 5497 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5498 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5499 if (err < 0)
e9edcee0
TI
5500 return err;
5501 return 0;
5502}
5503
05f5f477
TI
5504static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5505{
5506 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5507 return (pincap & AC_PINCAP_IN) != 0;
5508}
5509
e9edcee0 5510/* create playback/capture controls for input pins */
05f5f477
TI
5511static int alc_auto_create_input_ctls(struct hda_codec *codec,
5512 const struct auto_pin_cfg *cfg,
5513 hda_nid_t mixer,
5514 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5515{
05f5f477 5516 struct alc_spec *spec = codec->spec;
61b9b9b1 5517 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5518 int i, err, idx, type_idx = 0;
5519 const char *prev_label = NULL;
e9edcee0 5520
66ceeb6b 5521 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5522 hda_nid_t pin;
10a20af7 5523 const char *label;
05f5f477 5524
66ceeb6b 5525 pin = cfg->inputs[i].pin;
05f5f477
TI
5526 if (!alc_is_input_pin(codec, pin))
5527 continue;
5528
5322bf27
DH
5529 label = hda_get_autocfg_input_label(codec, cfg, i);
5530 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5531 type_idx++;
5532 else
5533 type_idx = 0;
5322bf27
DH
5534 prev_label = label;
5535
05f5f477
TI
5536 if (mixer) {
5537 idx = get_connection_index(codec, mixer, pin);
5538 if (idx >= 0) {
5539 err = new_analog_input(spec, pin,
10a20af7
TI
5540 label, type_idx,
5541 idx, mixer);
05f5f477
TI
5542 if (err < 0)
5543 return err;
5544 }
5545 }
5546
5547 if (!cap1)
5548 continue;
5549 idx = get_connection_index(codec, cap1, pin);
5550 if (idx < 0 && cap2)
5551 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5552 if (idx >= 0)
5553 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5554 }
5555 return 0;
5556}
5557
05f5f477
TI
5558static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5559 const struct auto_pin_cfg *cfg)
5560{
5561 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5562}
5563
f6c7e546
TI
5564static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5565 unsigned int pin_type)
5566{
5567 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5568 pin_type);
5569 /* unmute pin */
d260cdf6
TI
5570 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5571 AMP_OUT_UNMUTE);
f6c7e546
TI
5572}
5573
df694daa
KY
5574static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5575 hda_nid_t nid, int pin_type,
e9edcee0
TI
5576 int dac_idx)
5577{
f6c7e546 5578 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5579 /* need the manual connection? */
5580 if (alc880_is_multi_pin(nid)) {
5581 struct alc_spec *spec = codec->spec;
5582 int idx = alc880_multi_pin_idx(nid);
5583 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5584 AC_VERB_SET_CONNECT_SEL,
5585 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5586 }
5587}
5588
baba8ee9
TI
5589static int get_pin_type(int line_out_type)
5590{
5591 if (line_out_type == AUTO_PIN_HP_OUT)
5592 return PIN_HP;
5593 else
5594 return PIN_OUT;
5595}
5596
e9edcee0
TI
5597static void alc880_auto_init_multi_out(struct hda_codec *codec)
5598{
5599 struct alc_spec *spec = codec->spec;
5600 int i;
ea1fb29a 5601
e9edcee0
TI
5602 for (i = 0; i < spec->autocfg.line_outs; i++) {
5603 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5604 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5605 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5606 }
5607}
5608
8d88bc3d 5609static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5610{
5611 struct alc_spec *spec = codec->spec;
5612 hda_nid_t pin;
5613
82bc955f 5614 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5615 if (pin) /* connect to front */
5616 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5617 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5618 if (pin) /* connect to front */
5619 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5620}
5621
5622static void alc880_auto_init_analog_input(struct hda_codec *codec)
5623{
5624 struct alc_spec *spec = codec->spec;
66ceeb6b 5625 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5626 int i;
5627
66ceeb6b
TI
5628 for (i = 0; i < cfg->num_inputs; i++) {
5629 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5630 if (alc_is_input_pin(codec, nid)) {
30ea098f 5631 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5632 if (nid != ALC880_PIN_CD_NID &&
5633 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5634 snd_hda_codec_write(codec, nid, 0,
5635 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5636 AMP_OUT_MUTE);
5637 }
5638 }
5639}
5640
7f311a46
TI
5641static void alc880_auto_init_input_src(struct hda_codec *codec)
5642{
5643 struct alc_spec *spec = codec->spec;
5644 int c;
5645
5646 for (c = 0; c < spec->num_adc_nids; c++) {
5647 unsigned int mux_idx;
5648 const struct hda_input_mux *imux;
5649 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5650 imux = &spec->input_mux[mux_idx];
5651 if (!imux->num_items && mux_idx > 0)
5652 imux = &spec->input_mux[0];
5653 if (imux)
5654 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5655 AC_VERB_SET_CONNECT_SEL,
5656 imux->items[0].index);
5657 }
5658}
5659
ce764ab2
TI
5660static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5661
e9edcee0 5662/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5663/* return 1 if successful, 0 if the proper config is not found,
5664 * or a negative error code
5665 */
e9edcee0
TI
5666static int alc880_parse_auto_config(struct hda_codec *codec)
5667{
5668 struct alc_spec *spec = codec->spec;
757899ac 5669 int err;
4c6d72d1 5670 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5671
f12ab1e0
TI
5672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5673 alc880_ignore);
5674 if (err < 0)
e9edcee0 5675 return err;
f12ab1e0 5676 if (!spec->autocfg.line_outs)
e9edcee0 5677 return 0; /* can't find valid BIOS pin config */
df694daa 5678
f12ab1e0 5679 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5680 if (err < 0)
5681 return err;
5682 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5683 if (err < 0)
5684 return err;
5685 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5686 if (err < 0)
5687 return err;
5688 err = alc880_auto_create_extra_out(spec,
5689 spec->autocfg.speaker_pins[0],
5690 "Speaker");
5691 if (err < 0)
5692 return err;
5693 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5694 "Headphone");
5695 if (err < 0)
5696 return err;
05f5f477 5697 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5698 if (err < 0)
e9edcee0
TI
5699 return err;
5700
5701 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5702
757899ac 5703 alc_auto_parse_digital(codec);
e9edcee0 5704
603c4019 5705 if (spec->kctls.list)
d88897ea 5706 add_mixer(spec, spec->kctls.list);
e9edcee0 5707
d88897ea 5708 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5709
a1e8d2da 5710 spec->num_mux_defs = 1;
61b9b9b1 5711 spec->input_mux = &spec->private_imux[0];
e9edcee0 5712
6227cdce 5713 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5714
e9edcee0
TI
5715 return 1;
5716}
5717
ae6b813a
TI
5718/* additional initialization for auto-configuration model */
5719static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5720{
f6c7e546 5721 struct alc_spec *spec = codec->spec;
e9edcee0 5722 alc880_auto_init_multi_out(codec);
8d88bc3d 5723 alc880_auto_init_extra_out(codec);
e9edcee0 5724 alc880_auto_init_analog_input(codec);
7f311a46 5725 alc880_auto_init_input_src(codec);
757899ac 5726 alc_auto_init_digital(codec);
f6c7e546 5727 if (spec->unsol_event)
7fb0d78f 5728 alc_inithook(codec);
e9edcee0
TI
5729}
5730
b59bdf3b
TI
5731/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5732 * one of two digital mic pins, e.g. on ALC272
5733 */
5734static void fixup_automic_adc(struct hda_codec *codec)
5735{
5736 struct alc_spec *spec = codec->spec;
5737 int i;
5738
5739 for (i = 0; i < spec->num_adc_nids; i++) {
5740 hda_nid_t cap = spec->capsrc_nids ?
5741 spec->capsrc_nids[i] : spec->adc_nids[i];
5742 int iidx, eidx;
5743
5744 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5745 if (iidx < 0)
5746 continue;
5747 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5748 if (eidx < 0)
5749 continue;
5750 spec->int_mic.mux_idx = iidx;
5751 spec->ext_mic.mux_idx = eidx;
5752 if (spec->capsrc_nids)
5753 spec->capsrc_nids += i;
5754 spec->adc_nids += i;
5755 spec->num_adc_nids = 1;
8ed99d97
TI
5756 /* optional dock-mic */
5757 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5758 if (eidx < 0)
5759 spec->dock_mic.pin = 0;
5760 else
5761 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5762 return;
5763 }
5764 snd_printd(KERN_INFO "hda_codec: %s: "
5765 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5766 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5767 spec->auto_mic = 0; /* disable auto-mic to be sure */
5768}
5769
748cce43
TI
5770/* select or unmute the given capsrc route */
5771static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5772 int idx)
5773{
5774 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5775 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5776 HDA_AMP_MUTE, 0);
5777 } else {
5778 snd_hda_codec_write_cache(codec, cap, 0,
5779 AC_VERB_SET_CONNECT_SEL, idx);
5780 }
5781}
5782
840b64c0
TI
5783/* set the default connection to that pin */
5784static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5785{
5786 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5787 int i;
5788
8ed99d97
TI
5789 if (!pin)
5790 return 0;
eaa9b3a7
TI
5791 for (i = 0; i < spec->num_adc_nids; i++) {
5792 hda_nid_t cap = spec->capsrc_nids ?
5793 spec->capsrc_nids[i] : spec->adc_nids[i];
5794 int idx;
5795
5796 idx = get_connection_index(codec, cap, pin);
5797 if (idx < 0)
5798 continue;
748cce43 5799 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5800 return i; /* return the found index */
5801 }
5802 return -1; /* not found */
5803}
5804
5805/* choose the ADC/MUX containing the input pin and initialize the setup */
5806static void fixup_single_adc(struct hda_codec *codec)
5807{
5808 struct alc_spec *spec = codec->spec;
66ceeb6b 5809 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5810 int i;
5811
5812 /* search for the input pin; there must be only one */
66ceeb6b 5813 if (cfg->num_inputs != 1)
eaa9b3a7 5814 return;
66ceeb6b 5815 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5816 if (i >= 0) {
5817 /* use only this ADC */
5818 if (spec->capsrc_nids)
5819 spec->capsrc_nids += i;
5820 spec->adc_nids += i;
5821 spec->num_adc_nids = 1;
584c0c4c 5822 spec->single_input_src = 1;
eaa9b3a7
TI
5823 }
5824}
5825
840b64c0
TI
5826/* initialize dual adcs */
5827static void fixup_dual_adc_switch(struct hda_codec *codec)
5828{
5829 struct alc_spec *spec = codec->spec;
5830 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5831 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5832 init_capsrc_for_pin(codec, spec->int_mic.pin);
5833}
5834
584c0c4c
TI
5835/* initialize some special cases for input sources */
5836static void alc_init_special_input_src(struct hda_codec *codec)
5837{
5838 struct alc_spec *spec = codec->spec;
5839 if (spec->dual_adc_switch)
5840 fixup_dual_adc_switch(codec);
5841 else if (spec->single_input_src)
5842 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5843}
5844
b59bdf3b 5845static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5846{
b59bdf3b 5847 struct alc_spec *spec = codec->spec;
a9111321 5848 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5849 { alc_capture_mixer_nosrc1,
5850 alc_capture_mixer_nosrc2,
5851 alc_capture_mixer_nosrc3 },
5852 { alc_capture_mixer1,
5853 alc_capture_mixer2,
5854 alc_capture_mixer3 },
f9e336f6 5855 };
a23b688f 5856 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5857 int mux = 0;
840b64c0
TI
5858 int num_adcs = spec->num_adc_nids;
5859 if (spec->dual_adc_switch)
584c0c4c 5860 num_adcs = 1;
840b64c0 5861 else if (spec->auto_mic)
b59bdf3b 5862 fixup_automic_adc(codec);
eaa9b3a7
TI
5863 else if (spec->input_mux) {
5864 if (spec->input_mux->num_items > 1)
5865 mux = 1;
5866 else if (spec->input_mux->num_items == 1)
5867 fixup_single_adc(codec);
5868 }
840b64c0 5869 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5870 }
f9e336f6
TI
5871}
5872
6694635d 5873/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5874static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5875 int num_nids)
5876{
5877 struct alc_spec *spec = codec->spec;
66ceeb6b 5878 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5879 int n;
5880 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5881
5882 for (n = 0; n < num_nids; n++) {
5883 hda_nid_t adc, cap;
5884 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5885 int nconns, i, j;
5886
5887 adc = nids[n];
5888 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5889 continue;
5890 cap = adc;
5891 nconns = snd_hda_get_connections(codec, cap, conn,
5892 ARRAY_SIZE(conn));
5893 if (nconns == 1) {
5894 cap = conn[0];
5895 nconns = snd_hda_get_connections(codec, cap, conn,
5896 ARRAY_SIZE(conn));
5897 }
5898 if (nconns <= 0)
5899 continue;
5900 if (!fallback_adc) {
5901 fallback_adc = adc;
5902 fallback_cap = cap;
5903 }
66ceeb6b
TI
5904 for (i = 0; i < cfg->num_inputs; i++) {
5905 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5906 for (j = 0; j < nconns; j++) {
5907 if (conn[j] == nid)
5908 break;
5909 }
5910 if (j >= nconns)
5911 break;
5912 }
66ceeb6b 5913 if (i >= cfg->num_inputs) {
6694635d
TI
5914 int num_adcs = spec->num_adc_nids;
5915 spec->private_adc_nids[num_adcs] = adc;
5916 spec->private_capsrc_nids[num_adcs] = cap;
5917 spec->num_adc_nids++;
5918 spec->adc_nids = spec->private_adc_nids;
5919 if (adc != cap)
5920 spec->capsrc_nids = spec->private_capsrc_nids;
5921 }
5922 }
5923 if (!spec->num_adc_nids) {
5924 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5925 " using fallback 0x%x\n",
5926 codec->chip_name, fallback_adc);
6694635d
TI
5927 spec->private_adc_nids[0] = fallback_adc;
5928 spec->adc_nids = spec->private_adc_nids;
5929 if (fallback_adc != fallback_cap) {
5930 spec->private_capsrc_nids[0] = fallback_cap;
5931 spec->capsrc_nids = spec->private_adc_nids;
5932 }
5933 }
5934}
5935
67d634c0 5936#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5937#define set_beep_amp(spec, nid, idx, dir) \
5938 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5939
a9111321 5940static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5941 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5942 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5943 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5944 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5945 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5946 {}
5947};
5948
5949static inline int has_cdefine_beep(struct hda_codec *codec)
5950{
5951 struct alc_spec *spec = codec->spec;
5952 const struct snd_pci_quirk *q;
5953 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5954 if (q)
5955 return q->value;
5956 return spec->cdefine.enable_pcbeep;
5957}
67d634c0
TI
5958#else
5959#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5960#define has_cdefine_beep(codec) 0
67d634c0 5961#endif
45bdd1c1
TI
5962
5963/*
5964 * OK, here we have finally the patch for ALC880
5965 */
5966
1da177e4
LT
5967static int patch_alc880(struct hda_codec *codec)
5968{
5969 struct alc_spec *spec;
5970 int board_config;
df694daa 5971 int err;
1da177e4 5972
e560d8d8 5973 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5974 if (spec == NULL)
5975 return -ENOMEM;
5976
5977 codec->spec = spec;
5978
f5fcc13c
TI
5979 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5980 alc880_models,
5981 alc880_cfg_tbl);
5982 if (board_config < 0) {
9a11f1aa
TI
5983 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5984 codec->chip_name);
e9edcee0 5985 board_config = ALC880_AUTO;
1da177e4 5986 }
1da177e4 5987
e9edcee0
TI
5988 if (board_config == ALC880_AUTO) {
5989 /* automatic parse from the BIOS config */
5990 err = alc880_parse_auto_config(codec);
5991 if (err < 0) {
5992 alc_free(codec);
5993 return err;
f12ab1e0 5994 } else if (!err) {
9c7f852e
TI
5995 printk(KERN_INFO
5996 "hda_codec: Cannot set up configuration "
5997 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5998 board_config = ALC880_3ST;
5999 }
1da177e4
LT
6000 }
6001
680cd536
KK
6002 err = snd_hda_attach_beep_device(codec, 0x1);
6003 if (err < 0) {
6004 alc_free(codec);
6005 return err;
6006 }
6007
df694daa 6008 if (board_config != ALC880_AUTO)
e9c364c0 6009 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 6010
1da177e4
LT
6011 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6012 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 6013 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6014
1da177e4
LT
6015 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6016 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6017
f12ab1e0 6018 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 6019 /* check whether NID 0x07 is valid */
54d17403 6020 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 6021 /* get type */
a22d543a 6022 wcap = get_wcaps_type(wcap);
e9edcee0
TI
6023 if (wcap != AC_WID_AUD_IN) {
6024 spec->adc_nids = alc880_adc_nids_alt;
6025 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
6026 } else {
6027 spec->adc_nids = alc880_adc_nids;
6028 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
6029 }
6030 }
b59bdf3b 6031 set_capture_mixer(codec);
45bdd1c1 6032 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 6033
2134ea4f
TI
6034 spec->vmaster_nid = 0x0c;
6035
1da177e4 6036 codec->patch_ops = alc_patch_ops;
e9edcee0 6037 if (board_config == ALC880_AUTO)
ae6b813a 6038 spec->init_hook = alc880_auto_init;
cb53c626
TI
6039#ifdef CONFIG_SND_HDA_POWER_SAVE
6040 if (!spec->loopback.amplist)
6041 spec->loopback.amplist = alc880_loopbacks;
6042#endif
1da177e4
LT
6043
6044 return 0;
6045}
6046
e9edcee0 6047
1da177e4
LT
6048/*
6049 * ALC260 support
6050 */
6051
4c6d72d1 6052static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6053 /* front */
6054 0x02,
6055};
6056
4c6d72d1 6057static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6058 /* ADC0 */
6059 0x04,
6060};
6061
4c6d72d1 6062static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6063 /* ADC1 */
6064 0x05,
6065};
6066
d57fdac0
JW
6067/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6068 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6069 */
4c6d72d1 6070static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6071 /* ADC0, ADC1 */
6072 0x04, 0x05
6073};
6074
e9edcee0
TI
6075#define ALC260_DIGOUT_NID 0x03
6076#define ALC260_DIGIN_NID 0x06
6077
a9111321 6078static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6079 .num_items = 4,
6080 .items = {
6081 { "Mic", 0x0 },
6082 { "Front Mic", 0x1 },
6083 { "Line", 0x2 },
6084 { "CD", 0x4 },
6085 },
6086};
6087
17e7aec6 6088/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6089 * headphone jack and the internal CD lines since these are the only pins at
6090 * which audio can appear. For flexibility, also allow the option of
6091 * recording the mixer output on the second ADC (ADC0 doesn't have a
6092 * connection to the mixer output).
a9430dd8 6093 */
a9111321 6094static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6095 {
6096 .num_items = 3,
6097 .items = {
6098 { "Mic/Line", 0x0 },
6099 { "CD", 0x4 },
6100 { "Headphone", 0x2 },
6101 },
a9430dd8 6102 },
a1e8d2da
JW
6103 {
6104 .num_items = 4,
6105 .items = {
6106 { "Mic/Line", 0x0 },
6107 { "CD", 0x4 },
6108 { "Headphone", 0x2 },
6109 { "Mixer", 0x5 },
6110 },
6111 },
6112
a9430dd8
JW
6113};
6114
a1e8d2da
JW
6115/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6116 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6117 */
a9111321 6118static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6119 {
6120 .num_items = 4,
6121 .items = {
6122 { "Mic", 0x0 },
6123 { "Line", 0x2 },
6124 { "CD", 0x4 },
6125 { "Headphone", 0x5 },
6126 },
6127 },
6128 {
6129 .num_items = 5,
6130 .items = {
6131 { "Mic", 0x0 },
6132 { "Line", 0x2 },
6133 { "CD", 0x4 },
6134 { "Headphone", 0x6 },
6135 { "Mixer", 0x5 },
6136 },
0bfc90e9
JW
6137 },
6138};
cc959489
MS
6139
6140/* Maxdata Favorit 100XS */
a9111321 6141static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6142 {
6143 .num_items = 2,
6144 .items = {
6145 { "Line/Mic", 0x0 },
6146 { "CD", 0x4 },
6147 },
6148 },
6149 {
6150 .num_items = 3,
6151 .items = {
6152 { "Line/Mic", 0x0 },
6153 { "CD", 0x4 },
6154 { "Mixer", 0x5 },
6155 },
6156 },
6157};
6158
1da177e4
LT
6159/*
6160 * This is just place-holder, so there's something for alc_build_pcms to look
6161 * at when it calculates the maximum number of channels. ALC260 has no mixer
6162 * element which allows changing the channel mode, so the verb list is
6163 * never used.
6164 */
a9111321 6165static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6166 { 2, NULL },
6167};
6168
df694daa
KY
6169
6170/* Mixer combinations
6171 *
6172 * basic: base_output + input + pc_beep + capture
6173 * HP: base_output + input + capture_alt
6174 * HP_3013: hp_3013 + input + capture
6175 * fujitsu: fujitsu + capture
0bfc90e9 6176 * acer: acer + capture
df694daa
KY
6177 */
6178
a9111321 6179static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6180 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6181 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6183 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6184 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6185 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6186 { } /* end */
f12ab1e0 6187};
1da177e4 6188
a9111321 6189static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6190 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6191 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6192 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6193 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6195 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6198 { } /* end */
6199};
6200
bec15c3a 6201/* update HP, line and mono out pins according to the master switch */
e9427969 6202static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a
TI
6203{
6204 struct alc_spec *spec = codec->spec;
e9427969
TI
6205
6206 /* change HP pins */
6207 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
6208 spec->autocfg.hp_pins, spec->master_mute, true);
6209 update_speakers(codec);
bec15c3a
TI
6210}
6211
6212static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6213 struct snd_ctl_elem_value *ucontrol)
6214{
6215 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6216 struct alc_spec *spec = codec->spec;
e9427969 6217 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6218 return 0;
6219}
6220
6221static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6222 struct snd_ctl_elem_value *ucontrol)
6223{
6224 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6225 struct alc_spec *spec = codec->spec;
e9427969 6226 int val = !*ucontrol->value.integer.value;
bec15c3a 6227
e9427969 6228 if (val == spec->master_mute)
bec15c3a 6229 return 0;
e9427969
TI
6230 spec->master_mute = val;
6231 alc260_hp_master_update(codec);
bec15c3a
TI
6232 return 1;
6233}
6234
a9111321 6235static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6236 {
6237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6238 .name = "Master Playback Switch",
5b0cb1d8 6239 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6240 .info = snd_ctl_boolean_mono_info,
6241 .get = alc260_hp_master_sw_get,
6242 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6243 },
6244 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6245 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6246 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6247 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6248 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6249 HDA_OUTPUT),
6250 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6251 { } /* end */
6252};
6253
a9111321 6254static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6255 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6256 {},
6257};
6258
e9427969 6259static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6260{
6261 struct alc_spec *spec = codec->spec;
bec15c3a 6262
e9427969
TI
6263 spec->autocfg.hp_pins[0] = 0x0f;
6264 spec->autocfg.speaker_pins[0] = 0x10;
6265 spec->autocfg.speaker_pins[1] = 0x11;
6266 spec->automute = 1;
6267 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6268}
6269
a9111321 6270static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6271 {
6272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6273 .name = "Master Playback Switch",
5b0cb1d8 6274 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6275 .info = snd_ctl_boolean_mono_info,
6276 .get = alc260_hp_master_sw_get,
6277 .put = alc260_hp_master_sw_put,
bec15c3a 6278 },
df694daa
KY
6279 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6280 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6282 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6285 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6286 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6287 { } /* end */
6288};
6289
e9427969
TI
6290static void alc260_hp_3013_setup(struct hda_codec *codec)
6291{
6292 struct alc_spec *spec = codec->spec;
6293
6294 spec->autocfg.hp_pins[0] = 0x15;
6295 spec->autocfg.speaker_pins[0] = 0x10;
6296 spec->autocfg.speaker_pins[1] = 0x11;
6297 spec->automute = 1;
6298 spec->automute_mode = ALC_AUTOMUTE_PIN;
6299}
6300
a9111321 6301static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6302 .ops = &snd_hda_bind_vol,
6303 .values = {
6304 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6305 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6306 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6307 0
6308 },
6309};
6310
a9111321 6311static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6312 .ops = &snd_hda_bind_sw,
6313 .values = {
6314 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6315 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6316 0
6317 },
6318};
6319
a9111321 6320static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6321 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6322 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6324 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6325 { } /* end */
6326};
6327
a9111321 6328static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6330 {},
6331};
6332
e9427969 6333static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6334{
6335 struct alc_spec *spec = codec->spec;
bec15c3a 6336
e9427969
TI
6337 spec->autocfg.hp_pins[0] = 0x10;
6338 spec->autocfg.speaker_pins[0] = 0x0f;
6339 spec->autocfg.speaker_pins[1] = 0x11;
6340 spec->autocfg.speaker_pins[2] = 0x15;
6341 spec->automute = 1;
6342 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6343}
6344
6345/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6346 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6347 */
a9111321 6348static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6349 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6350 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6351 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6352 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6353 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6355 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6356 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6358 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6359 { } /* end */
6360};
6361
a1e8d2da
JW
6362/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6363 * versions of the ALC260 don't act on requests to enable mic bias from NID
6364 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6365 * datasheet doesn't mention this restriction. At this stage it's not clear
6366 * whether this behaviour is intentional or is a hardware bug in chip
6367 * revisions available in early 2006. Therefore for now allow the
6368 * "Headphone Jack Mode" control to span all choices, but if it turns out
6369 * that the lack of mic bias for this NID is intentional we could change the
6370 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6371 *
6372 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6373 * don't appear to make the mic bias available from the "line" jack, even
6374 * though the NID used for this jack (0x14) can supply it. The theory is
6375 * that perhaps Acer have included blocking capacitors between the ALC260
6376 * and the output jack. If this turns out to be the case for all such
6377 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6378 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6379 *
6380 * The C20x Tablet series have a mono internal speaker which is controlled
6381 * via the chip's Mono sum widget and pin complex, so include the necessary
6382 * controls for such models. On models without a "mono speaker" the control
6383 * won't do anything.
a1e8d2da 6384 */
a9111321 6385static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6386 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6387 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6388 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6389 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6390 HDA_OUTPUT),
31bffaa9 6391 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6392 HDA_INPUT),
0bfc90e9
JW
6393 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6394 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6396 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6397 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6398 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6399 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6400 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6401 { } /* end */
6402};
6403
cc959489
MS
6404/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6405 */
a9111321 6406static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6407 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6409 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6411 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6412 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6413 { } /* end */
6414};
6415
bc9f98a9
KY
6416/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6417 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6418 */
a9111321 6419static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6420 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6421 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6423 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6424 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6425 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6426 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6427 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6428 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6429 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6430 { } /* end */
6431};
6432
6433/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6434 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6435 */
a9111321 6436static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6437 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6438 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6440 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6441 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6442 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6443 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6444 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6445 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6446 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6447 { } /* end */
6448};
6449
df694daa
KY
6450/*
6451 * initialization verbs
6452 */
a9111321 6453static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6454 /* Line In pin widget for input */
05acb863 6455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6456 /* CD pin widget for input */
05acb863 6457 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6458 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6460 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6461 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6462 /* LINE-2 is used for line-out in rear */
05acb863 6463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6464 /* select line-out */
fd56f2db 6465 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6466 /* LINE-OUT pin */
05acb863 6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6468 /* enable HP */
05acb863 6469 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6470 /* enable Mono */
05acb863
TI
6471 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6472 /* mute capture amp left and right */
16ded525 6473 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6474 /* set connection select to line in (default select for this ADC) */
6475 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6476 /* mute capture amp left and right */
6477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6478 /* set connection select to line in (default select for this ADC) */
6479 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6480 /* set vol=0 Line-Out mixer amp left and right */
6481 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6482 /* unmute pin widget amp left and right (no gain on this amp) */
6483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6484 /* set vol=0 HP mixer amp left and right */
6485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6486 /* unmute pin widget amp left and right (no gain on this amp) */
6487 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6488 /* set vol=0 Mono mixer amp left and right */
6489 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 /* unmute pin widget amp left and right (no gain on this amp) */
6491 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6492 /* unmute LINE-2 out pin */
6493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6494 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6495 * Line In 2 = 0x03
6496 */
cb53c626
TI
6497 /* mute analog inputs */
6498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6503 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6504 /* mute Front out path */
6505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6507 /* mute Headphone out path */
6508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6510 /* mute Mono out path */
6511 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6513 { }
6514};
6515
474167d6 6516#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6517static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6518 /* Headphone and output */
6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6520 /* mono output */
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6522 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6523 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6524 /* Mic2 (front panel) pin widget for input and vref at 80% */
6525 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6526 /* Line In pin widget for input */
6527 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6528 /* Line-2 pin widget for output */
6529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6530 /* CD pin widget for input */
6531 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6532 /* unmute amp left and right */
6533 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6534 /* set connection select to line in (default select for this ADC) */
6535 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6536 /* unmute Line-Out mixer amp left and right (volume = 0) */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6538 /* mute pin widget amp left and right (no gain on this amp) */
6539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6540 /* unmute HP mixer amp left and right (volume = 0) */
6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6542 /* mute pin widget amp left and right (no gain on this amp) */
6543 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6545 * Line In 2 = 0x03
6546 */
cb53c626
TI
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6554 /* Unmute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6557 /* Unmute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6560 /* Unmute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6563 { }
6564};
474167d6 6565#endif
df694daa 6566
a9111321 6567static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6568 /* Line out and output */
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6570 /* mono output */
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Headphone pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6595 * Line In 2 = 0x03
6596 */
cb53c626
TI
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6613 { }
6614};
6615
a9430dd8 6616/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6617 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6618 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6619 */
a9111321 6620static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6621 /* Disable all GPIOs */
6622 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6623 /* Internal speaker is connected to headphone pin */
6624 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6625 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6627 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6628 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6629 /* Ensure all other unused pins are disabled and muted. */
6630 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6632 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6633 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6634 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6635 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6638
6639 /* Disable digital (SPDIF) pins */
6640 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6641 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6642
ea1fb29a 6643 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6644 * when acting as an output.
6645 */
6646 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6647
f7ace40d 6648 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6652 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6655 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6657 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6658
f7ace40d
JW
6659 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6660 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 /* Unmute Line1 pin widget output buffer since it starts as an output.
6662 * If the pin mode is changed by the user the pin mode control will
6663 * take care of enabling the pin's input/output buffers as needed.
6664 * Therefore there's no need to enable the input buffer at this
6665 * stage.
cdcd9268 6666 */
f7ace40d 6667 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6668 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6669 * mixer ctrl)
6670 */
f7ace40d
JW
6671 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6672
6673 /* Mute capture amp left and right */
6674 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6675 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6676 * in (on mic1 pin)
6677 */
6678 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6679
6680 /* Do the same for the second ADC: mute capture input amp and
6681 * set ADC connection to line in (on mic1 pin)
6682 */
6683 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6684 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6685
6686 /* Mute all inputs to mixer widget (even unconnected ones) */
6687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6695
6696 { }
a9430dd8
JW
6697};
6698
0bfc90e9
JW
6699/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6700 * similar laptops (adapted from Fujitsu init verbs).
6701 */
a9111321 6702static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6703 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6704 * the headphone jack. Turn this on and rely on the standard mute
6705 * methods whenever the user wants to turn these outputs off.
6706 */
6707 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6708 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6709 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6710 /* Internal speaker/Headphone jack is connected to Line-out pin */
6711 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6712 /* Internal microphone/Mic jack is connected to Mic1 pin */
6713 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6714 /* Line In jack is connected to Line1 pin */
6715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6716 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6717 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6718 /* Ensure all other unused pins are disabled and muted. */
6719 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6720 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6721 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6722 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725 /* Disable digital (SPDIF) pins */
6726 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6727 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6728
ea1fb29a 6729 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6730 * bus when acting as outputs.
6731 */
6732 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6733 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6734
6735 /* Start with output sum widgets muted and their output gains at min */
6736 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6742 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6745
f12ab1e0
TI
6746 /* Unmute Line-out pin widget amp left and right
6747 * (no equiv mixer ctrl)
6748 */
0bfc90e9 6749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6750 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6751 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6752 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6753 * inputs. If the pin mode is changed by the user the pin mode control
6754 * will take care of enabling the pin's input/output buffers as needed.
6755 * Therefore there's no need to enable the input buffer at this
6756 * stage.
6757 */
6758 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760
6761 /* Mute capture amp left and right */
6762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6763 /* Set ADC connection select to match default mixer setting - mic
6764 * (on mic1 pin)
6765 */
6766 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6767
6768 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6769 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6770 */
6771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6772 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6773
6774 /* Mute all inputs to mixer widget (even unconnected ones) */
6775 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6783
6784 { }
6785};
6786
cc959489
MS
6787/* Initialisation sequence for Maxdata Favorit 100XS
6788 * (adapted from Acer init verbs).
6789 */
a9111321 6790static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6791 /* GPIO 0 enables the output jack.
6792 * Turn this on and rely on the standard mute
6793 * methods whenever the user wants to turn these outputs off.
6794 */
6795 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6796 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6797 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6798 /* Line/Mic input jack is connected to Mic1 pin */
6799 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6800 /* Ensure all other unused pins are disabled and muted. */
6801 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6802 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6803 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6804 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6805 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6806 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6808 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6811 /* Disable digital (SPDIF) pins */
6812 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6813 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6814
6815 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6816 * bus when acting as outputs.
6817 */
6818 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6819 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6820
6821 /* Start with output sum widgets muted and their output gains at min */
6822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6827 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6828 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6830 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6831
6832 /* Unmute Line-out pin widget amp left and right
6833 * (no equiv mixer ctrl)
6834 */
6835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6836 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6837 * inputs. If the pin mode is changed by the user the pin mode control
6838 * will take care of enabling the pin's input/output buffers as needed.
6839 * Therefore there's no need to enable the input buffer at this
6840 * stage.
6841 */
6842 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6843
6844 /* Mute capture amp left and right */
6845 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6846 /* Set ADC connection select to match default mixer setting - mic
6847 * (on mic1 pin)
6848 */
6849 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6850
6851 /* Do similar with the second ADC: mute capture input amp and
6852 * set ADC connection to mic to match ALSA's default state.
6853 */
6854 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6856
6857 /* Mute all inputs to mixer widget (even unconnected ones) */
6858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6866
6867 { }
6868};
6869
a9111321 6870static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6871 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6872 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6873 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6874 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6875 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6876 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6877 {}
6878};
6879
a9111321 6880static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6881 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6882 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6883 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6884
6885 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6887 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6888
6889 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6890 {}
6891};
6892
6893/* toggle speaker-output according to the hp-jack state */
6894static void alc260_replacer_672v_automute(struct hda_codec *codec)
6895{
6896 unsigned int present;
6897
6898 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6899 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6900 if (present) {
82beb8fd
TI
6901 snd_hda_codec_write_cache(codec, 0x01, 0,
6902 AC_VERB_SET_GPIO_DATA, 1);
6903 snd_hda_codec_write_cache(codec, 0x0f, 0,
6904 AC_VERB_SET_PIN_WIDGET_CONTROL,
6905 PIN_HP);
bc9f98a9 6906 } else {
82beb8fd
TI
6907 snd_hda_codec_write_cache(codec, 0x01, 0,
6908 AC_VERB_SET_GPIO_DATA, 0);
6909 snd_hda_codec_write_cache(codec, 0x0f, 0,
6910 AC_VERB_SET_PIN_WIDGET_CONTROL,
6911 PIN_OUT);
bc9f98a9
KY
6912 }
6913}
6914
6915static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6916 unsigned int res)
6917{
6918 if ((res >> 26) == ALC880_HP_EVENT)
6919 alc260_replacer_672v_automute(codec);
6920}
6921
a9111321 6922static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6923 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6924 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6925 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6926 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6927 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6930 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6931 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6932 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6933 {}
6934};
6935
7cf51e48
JW
6936/* Test configuration for debugging, modelled after the ALC880 test
6937 * configuration.
6938 */
6939#ifdef CONFIG_SND_DEBUG
4c6d72d1 6940static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6941 0x02,
6942};
4c6d72d1 6943static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6944 0x04, 0x05,
6945};
a1e8d2da 6946/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6947 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6948 * is NID 0x04.
17e7aec6 6949 */
a9111321 6950static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6951 {
6952 .num_items = 7,
6953 .items = {
6954 { "MIC1 pin", 0x0 },
6955 { "MIC2 pin", 0x1 },
6956 { "LINE1 pin", 0x2 },
6957 { "LINE2 pin", 0x3 },
6958 { "CD pin", 0x4 },
6959 { "LINE-OUT pin", 0x5 },
6960 { "HP-OUT pin", 0x6 },
6961 },
6962 },
6963 {
6964 .num_items = 8,
6965 .items = {
6966 { "MIC1 pin", 0x0 },
6967 { "MIC2 pin", 0x1 },
6968 { "LINE1 pin", 0x2 },
6969 { "LINE2 pin", 0x3 },
6970 { "CD pin", 0x4 },
6971 { "Mixer", 0x5 },
6972 { "LINE-OUT pin", 0x6 },
6973 { "HP-OUT pin", 0x7 },
6974 },
7cf51e48
JW
6975 },
6976};
a9111321 6977static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6978 /* Output driver widgets */
6979 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6980 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6981 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6982 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6983 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6984 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6985
a1e8d2da
JW
6986 /* Modes for retasking pin widgets
6987 * Note: the ALC260 doesn't seem to act on requests to enable mic
6988 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6989 * mention this restriction. At this stage it's not clear whether
6990 * this behaviour is intentional or is a hardware bug in chip
6991 * revisions available at least up until early 2006. Therefore for
6992 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6993 * choices, but if it turns out that the lack of mic bias for these
6994 * NIDs is intentional we could change their modes from
6995 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6996 */
7cf51e48
JW
6997 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6998 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6999 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7000 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7001 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7002 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7003
7004 /* Loopback mixer controls */
7005 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7006 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7007 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7008 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7009 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7010 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7011 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7012 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
7015 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7016 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7017 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7018 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
7019
7020 /* Controls for GPIO pins, assuming they are configured as outputs */
7021 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7022 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7023 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7024 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7025
92621f13
JW
7026 /* Switches to allow the digital IO pins to be enabled. The datasheet
7027 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 7028 * make this output available should provide clarification.
92621f13
JW
7029 */
7030 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7031 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7032
f8225f6d
JW
7033 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7034 * this output to turn on an external amplifier.
7035 */
7036 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7037 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7038
7cf51e48
JW
7039 { } /* end */
7040};
a9111321 7041static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
7042 /* Enable all GPIOs as outputs with an initial value of 0 */
7043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7044 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7045 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7046
7cf51e48
JW
7047 /* Enable retasking pins as output, initially without power amp */
7048 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7049 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7053 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054
92621f13
JW
7055 /* Disable digital (SPDIF) pins initially, but users can enable
7056 * them via a mixer switch. In the case of SPDIF-out, this initverb
7057 * payload also sets the generation to 0, output to be in "consumer"
7058 * PCM format, copyright asserted, no pre-emphasis and no validity
7059 * control.
7060 */
7cf51e48
JW
7061 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7062 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7063
ea1fb29a 7064 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7065 * OUT1 sum bus when acting as an output.
7066 */
7067 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7068 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7069 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7070 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7071
7072 /* Start with output sum widgets muted and their output gains at min */
7073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7077 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7080 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7081 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7082
cdcd9268
JW
7083 /* Unmute retasking pin widget output buffers since the default
7084 * state appears to be output. As the pin mode is changed by the
7085 * user the pin mode control will take care of enabling the pin's
7086 * input/output buffers as needed.
7087 */
7cf51e48
JW
7088 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7089 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7093 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7094 /* Also unmute the mono-out pin widget */
7095 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7096
7cf51e48
JW
7097 /* Mute capture amp left and right */
7098 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7099 /* Set ADC connection select to match default mixer setting (mic1
7100 * pin)
7cf51e48
JW
7101 */
7102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7103
7104 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7105 * set ADC connection to mic1 pin
7cf51e48
JW
7106 */
7107 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7108 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7109
7110 /* Mute all inputs to mixer widget (even unconnected ones) */
7111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7119
7120 { }
7121};
7122#endif
7123
6330079f
TI
7124#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7125#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7126
a3bcba38
TI
7127#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7128#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7129
df694daa
KY
7130/*
7131 * for BIOS auto-configuration
7132 */
16ded525 7133
df694daa 7134static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7135 const char *pfx, int *vol_bits)
df694daa
KY
7136{
7137 hda_nid_t nid_vol;
7138 unsigned long vol_val, sw_val;
df694daa
KY
7139 int err;
7140
7141 if (nid >= 0x0f && nid < 0x11) {
7142 nid_vol = nid - 0x7;
7143 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7144 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7145 } else if (nid == 0x11) {
7146 nid_vol = nid - 0x7;
7147 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7148 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7149 } else if (nid >= 0x12 && nid <= 0x15) {
7150 nid_vol = 0x08;
7151 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7152 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7153 } else
7154 return 0; /* N/A */
ea1fb29a 7155
863b4518
TI
7156 if (!(*vol_bits & (1 << nid_vol))) {
7157 /* first control for the volume widget */
0afe5f89 7158 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7159 if (err < 0)
7160 return err;
7161 *vol_bits |= (1 << nid_vol);
7162 }
0afe5f89 7163 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7164 if (err < 0)
df694daa
KY
7165 return err;
7166 return 1;
7167}
7168
7169/* add playback controls from the parsed DAC table */
7170static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7171 const struct auto_pin_cfg *cfg)
7172{
7173 hda_nid_t nid;
7174 int err;
863b4518 7175 int vols = 0;
df694daa
KY
7176
7177 spec->multiout.num_dacs = 1;
7178 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7179 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7180
7181 nid = cfg->line_out_pins[0];
7182 if (nid) {
23112d6d
TI
7183 const char *pfx;
7184 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7185 pfx = "Master";
7186 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7187 pfx = "Speaker";
7188 else
7189 pfx = "Front";
7190 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7191 if (err < 0)
7192 return err;
7193 }
7194
82bc955f 7195 nid = cfg->speaker_pins[0];
df694daa 7196 if (nid) {
863b4518 7197 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7198 if (err < 0)
7199 return err;
7200 }
7201
eb06ed8f 7202 nid = cfg->hp_pins[0];
df694daa 7203 if (nid) {
863b4518
TI
7204 err = alc260_add_playback_controls(spec, nid, "Headphone",
7205 &vols);
df694daa
KY
7206 if (err < 0)
7207 return err;
7208 }
f12ab1e0 7209 return 0;
df694daa
KY
7210}
7211
7212/* create playback/capture controls for input pins */
05f5f477 7213static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7214 const struct auto_pin_cfg *cfg)
7215{
05f5f477 7216 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7217}
7218
7219static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7220 hda_nid_t nid, int pin_type,
7221 int sel_idx)
7222{
f6c7e546 7223 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7224 /* need the manual connection? */
7225 if (nid >= 0x12) {
7226 int idx = nid - 0x12;
7227 snd_hda_codec_write(codec, idx + 0x0b, 0,
7228 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7229 }
7230}
7231
7232static void alc260_auto_init_multi_out(struct hda_codec *codec)
7233{
7234 struct alc_spec *spec = codec->spec;
7235 hda_nid_t nid;
7236
f12ab1e0 7237 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7238 if (nid) {
7239 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7240 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7241 }
ea1fb29a 7242
82bc955f 7243 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7244 if (nid)
7245 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7246
eb06ed8f 7247 nid = spec->autocfg.hp_pins[0];
df694daa 7248 if (nid)
baba8ee9 7249 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7250}
df694daa
KY
7251
7252#define ALC260_PIN_CD_NID 0x16
7253static void alc260_auto_init_analog_input(struct hda_codec *codec)
7254{
7255 struct alc_spec *spec = codec->spec;
66ceeb6b 7256 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7257 int i;
7258
66ceeb6b
TI
7259 for (i = 0; i < cfg->num_inputs; i++) {
7260 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7261 if (nid >= 0x12) {
30ea098f 7262 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7263 if (nid != ALC260_PIN_CD_NID &&
7264 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7265 snd_hda_codec_write(codec, nid, 0,
7266 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7267 AMP_OUT_MUTE);
7268 }
7269 }
7270}
7271
7f311a46
TI
7272#define alc260_auto_init_input_src alc880_auto_init_input_src
7273
df694daa
KY
7274/*
7275 * generic initialization of ADC, input mixers and output mixers
7276 */
a9111321 7277static const struct hda_verb alc260_volume_init_verbs[] = {
df694daa
KY
7278 /*
7279 * Unmute ADC0-1 and set the default input to mic-in
7280 */
7281 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7282 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7283 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7284 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7285
df694daa
KY
7286 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7287 * mixer widget
f12ab1e0
TI
7288 * Note: PASD motherboards uses the Line In 2 as the input for
7289 * front panel mic (mic 2)
df694daa
KY
7290 */
7291 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7292 /* mute analog inputs */
7293 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7295 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7297 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7298
7299 /*
7300 * Set up output mixers (0x08 - 0x0a)
7301 */
7302 /* set vol=0 to output mixers */
7303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7305 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 /* set up input amps for analog loopback */
7307 /* Amp Indices: DAC = 0, mixer = 1 */
7308 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7310 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7313 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7314
df694daa
KY
7315 { }
7316};
7317
7318static int alc260_parse_auto_config(struct hda_codec *codec)
7319{
7320 struct alc_spec *spec = codec->spec;
df694daa 7321 int err;
4c6d72d1 7322 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7323
f12ab1e0
TI
7324 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7325 alc260_ignore);
7326 if (err < 0)
df694daa 7327 return err;
f12ab1e0
TI
7328 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7329 if (err < 0)
4a471b7d 7330 return err;
603c4019 7331 if (!spec->kctls.list)
df694daa 7332 return 0; /* can't find valid BIOS pin config */
05f5f477 7333 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7334 if (err < 0)
df694daa
KY
7335 return err;
7336
7337 spec->multiout.max_channels = 2;
7338
0852d7a6 7339 if (spec->autocfg.dig_outs)
df694daa 7340 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7341 if (spec->kctls.list)
d88897ea 7342 add_mixer(spec, spec->kctls.list);
df694daa 7343
d88897ea 7344 add_verb(spec, alc260_volume_init_verbs);
df694daa 7345
a1e8d2da 7346 spec->num_mux_defs = 1;
61b9b9b1 7347 spec->input_mux = &spec->private_imux[0];
df694daa 7348
6227cdce 7349 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7350
df694daa
KY
7351 return 1;
7352}
7353
ae6b813a
TI
7354/* additional initialization for auto-configuration model */
7355static void alc260_auto_init(struct hda_codec *codec)
df694daa 7356{
f6c7e546 7357 struct alc_spec *spec = codec->spec;
df694daa
KY
7358 alc260_auto_init_multi_out(codec);
7359 alc260_auto_init_analog_input(codec);
7f311a46 7360 alc260_auto_init_input_src(codec);
757899ac 7361 alc_auto_init_digital(codec);
f6c7e546 7362 if (spec->unsol_event)
7fb0d78f 7363 alc_inithook(codec);
df694daa
KY
7364}
7365
cb53c626 7366#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7367static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7368 { 0x07, HDA_INPUT, 0 },
7369 { 0x07, HDA_INPUT, 1 },
7370 { 0x07, HDA_INPUT, 2 },
7371 { 0x07, HDA_INPUT, 3 },
7372 { 0x07, HDA_INPUT, 4 },
7373 { } /* end */
7374};
7375#endif
7376
fc091769
TI
7377/*
7378 * Pin config fixes
7379 */
7380enum {
7381 PINFIX_HP_DC5750,
7382};
7383
fc091769
TI
7384static const struct alc_fixup alc260_fixups[] = {
7385 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7386 .type = ALC_FIXUP_PINS,
7387 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7388 { 0x11, 0x90130110 }, /* speaker */
7389 { }
7390 }
fc091769
TI
7391 },
7392};
7393
a9111321 7394static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7395 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7396 {}
7397};
7398
df694daa
KY
7399/*
7400 * ALC260 configurations
7401 */
ea734963 7402static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7403 [ALC260_BASIC] = "basic",
7404 [ALC260_HP] = "hp",
7405 [ALC260_HP_3013] = "hp-3013",
2922c9af 7406 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7407 [ALC260_FUJITSU_S702X] = "fujitsu",
7408 [ALC260_ACER] = "acer",
bc9f98a9
KY
7409 [ALC260_WILL] = "will",
7410 [ALC260_REPLACER_672V] = "replacer",
cc959489 7411 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7412#ifdef CONFIG_SND_DEBUG
f5fcc13c 7413 [ALC260_TEST] = "test",
7cf51e48 7414#endif
f5fcc13c
TI
7415 [ALC260_AUTO] = "auto",
7416};
7417
a9111321 7418static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7419 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7420 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7421 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7422 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7423 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7424 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7425 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7426 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7427 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7428 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7429 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7432 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7435 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7436 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7437 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7438 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7439 {}
7440};
7441
a9111321 7442static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7443 [ALC260_BASIC] = {
7444 .mixers = { alc260_base_output_mixer,
45bdd1c1 7445 alc260_input_mixer },
df694daa
KY
7446 .init_verbs = { alc260_init_verbs },
7447 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7448 .dac_nids = alc260_dac_nids,
f9e336f6 7449 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7450 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7451 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7452 .channel_mode = alc260_modes,
7453 .input_mux = &alc260_capture_source,
7454 },
7455 [ALC260_HP] = {
bec15c3a 7456 .mixers = { alc260_hp_output_mixer,
f9e336f6 7457 alc260_input_mixer },
bec15c3a
TI
7458 .init_verbs = { alc260_init_verbs,
7459 alc260_hp_unsol_verbs },
df694daa
KY
7460 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7461 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7462 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7463 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7464 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7465 .channel_mode = alc260_modes,
7466 .input_mux = &alc260_capture_source,
e9427969
TI
7467 .unsol_event = alc_sku_unsol_event,
7468 .setup = alc260_hp_setup,
7469 .init_hook = alc_inithook,
df694daa 7470 },
3f878308
KY
7471 [ALC260_HP_DC7600] = {
7472 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7473 alc260_input_mixer },
3f878308
KY
7474 .init_verbs = { alc260_init_verbs,
7475 alc260_hp_dc7600_verbs },
7476 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7477 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7478 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7479 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7480 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7481 .channel_mode = alc260_modes,
7482 .input_mux = &alc260_capture_source,
e9427969
TI
7483 .unsol_event = alc_sku_unsol_event,
7484 .setup = alc260_hp_3012_setup,
7485 .init_hook = alc_inithook,
3f878308 7486 },
df694daa
KY
7487 [ALC260_HP_3013] = {
7488 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7489 alc260_input_mixer },
bec15c3a
TI
7490 .init_verbs = { alc260_hp_3013_init_verbs,
7491 alc260_hp_3013_unsol_verbs },
df694daa
KY
7492 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7493 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7494 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7495 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7496 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7497 .channel_mode = alc260_modes,
7498 .input_mux = &alc260_capture_source,
e9427969
TI
7499 .unsol_event = alc_sku_unsol_event,
7500 .setup = alc260_hp_3013_setup,
7501 .init_hook = alc_inithook,
df694daa
KY
7502 },
7503 [ALC260_FUJITSU_S702X] = {
f9e336f6 7504 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7505 .init_verbs = { alc260_fujitsu_init_verbs },
7506 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7507 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7508 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7509 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7510 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7511 .channel_mode = alc260_modes,
a1e8d2da
JW
7512 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7513 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7514 },
0bfc90e9 7515 [ALC260_ACER] = {
f9e336f6 7516 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7517 .init_verbs = { alc260_acer_init_verbs },
7518 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7519 .dac_nids = alc260_dac_nids,
7520 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7521 .adc_nids = alc260_dual_adc_nids,
7522 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7523 .channel_mode = alc260_modes,
a1e8d2da
JW
7524 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7525 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7526 },
cc959489
MS
7527 [ALC260_FAVORIT100] = {
7528 .mixers = { alc260_favorit100_mixer },
7529 .init_verbs = { alc260_favorit100_init_verbs },
7530 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7531 .dac_nids = alc260_dac_nids,
7532 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7533 .adc_nids = alc260_dual_adc_nids,
7534 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7535 .channel_mode = alc260_modes,
7536 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7537 .input_mux = alc260_favorit100_capture_sources,
7538 },
bc9f98a9 7539 [ALC260_WILL] = {
f9e336f6 7540 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7541 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7542 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7543 .dac_nids = alc260_dac_nids,
7544 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7545 .adc_nids = alc260_adc_nids,
7546 .dig_out_nid = ALC260_DIGOUT_NID,
7547 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7548 .channel_mode = alc260_modes,
7549 .input_mux = &alc260_capture_source,
7550 },
7551 [ALC260_REPLACER_672V] = {
f9e336f6 7552 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7553 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7554 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7555 .dac_nids = alc260_dac_nids,
7556 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7557 .adc_nids = alc260_adc_nids,
7558 .dig_out_nid = ALC260_DIGOUT_NID,
7559 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7560 .channel_mode = alc260_modes,
7561 .input_mux = &alc260_capture_source,
7562 .unsol_event = alc260_replacer_672v_unsol_event,
7563 .init_hook = alc260_replacer_672v_automute,
7564 },
7cf51e48
JW
7565#ifdef CONFIG_SND_DEBUG
7566 [ALC260_TEST] = {
f9e336f6 7567 .mixers = { alc260_test_mixer },
7cf51e48
JW
7568 .init_verbs = { alc260_test_init_verbs },
7569 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7570 .dac_nids = alc260_test_dac_nids,
7571 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7572 .adc_nids = alc260_test_adc_nids,
7573 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7574 .channel_mode = alc260_modes,
a1e8d2da
JW
7575 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7576 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7577 },
7578#endif
df694daa
KY
7579};
7580
7581static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7582{
7583 struct alc_spec *spec;
df694daa 7584 int err, board_config;
1da177e4 7585
e560d8d8 7586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7587 if (spec == NULL)
7588 return -ENOMEM;
7589
7590 codec->spec = spec;
7591
f5fcc13c
TI
7592 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7593 alc260_models,
7594 alc260_cfg_tbl);
7595 if (board_config < 0) {
9a11f1aa 7596 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7597 codec->chip_name);
df694daa 7598 board_config = ALC260_AUTO;
16ded525 7599 }
1da177e4 7600
b5bfbc67
TI
7601 if (board_config == ALC260_AUTO) {
7602 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7603 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7604 }
fc091769 7605
df694daa
KY
7606 if (board_config == ALC260_AUTO) {
7607 /* automatic parse from the BIOS config */
7608 err = alc260_parse_auto_config(codec);
7609 if (err < 0) {
7610 alc_free(codec);
7611 return err;
f12ab1e0 7612 } else if (!err) {
9c7f852e
TI
7613 printk(KERN_INFO
7614 "hda_codec: Cannot set up configuration "
7615 "from BIOS. Using base mode...\n");
df694daa
KY
7616 board_config = ALC260_BASIC;
7617 }
a9430dd8 7618 }
e9edcee0 7619
680cd536
KK
7620 err = snd_hda_attach_beep_device(codec, 0x1);
7621 if (err < 0) {
7622 alc_free(codec);
7623 return err;
7624 }
7625
df694daa 7626 if (board_config != ALC260_AUTO)
e9c364c0 7627 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7628
1da177e4
LT
7629 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7630 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7631 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7632
a3bcba38
TI
7633 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7634 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7635
4ef0ef19
TI
7636 if (!spec->adc_nids && spec->input_mux) {
7637 /* check whether NID 0x04 is valid */
7638 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7639 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7640 /* get type */
7641 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7642 spec->adc_nids = alc260_adc_nids_alt;
7643 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7644 } else {
7645 spec->adc_nids = alc260_adc_nids;
7646 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7647 }
7648 }
b59bdf3b 7649 set_capture_mixer(codec);
45bdd1c1 7650 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7651
b5bfbc67 7652 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7653
2134ea4f
TI
7654 spec->vmaster_nid = 0x08;
7655
1da177e4 7656 codec->patch_ops = alc_patch_ops;
df694daa 7657 if (board_config == ALC260_AUTO)
ae6b813a 7658 spec->init_hook = alc260_auto_init;
1c716153 7659 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7660#ifdef CONFIG_SND_HDA_POWER_SAVE
7661 if (!spec->loopback.amplist)
7662 spec->loopback.amplist = alc260_loopbacks;
7663#endif
1da177e4
LT
7664
7665 return 0;
7666}
7667
e9edcee0 7668
1da177e4 7669/*
4953550a 7670 * ALC882/883/885/888/889 support
1da177e4
LT
7671 *
7672 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7673 * configuration. Each pin widget can choose any input DACs and a mixer.
7674 * Each ADC is connected from a mixer of all inputs. This makes possible
7675 * 6-channel independent captures.
7676 *
7677 * In addition, an independent DAC for the multi-playback (not used in this
7678 * driver yet).
7679 */
df694daa
KY
7680#define ALC882_DIGOUT_NID 0x06
7681#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7682#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7683#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7684#define ALC1200_DIGOUT_NID 0x10
7685
1da177e4 7686
a9111321 7687static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7688 { 8, NULL }
7689};
7690
4953550a 7691/* DACs */
4c6d72d1 7692static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7693 /* front, rear, clfe, rear_surr */
7694 0x02, 0x03, 0x04, 0x05
7695};
4953550a 7696#define alc883_dac_nids alc882_dac_nids
1da177e4 7697
4953550a 7698/* ADCs */
df694daa
KY
7699#define alc882_adc_nids alc880_adc_nids
7700#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7701#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7702static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7703static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7704#define alc889_adc_nids alc880_adc_nids
1da177e4 7705
4c6d72d1
TI
7706static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7707static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7708#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7709static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7710#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7711
1da177e4
LT
7712/* input MUX */
7713/* FIXME: should be a matrix-type input source selection */
7714
a9111321 7715static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7716 .num_items = 4,
7717 .items = {
7718 { "Mic", 0x0 },
7719 { "Front Mic", 0x1 },
7720 { "Line", 0x2 },
7721 { "CD", 0x4 },
7722 },
7723};
41d5545d 7724
4953550a
TI
7725#define alc883_capture_source alc882_capture_source
7726
a9111321 7727static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7728 .num_items = 3,
7729 .items = {
7730 { "Front Mic", 0x0 },
7731 { "Mic", 0x3 },
7732 { "Line", 0x2 },
7733 },
7734};
7735
a9111321 7736static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7737 .num_items = 3,
7738 .items = {
7739 { "Mic", 0x1 },
b8f171e7 7740 { "Line", 0x7 },
41d5545d
KS
7741 { "CD", 0x4 },
7742 },
7743};
7744
a9111321 7745static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7746 .num_items = 2,
7747 .items = {
7748 { "Line", 0x2 },
7749 { "CD", 0x4 },
7750 },
7751};
7752
a9111321 7753static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7754 .num_items = 4,
7755 .items = {
7756 { "Mic", 0x1 },
7757 { "Front Mic", 0x0 },
7758 { "Line", 0x2 },
7759 { "CD", 0x4 },
7760 },
7761};
7762
a9111321 7763static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7764 .num_items = 2,
7765 .items = {
7766 { "Mic", 0x1 },
7767 { "Line", 0x2 },
7768 },
7769};
7770
a9111321 7771static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7772 .num_items = 4,
7773 .items = {
7774 { "Mic", 0x0 },
28c4edb7 7775 { "Internal Mic", 0x1 },
4953550a
TI
7776 { "Line", 0x2 },
7777 { "CD", 0x4 },
7778 },
7779};
7780
a9111321 7781static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7782 .num_items = 2,
7783 .items = {
7784 { "Mic", 0x0 },
28c4edb7 7785 { "Internal Mic", 0x1 },
4953550a
TI
7786 },
7787};
7788
a9111321 7789static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7790 .num_items = 3,
7791 .items = {
7792 { "Mic", 0x0 },
7793 { "Front Mic", 0x1 },
7794 { "Line", 0x4 },
7795 },
7796};
7797
a9111321 7798static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7799 .num_items = 2,
7800 .items = {
7801 { "Mic", 0x0 },
7802 { "Line", 0x2 },
7803 },
7804};
7805
a9111321 7806static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7807 .num_items = 2,
7808 .items = {
7809 { "Mic", 0x0 },
7810 /* Front Mic (0x01) unused */
7811 { "Line", 0x2 },
7812 /* Line 2 (0x03) unused */
af901ca1 7813 /* CD (0x04) unused? */
4953550a
TI
7814 },
7815};
7816
a9111321 7817static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7818 .num_items = 2,
7819 .items = {
7820 { "Mic", 0x01 },
7821 { "Line", 0x2 }, /* Not sure! */
7822 },
7823};
7824
4953550a
TI
7825/*
7826 * 2ch mode
7827 */
a9111321 7828static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7829 { 2, NULL }
7830};
7831
272a527c
KY
7832/*
7833 * 2ch mode
7834 */
a9111321 7835static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 { } /* end */
7841};
7842
4953550a
TI
7843/*
7844 * 4ch mode
7845 */
a9111321 7846static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7851 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7852 { } /* end */
7853};
7854
272a527c
KY
7855/*
7856 * 6ch mode
7857 */
a9111321 7858static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7859 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7861 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7864 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7865 { } /* end */
7866};
7867
a9111321 7868static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7869 { 2, alc882_3ST_ch2_init },
4953550a 7870 { 4, alc882_3ST_ch4_init },
272a527c
KY
7871 { 6, alc882_3ST_ch6_init },
7872};
7873
4953550a
TI
7874#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7875
a65cc60f 7876/*
7877 * 2ch mode
7878 */
a9111321 7879static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7880 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7881 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7882 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7883 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7884 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7885 { } /* end */
7886};
7887
7888/*
7889 * 4ch mode
7890 */
a9111321 7891static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7894 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7897 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7898 { } /* end */
7899};
7900
7901/*
7902 * 6ch mode
7903 */
a9111321 7904static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7908 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7909 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7911 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7912 { } /* end */
7913};
7914
a9111321 7915static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7916 { 2, alc883_3ST_ch2_clevo_init },
7917 { 4, alc883_3ST_ch4_clevo_init },
7918 { 6, alc883_3ST_ch6_clevo_init },
7919};
7920
7921
df694daa
KY
7922/*
7923 * 6ch mode
7924 */
a9111321 7925static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { } /* end */
7931};
7932
7933/*
7934 * 8ch mode
7935 */
a9111321 7936static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { } /* end */
7942};
7943
a9111321 7944static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7945 { 6, alc882_sixstack_ch6_init },
7946 { 8, alc882_sixstack_ch8_init },
7947};
7948
76e6f5a9
RH
7949
7950/* Macbook Air 2,1 */
7951
a9111321 7952static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7953 { 2, NULL },
7954};
7955
87350ad0 7956/*
def319f9 7957 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7958 */
7959
7960/*
7961 * 2ch mode
7962 */
a9111321 7963static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7965 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7967 { } /* end */
7968};
7969
7970/*
a3f730af 7971 * 4ch mode
87350ad0 7972 */
a9111321 7973static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7974 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7975 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7976 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7977 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7979 { } /* end */
7980};
7981
a9111321 7982static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7983 { 2, alc885_mbp_ch2_init },
a3f730af 7984 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7985};
7986
92b9de83
KS
7987/*
7988 * 2ch
7989 * Speakers/Woofer/HP = Front
7990 * LineIn = Input
7991 */
a9111321 7992static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7995 { } /* end */
7996};
7997
7998/*
7999 * 6ch mode
8000 * Speakers/HP = Front
8001 * Woofer = LFE
8002 * LineIn = Surround
8003 */
a9111321 8004static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
8005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8008 { } /* end */
8009};
8010
a9111321 8011static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
8012 { 2, alc885_mb5_ch2_init },
8013 { 6, alc885_mb5_ch6_init },
8014};
87350ad0 8015
d01aecdf 8016#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
8017
8018/*
8019 * 2ch mode
8020 */
a9111321 8021static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
8022 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8023 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8024 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8025 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8026 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8027 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8028 { } /* end */
8029};
8030
8031/*
8032 * 4ch mode
8033 */
a9111321 8034static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
8035 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8036 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8038 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8039 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8041 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8042 { } /* end */
8043};
8044
8045/*
8046 * 6ch mode
8047 */
a9111321 8048static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8049 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8050 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8053 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8055 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8056 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8057 { } /* end */
8058};
8059
8060/*
8061 * 8ch mode
8062 */
a9111321 8063static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8064 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8065 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8066 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8067 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8070 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8071 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8072 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8073 { } /* end */
8074};
8075
a9111321 8076static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8077 { 2, alc883_4ST_ch2_init },
8078 { 4, alc883_4ST_ch4_init },
8079 { 6, alc883_4ST_ch6_init },
8080 { 8, alc883_4ST_ch8_init },
8081};
8082
8083
8084/*
8085 * 2ch mode
8086 */
a9111321 8087static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8088 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8089 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8090 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8091 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8092 { } /* end */
8093};
8094
8095/*
8096 * 4ch mode
8097 */
a9111321 8098static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8099 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8100 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8101 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8102 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8103 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8104 { } /* end */
8105};
8106
8107/*
8108 * 6ch mode
8109 */
a9111321 8110static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8111 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8112 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8113 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8114 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8115 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8116 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8117 { } /* end */
8118};
8119
a9111321 8120static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8121 { 2, alc883_3ST_ch2_intel_init },
8122 { 4, alc883_3ST_ch4_intel_init },
8123 { 6, alc883_3ST_ch6_intel_init },
8124};
8125
dd7714c9
WF
8126/*
8127 * 2ch mode
8128 */
a9111321 8129static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8130 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8131 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8135 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8136 { } /* end */
8137};
8138
87a8c370
JK
8139/*
8140 * 6ch mode
8141 */
a9111321 8142static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8143 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8144 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8145 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8146 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8149 { } /* end */
8150};
8151
8152/*
8153 * 8ch mode
8154 */
a9111321 8155static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8156 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8157 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8158 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8159 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8160 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8163 { } /* end */
8164};
8165
a9111321 8166static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8167 { 2, alc889_ch2_intel_init },
87a8c370
JK
8168 { 6, alc889_ch6_intel_init },
8169 { 8, alc889_ch8_intel_init },
8170};
8171
4953550a
TI
8172/*
8173 * 6ch mode
8174 */
a9111321 8175static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8176 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8177 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8178 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { } /* end */
8181};
8182
8183/*
8184 * 8ch mode
8185 */
a9111321 8186static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8187 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8188 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { } /* end */
8192};
8193
a9111321 8194static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8195 { 6, alc883_sixstack_ch6_init },
8196 { 8, alc883_sixstack_ch8_init },
8197};
8198
8199
1da177e4
LT
8200/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8201 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8202 */
a9111321 8203static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8212 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8213 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8214 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8215 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8216 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8223 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8224 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8225 { } /* end */
8226};
8227
76e6f5a9
RH
8228/* Macbook Air 2,1 same control for HP and internal Speaker */
8229
a9111321 8230static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8233 { }
8234};
8235
8236
a9111321 8237static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8238 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8239 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8241 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8244 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8246 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8247 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8249 { } /* end */
8250};
41d5545d 8251
a9111321 8252static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8254 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8256 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8257 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8258 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8260 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8262 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8264 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8265 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8267 { } /* end */
8268};
92b9de83 8269
a9111321 8270static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8272 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8274 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8275 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8276 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8278 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8280 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8281 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8282 { } /* end */
8283};
8284
a9111321 8285static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8287 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8288 { } /* end */
8289};
8290
8291
a9111321 8292static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8294 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8295 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8296 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8300 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8302 { } /* end */
8303};
8304
a9111321 8305static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8310 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8315 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8316 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8317 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8318 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8319 { } /* end */
8320};
8321
8322/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8323 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8324 */
a9111321 8325static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8335 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8338 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8339 { } /* end */
8340};
8341
a9111321 8342static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8346 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8347 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8351 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8353 { } /* end */
8354};
8355
a9111321 8356static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8357 {
8358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8359 .name = "Channel Mode",
8360 .info = alc_ch_mode_info,
8361 .get = alc_ch_mode_get,
8362 .put = alc_ch_mode_put,
8363 },
8364 { } /* end */
8365};
8366
a9111321 8367static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8368 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8371 /* Rear mixer */
05acb863
TI
8372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8374 /* CLFE mixer */
05acb863
TI
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8377 /* Side mixer */
05acb863
TI
8378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8380
e9edcee0 8381 /* Front Pin: output 0 (0x0c) */
05acb863 8382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8385 /* Rear Pin: output 1 (0x0d) */
05acb863 8386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8389 /* CLFE Pin: output 2 (0x0e) */
05acb863 8390 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8393 /* Side Pin: output 3 (0x0f) */
05acb863 8394 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8395 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8396 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8397 /* Mic (rear) pin: input vref at 80% */
16ded525 8398 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Front Mic pin: input vref at 80% */
16ded525 8401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line In pin: input */
05acb863 8404 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8405 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8406 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8408 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8410 /* CD pin widget for input */
05acb863 8411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8412
8413 /* FIXME: use matrix-type input source selection */
8414 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8415 /* Input mixer2 */
05acb863 8416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8417 /* Input mixer3 */
05acb863 8418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8419 /* ADC2: mute amp left and right */
8420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8421 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8422 /* ADC3: mute amp left and right */
8423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8424 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8425
8426 { }
8427};
8428
a9111321 8429static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8430 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8435 /* ADC1: mute amp left and right */
8436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 { }
8439};
8440
a9111321 8441static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8442 /* change to EAPD mode */
8443 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8444 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8445 { }
4b146cb0
TI
8446};
8447
a9111321 8448static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8449 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8450 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 { }
8452};
8453
a9111321 8454static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8457 {}
8458};
87a8c370 8459
a9111321 8460static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8461 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8464 /* Rear mixer */
88102f3f
KY
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8467 /* CLFE mixer */
88102f3f
KY
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8470 /* Side mixer */
88102f3f
KY
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8473
8474 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8476 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* Front Pin: output 0 (0x0c) */
8479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8482 /* Rear Pin: output 1 (0x0d) */
8483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8486 /* CLFE Pin: output 2 (0x0e) */
8487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8489 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8490 /* Side Pin: output 3 (0x0f) */
8491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8493 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8494 /* Mic (rear) pin: input vref at 80% */
8495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8496 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8497 /* Front Mic pin: input vref at 80% */
8498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8500 /* Line In pin: input */
8501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8503
8504 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8505 /* Input mixer1 */
88102f3f 8506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8507 /* Input mixer2 */
8508 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8509 /* Input mixer3 */
88102f3f 8510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8511 /* ADC2: mute amp left and right */
8512 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8513 /* ADC3: mute amp left and right */
8514 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8515
8516 { }
8517};
8518
a9111321 8519static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8523 { }
8524};
8525
8526
8527/* Unmute Selector 24h and set the default input to front mic */
a9111321 8528static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8529 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8531 { }
8532};
8533
8534
4953550a
TI
8535#define alc883_init_verbs alc882_base_init_verbs
8536
9102cd1c 8537/* Mac Pro test */
a9111321 8538static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8540 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8544 /* FIXME: this looks suspicious...
d355c82a
JK
8545 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8546 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8547 */
9102cd1c
TD
8548 { } /* end */
8549};
8550
a9111321 8551static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8552 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 /* Front Pin: output 0 (0x0c) */
8557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8560 /* Front Mic pin: input vref at 80% */
8561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8563 /* Speaker: output */
8564 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8565 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8566 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8567 /* Headphone output (output 0 - 0x0c) */
8568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8571
8572 /* FIXME: use matrix-type input source selection */
8573 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8574 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8579 /* Input mixer2 */
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8584 /* Input mixer3 */
8585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8589 /* ADC1: mute amp left and right */
8590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8591 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* ADC2: mute amp left and right */
8593 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8595 /* ADC3: mute amp left and right */
8596 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8597 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8598
8599 { }
8600};
f12ab1e0 8601
41d5545d 8602/* Macbook 5,1 */
a9111321 8603static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8604 /* DACs */
8605 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8609 /* Front mixer */
41d5545d
KS
8610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8613 /* Surround mixer */
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8617 /* LFE mixer */
8618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8621 /* HP mixer */
8622 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8625 /* Front Pin (0x0c) */
41d5545d
KS
8626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8629 /* LFE Pin (0x0e) */
8630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8632 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8633 /* HP Pin (0x0f) */
41d5545d
KS
8634 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8635 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8636 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8638 /* Front Mic pin: input vref at 80% */
8639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8640 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8641 /* Line In pin */
8642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8644
b8f171e7
AM
8645 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8648 { }
8649};
8650
e458b1fa 8651/* Macmini 3,1 */
a9111321 8652static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8653 /* DACs */
8654 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8655 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 /* Front mixer */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* Surround mixer */
8663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8666 /* LFE mixer */
8667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8670 /* HP mixer */
8671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8674 /* Front Pin (0x0c) */
8675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8677 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8678 /* LFE Pin (0x0e) */
8679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8681 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8682 /* HP Pin (0x0f) */
8683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8685 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8686 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8687 /* Line In pin */
8688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8690
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8695 { }
8696};
8697
76e6f5a9 8698
a9111321 8699static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8700 /*Internal and HP Speaker Mixer*/
8701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8704 /*Internal Speaker Pin (0x0c)*/
8705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8707 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8708 /* HP Pin: output 0 (0x0e) */
8709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8711 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8712 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8713 /* Line in (is hp when jack connected)*/
8714 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8715 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8716
8717 { }
8718 };
8719
8720
87350ad0 8721/* Macbook Pro rev3 */
a9111321 8722static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8723 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8727 /* Rear mixer */
8728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8731 /* HP mixer */
8732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8735 /* Front Pin: output 0 (0x0c) */
8736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8738 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8739 /* HP Pin: output 0 (0x0e) */
87350ad0 8740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8743 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8744 /* Mic (rear) pin: input vref at 80% */
8745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8747 /* Front Mic pin: input vref at 80% */
8748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8750 /* Line In pin: use output 1 when in LineOut mode */
8751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8753 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8754
8755 /* FIXME: use matrix-type input source selection */
8756 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8757 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8762 /* Input mixer2 */
8763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8767 /* Input mixer3 */
8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8772 /* ADC1: mute amp left and right */
8773 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8774 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8775 /* ADC2: mute amp left and right */
8776 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8777 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8778 /* ADC3: mute amp left and right */
8779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8781
8782 { }
8783};
8784
4b7e1803 8785/* iMac 9,1 */
a9111321 8786static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8787 /* Internal Speaker Pin (0x0c) */
8788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8793 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 /* HP Pin: Rear */
4b7e1803
JM
8795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8797 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8798 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8799 /* Line in Rear */
8800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8802 /* Front Mic pin: input vref at 80% */
8803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8804 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8805 /* Rear mixer */
8806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8809 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8813 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8818 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8823 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8828 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8830 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8831 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8834 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8837 { }
8838};
8839
c54728d8 8840/* iMac 24 mixer. */
a9111321 8841static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8842 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8843 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8844 { } /* end */
8845};
8846
8847/* iMac 24 init verbs. */
a9111321 8848static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8849 /* Internal speakers: output 0 (0x0c) */
8850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8852 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8853 /* Internal speakers: output 0 (0x0c) */
8854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8856 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8857 /* Headphone: output 0 (0x0c) */
8858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8860 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8862 /* Front Mic: input vref at 80% */
8863 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8864 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8865 { }
8866};
8867
8868/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8869static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8870{
a9fd4f3f 8871 struct alc_spec *spec = codec->spec;
c54728d8 8872
a9fd4f3f
TI
8873 spec->autocfg.hp_pins[0] = 0x14;
8874 spec->autocfg.speaker_pins[0] = 0x18;
8875 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8876 spec->automute = 1;
8877 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8878}
8879
9d54f08b
TI
8880#define alc885_mb5_setup alc885_imac24_setup
8881#define alc885_macmini3_setup alc885_imac24_setup
8882
76e6f5a9
RH
8883/* Macbook Air 2,1 */
8884static void alc885_mba21_setup(struct hda_codec *codec)
8885{
8886 struct alc_spec *spec = codec->spec;
8887
8888 spec->autocfg.hp_pins[0] = 0x14;
8889 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8892}
8893
8894
8895
4f5d1706 8896static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8897{
a9fd4f3f 8898 struct alc_spec *spec = codec->spec;
87350ad0 8899
a9fd4f3f
TI
8900 spec->autocfg.hp_pins[0] = 0x15;
8901 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8902 spec->automute = 1;
8903 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8904}
8905
9d54f08b 8906static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8907{
9d54f08b 8908 struct alc_spec *spec = codec->spec;
4b7e1803 8909
9d54f08b 8910 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8911 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8912 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8913 spec->automute = 1;
8914 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8915}
87350ad0 8916
a9111321 8917static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920
8921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8923
272a527c
KY
8924 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8925 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8927
8928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8929 { } /* end */
8930};
8931
8932/* toggle speaker-output according to the hp-jack state */
8933static void alc882_targa_automute(struct hda_codec *codec)
8934{
a9fd4f3f 8935 struct alc_spec *spec = codec->spec;
d922b51d 8936 alc_hp_automute(codec);
82beb8fd 8937 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8938 spec->jack_present ? 1 : 3);
8939}
8940
4f5d1706 8941static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8942{
8943 struct alc_spec *spec = codec->spec;
8944
8945 spec->autocfg.hp_pins[0] = 0x14;
8946 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8947 spec->automute = 1;
8948 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8949}
8950
8951static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8952{
a9fd4f3f 8953 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8954 alc882_targa_automute(codec);
272a527c
KY
8955}
8956
a9111321 8957static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8960
8961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8964
272a527c
KY
8965 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8967 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8968
8969 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8970 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8972 { } /* end */
8973};
8974
a9111321 8975static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8978
8979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8982
914759b7
TI
8983 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8984 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8985 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8986
8987 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8988 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8989 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8990 { } /* end */
8991};
8992
9102cd1c
TD
8993static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8994{
8995 unsigned int gpiostate, gpiomask, gpiodir;
8996
8997 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8998 AC_VERB_GET_GPIO_DATA, 0);
8999
9000 if (!muted)
9001 gpiostate |= (1 << pin);
9002 else
9003 gpiostate &= ~(1 << pin);
9004
9005 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9006 AC_VERB_GET_GPIO_MASK, 0);
9007 gpiomask |= (1 << pin);
9008
9009 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9010 AC_VERB_GET_GPIO_DIRECTION, 0);
9011 gpiodir |= (1 << pin);
9012
9013
9014 snd_hda_codec_write(codec, codec->afg, 0,
9015 AC_VERB_SET_GPIO_MASK, gpiomask);
9016 snd_hda_codec_write(codec, codec->afg, 0,
9017 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9018
9019 msleep(1);
9020
9021 snd_hda_codec_write(codec, codec->afg, 0,
9022 AC_VERB_SET_GPIO_DATA, gpiostate);
9023}
9024
7debbe51
TI
9025/* set up GPIO at initialization */
9026static void alc885_macpro_init_hook(struct hda_codec *codec)
9027{
9028 alc882_gpio_mute(codec, 0, 0);
9029 alc882_gpio_mute(codec, 1, 0);
9030}
9031
9032/* set up GPIO and update auto-muting at initialization */
9033static void alc885_imac24_init_hook(struct hda_codec *codec)
9034{
9035 alc885_macpro_init_hook(codec);
d922b51d 9036 alc_hp_automute(codec);
7debbe51
TI
9037}
9038
df694daa
KY
9039/*
9040 * generic initialization of ADC, input mixers and output mixers
9041 */
a9111321 9042static const struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
9043 /*
9044 * Unmute ADC0-2 and set the default input to mic-in
9045 */
4953550a
TI
9046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 9050
4953550a
TI
9051 /*
9052 * Set up output mixers (0x0c - 0x0f)
9053 */
9054 /* set vol=0 to output mixers */
9055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9059 /* set up input amps for analog loopback */
9060 /* Amp Indices: DAC = 0, mixer = 1 */
9061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9069 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9071
4953550a
TI
9072 /* FIXME: use matrix-type input source selection */
9073 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9074 /* Input mixer2 */
88102f3f 9075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9076 /* Input mixer3 */
88102f3f 9077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9078 { }
9c7f852e
TI
9079};
9080
eb4c41d3 9081/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9082static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9084 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9087 { } /* end */
9088};
9089
9090/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9091static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9096 { } /* end */
9097};
9098
9099/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9100static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9105 { } /* end */
9106};
9107
9108/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9109static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9114 { } /* end */
9115};
9116
a9111321 9117static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9118 { 2, alc889A_mb31_ch2_init },
9119 { 4, alc889A_mb31_ch4_init },
9120 { 5, alc889A_mb31_ch5_init },
9121 { 6, alc889A_mb31_ch6_init },
9122};
9123
a9111321 9124static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9125 /* eanable EAPD on medion laptop */
9126 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9127 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9128 { }
9129};
9130
4953550a 9131#define alc883_base_mixer alc882_base_mixer
834be88d 9132
a9111321 9133static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9136 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9138 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9139 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9145 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9147 { } /* end */
9148};
9149
a9111321 9150static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9151 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9154 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9158 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9159 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9160 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9161 { } /* end */
9162};
9163
a9111321 9164static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9168 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9172 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9175 { } /* end */
9176};
9177
a9111321 9178static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9179 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9180 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9181 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9182 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9183 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9185 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9190 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9192 { } /* end */
9193};
df694daa 9194
a9111321 9195static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9201 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9202 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9203 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9206 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9208 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9213 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9215 { } /* end */
9216};
9217
a9111321 9218static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9222 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9224 HDA_OUTPUT),
9225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9239 { } /* end */
9240};
9241
a9111321 9242static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9248 HDA_OUTPUT),
9249 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9251 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9252 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9253 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9255 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9256 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9260 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9261 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9263 { } /* end */
9264};
9265
a9111321 9266static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9283 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9284 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9286 { } /* end */
9287};
9288
a9111321 9289static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9291 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9295 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9307 { } /* end */
f12ab1e0 9308};
ccc656ce 9309
a9111321 9310static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9311 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9312 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9314 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9315 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9316 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9318 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9320 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9321 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9322 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9323 { } /* end */
f12ab1e0 9324};
ccc656ce 9325
a9111321 9326static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9327 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9328 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9329 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9330 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9331 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9332 { } /* end */
9333};
9334
a9111321 9335static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9339 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9340 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9342 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9344 { } /* end */
f12ab1e0 9345};
bc9f98a9 9346
a9111321 9347static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9349 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9351 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9352 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9355 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9356 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9357 { } /* end */
ea1fb29a 9358};
272a527c 9359
a9111321 9360static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9361 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9362 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9366 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9367 { } /* end */
9368};
9369
a9111321 9370static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9371 /* Unmute front mixer */
9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9374
9375 /* Set speaker pin to front mixer */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377
9378 /* Init headphone pin */
9379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9381 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9382 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9383
9384 { } /* end */
9385};
9386
9387/* toggle speaker-output according to the hp-jack state */
9388static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9389{
9390 struct alc_spec *spec = codec->spec;
9391
9392 spec->autocfg.hp_pins[0] = 0x1a;
9393 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9394 spec->automute = 1;
9395 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9396}
9397
a9111321 9398static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9400 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9405 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9407 { } /* end */
d1a991a6 9408};
2880a867 9409
a9111321 9410static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9412 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9418 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9420 { } /* end */
9421};
9422
a9111321 9423static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9427 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9428 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9429 0x0d, 1, 0x0, HDA_OUTPUT),
9430 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9431 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9432 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9433 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9434 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9443 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9444 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9445 { } /* end */
9446};
9447
a9111321 9448static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9449 /* Output mixers */
9450 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9451 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9452 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9453 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9454 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9455 HDA_OUTPUT),
9456 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9457 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9458 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9459 /* Output switches */
9460 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9461 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9462 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9463 /* Boost mixers */
5f99f86a
DH
9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9465 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9466 /* Input mixers */
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9471 { } /* end */
9472};
9473
a9111321 9474static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9477 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9479 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9481 { } /* end */
9482};
9483
a9111321 9484static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9485 .ops = &snd_hda_bind_vol,
9486 .values = {
9487 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9488 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9489 0
9490 },
9491};
9492
a9111321 9493static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9494 .ops = &snd_hda_bind_sw,
9495 .values = {
9496 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9497 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9498 0
9499 },
9500};
9501
a9111321 9502static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9504 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9509 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9511 { } /* end */
9512};
df694daa 9513
a9111321 9514static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9515 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9516 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9517 {
9518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9519 /* .name = "Capture Source", */
9520 .name = "Input Source",
9521 .count = 1,
9522 .info = alc_mux_enum_info,
9523 .get = alc_mux_enum_get,
9524 .put = alc_mux_enum_put,
9525 },
9526 { } /* end */
9527};
9c7f852e 9528
a9111321 9529static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9530 {
9531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9532 .name = "Channel Mode",
9533 .info = alc_ch_mode_info,
9534 .get = alc_ch_mode_get,
9535 .put = alc_ch_mode_put,
9536 },
9537 { } /* end */
9c7f852e
TI
9538};
9539
a8848bd6 9540/* toggle speaker-output according to the hp-jack state */
4f5d1706 9541static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9542{
a9fd4f3f 9543 struct alc_spec *spec = codec->spec;
a8848bd6 9544
a9fd4f3f
TI
9545 spec->autocfg.hp_pins[0] = 0x15;
9546 spec->autocfg.speaker_pins[0] = 0x14;
9547 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9548 spec->automute = 1;
9549 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9550}
9551
a9111321 9552static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9553 /* HP */
9554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9556 /* Subwoofer */
9557 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9558 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9559
9560 /* enable unsolicited event */
9561 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9562 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9563
9564 { } /* end */
9565};
9566
a9111321 9567static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9568 /* HP */
9569 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9571 /* Int speaker */
9572 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9573
9574 /* enable unsolicited event */
9575 /*
9576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9578 */
9579
9580 { } /* end */
9581};
9582
a9111321 9583static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9584 /* HP */
9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9587 /* Int speaker */
9588 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590
9591 /* enable unsolicited event */
9592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9593 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9594
9595 { } /* end */
9596};
9597
a9111321 9598static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9599 /* HP */
9600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9602 /* Subwoofer */
9603 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9605
9606 /* enable unsolicited event */
9607 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9608
9609 { } /* end */
9610};
9611
a9111321 9612static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9615
9616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9618
64a8be74
DH
9619/* Connect Line-Out side jack (SPDIF) to Side */
9620 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9621 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9622 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9623/* Connect Mic jack to CLFE */
9624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9626 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9627/* Connect Line-in jack to Surround */
9628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9630 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9631/* Connect HP out jack to Front */
9632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9635
9636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9637
9638 { } /* end */
9639};
9640
a9111321 9641static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9645 { } /* end */
9646};
9647
a9111321 9648static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 { } /* end */
9654};
9655
a9111321 9656static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9661 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9662 { } /* end */
9663};
9664
a9111321 9665static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9668
9669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9670
9671 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9673 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9675 { } /* end */
9676};
9677
a9111321 9678static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9685 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9687 { } /* end */
9688};
9689
a9111321 9690static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692 { }
9693};
9694
a9111321 9695static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9696 /* HP */
9697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9699
9700 /* enable unsolicited event */
9701 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9702
9703 { } /* end */
9704};
9705
4f5d1706 9706static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9707{
a9fd4f3f 9708 struct alc_spec *spec = codec->spec;
8718b700 9709
a9fd4f3f
TI
9710 spec->autocfg.hp_pins[0] = 0x1b;
9711 spec->autocfg.speaker_pins[0] = 0x14;
9712 spec->autocfg.speaker_pins[1] = 0x16;
9713 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9714 spec->automute = 1;
9715 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9716}
9717
a9111321 9718static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9719 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9720 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9722 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9723 { } /* end */
5795b9e6
CM
9724};
9725
3ea0d7cf
HRK
9726/*
9727 * 2ch mode
9728 */
a9111321 9729static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9733 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9734 { } /* end */
8341de60
CM
9735};
9736
3ea0d7cf
HRK
9737/*
9738 * 4ch mode
9739 */
a9111321 9740static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9743 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9744 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9745 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9746 { } /* end */
9747};
9748
9749/*
9750 * 6ch mode
9751 */
a9111321 9752static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9755 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9756 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9757 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9758 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9759 { } /* end */
8341de60
CM
9760};
9761
a9111321 9762static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9763 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9764 { 4, alc888_3st_hp_4ch_init },
4723c022 9765 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9766};
9767
e6a5e1b7 9768static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9769{
e6a5e1b7 9770 struct alc_spec *spec = codec->spec;
47fd830a 9771
e6a5e1b7
TI
9772 spec->autocfg.hp_pins[0] = 0x1b;
9773 spec->autocfg.line_out_pins[0] = 0x14;
9774 spec->autocfg.speaker_pins[0] = 0x15;
9775 spec->automute = 1;
9776 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9777}
9778
272a527c 9779/* toggle speaker-output according to the hp-jack state */
dc427170 9780static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9781{
a9fd4f3f 9782 struct alc_spec *spec = codec->spec;
272a527c 9783
a9fd4f3f
TI
9784 spec->autocfg.hp_pins[0] = 0x14;
9785 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9786 spec->automute = 1;
9787 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9788}
9789
ccc656ce 9790/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9791#define alc883_targa_init_hook alc882_targa_init_hook
9792#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9793
4f5d1706 9794static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9795{
a9fd4f3f
TI
9796 struct alc_spec *spec = codec->spec;
9797
9798 spec->autocfg.hp_pins[0] = 0x15;
9799 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9802}
9803
9804static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9805{
d922b51d 9806 alc_hp_automute(codec);
eeb43387 9807 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9808}
9809
9810static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9811 unsigned int res)
9812{
0c4cc443 9813 switch (res >> 26) {
0c4cc443 9814 case ALC880_MIC_EVENT:
eeb43387 9815 alc88x_simple_mic_automute(codec);
0c4cc443 9816 break;
a9fd4f3f 9817 default:
d922b51d 9818 alc_sku_unsol_event(codec, res);
a9fd4f3f 9819 break;
0c4cc443 9820 }
368c7a95
J
9821}
9822
fb97dc67 9823/* toggle speaker-output according to the hp-jack state */
4f5d1706 9824static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9825{
a9fd4f3f 9826 struct alc_spec *spec = codec->spec;
fb97dc67 9827
a9fd4f3f
TI
9828 spec->autocfg.hp_pins[0] = 0x14;
9829 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9830 spec->automute = 1;
9831 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9832}
9833
4f5d1706 9834static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9835{
a9fd4f3f 9836 struct alc_spec *spec = codec->spec;
189609ae 9837
a9fd4f3f
TI
9838 spec->autocfg.hp_pins[0] = 0x1b;
9839 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9840 spec->automute = 1;
9841 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9842}
9843
e6a5e1b7 9844static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9845{
e6a5e1b7 9846 struct alc_spec *spec = codec->spec;
bc9f98a9 9847
e6a5e1b7
TI
9848 spec->autocfg.hp_pins[0] = 0x1b;
9849 spec->autocfg.line_out_pins[0] = 0x14;
9850 spec->autocfg.speaker_pins[0] = 0x15;
9851 spec->automute = 1;
9852 spec->detect_line = 1;
9853 spec->automute_lines = 1;
9854 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9855}
9856
676a9b53 9857/* toggle speaker-output according to the hp-jack state */
4f5d1706 9858static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9859{
a9fd4f3f 9860 struct alc_spec *spec = codec->spec;
676a9b53 9861
a9fd4f3f
TI
9862 spec->autocfg.hp_pins[0] = 0x14;
9863 spec->autocfg.speaker_pins[0] = 0x15;
9864 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9865 spec->automute = 1;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9867}
9868
a9111321 9869static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9870 /* HP Pin: output 0 (0x0c) */
9871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9873 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9874 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9876 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9877 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9878 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9879 /* eanable EAPD on medion laptop */
9880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9881 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9882 /* enable unsolicited event */
9883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9884 { }
9885};
9886
4f5d1706 9887static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9888{
a9fd4f3f 9889 struct alc_spec *spec = codec->spec;
5795b9e6 9890
a9fd4f3f
TI
9891 spec->autocfg.hp_pins[0] = 0x1b;
9892 spec->autocfg.speaker_pins[0] = 0x14;
9893 spec->autocfg.speaker_pins[1] = 0x15;
9894 spec->autocfg.speaker_pins[2] = 0x16;
9895 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9896 spec->automute = 1;
9897 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9898}
9899
4f5d1706 9900static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9901{
a9fd4f3f 9902 struct alc_spec *spec = codec->spec;
e2757d5e 9903
a9fd4f3f
TI
9904 spec->autocfg.hp_pins[0] = 0x1b;
9905 spec->autocfg.speaker_pins[0] = 0x14;
9906 spec->autocfg.speaker_pins[1] = 0x15;
9907 spec->autocfg.speaker_pins[2] = 0x16;
9908 spec->autocfg.speaker_pins[3] = 0x17;
9909 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9912}
9913
4f5d1706 9914static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9915{
9916 struct alc_spec *spec = codec->spec;
9917
9918 spec->autocfg.hp_pins[0] = 0x15;
9919 spec->autocfg.speaker_pins[0] = 0x14;
9920 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9921 spec->automute = 1;
9922 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9923}
9924
a9111321 9925static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9929 /* enable unsolicited event */
9930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9932 { } /* end */
9933};
9934
4f5d1706 9935static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9936{
a9fd4f3f 9937 struct alc_spec *spec = codec->spec;
e2757d5e 9938
a9fd4f3f
TI
9939 spec->autocfg.hp_pins[0] = 0x1b;
9940 spec->autocfg.speaker_pins[0] = 0x14;
9941 spec->autocfg.speaker_pins[1] = 0x15;
9942 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9943 spec->ext_mic.pin = 0x18;
9944 spec->int_mic.pin = 0x19;
9945 spec->ext_mic.mux_idx = 0;
9946 spec->int_mic.mux_idx = 1;
9947 spec->auto_mic = 1;
d922b51d
TI
9948 spec->automute = 1;
9949 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9950}
9951
a9111321 9952static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9958 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9959 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9960 /* enable unsolicited event */
9961 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9962 { } /* end */
9963};
9964
e2757d5e
KY
9965static void alc883_eee1601_inithook(struct hda_codec *codec)
9966{
a9fd4f3f
TI
9967 struct alc_spec *spec = codec->spec;
9968
9969 spec->autocfg.hp_pins[0] = 0x14;
9970 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9971 alc_hp_automute(codec);
e2757d5e
KY
9972}
9973
a9111321 9974static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9975 /* Init rear pin (used as headphone output) */
9976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9979 /* Init line pin (used as output in 4ch and 6ch mode) */
9980 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9981 /* Init line 2 pin (used as headphone out by default) */
9982 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9983 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9984 { } /* end */
9985};
9986
9987/* Mute speakers according to the headphone jack state */
9988static void alc889A_mb31_automute(struct hda_codec *codec)
9989{
9990 unsigned int present;
9991
9992 /* Mute only in 2ch or 4ch mode */
9993 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9994 == 0x00) {
864f92be 9995 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9996 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9997 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9998 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9999 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10000 }
10001}
10002
10003static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10004{
10005 if ((res >> 26) == ALC880_HP_EVENT)
10006 alc889A_mb31_automute(codec);
10007}
10008
4953550a 10009
cb53c626 10010#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 10011#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
10012#endif
10013
def319f9 10014/* pcm configuration: identical with ALC880 */
4953550a
TI
10015#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10016#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10017#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10018#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10019
4c6d72d1 10020static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
10021 ALC1200_DIGOUT_NID, 0,
10022};
10023
4c6d72d1 10024static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
10025 ALC883_DIGOUT_NID, 0,
10026};
9c7f852e
TI
10027
10028/*
10029 * configuration and preset
10030 */
ea734963 10031static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
10032 [ALC882_3ST_DIG] = "3stack-dig",
10033 [ALC882_6ST_DIG] = "6stack-dig",
10034 [ALC882_ARIMA] = "arima",
10035 [ALC882_W2JC] = "w2jc",
10036 [ALC882_TARGA] = "targa",
10037 [ALC882_ASUS_A7J] = "asus-a7j",
10038 [ALC882_ASUS_A7M] = "asus-a7m",
10039 [ALC885_MACPRO] = "macpro",
10040 [ALC885_MB5] = "mb5",
e458b1fa 10041 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 10042 [ALC885_MBA21] = "mba21",
4953550a
TI
10043 [ALC885_MBP3] = "mbp3",
10044 [ALC885_IMAC24] = "imac24",
4b7e1803 10045 [ALC885_IMAC91] = "imac91",
4953550a 10046 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10047 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10048 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10049 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10050 [ALC883_TARGA_DIG] = "targa-dig",
10051 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10052 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10053 [ALC883_ACER] = "acer",
2880a867 10054 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10055 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10056 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10057 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10058 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10059 [ALC883_MEDION] = "medion",
7ad7b218 10060 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10061 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10062 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10063 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10064 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10065 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10066 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10067 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10068 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10069 [ALC883_MITAC] = "mitac",
a65cc60f 10070 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10071 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10072 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10073 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10074 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10075 [ALC889A_INTEL] = "intel-alc889a",
10076 [ALC889_INTEL] = "intel-x58",
3ab90935 10077 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10078 [ALC889A_MB31] = "mb31",
3e1647c5 10079 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10080 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10081};
10082
a9111321 10083static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10084 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10085
ac3e3741 10086 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10087 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10088 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10089 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10090 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10091 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10092 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10093 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10094 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10095 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10096 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10097 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10098 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10099 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10100 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10101 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10102 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10103 ALC888_ACER_ASPIRE_6530G),
cc374c47 10104 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10105 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10106 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10107 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10108 /* default Acer -- disabled as it causes more problems.
10109 * model=auto should work fine now
10110 */
10111 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10112
5795b9e6 10113 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10114
25985edc 10115 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10116 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10117 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10118 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10119 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10120 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10121
10122 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10123 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10124 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10125 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10126 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10127 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10128 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10129 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10130 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10131 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10132 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10133
10134 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10135 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10136 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10137 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10138 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10139 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10140 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10141 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10142 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10143
6f3bf657 10144 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10145 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10146 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10147 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10148 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10149 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10150 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10151 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10152 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10153 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10154 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10155 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10156 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10157 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10158 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10159 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10160 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10162 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10163 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10164 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10165 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10167 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10168 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10169 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10170 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10171 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10172 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10173 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10174 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10175
ac3e3741 10176 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10177 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10178 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10179 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10180 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10181 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10182 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10183 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10184 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10185 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10186 ALC883_FUJITSU_PI2515),
bfb53037 10187 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10188 ALC888_FUJITSU_XA3530),
272a527c 10189 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10190 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10191 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10192 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10193 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10194 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10195 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10196 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10197
17bba1b7
J
10198 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10199 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10200 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10201 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10202 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10203 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10204 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10205
4953550a 10206 {}
f3cd3f5d
WF
10207};
10208
4953550a 10209/* codec SSID table for Intel Mac */
a9111321 10210static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10211 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10212 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10213 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10214 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10215 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10216 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10217 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10218 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10219 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10220 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10221 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10222 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10223 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10224 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10225 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10226 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10227 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10228 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10229 * so apparently no perfect solution yet
4953550a
TI
10230 */
10231 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10232 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10233 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10234 {} /* terminator */
b25c9da1
WF
10235};
10236
a9111321 10237static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10238 [ALC882_3ST_DIG] = {
10239 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10240 .init_verbs = { alc882_base_init_verbs,
10241 alc882_adc1_init_verbs },
4953550a
TI
10242 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10243 .dac_nids = alc882_dac_nids,
10244 .dig_out_nid = ALC882_DIGOUT_NID,
10245 .dig_in_nid = ALC882_DIGIN_NID,
10246 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10247 .channel_mode = alc882_ch_modes,
10248 .need_dac_fix = 1,
10249 .input_mux = &alc882_capture_source,
10250 },
10251 [ALC882_6ST_DIG] = {
10252 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10253 .init_verbs = { alc882_base_init_verbs,
10254 alc882_adc1_init_verbs },
4953550a
TI
10255 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10256 .dac_nids = alc882_dac_nids,
10257 .dig_out_nid = ALC882_DIGOUT_NID,
10258 .dig_in_nid = ALC882_DIGIN_NID,
10259 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10260 .channel_mode = alc882_sixstack_modes,
10261 .input_mux = &alc882_capture_source,
10262 },
10263 [ALC882_ARIMA] = {
10264 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10265 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10266 alc882_eapd_verbs },
4953550a
TI
10267 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10268 .dac_nids = alc882_dac_nids,
10269 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10270 .channel_mode = alc882_sixstack_modes,
10271 .input_mux = &alc882_capture_source,
10272 },
10273 [ALC882_W2JC] = {
10274 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10275 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10276 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10277 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10278 .dac_nids = alc882_dac_nids,
10279 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10280 .channel_mode = alc880_threestack_modes,
10281 .need_dac_fix = 1,
10282 .input_mux = &alc882_capture_source,
10283 .dig_out_nid = ALC882_DIGOUT_NID,
10284 },
76e6f5a9
RH
10285 [ALC885_MBA21] = {
10286 .mixers = { alc885_mba21_mixer },
10287 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10288 .num_dacs = 2,
10289 .dac_nids = alc882_dac_nids,
10290 .channel_mode = alc885_mba21_ch_modes,
10291 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10292 .input_mux = &alc882_capture_source,
d922b51d 10293 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10294 .setup = alc885_mba21_setup,
d922b51d 10295 .init_hook = alc_hp_automute,
76e6f5a9 10296 },
4953550a
TI
10297 [ALC885_MBP3] = {
10298 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10299 .init_verbs = { alc885_mbp3_init_verbs,
10300 alc880_gpio1_init_verbs },
be0ae923 10301 .num_dacs = 2,
4953550a 10302 .dac_nids = alc882_dac_nids,
be0ae923
TI
10303 .hp_nid = 0x04,
10304 .channel_mode = alc885_mbp_4ch_modes,
10305 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10306 .input_mux = &alc882_capture_source,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10309 .unsol_event = alc_sku_unsol_event,
4f5d1706 10310 .setup = alc885_mbp3_setup,
d922b51d 10311 .init_hook = alc_hp_automute,
4953550a
TI
10312 },
10313 [ALC885_MB5] = {
10314 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10315 .init_verbs = { alc885_mb5_init_verbs,
10316 alc880_gpio1_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .channel_mode = alc885_mb5_6ch_modes,
10320 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10321 .input_mux = &mb5_capture_source,
10322 .dig_out_nid = ALC882_DIGOUT_NID,
10323 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10324 .unsol_event = alc_sku_unsol_event,
9d54f08b 10325 .setup = alc885_mb5_setup,
d922b51d 10326 .init_hook = alc_hp_automute,
4953550a 10327 },
e458b1fa
LY
10328 [ALC885_MACMINI3] = {
10329 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10330 .init_verbs = { alc885_macmini3_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
10334 .channel_mode = alc885_macmini3_6ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10336 .input_mux = &macmini3_capture_source,
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10339 .unsol_event = alc_sku_unsol_event,
9d54f08b 10340 .setup = alc885_macmini3_setup,
d922b51d 10341 .init_hook = alc_hp_automute,
e458b1fa 10342 },
4953550a
TI
10343 [ALC885_MACPRO] = {
10344 .mixers = { alc882_macpro_mixer },
10345 .init_verbs = { alc882_macpro_init_verbs },
10346 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10347 .dac_nids = alc882_dac_nids,
10348 .dig_out_nid = ALC882_DIGOUT_NID,
10349 .dig_in_nid = ALC882_DIGIN_NID,
10350 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10351 .channel_mode = alc882_ch_modes,
10352 .input_mux = &alc882_capture_source,
10353 .init_hook = alc885_macpro_init_hook,
10354 },
10355 [ALC885_IMAC24] = {
10356 .mixers = { alc885_imac24_mixer },
10357 .init_verbs = { alc885_imac24_init_verbs },
10358 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10359 .dac_nids = alc882_dac_nids,
10360 .dig_out_nid = ALC882_DIGOUT_NID,
10361 .dig_in_nid = ALC882_DIGIN_NID,
10362 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10363 .channel_mode = alc882_ch_modes,
10364 .input_mux = &alc882_capture_source,
d922b51d 10365 .unsol_event = alc_sku_unsol_event,
4f5d1706 10366 .setup = alc885_imac24_setup,
4953550a
TI
10367 .init_hook = alc885_imac24_init_hook,
10368 },
4b7e1803 10369 [ALC885_IMAC91] = {
b7cccc52 10370 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10371 .init_verbs = { alc885_imac91_init_verbs,
10372 alc880_gpio1_init_verbs },
10373 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10374 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10375 .channel_mode = alc885_mba21_ch_modes,
10376 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10377 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10378 .dig_out_nid = ALC882_DIGOUT_NID,
10379 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10380 .unsol_event = alc_sku_unsol_event,
9d54f08b 10381 .setup = alc885_imac91_setup,
d922b51d 10382 .init_hook = alc_hp_automute,
4b7e1803 10383 },
4953550a
TI
10384 [ALC882_TARGA] = {
10385 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10386 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10387 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10388 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10389 .dac_nids = alc882_dac_nids,
10390 .dig_out_nid = ALC882_DIGOUT_NID,
10391 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10392 .adc_nids = alc882_adc_nids,
10393 .capsrc_nids = alc882_capsrc_nids,
10394 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10395 .channel_mode = alc882_3ST_6ch_modes,
10396 .need_dac_fix = 1,
10397 .input_mux = &alc882_capture_source,
d922b51d 10398 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10399 .setup = alc882_targa_setup,
10400 .init_hook = alc882_targa_automute,
4953550a
TI
10401 },
10402 [ALC882_ASUS_A7J] = {
10403 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10404 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10405 alc882_asus_a7j_verbs},
4953550a
TI
10406 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10407 .dac_nids = alc882_dac_nids,
10408 .dig_out_nid = ALC882_DIGOUT_NID,
10409 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10410 .adc_nids = alc882_adc_nids,
10411 .capsrc_nids = alc882_capsrc_nids,
10412 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10413 .channel_mode = alc882_3ST_6ch_modes,
10414 .need_dac_fix = 1,
10415 .input_mux = &alc882_capture_source,
10416 },
10417 [ALC882_ASUS_A7M] = {
10418 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10419 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10420 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10421 alc882_asus_a7m_verbs },
10422 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10423 .dac_nids = alc882_dac_nids,
10424 .dig_out_nid = ALC882_DIGOUT_NID,
10425 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10426 .channel_mode = alc880_threestack_modes,
10427 .need_dac_fix = 1,
10428 .input_mux = &alc882_capture_source,
10429 },
9c7f852e
TI
10430 [ALC883_3ST_2ch_DIG] = {
10431 .mixers = { alc883_3ST_2ch_mixer },
10432 .init_verbs = { alc883_init_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10436 .dig_in_nid = ALC883_DIGIN_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .input_mux = &alc883_capture_source,
10440 },
10441 [ALC883_3ST_6ch_DIG] = {
10442 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10443 .init_verbs = { alc883_init_verbs },
10444 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10445 .dac_nids = alc883_dac_nids,
10446 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10447 .dig_in_nid = ALC883_DIGIN_NID,
10448 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10449 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10450 .need_dac_fix = 1,
9c7f852e 10451 .input_mux = &alc883_capture_source,
f12ab1e0 10452 },
9c7f852e
TI
10453 [ALC883_3ST_6ch] = {
10454 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10455 .init_verbs = { alc883_init_verbs },
10456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10457 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10460 .need_dac_fix = 1,
9c7f852e 10461 .input_mux = &alc883_capture_source,
f12ab1e0 10462 },
17bba1b7
J
10463 [ALC883_3ST_6ch_INTEL] = {
10464 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10465 .init_verbs = { alc883_init_verbs },
10466 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10467 .dac_nids = alc883_dac_nids,
10468 .dig_out_nid = ALC883_DIGOUT_NID,
10469 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10470 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10471 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10472 .channel_mode = alc883_3ST_6ch_intel_modes,
10473 .need_dac_fix = 1,
10474 .input_mux = &alc883_3stack_6ch_intel,
10475 },
87a8c370
JK
10476 [ALC889A_INTEL] = {
10477 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10478 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10479 alc_hp15_unsol_verbs },
87a8c370
JK
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
10482 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10483 .adc_nids = alc889_adc_nids,
10484 .dig_out_nid = ALC883_DIGOUT_NID,
10485 .dig_in_nid = ALC883_DIGIN_NID,
10486 .slave_dig_outs = alc883_slave_dig_outs,
10487 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10488 .channel_mode = alc889_8ch_intel_modes,
10489 .capsrc_nids = alc889_capsrc_nids,
10490 .input_mux = &alc889_capture_source,
4f5d1706 10491 .setup = alc889_automute_setup,
d922b51d
TI
10492 .init_hook = alc_hp_automute,
10493 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10494 .need_dac_fix = 1,
10495 },
10496 [ALC889_INTEL] = {
10497 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10498 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10499 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501 .dac_nids = alc883_dac_nids,
10502 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10503 .adc_nids = alc889_adc_nids,
10504 .dig_out_nid = ALC883_DIGOUT_NID,
10505 .dig_in_nid = ALC883_DIGIN_NID,
10506 .slave_dig_outs = alc883_slave_dig_outs,
10507 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10508 .channel_mode = alc889_8ch_intel_modes,
10509 .capsrc_nids = alc889_capsrc_nids,
10510 .input_mux = &alc889_capture_source,
4f5d1706 10511 .setup = alc889_automute_setup,
6732bd0d 10512 .init_hook = alc889_intel_init_hook,
d922b51d 10513 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10514 .need_dac_fix = 1,
10515 },
9c7f852e
TI
10516 [ALC883_6ST_DIG] = {
10517 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10518 .init_verbs = { alc883_init_verbs },
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
10521 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10522 .dig_in_nid = ALC883_DIGIN_NID,
10523 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10524 .channel_mode = alc883_sixstack_modes,
10525 .input_mux = &alc883_capture_source,
10526 },
ccc656ce 10527 [ALC883_TARGA_DIG] = {
c259249f 10528 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10529 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10530 alc883_targa_verbs},
ccc656ce
KY
10531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10532 .dac_nids = alc883_dac_nids,
10533 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10534 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10535 .channel_mode = alc883_3ST_6ch_modes,
10536 .need_dac_fix = 1,
10537 .input_mux = &alc883_capture_source,
c259249f 10538 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10539 .setup = alc882_targa_setup,
10540 .init_hook = alc882_targa_automute,
ccc656ce
KY
10541 },
10542 [ALC883_TARGA_2ch_DIG] = {
c259249f 10543 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10544 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10545 alc883_targa_verbs},
ccc656ce
KY
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10548 .adc_nids = alc883_adc_nids_alt,
10549 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10550 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10551 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10552 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10553 .channel_mode = alc883_3ST_2ch_modes,
10554 .input_mux = &alc883_capture_source,
c259249f 10555 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10556 .setup = alc882_targa_setup,
10557 .init_hook = alc882_targa_automute,
ccc656ce 10558 },
64a8be74 10559 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10560 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10561 alc883_chmode_mixer },
64a8be74 10562 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10563 alc883_targa_verbs },
64a8be74
DH
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10567 .adc_nids = alc883_adc_nids_rev,
10568 .capsrc_nids = alc883_capsrc_nids_rev,
10569 .dig_out_nid = ALC883_DIGOUT_NID,
10570 .dig_in_nid = ALC883_DIGIN_NID,
10571 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10572 .channel_mode = alc883_4ST_8ch_modes,
10573 .need_dac_fix = 1,
10574 .input_mux = &alc883_capture_source,
c259249f 10575 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10576 .setup = alc882_targa_setup,
10577 .init_hook = alc882_targa_automute,
64a8be74 10578 },
bab282b9 10579 [ALC883_ACER] = {
676a9b53 10580 .mixers = { alc883_base_mixer },
bab282b9
VA
10581 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10582 * and the headphone jack. Turn this on and rely on the
10583 * standard mute methods whenever the user wants to turn
10584 * these outputs off.
10585 */
10586 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10588 .dac_nids = alc883_dac_nids,
bab282b9
VA
10589 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10590 .channel_mode = alc883_3ST_2ch_modes,
10591 .input_mux = &alc883_capture_source,
10592 },
2880a867 10593 [ALC883_ACER_ASPIRE] = {
676a9b53 10594 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10595 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10597 .dac_nids = alc883_dac_nids,
10598 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10600 .channel_mode = alc883_3ST_2ch_modes,
10601 .input_mux = &alc883_capture_source,
d922b51d 10602 .unsol_event = alc_sku_unsol_event,
4f5d1706 10603 .setup = alc883_acer_aspire_setup,
d922b51d 10604 .init_hook = alc_hp_automute,
d1a991a6 10605 },
5b2d1eca 10606 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10607 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10610 alc888_acer_aspire_4930g_verbs },
10611 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10612 .dac_nids = alc883_dac_nids,
10613 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10614 .adc_nids = alc883_adc_nids_rev,
10615 .capsrc_nids = alc883_capsrc_nids_rev,
10616 .dig_out_nid = ALC883_DIGOUT_NID,
10617 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10618 .channel_mode = alc883_3ST_6ch_modes,
10619 .need_dac_fix = 1,
973b8cb0 10620 .const_channel_count = 6,
5b2d1eca 10621 .num_mux_defs =
ef8ef5fb
VP
10622 ARRAY_SIZE(alc888_2_capture_sources),
10623 .input_mux = alc888_2_capture_sources,
d922b51d 10624 .unsol_event = alc_sku_unsol_event,
4f5d1706 10625 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10626 .init_hook = alc_hp_automute,
d2fd4b09
TV
10627 },
10628 [ALC888_ACER_ASPIRE_6530G] = {
10629 .mixers = { alc888_acer_aspire_6530_mixer },
10630 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10631 alc888_acer_aspire_6530g_verbs },
10632 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10633 .dac_nids = alc883_dac_nids,
10634 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10635 .adc_nids = alc883_adc_nids_rev,
10636 .capsrc_nids = alc883_capsrc_nids_rev,
10637 .dig_out_nid = ALC883_DIGOUT_NID,
10638 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10639 .channel_mode = alc883_3ST_2ch_modes,
10640 .num_mux_defs =
10641 ARRAY_SIZE(alc888_2_capture_sources),
10642 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10643 .unsol_event = alc_sku_unsol_event,
4f5d1706 10644 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10645 .init_hook = alc_hp_automute,
5b2d1eca 10646 },
3b315d70 10647 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10648 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10649 alc883_chmode_mixer },
10650 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10651 alc889_acer_aspire_8930g_verbs,
10652 alc889_eapd_verbs},
3b315d70
HM
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
018df418
HM
10655 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10656 .adc_nids = alc889_adc_nids,
10657 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10660 .channel_mode = alc883_3ST_6ch_modes,
10661 .need_dac_fix = 1,
10662 .const_channel_count = 6,
10663 .num_mux_defs =
018df418
HM
10664 ARRAY_SIZE(alc889_capture_sources),
10665 .input_mux = alc889_capture_sources,
d922b51d 10666 .unsol_event = alc_sku_unsol_event,
4f5d1706 10667 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10668 .init_hook = alc_hp_automute,
f5de24b0 10669#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10670 .power_hook = alc_power_eapd,
f5de24b0 10671#endif
3b315d70 10672 },
fc86f954
DK
10673 [ALC888_ACER_ASPIRE_7730G] = {
10674 .mixers = { alc883_3ST_6ch_mixer,
10675 alc883_chmode_mixer },
10676 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10677 alc888_acer_aspire_7730G_verbs },
10678 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10679 .dac_nids = alc883_dac_nids,
10680 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10681 .adc_nids = alc883_adc_nids_rev,
10682 .capsrc_nids = alc883_capsrc_nids_rev,
10683 .dig_out_nid = ALC883_DIGOUT_NID,
10684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10685 .channel_mode = alc883_3ST_6ch_modes,
10686 .need_dac_fix = 1,
10687 .const_channel_count = 6,
10688 .input_mux = &alc883_capture_source,
d922b51d 10689 .unsol_event = alc_sku_unsol_event,
d9477207 10690 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10691 .init_hook = alc_hp_automute,
fc86f954 10692 },
c07584c8
TD
10693 [ALC883_MEDION] = {
10694 .mixers = { alc883_fivestack_mixer,
10695 alc883_chmode_mixer },
10696 .init_verbs = { alc883_init_verbs,
b373bdeb 10697 alc883_medion_eapd_verbs },
c07584c8
TD
10698 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10699 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10700 .adc_nids = alc883_adc_nids_alt,
10701 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10702 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10703 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10704 .channel_mode = alc883_sixstack_modes,
10705 .input_mux = &alc883_capture_source,
b373bdeb 10706 },
7ad7b218
MC
10707 [ALC883_MEDION_WIM2160] = {
10708 .mixers = { alc883_medion_wim2160_mixer },
10709 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10710 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10711 .dac_nids = alc883_dac_nids,
10712 .dig_out_nid = ALC883_DIGOUT_NID,
10713 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10714 .adc_nids = alc883_adc_nids,
10715 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10716 .channel_mode = alc883_3ST_2ch_modes,
10717 .input_mux = &alc883_capture_source,
d922b51d 10718 .unsol_event = alc_sku_unsol_event,
7ad7b218 10719 .setup = alc883_medion_wim2160_setup,
d922b51d 10720 .init_hook = alc_hp_automute,
7ad7b218 10721 },
b373bdeb 10722 [ALC883_LAPTOP_EAPD] = {
676a9b53 10723 .mixers = { alc883_base_mixer },
b373bdeb
AN
10724 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10725 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10726 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10727 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10728 .channel_mode = alc883_3ST_2ch_modes,
10729 .input_mux = &alc883_capture_source,
10730 },
a65cc60f 10731 [ALC883_CLEVO_M540R] = {
10732 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10733 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735 .dac_nids = alc883_dac_nids,
10736 .dig_out_nid = ALC883_DIGOUT_NID,
10737 .dig_in_nid = ALC883_DIGIN_NID,
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10739 .channel_mode = alc883_3ST_6ch_clevo_modes,
10740 .need_dac_fix = 1,
10741 .input_mux = &alc883_capture_source,
10742 /* This machine has the hardware HP auto-muting, thus
10743 * we need no software mute via unsol event
10744 */
10745 },
0c4cc443
HRK
10746 [ALC883_CLEVO_M720] = {
10747 .mixers = { alc883_clevo_m720_mixer },
10748 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10753 .channel_mode = alc883_3ST_2ch_modes,
10754 .input_mux = &alc883_capture_source,
0c4cc443 10755 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10756 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10757 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10758 },
bc9f98a9
KY
10759 [ALC883_LENOVO_101E_2ch] = {
10760 .mixers = { alc883_lenovo_101e_2ch_mixer},
10761 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10762 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10763 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10764 .adc_nids = alc883_adc_nids_alt,
10765 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10766 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10767 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10768 .channel_mode = alc883_3ST_2ch_modes,
10769 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10770 .setup = alc883_lenovo_101e_setup,
10771 .unsol_event = alc_sku_unsol_event,
10772 .init_hook = alc_inithook,
bc9f98a9 10773 },
272a527c
KY
10774 [ALC883_LENOVO_NB0763] = {
10775 .mixers = { alc883_lenovo_nb0763_mixer },
10776 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10778 .dac_nids = alc883_dac_nids,
272a527c
KY
10779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10780 .channel_mode = alc883_3ST_2ch_modes,
10781 .need_dac_fix = 1,
10782 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10783 .unsol_event = alc_sku_unsol_event,
dc427170 10784 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10785 .init_hook = alc_hp_automute,
272a527c
KY
10786 },
10787 [ALC888_LENOVO_MS7195_DIG] = {
10788 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10789 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10790 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10791 .dac_nids = alc883_dac_nids,
10792 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10793 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10794 .channel_mode = alc883_3ST_6ch_modes,
10795 .need_dac_fix = 1,
10796 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10797 .unsol_event = alc_sku_unsol_event,
10798 .setup = alc888_lenovo_ms7195_setup,
10799 .init_hook = alc_inithook,
189609ae
KY
10800 },
10801 [ALC883_HAIER_W66] = {
c259249f 10802 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10803 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10804 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10805 .dac_nids = alc883_dac_nids,
10806 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10808 .channel_mode = alc883_3ST_2ch_modes,
10809 .input_mux = &alc883_capture_source,
d922b51d 10810 .unsol_event = alc_sku_unsol_event,
4f5d1706 10811 .setup = alc883_haier_w66_setup,
d922b51d 10812 .init_hook = alc_hp_automute,
eea6419e 10813 },
4723c022 10814 [ALC888_3ST_HP] = {
eea6419e 10815 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10816 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10817 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10818 .dac_nids = alc883_dac_nids,
4723c022
CM
10819 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10820 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10821 .need_dac_fix = 1,
10822 .input_mux = &alc883_capture_source,
d922b51d 10823 .unsol_event = alc_sku_unsol_event,
4f5d1706 10824 .setup = alc888_3st_hp_setup,
d922b51d 10825 .init_hook = alc_hp_automute,
8341de60 10826 },
5795b9e6 10827 [ALC888_6ST_DELL] = {
f24dbdc6 10828 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10829 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10833 .dig_in_nid = ALC883_DIGIN_NID,
10834 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10835 .channel_mode = alc883_sixstack_modes,
10836 .input_mux = &alc883_capture_source,
d922b51d 10837 .unsol_event = alc_sku_unsol_event,
4f5d1706 10838 .setup = alc888_6st_dell_setup,
d922b51d 10839 .init_hook = alc_hp_automute,
5795b9e6 10840 },
a8848bd6
AS
10841 [ALC883_MITAC] = {
10842 .mixers = { alc883_mitac_mixer },
10843 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10847 .channel_mode = alc883_3ST_2ch_modes,
10848 .input_mux = &alc883_capture_source,
d922b51d 10849 .unsol_event = alc_sku_unsol_event,
4f5d1706 10850 .setup = alc883_mitac_setup,
d922b51d 10851 .init_hook = alc_hp_automute,
a8848bd6 10852 },
fb97dc67
J
10853 [ALC883_FUJITSU_PI2515] = {
10854 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10855 .init_verbs = { alc883_init_verbs,
10856 alc883_2ch_fujitsu_pi2515_verbs},
10857 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10858 .dac_nids = alc883_dac_nids,
10859 .dig_out_nid = ALC883_DIGOUT_NID,
10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10861 .channel_mode = alc883_3ST_2ch_modes,
10862 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10863 .unsol_event = alc_sku_unsol_event,
4f5d1706 10864 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10865 .init_hook = alc_hp_automute,
fb97dc67 10866 },
ef8ef5fb
VP
10867 [ALC888_FUJITSU_XA3530] = {
10868 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10869 .init_verbs = { alc883_init_verbs,
10870 alc888_fujitsu_xa3530_verbs },
10871 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10872 .dac_nids = alc883_dac_nids,
10873 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10874 .adc_nids = alc883_adc_nids_rev,
10875 .capsrc_nids = alc883_capsrc_nids_rev,
10876 .dig_out_nid = ALC883_DIGOUT_NID,
10877 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10878 .channel_mode = alc888_4ST_8ch_intel_modes,
10879 .num_mux_defs =
10880 ARRAY_SIZE(alc888_2_capture_sources),
10881 .input_mux = alc888_2_capture_sources,
d922b51d 10882 .unsol_event = alc_sku_unsol_event,
4f5d1706 10883 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10884 .init_hook = alc_hp_automute,
ef8ef5fb 10885 },
e2757d5e
KY
10886 [ALC888_LENOVO_SKY] = {
10887 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10888 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10889 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10890 .dac_nids = alc883_dac_nids,
10891 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10892 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10893 .channel_mode = alc883_sixstack_modes,
10894 .need_dac_fix = 1,
10895 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10896 .unsol_event = alc_sku_unsol_event,
4f5d1706 10897 .setup = alc888_lenovo_sky_setup,
d922b51d 10898 .init_hook = alc_hp_automute,
e2757d5e
KY
10899 },
10900 [ALC888_ASUS_M90V] = {
10901 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10902 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10903 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904 .dac_nids = alc883_dac_nids,
10905 .dig_out_nid = ALC883_DIGOUT_NID,
10906 .dig_in_nid = ALC883_DIGIN_NID,
10907 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10908 .channel_mode = alc883_3ST_6ch_modes,
10909 .need_dac_fix = 1,
10910 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10911 .unsol_event = alc_sku_unsol_event,
10912 .setup = alc883_mode2_setup,
10913 .init_hook = alc_inithook,
e2757d5e
KY
10914 },
10915 [ALC888_ASUS_EEE1601] = {
10916 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10917 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10918 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10919 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10920 .dac_nids = alc883_dac_nids,
10921 .dig_out_nid = ALC883_DIGOUT_NID,
10922 .dig_in_nid = ALC883_DIGIN_NID,
10923 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10924 .channel_mode = alc883_3ST_2ch_modes,
10925 .need_dac_fix = 1,
10926 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10927 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10928 .init_hook = alc883_eee1601_inithook,
10929 },
3ab90935
WF
10930 [ALC1200_ASUS_P5Q] = {
10931 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10932 .init_verbs = { alc883_init_verbs },
10933 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10934 .dac_nids = alc883_dac_nids,
10935 .dig_out_nid = ALC1200_DIGOUT_NID,
10936 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10937 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10938 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10939 .channel_mode = alc883_sixstack_modes,
10940 .input_mux = &alc883_capture_source,
10941 },
eb4c41d3
TS
10942 [ALC889A_MB31] = {
10943 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10944 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10945 alc880_gpio1_init_verbs },
10946 .adc_nids = alc883_adc_nids,
10947 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10948 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10949 .dac_nids = alc883_dac_nids,
10950 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10951 .channel_mode = alc889A_mb31_6ch_modes,
10952 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10953 .input_mux = &alc889A_mb31_capture_source,
10954 .dig_out_nid = ALC883_DIGOUT_NID,
10955 .unsol_event = alc889A_mb31_unsol_event,
10956 .init_hook = alc889A_mb31_automute,
10957 },
3e1647c5
GG
10958 [ALC883_SONY_VAIO_TT] = {
10959 .mixers = { alc883_vaiott_mixer },
10960 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10962 .dac_nids = alc883_dac_nids,
10963 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10964 .channel_mode = alc883_3ST_2ch_modes,
10965 .input_mux = &alc883_capture_source,
d922b51d 10966 .unsol_event = alc_sku_unsol_event,
4f5d1706 10967 .setup = alc883_vaiott_setup,
d922b51d 10968 .init_hook = alc_hp_automute,
3e1647c5 10969 },
9c7f852e
TI
10970};
10971
10972
4953550a
TI
10973/*
10974 * Pin config fixes
10975 */
10976enum {
954a29c8 10977 PINFIX_ABIT_AW9D_MAX,
32eea388 10978 PINFIX_LENOVO_Y530,
954a29c8 10979 PINFIX_PB_M5210,
c3d226ab 10980 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10981};
10982
f8f25ba3
TI
10983static const struct alc_fixup alc882_fixups[] = {
10984 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10985 .type = ALC_FIXUP_PINS,
10986 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10987 { 0x15, 0x01080104 }, /* side */
10988 { 0x16, 0x01011012 }, /* rear */
10989 { 0x17, 0x01016011 }, /* clfe */
10990 { }
10991 }
f8f25ba3 10992 },
32eea388
DH
10993 [PINFIX_LENOVO_Y530] = {
10994 .type = ALC_FIXUP_PINS,
10995 .v.pins = (const struct alc_pincfg[]) {
10996 { 0x15, 0x99130112 }, /* rear int speakers */
10997 { 0x16, 0x99130111 }, /* subwoofer */
10998 { }
10999 }
11000 },
954a29c8 11001 [PINFIX_PB_M5210] = {
b5bfbc67
TI
11002 .type = ALC_FIXUP_VERBS,
11003 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
11004 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11005 {}
11006 }
954a29c8 11007 },
c3d226ab 11008 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
11009 .type = ALC_FIXUP_SKU,
11010 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 11011 },
4953550a
TI
11012};
11013
a9111321 11014static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 11015 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 11016 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 11017 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 11018 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
11019 {}
11020};
11021
9c7f852e
TI
11022/*
11023 * BIOS auto configuration
11024 */
05f5f477
TI
11025static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11026 const struct auto_pin_cfg *cfg)
11027{
11028 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11029}
11030
4953550a 11031static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 11032 hda_nid_t nid, int pin_type,
489008cd 11033 hda_nid_t dac)
9c7f852e 11034{
f12ab1e0
TI
11035 int idx;
11036
489008cd 11037 /* set as output */
f6c7e546 11038 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
11039
11040 if (dac == 0x25)
9c7f852e 11041 idx = 4;
489008cd
TI
11042 else if (dac >= 0x02 && dac <= 0x05)
11043 idx = dac - 2;
f9700d5a 11044 else
489008cd 11045 return;
9c7f852e 11046 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11047}
11048
4953550a 11049static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11050{
11051 struct alc_spec *spec = codec->spec;
11052 int i;
11053
11054 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11055 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11056 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11057 if (nid)
4953550a 11058 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11059 spec->multiout.dac_nids[i]);
9c7f852e
TI
11060 }
11061}
11062
4953550a 11063static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11064{
11065 struct alc_spec *spec = codec->spec;
489008cd 11066 hda_nid_t pin, dac;
5855fb80 11067 int i;
9c7f852e 11068
0a3fabe3
DH
11069 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11070 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11071 pin = spec->autocfg.hp_pins[i];
11072 if (!pin)
11073 break;
11074 dac = spec->multiout.hp_nid;
11075 if (!dac)
11076 dac = spec->multiout.dac_nids[0]; /* to front */
11077 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11078 }
489008cd 11079 }
0a3fabe3
DH
11080
11081 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11082 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11083 pin = spec->autocfg.speaker_pins[i];
11084 if (!pin)
11085 break;
11086 dac = spec->multiout.extra_out_nid[0];
11087 if (!dac)
11088 dac = spec->multiout.dac_nids[0]; /* to front */
11089 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11090 }
489008cd 11091 }
9c7f852e
TI
11092}
11093
4953550a 11094static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11095{
11096 struct alc_spec *spec = codec->spec;
66ceeb6b 11097 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11098 int i;
11099
66ceeb6b
TI
11100 for (i = 0; i < cfg->num_inputs; i++) {
11101 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11102 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11103 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11104 snd_hda_codec_write(codec, nid, 0,
11105 AC_VERB_SET_AMP_GAIN_MUTE,
11106 AMP_OUT_MUTE);
11107 }
11108}
11109
11110static void alc882_auto_init_input_src(struct hda_codec *codec)
11111{
11112 struct alc_spec *spec = codec->spec;
11113 int c;
11114
11115 for (c = 0; c < spec->num_adc_nids; c++) {
11116 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11117 hda_nid_t nid = spec->capsrc_nids[c];
11118 unsigned int mux_idx;
11119 const struct hda_input_mux *imux;
11120 int conns, mute, idx, item;
11121
10696aa0
TI
11122 /* mute ADC */
11123 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11124 AC_VERB_SET_AMP_GAIN_MUTE,
11125 AMP_IN_MUTE(0));
11126
4953550a
TI
11127 conns = snd_hda_get_connections(codec, nid, conn_list,
11128 ARRAY_SIZE(conn_list));
11129 if (conns < 0)
11130 continue;
11131 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11132 imux = &spec->input_mux[mux_idx];
5311114d
TI
11133 if (!imux->num_items && mux_idx > 0)
11134 imux = &spec->input_mux[0];
4953550a
TI
11135 for (idx = 0; idx < conns; idx++) {
11136 /* if the current connection is the selected one,
11137 * unmute it as default - otherwise mute it
11138 */
11139 mute = AMP_IN_MUTE(idx);
11140 for (item = 0; item < imux->num_items; item++) {
11141 if (imux->items[item].index == idx) {
11142 if (spec->cur_mux[c] == item)
11143 mute = AMP_IN_UNMUTE(idx);
11144 break;
11145 }
11146 }
11147 /* check if we have a selector or mixer
11148 * we could check for the widget type instead, but
11149 * just check for Amp-In presence (in case of mixer
11150 * without amp-in there is something wrong, this
11151 * function shouldn't be used or capsrc nid is wrong)
11152 */
11153 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11154 snd_hda_codec_write(codec, nid, 0,
11155 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11156 mute);
11157 else if (mute != AMP_IN_MUTE(idx))
11158 snd_hda_codec_write(codec, nid, 0,
11159 AC_VERB_SET_CONNECT_SEL,
11160 idx);
9c7f852e
TI
11161 }
11162 }
11163}
11164
4953550a
TI
11165/* add mic boosts if needed */
11166static int alc_auto_add_mic_boost(struct hda_codec *codec)
11167{
11168 struct alc_spec *spec = codec->spec;
66ceeb6b 11169 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11170 int i, err;
53e8c323 11171 int type_idx = 0;
4953550a 11172 hda_nid_t nid;
5322bf27 11173 const char *prev_label = NULL;
4953550a 11174
66ceeb6b 11175 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11176 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11177 break;
11178 nid = cfg->inputs[i].pin;
11179 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11180 const char *label;
11181 char boost_label[32];
11182
11183 label = hda_get_autocfg_input_label(codec, cfg, i);
11184 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11185 type_idx++;
11186 else
11187 type_idx = 0;
5322bf27
DH
11188 prev_label = label;
11189
11190 snprintf(boost_label, sizeof(boost_label),
11191 "%s Boost Volume", label);
11192 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11193 boost_label, type_idx,
4953550a 11194 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11195 if (err < 0)
11196 return err;
11197 }
4953550a
TI
11198 }
11199 return 0;
11200}
f511b01c 11201
9c7f852e 11202/* almost identical with ALC880 parser... */
4953550a 11203static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11204{
11205 struct alc_spec *spec = codec->spec;
4c6d72d1 11206 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11207 int err;
9c7f852e 11208
05f5f477
TI
11209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11210 alc882_ignore);
9c7f852e
TI
11211 if (err < 0)
11212 return err;
05f5f477
TI
11213 if (!spec->autocfg.line_outs)
11214 return 0; /* can't find valid BIOS pin config */
776e184e 11215
05f5f477 11216 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11217 if (err < 0)
11218 return err;
11219 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11220 if (err < 0)
11221 return err;
569ed348 11222 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11223 if (err < 0)
11224 return err;
11225 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11226 "Headphone");
05f5f477
TI
11227 if (err < 0)
11228 return err;
11229 err = alc880_auto_create_extra_out(spec,
11230 spec->autocfg.speaker_pins[0],
11231 "Speaker");
11232 if (err < 0)
11233 return err;
05f5f477 11234 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11235 if (err < 0)
11236 return err;
11237
05f5f477
TI
11238 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11239
757899ac 11240 alc_auto_parse_digital(codec);
05f5f477
TI
11241
11242 if (spec->kctls.list)
11243 add_mixer(spec, spec->kctls.list);
11244
11245 add_verb(spec, alc883_auto_init_verbs);
4953550a 11246 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11247 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11248 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11249
05f5f477
TI
11250 spec->num_mux_defs = 1;
11251 spec->input_mux = &spec->private_imux[0];
11252
6227cdce 11253 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11254
11255 err = alc_auto_add_mic_boost(codec);
11256 if (err < 0)
11257 return err;
61b9b9b1 11258
776e184e 11259 return 1; /* config found */
9c7f852e
TI
11260}
11261
11262/* additional initialization for auto-configuration model */
4953550a 11263static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11264{
f6c7e546 11265 struct alc_spec *spec = codec->spec;
4953550a
TI
11266 alc882_auto_init_multi_out(codec);
11267 alc882_auto_init_hp_out(codec);
11268 alc882_auto_init_analog_input(codec);
11269 alc882_auto_init_input_src(codec);
757899ac 11270 alc_auto_init_digital(codec);
f6c7e546 11271 if (spec->unsol_event)
7fb0d78f 11272 alc_inithook(codec);
9c7f852e
TI
11273}
11274
4953550a 11275static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11276{
11277 struct alc_spec *spec;
11278 int err, board_config;
11279
11280 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11281 if (spec == NULL)
11282 return -ENOMEM;
11283
11284 codec->spec = spec;
11285
4953550a
TI
11286 switch (codec->vendor_id) {
11287 case 0x10ec0882:
11288 case 0x10ec0885:
11289 break;
11290 default:
11291 /* ALC883 and variants */
11292 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11293 break;
11294 }
2c3bf9ab 11295
4953550a
TI
11296 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11297 alc882_models,
11298 alc882_cfg_tbl);
11299
11300 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11301 board_config = snd_hda_check_board_codec_sid_config(codec,
11302 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11303
11304 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11305 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11306 codec->chip_name);
11307 board_config = ALC882_AUTO;
9c7f852e
TI
11308 }
11309
b5bfbc67
TI
11310 if (board_config == ALC882_AUTO) {
11311 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11312 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11313 }
4953550a 11314
90622917
DH
11315 alc_auto_parse_customize_define(codec);
11316
4953550a 11317 if (board_config == ALC882_AUTO) {
9c7f852e 11318 /* automatic parse from the BIOS config */
4953550a 11319 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11320 if (err < 0) {
11321 alc_free(codec);
11322 return err;
f12ab1e0 11323 } else if (!err) {
9c7f852e
TI
11324 printk(KERN_INFO
11325 "hda_codec: Cannot set up configuration "
11326 "from BIOS. Using base mode...\n");
4953550a 11327 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11328 }
11329 }
11330
dc1eae25 11331 if (has_cdefine_beep(codec)) {
8af2591d
TI
11332 err = snd_hda_attach_beep_device(codec, 0x1);
11333 if (err < 0) {
11334 alc_free(codec);
11335 return err;
11336 }
680cd536
KK
11337 }
11338
4953550a 11339 if (board_config != ALC882_AUTO)
e9c364c0 11340 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11341
4953550a
TI
11342 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11343 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11344 /* FIXME: setup DAC5 */
11345 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11346 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11347
11348 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11349 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11350
4953550a 11351 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11352 int i, j;
4953550a
TI
11353 spec->num_adc_nids = 0;
11354 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11355 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11356 hda_nid_t cap;
d11f74c6 11357 hda_nid_t items[16];
4953550a
TI
11358 hda_nid_t nid = alc882_adc_nids[i];
11359 unsigned int wcap = get_wcaps(codec, nid);
11360 /* get type */
a22d543a 11361 wcap = get_wcaps_type(wcap);
4953550a
TI
11362 if (wcap != AC_WID_AUD_IN)
11363 continue;
11364 spec->private_adc_nids[spec->num_adc_nids] = nid;
11365 err = snd_hda_get_connections(codec, nid, &cap, 1);
11366 if (err < 0)
11367 continue;
d11f74c6
TI
11368 err = snd_hda_get_connections(codec, cap, items,
11369 ARRAY_SIZE(items));
11370 if (err < 0)
11371 continue;
11372 for (j = 0; j < imux->num_items; j++)
11373 if (imux->items[j].index >= err)
11374 break;
11375 if (j < imux->num_items)
11376 continue;
4953550a
TI
11377 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11378 spec->num_adc_nids++;
61b9b9b1 11379 }
4953550a
TI
11380 spec->adc_nids = spec->private_adc_nids;
11381 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11382 }
11383
b59bdf3b 11384 set_capture_mixer(codec);
da00c244 11385
dc1eae25 11386 if (has_cdefine_beep(codec))
da00c244 11387 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11388
b5bfbc67 11389 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11390
2134ea4f
TI
11391 spec->vmaster_nid = 0x0c;
11392
9c7f852e 11393 codec->patch_ops = alc_patch_ops;
4953550a
TI
11394 if (board_config == ALC882_AUTO)
11395 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11396
11397 alc_init_jacks(codec);
cb53c626
TI
11398#ifdef CONFIG_SND_HDA_POWER_SAVE
11399 if (!spec->loopback.amplist)
4953550a 11400 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11401#endif
9c7f852e
TI
11402
11403 return 0;
11404}
11405
4953550a 11406
9c7f852e
TI
11407/*
11408 * ALC262 support
11409 */
11410
11411#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11412#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11413
11414#define alc262_dac_nids alc260_dac_nids
11415#define alc262_adc_nids alc882_adc_nids
11416#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11417#define alc262_capsrc_nids alc882_capsrc_nids
11418#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11419
11420#define alc262_modes alc260_modes
11421#define alc262_capture_source alc882_capture_source
11422
4c6d72d1 11423static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11424 /* ADC0 */
11425 0x09
11426};
11427
4c6d72d1 11428static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11429
a9111321 11430static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11431 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11432 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11434 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11439 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11442 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11443 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11447 { } /* end */
11448};
11449
ce875f07 11450/* update HP, line and mono-out pins according to the master switch */
e9427969 11451#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11452
e9427969 11453static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11454{
11455 struct alc_spec *spec = codec->spec;
864f92be 11456
e9427969
TI
11457 spec->autocfg.hp_pins[0] = 0x1b;
11458 spec->autocfg.speaker_pins[0] = 0x16;
11459 spec->automute = 1;
11460 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11461}
11462
e9427969 11463static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11464{
11465 struct alc_spec *spec = codec->spec;
864f92be 11466
e9427969
TI
11467 spec->autocfg.hp_pins[0] = 0x15;
11468 spec->autocfg.speaker_pins[0] = 0x16;
11469 spec->automute = 1;
11470 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11471}
11472
b72519b5 11473#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11474#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11475
b72519b5
TI
11476#define ALC262_HP_MASTER_SWITCH \
11477 { \
11478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11479 .name = "Master Playback Switch", \
11480 .info = snd_ctl_boolean_mono_info, \
11481 .get = alc262_hp_master_sw_get, \
11482 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11483 }, \
11484 { \
11485 .iface = NID_MAPPING, \
11486 .name = "Master Playback Switch", \
11487 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11488 }
11489
5b0cb1d8 11490
a9111321 11491static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11492 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11494 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11496 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11497 HDA_OUTPUT),
11498 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11499 HDA_OUTPUT),
9c7f852e
TI
11500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11503 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11505 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11510 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11511 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11512 { } /* end */
11513};
11514
a9111321 11515static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11516 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11518 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11521 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11522 HDA_OUTPUT),
11523 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11524 HDA_OUTPUT),
cd7509a4
KY
11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11528 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11529 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11532 { } /* end */
11533};
11534
a9111321 11535static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11536 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11537 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11538 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11539 { } /* end */
11540};
11541
66d2a9d6 11542/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11543static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11544{
11545 struct alc_spec *spec = codec->spec;
66d2a9d6 11546
a9fd4f3f 11547 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11548 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11549 spec->automute = 1;
11550 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11551}
11552
a9111321 11553static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11561 { } /* end */
11562};
11563
a9111321 11564static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11567
11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11569 { }
11570};
11571
a9111321 11572static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11576 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11579 { } /* end */
11580};
11581
a9111321 11582static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11584 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11586 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11593 {}
11594};
11595
a9111321 11596static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11597 .num_items = 1,
11598 .items = {
11599 { "Line", 0x1 },
11600 },
11601};
11602
42171c17 11603/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11604#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11605#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11606#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11607
11608#define ALC262_HIPPO_MASTER_SWITCH \
11609 { \
11610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11611 .name = "Master Playback Switch", \
11612 .info = snd_ctl_boolean_mono_info, \
11613 .get = alc262_hippo_master_sw_get, \
11614 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11615 }, \
11616 { \
11617 .iface = NID_MAPPING, \
11618 .name = "Master Playback Switch", \
11619 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11620 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11621 }
42171c17 11622
a9111321 11623static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11624 ALC262_HIPPO_MASTER_SWITCH,
11625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11632 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11635 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11637 { } /* end */
11638};
11639
a9111321 11640static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11641 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11642 ALC262_HIPPO_MASTER_SWITCH,
11643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11649 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11652 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11653 { } /* end */
11654};
11655
11656/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11657static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11658{
11659 struct alc_spec *spec = codec->spec;
11660
11661 spec->autocfg.hp_pins[0] = 0x15;
11662 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11663 spec->automute = 1;
11664 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11665}
11666
4f5d1706 11667static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11668{
11669 struct alc_spec *spec = codec->spec;
11670
11671 spec->autocfg.hp_pins[0] = 0x1b;
11672 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11673 spec->automute = 1;
11674 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11675}
11676
11677
a9111321 11678static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11679 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11680 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11683 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11684 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11685 { } /* end */
11686};
11687
a9111321 11688static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11689 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11690 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11695 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11696 { } /* end */
11697};
272a527c 11698
a9111321 11699static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11700 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11701 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11702 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11703 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11708 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11709 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11711 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11712 { } /* end */
11713};
11714
a9111321 11715static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11716 /* Headphone automute */
11717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11720
11721 /* P11 AUX_IN, white 4-pin connector */
11722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11723 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11724 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11725 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11726
11727 {}
11728};
11729
11730/* unsolicited event for HP jack sensing */
4f5d1706 11731static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11732{
a9fd4f3f 11733 struct alc_spec *spec = codec->spec;
ba340e82 11734
a9fd4f3f
TI
11735 spec->autocfg.hp_pins[0] = 0x1b;
11736 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11737 spec->automute = 1;
11738 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11739}
11740
ba340e82 11741
9c7f852e
TI
11742#define alc262_capture_mixer alc882_capture_mixer
11743#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11744
11745/*
11746 * generic initialization of ADC, input mixers and output mixers
11747 */
a9111321 11748static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11749 /*
11750 * Unmute ADC0-2 and set the default input to mic-in
11751 */
11752 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11754 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11756 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11757 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11758
cb53c626 11759 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11760 * mixer widget
f12ab1e0
TI
11761 * Note: PASD motherboards uses the Line In 2 as the input for
11762 * front panel mic (mic 2)
9c7f852e
TI
11763 */
11764 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11770
11771 /*
df694daa
KY
11772 * Set up output mixers (0x0c - 0x0e)
11773 */
11774 /* set vol=0 to output mixers */
11775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11778 /* set up input amps for analog loopback */
11779 /* Amp Indices: DAC = 0, mixer = 1 */
11780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11786
11787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11792 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11793
11794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11797 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11799
df694daa
KY
11800 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11802
df694daa
KY
11803 /* FIXME: use matrix-type input source selection */
11804 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11805 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11810 /* Input mixer2 */
11811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11815 /* Input mixer3 */
11816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11820
11821 { }
11822};
1da177e4 11823
a9111321 11824static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11827 { }
11828};
11829
a9111321 11830static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11832 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11834
11835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11837 {}
11838};
11839
a9111321 11840static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11844
11845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11847 {}
272a527c
KY
11848};
11849
a9111321 11850static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11852 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11856 { } /* end */
11857};
11858
a9111321 11859static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11864 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11865 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11868 {}
11869};
11870
4f5d1706 11871static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11872{
a9fd4f3f
TI
11873 struct alc_spec *spec = codec->spec;
11874
11875 spec->autocfg.hp_pins[0] = 0x15;
11876 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11877 spec->ext_mic.pin = 0x18;
11878 spec->ext_mic.mux_idx = 0;
11879 spec->int_mic.pin = 0x12;
11880 spec->int_mic.mux_idx = 9;
11881 spec->auto_mic = 1;
d922b51d
TI
11882 spec->automute = 1;
11883 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11884}
11885
e8f9ae2a
PT
11886/*
11887 * nec model
11888 * 0x15 = headphone
11889 * 0x16 = internal speaker
11890 * 0x18 = external mic
11891 */
11892
a9111321 11893static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11895 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11896
11897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11899 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11900
11901 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11903 { } /* end */
11904};
11905
a9111321 11906static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11907 /* Unmute Speaker */
11908 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11909
11910 /* Headphone */
11911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11913
11914 /* External mic to headphone */
11915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11916 /* External mic to speaker */
11917 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11918 {}
11919};
11920
834be88d
TI
11921/*
11922 * fujitsu model
5d9fab2d
TV
11923 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11924 * 0x1b = port replicator headphone out
834be88d
TI
11925 */
11926
20f5e0b3 11927#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11928
a9111321 11929static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11930 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11934 {}
11935};
11936
a9111321 11937static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11940 {}
11941};
11942
a9111321 11943static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11944 /* Front Mic pin: input vref at 50% */
11945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11947 {}
11948};
11949
a9111321 11950static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11951 .num_items = 3,
834be88d
TI
11952 .items = {
11953 { "Mic", 0x0 },
28c4edb7 11954 { "Internal Mic", 0x1 },
834be88d
TI
11955 { "CD", 0x4 },
11956 },
11957};
11958
a9111321 11959static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11960 .num_items = 5,
11961 .items = {
11962 { "Mic", 0x0 },
accbe498 11963 { "Front Mic", 0x1 },
9c7f852e
TI
11964 { "Line", 0x2 },
11965 { "CD", 0x4 },
11966 { "AUX IN", 0x6 },
11967 },
11968};
11969
a9111321 11970static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11971 .num_items = 4,
11972 .items = {
11973 { "Mic", 0x0 },
11974 { "Front Mic", 0x2 },
11975 { "Line", 0x1 },
11976 { "CD", 0x4 },
11977 },
11978};
11979
0f0f391c 11980static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11981{
11982 struct alc_spec *spec = codec->spec;
834be88d 11983
0f0f391c
TI
11984 spec->autocfg.hp_pins[0] = 0x14;
11985 spec->autocfg.hp_pins[1] = 0x1b;
11986 spec->autocfg.speaker_pins[0] = 0x15;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11989}
11990
834be88d 11991/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11992static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11993 .ops = &snd_hda_bind_vol,
11994 .values = {
11995 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11996 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11997 0
11998 },
11999};
834be88d 12000
a9111321 12001static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 12002 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
12003 {
12004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12005 .name = "Master Playback Switch",
0f0f391c
TI
12006 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12007 .info = snd_ctl_boolean_mono_info,
12008 .get = alc262_hp_master_sw_get,
12009 .put = alc262_hp_master_sw_put,
834be88d 12010 },
5b0cb1d8
JK
12011 {
12012 .iface = NID_MAPPING,
12013 .name = "Master Playback Switch",
12014 .private_value = 0x1b,
12015 },
834be88d
TI
12016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12018 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
12019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12022 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
12024 { } /* end */
12025};
12026
0f0f391c 12027static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 12028{
0f0f391c 12029 struct alc_spec *spec = codec->spec;
0e31daf7 12030
0f0f391c
TI
12031 spec->autocfg.hp_pins[0] = 0x1b;
12032 spec->autocfg.speaker_pins[0] = 0x14;
12033 spec->autocfg.speaker_pins[1] = 0x16;
12034 spec->automute = 1;
12035 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
12036}
12037
a9111321 12038static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
12039 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12040 {
12041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12042 .name = "Master Playback Switch",
0f0f391c
TI
12043 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12044 .info = snd_ctl_boolean_mono_info,
12045 .get = alc262_hp_master_sw_get,
12046 .put = alc262_hp_master_sw_put,
0e31daf7
J
12047 },
12048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12050 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12053 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12054 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12055 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12056 { } /* end */
12057};
12058
a9111321 12059static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12060 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12061 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12067 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12068 { } /* end */
12069};
12070
304dcaac 12071/* additional init verbs for Benq laptops */
a9111321 12072static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12073 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12074 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12075 {}
12076};
12077
a9111321 12078static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12079 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12081
12082 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12083 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12084 {}
12085};
12086
f651b50b 12087/* Samsung Q1 Ultra Vista model setup */
a9111321 12088static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12089 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12090 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12094 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12095 { } /* end */
12096};
12097
a9111321 12098static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12099 /* output mixer */
12100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12103 /* speaker */
12104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12108 /* HP */
f651b50b 12109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12114 /* internal mic */
12115 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12117 /* ADC, choose mic */
12118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12128 {}
12129};
12130
f651b50b
TD
12131/* mute/unmute internal speaker according to the hp jack and mute state */
12132static void alc262_ultra_automute(struct hda_codec *codec)
12133{
12134 struct alc_spec *spec = codec->spec;
12135 unsigned int mute;
f651b50b 12136
bb9f76cd
TI
12137 mute = 0;
12138 /* auto-mute only when HP is used as HP */
12139 if (!spec->cur_mux[0]) {
864f92be 12140 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12141 if (spec->jack_present)
12142 mute = HDA_AMP_MUTE;
f651b50b 12143 }
bb9f76cd
TI
12144 /* mute/unmute internal speaker */
12145 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12146 HDA_AMP_MUTE, mute);
12147 /* mute/unmute HP */
12148 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12149 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12150}
12151
12152/* unsolicited event for HP jack sensing */
12153static void alc262_ultra_unsol_event(struct hda_codec *codec,
12154 unsigned int res)
12155{
12156 if ((res >> 26) != ALC880_HP_EVENT)
12157 return;
12158 alc262_ultra_automute(codec);
12159}
12160
a9111321 12161static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12162 .num_items = 2,
12163 .items = {
12164 { "Mic", 0x1 },
12165 { "Headphone", 0x7 },
12166 },
12167};
12168
12169static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12170 struct snd_ctl_elem_value *ucontrol)
12171{
12172 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12173 struct alc_spec *spec = codec->spec;
12174 int ret;
12175
54cbc9ab 12176 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12177 if (!ret)
12178 return 0;
12179 /* reprogram the HP pin as mic or HP according to the input source */
12180 snd_hda_codec_write_cache(codec, 0x15, 0,
12181 AC_VERB_SET_PIN_WIDGET_CONTROL,
12182 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12183 alc262_ultra_automute(codec); /* mute/unmute HP */
12184 return ret;
12185}
12186
a9111321 12187static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12188 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12189 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12190 {
12191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12192 .name = "Capture Source",
54cbc9ab
TI
12193 .info = alc_mux_enum_info,
12194 .get = alc_mux_enum_get,
bb9f76cd
TI
12195 .put = alc262_ultra_mux_enum_put,
12196 },
5b0cb1d8
JK
12197 {
12198 .iface = NID_MAPPING,
12199 .name = "Capture Source",
12200 .private_value = 0x15,
12201 },
bb9f76cd
TI
12202 { } /* end */
12203};
12204
c3fc1f50
TI
12205/* We use two mixers depending on the output pin; 0x16 is a mono output
12206 * and thus it's bound with a different mixer.
12207 * This function returns which mixer amp should be used.
12208 */
12209static int alc262_check_volbit(hda_nid_t nid)
12210{
12211 if (!nid)
12212 return 0;
12213 else if (nid == 0x16)
12214 return 2;
12215 else
12216 return 1;
12217}
12218
12219static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12220 const char *pfx, int *vbits, int idx)
c3fc1f50 12221{
c3fc1f50
TI
12222 unsigned long val;
12223 int vbit;
12224
12225 vbit = alc262_check_volbit(nid);
12226 if (!vbit)
12227 return 0;
12228 if (*vbits & vbit) /* a volume control for this mixer already there */
12229 return 0;
12230 *vbits |= vbit;
c3fc1f50
TI
12231 if (vbit == 2)
12232 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12233 else
12234 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12235 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12236}
12237
12238static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12239 const char *pfx, int idx)
c3fc1f50 12240{
c3fc1f50
TI
12241 unsigned long val;
12242
12243 if (!nid)
12244 return 0;
c3fc1f50
TI
12245 if (nid == 0x16)
12246 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12247 else
12248 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12249 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12250}
12251
df694daa 12252/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12253static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12254 const struct auto_pin_cfg *cfg)
df694daa 12255{
c3fc1f50
TI
12256 const char *pfx;
12257 int vbits;
033688a5 12258 int i, err;
df694daa
KY
12259
12260 spec->multiout.num_dacs = 1; /* only use one dac */
12261 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12262 spec->private_dac_nids[0] = 2;
df694daa 12263
ce764ab2 12264 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12265 if (!pfx)
c3fc1f50 12266 pfx = "Front";
033688a5
TI
12267 for (i = 0; i < 2; i++) {
12268 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12269 if (err < 0)
12270 return err;
12271 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12272 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12273 "Speaker", i);
12274 if (err < 0)
12275 return err;
12276 }
12277 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12278 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12279 "Headphone", i);
12280 if (err < 0)
12281 return err;
12282 }
12283 }
df694daa 12284
c3fc1f50
TI
12285 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12286 alc262_check_volbit(cfg->speaker_pins[0]) |
12287 alc262_check_volbit(cfg->hp_pins[0]);
12288 if (vbits == 1 || vbits == 2)
12289 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12290 vbits = 0;
033688a5
TI
12291 for (i = 0; i < 2; i++) {
12292 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12293 &vbits, i);
12294 if (err < 0)
12295 return err;
12296 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12297 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12298 "Speaker", &vbits, i);
12299 if (err < 0)
12300 return err;
12301 }
12302 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12303 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12304 "Headphone", &vbits, i);
12305 if (err < 0)
12306 return err;
12307 }
12308 }
f12ab1e0 12309 return 0;
df694daa
KY
12310}
12311
05f5f477 12312#define alc262_auto_create_input_ctls \
eaa9b3a7 12313 alc882_auto_create_input_ctls
df694daa
KY
12314
12315/*
12316 * generic initialization of ADC, input mixers and output mixers
12317 */
a9111321 12318static const struct hda_verb alc262_volume_init_verbs[] = {
df694daa
KY
12319 /*
12320 * Unmute ADC0-2 and set the default input to mic-in
12321 */
12322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12328
cb53c626 12329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12330 * mixer widget
f12ab1e0
TI
12331 * Note: PASD motherboards uses the Line In 2 as the input for
12332 * front panel mic (mic 2)
df694daa
KY
12333 */
12334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12340
12341 /*
12342 * Set up output mixers (0x0c - 0x0f)
12343 */
12344 /* set vol=0 to output mixers */
12345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12348
df694daa
KY
12349 /* set up input amps for analog loopback */
12350 /* Amp Indices: DAC = 0, mixer = 1 */
12351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12357
12358 /* FIXME: use matrix-type input source selection */
12359 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12360 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12365 /* Input mixer2 */
12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12370 /* Input mixer3 */
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12375
12376 { }
12377};
12378
a9111321 12379static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12380 /*
12381 * Unmute ADC0-2 and set the default input to mic-in
12382 */
12383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12385 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389
cb53c626 12390 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12391 * mixer widget
f12ab1e0
TI
12392 * Note: PASD motherboards uses the Line In 2 as the input for
12393 * front panel mic (mic 2)
9c7f852e
TI
12394 */
12395 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12403
9c7f852e
TI
12404 /*
12405 * Set up output mixers (0x0c - 0x0e)
12406 */
12407 /* set vol=0 to output mixers */
12408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411
12412 /* set up input amps for analog loopback */
12413 /* Amp Indices: DAC = 0, mixer = 1 */
12414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420
ce875f07 12421 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12424
12425 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427
12428 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12429 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12430
12431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12435 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12436
0e4835c1 12437 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12438 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12441 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443
12444
12445 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12447 /* Input mixer1: only unmute Mic */
9c7f852e 12448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12457 /* Input mixer2 */
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12467 /* Input mixer3 */
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12477
ce875f07
TI
12478 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12479
9c7f852e
TI
12480 { }
12481};
12482
a9111321 12483static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12484 /*
12485 * Unmute ADC0-2 and set the default input to mic-in
12486 */
12487 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12493
cb53c626 12494 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12495 * mixer widget
12496 * Note: PASD motherboards uses the Line In 2 as the input for front
12497 * panel mic (mic 2)
12498 */
12499 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12508 /*
12509 * Set up output mixers (0x0c - 0x0e)
12510 */
12511 /* set vol=0 to output mixers */
12512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12515
12516 /* set up input amps for analog loopback */
12517 /* Amp Indices: DAC = 0, mixer = 1 */
12518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12524
12525
12526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12529 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12532 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12533
12534 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12535 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536
12537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12538 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12539
12540 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12545 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12546
12547 /* FIXME: use matrix-type input source selection */
12548 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12549 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12555 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12557 /* Input mixer2 */
12558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12563 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12565 /* Input mixer3 */
12566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12571 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12573
ce875f07
TI
12574 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12575
cd7509a4
KY
12576 { }
12577};
12578
a9111321 12579static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12580
12581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12584
12585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12589
12590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12593 {}
12594};
12595
18675e42
TI
12596/*
12597 * Pin config fixes
12598 */
12599enum {
12600 PINFIX_FSC_H270,
12601};
12602
12603static const struct alc_fixup alc262_fixups[] = {
12604 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12605 .type = ALC_FIXUP_PINS,
12606 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12607 { 0x14, 0x99130110 }, /* speaker */
12608 { 0x15, 0x0221142f }, /* front HP */
12609 { 0x1b, 0x0121141f }, /* rear HP */
12610 { }
12611 }
12612 },
18675e42
TI
12613};
12614
a9111321 12615static const struct snd_pci_quirk alc262_fixup_tbl[] = {
18675e42
TI
12616 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12617 {}
12618};
12619
9f99a638 12620
cb53c626
TI
12621#ifdef CONFIG_SND_HDA_POWER_SAVE
12622#define alc262_loopbacks alc880_loopbacks
12623#endif
12624
def319f9 12625/* pcm configuration: identical with ALC880 */
df694daa
KY
12626#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12627#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12628#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12629#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12630
12631/*
12632 * BIOS auto configuration
12633 */
12634static int alc262_parse_auto_config(struct hda_codec *codec)
12635{
12636 struct alc_spec *spec = codec->spec;
12637 int err;
4c6d72d1 12638 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12639
f12ab1e0
TI
12640 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12641 alc262_ignore);
12642 if (err < 0)
df694daa 12643 return err;
e64f14f4 12644 if (!spec->autocfg.line_outs) {
0852d7a6 12645 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12646 spec->multiout.max_channels = 2;
12647 spec->no_analog = 1;
12648 goto dig_only;
12649 }
df694daa 12650 return 0; /* can't find valid BIOS pin config */
e64f14f4 12651 }
f12ab1e0
TI
12652 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12653 if (err < 0)
12654 return err;
05f5f477 12655 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12656 if (err < 0)
df694daa
KY
12657 return err;
12658
12659 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12660
e64f14f4 12661 dig_only:
757899ac 12662 alc_auto_parse_digital(codec);
df694daa 12663
603c4019 12664 if (spec->kctls.list)
d88897ea 12665 add_mixer(spec, spec->kctls.list);
df694daa 12666
d88897ea 12667 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12668 spec->num_mux_defs = 1;
61b9b9b1 12669 spec->input_mux = &spec->private_imux[0];
df694daa 12670
776e184e
TI
12671 err = alc_auto_add_mic_boost(codec);
12672 if (err < 0)
12673 return err;
12674
6227cdce 12675 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12676
df694daa
KY
12677 return 1;
12678}
12679
12680#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12681#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12682#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12683#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12684
12685
12686/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12687static void alc262_auto_init(struct hda_codec *codec)
df694daa 12688{
f6c7e546 12689 struct alc_spec *spec = codec->spec;
df694daa
KY
12690 alc262_auto_init_multi_out(codec);
12691 alc262_auto_init_hp_out(codec);
12692 alc262_auto_init_analog_input(codec);
f511b01c 12693 alc262_auto_init_input_src(codec);
757899ac 12694 alc_auto_init_digital(codec);
f6c7e546 12695 if (spec->unsol_event)
7fb0d78f 12696 alc_inithook(codec);
df694daa
KY
12697}
12698
12699/*
12700 * configuration and preset
12701 */
ea734963 12702static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12703 [ALC262_BASIC] = "basic",
12704 [ALC262_HIPPO] = "hippo",
12705 [ALC262_HIPPO_1] = "hippo_1",
12706 [ALC262_FUJITSU] = "fujitsu",
12707 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12708 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12709 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12710 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12711 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12712 [ALC262_BENQ_T31] = "benq-t31",
12713 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12714 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12715 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12716 [ALC262_ULTRA] = "ultra",
0e31daf7 12717 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12718 [ALC262_NEC] = "nec",
ba340e82 12719 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12720 [ALC262_AUTO] = "auto",
12721};
12722
a9111321 12723static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12724 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12725 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12726 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12727 ALC262_HP_BPC),
12728 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12729 ALC262_HP_BPC),
5734a07c
TI
12730 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12731 ALC262_HP_BPC),
53eff7e1
TI
12732 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12733 ALC262_HP_BPC),
cd7509a4 12734 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12735 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12736 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12737 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12738 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12739 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12740 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12741 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12742 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12743 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12744 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12745 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12746 ALC262_HP_TC_T5735),
8c427226 12747 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12748 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12749 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12750 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12751 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12752 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12753 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12754 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12755#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12756 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12757 ALC262_SONY_ASSAMD),
c5b5165c 12758#endif
36ca6e13 12759 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12760 ALC262_TOSHIBA_RX1),
80ffe869 12761 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12762 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12763 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12764 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12765 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12766 ALC262_ULTRA),
3e420e78 12767 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12768 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12769 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12770 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12771 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12772 {}
12773};
12774
a9111321 12775static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12776 [ALC262_BASIC] = {
12777 .mixers = { alc262_base_mixer },
12778 .init_verbs = { alc262_init_verbs },
12779 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12780 .dac_nids = alc262_dac_nids,
12781 .hp_nid = 0x03,
12782 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12783 .channel_mode = alc262_modes,
a3bcba38 12784 .input_mux = &alc262_capture_source,
df694daa 12785 },
ccc656ce 12786 [ALC262_HIPPO] = {
42171c17 12787 .mixers = { alc262_hippo_mixer },
6732bd0d 12788 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12789 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12790 .dac_nids = alc262_dac_nids,
12791 .hp_nid = 0x03,
12792 .dig_out_nid = ALC262_DIGOUT_NID,
12793 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12794 .channel_mode = alc262_modes,
12795 .input_mux = &alc262_capture_source,
e9427969 12796 .unsol_event = alc_sku_unsol_event,
4f5d1706 12797 .setup = alc262_hippo_setup,
e9427969 12798 .init_hook = alc_inithook,
ccc656ce
KY
12799 },
12800 [ALC262_HIPPO_1] = {
12801 .mixers = { alc262_hippo1_mixer },
12802 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12804 .dac_nids = alc262_dac_nids,
12805 .hp_nid = 0x02,
12806 .dig_out_nid = ALC262_DIGOUT_NID,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
e9427969 12810 .unsol_event = alc_sku_unsol_event,
4f5d1706 12811 .setup = alc262_hippo1_setup,
e9427969 12812 .init_hook = alc_inithook,
ccc656ce 12813 },
834be88d
TI
12814 [ALC262_FUJITSU] = {
12815 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12816 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12817 alc262_fujitsu_unsol_verbs },
834be88d
TI
12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819 .dac_nids = alc262_dac_nids,
12820 .hp_nid = 0x03,
12821 .dig_out_nid = ALC262_DIGOUT_NID,
12822 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12823 .channel_mode = alc262_modes,
12824 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12825 .unsol_event = alc_sku_unsol_event,
12826 .setup = alc262_fujitsu_setup,
12827 .init_hook = alc_inithook,
834be88d 12828 },
9c7f852e
TI
12829 [ALC262_HP_BPC] = {
12830 .mixers = { alc262_HP_BPC_mixer },
12831 .init_verbs = { alc262_HP_BPC_init_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .dac_nids = alc262_dac_nids,
12834 .hp_nid = 0x03,
12835 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12836 .channel_mode = alc262_modes,
12837 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12838 .unsol_event = alc_sku_unsol_event,
12839 .setup = alc262_hp_bpc_setup,
12840 .init_hook = alc_inithook,
f12ab1e0 12841 },
cd7509a4
KY
12842 [ALC262_HP_BPC_D7000_WF] = {
12843 .mixers = { alc262_HP_BPC_WildWest_mixer },
12844 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12845 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12846 .dac_nids = alc262_dac_nids,
12847 .hp_nid = 0x03,
12848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12849 .channel_mode = alc262_modes,
accbe498 12850 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12851 .unsol_event = alc_sku_unsol_event,
12852 .setup = alc262_hp_wildwest_setup,
12853 .init_hook = alc_inithook,
f12ab1e0 12854 },
cd7509a4
KY
12855 [ALC262_HP_BPC_D7000_WL] = {
12856 .mixers = { alc262_HP_BPC_WildWest_mixer,
12857 alc262_HP_BPC_WildWest_option_mixer },
12858 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12859 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12860 .dac_nids = alc262_dac_nids,
12861 .hp_nid = 0x03,
12862 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12863 .channel_mode = alc262_modes,
accbe498 12864 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12865 .unsol_event = alc_sku_unsol_event,
12866 .setup = alc262_hp_wildwest_setup,
12867 .init_hook = alc_inithook,
f12ab1e0 12868 },
66d2a9d6
KY
12869 [ALC262_HP_TC_T5735] = {
12870 .mixers = { alc262_hp_t5735_mixer },
12871 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12872 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12873 .dac_nids = alc262_dac_nids,
12874 .hp_nid = 0x03,
12875 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12876 .channel_mode = alc262_modes,
12877 .input_mux = &alc262_capture_source,
dc99be47 12878 .unsol_event = alc_sku_unsol_event,
4f5d1706 12879 .setup = alc262_hp_t5735_setup,
dc99be47 12880 .init_hook = alc_inithook,
8c427226
KY
12881 },
12882 [ALC262_HP_RP5700] = {
12883 .mixers = { alc262_hp_rp5700_mixer },
12884 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12885 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12886 .dac_nids = alc262_dac_nids,
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
12889 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12890 },
304dcaac
TI
12891 [ALC262_BENQ_ED8] = {
12892 .mixers = { alc262_base_mixer },
12893 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12894 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12895 .dac_nids = alc262_dac_nids,
12896 .hp_nid = 0x03,
12897 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12898 .channel_mode = alc262_modes,
12899 .input_mux = &alc262_capture_source,
f12ab1e0 12900 },
272a527c
KY
12901 [ALC262_SONY_ASSAMD] = {
12902 .mixers = { alc262_sony_mixer },
12903 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12904 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12905 .dac_nids = alc262_dac_nids,
12906 .hp_nid = 0x02,
12907 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12908 .channel_mode = alc262_modes,
12909 .input_mux = &alc262_capture_source,
e9427969 12910 .unsol_event = alc_sku_unsol_event,
4f5d1706 12911 .setup = alc262_hippo_setup,
e9427969 12912 .init_hook = alc_inithook,
83c34218
KY
12913 },
12914 [ALC262_BENQ_T31] = {
12915 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12916 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12917 alc_hp15_unsol_verbs },
83c34218
KY
12918 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12919 .dac_nids = alc262_dac_nids,
12920 .hp_nid = 0x03,
12921 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12922 .channel_mode = alc262_modes,
12923 .input_mux = &alc262_capture_source,
e9427969 12924 .unsol_event = alc_sku_unsol_event,
4f5d1706 12925 .setup = alc262_hippo_setup,
e9427969 12926 .init_hook = alc_inithook,
ea1fb29a 12927 },
f651b50b 12928 [ALC262_ULTRA] = {
f9e336f6
TI
12929 .mixers = { alc262_ultra_mixer },
12930 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12931 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12932 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12933 .dac_nids = alc262_dac_nids,
f651b50b
TD
12934 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12935 .channel_mode = alc262_modes,
12936 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12937 .adc_nids = alc262_adc_nids, /* ADC0 */
12938 .capsrc_nids = alc262_capsrc_nids,
12939 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12940 .unsol_event = alc262_ultra_unsol_event,
12941 .init_hook = alc262_ultra_automute,
12942 },
0e31daf7
J
12943 [ALC262_LENOVO_3000] = {
12944 .mixers = { alc262_lenovo_3000_mixer },
12945 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12946 alc262_lenovo_3000_unsol_verbs,
12947 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12948 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12949 .dac_nids = alc262_dac_nids,
12950 .hp_nid = 0x03,
12951 .dig_out_nid = ALC262_DIGOUT_NID,
12952 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12953 .channel_mode = alc262_modes,
12954 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12955 .unsol_event = alc_sku_unsol_event,
12956 .setup = alc262_lenovo_3000_setup,
12957 .init_hook = alc_inithook,
0e31daf7 12958 },
e8f9ae2a
PT
12959 [ALC262_NEC] = {
12960 .mixers = { alc262_nec_mixer },
12961 .init_verbs = { alc262_nec_verbs },
12962 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12963 .dac_nids = alc262_dac_nids,
12964 .hp_nid = 0x03,
12965 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12966 .channel_mode = alc262_modes,
12967 .input_mux = &alc262_capture_source,
12968 },
4e555fe5
KY
12969 [ALC262_TOSHIBA_S06] = {
12970 .mixers = { alc262_toshiba_s06_mixer },
12971 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12972 alc262_eapd_verbs },
12973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12974 .capsrc_nids = alc262_dmic_capsrc_nids,
12975 .dac_nids = alc262_dac_nids,
12976 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12977 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12978 .dig_out_nid = ALC262_DIGOUT_NID,
12979 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12980 .channel_mode = alc262_modes,
4f5d1706
TI
12981 .unsol_event = alc_sku_unsol_event,
12982 .setup = alc262_toshiba_s06_setup,
12983 .init_hook = alc_inithook,
4e555fe5 12984 },
9f99a638
HM
12985 [ALC262_TOSHIBA_RX1] = {
12986 .mixers = { alc262_toshiba_rx1_mixer },
12987 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12988 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12989 .dac_nids = alc262_dac_nids,
12990 .hp_nid = 0x03,
12991 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12992 .channel_mode = alc262_modes,
12993 .input_mux = &alc262_capture_source,
e9427969 12994 .unsol_event = alc_sku_unsol_event,
4f5d1706 12995 .setup = alc262_hippo_setup,
e9427969 12996 .init_hook = alc_inithook,
9f99a638 12997 },
ba340e82
TV
12998 [ALC262_TYAN] = {
12999 .mixers = { alc262_tyan_mixer },
13000 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13001 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13002 .dac_nids = alc262_dac_nids,
13003 .hp_nid = 0x02,
13004 .dig_out_nid = ALC262_DIGOUT_NID,
13005 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13006 .channel_mode = alc262_modes,
13007 .input_mux = &alc262_capture_source,
d922b51d 13008 .unsol_event = alc_sku_unsol_event,
4f5d1706 13009 .setup = alc262_tyan_setup,
d922b51d 13010 .init_hook = alc_hp_automute,
ba340e82 13011 },
df694daa
KY
13012};
13013
13014static int patch_alc262(struct hda_codec *codec)
13015{
13016 struct alc_spec *spec;
13017 int board_config;
13018 int err;
13019
dc041e0b 13020 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13021 if (spec == NULL)
13022 return -ENOMEM;
13023
13024 codec->spec = spec;
13025#if 0
f12ab1e0
TI
13026 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13027 * under-run
13028 */
df694daa
KY
13029 {
13030 int tmp;
13031 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13032 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13033 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13034 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13035 }
13036#endif
da00c244 13037 alc_auto_parse_customize_define(codec);
df694daa 13038
2c3bf9ab
TI
13039 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13040
f5fcc13c
TI
13041 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13042 alc262_models,
13043 alc262_cfg_tbl);
cd7509a4 13044
f5fcc13c 13045 if (board_config < 0) {
9a11f1aa
TI
13046 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13047 codec->chip_name);
df694daa
KY
13048 board_config = ALC262_AUTO;
13049 }
13050
b5bfbc67
TI
13051 if (board_config == ALC262_AUTO) {
13052 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13053 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13054 }
18675e42 13055
df694daa
KY
13056 if (board_config == ALC262_AUTO) {
13057 /* automatic parse from the BIOS config */
13058 err = alc262_parse_auto_config(codec);
13059 if (err < 0) {
13060 alc_free(codec);
13061 return err;
f12ab1e0 13062 } else if (!err) {
9c7f852e
TI
13063 printk(KERN_INFO
13064 "hda_codec: Cannot set up configuration "
13065 "from BIOS. Using base mode...\n");
df694daa
KY
13066 board_config = ALC262_BASIC;
13067 }
13068 }
13069
dc1eae25 13070 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13071 err = snd_hda_attach_beep_device(codec, 0x1);
13072 if (err < 0) {
13073 alc_free(codec);
13074 return err;
13075 }
680cd536
KK
13076 }
13077
df694daa 13078 if (board_config != ALC262_AUTO)
e9c364c0 13079 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13080
df694daa
KY
13081 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13082 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13083
df694daa
KY
13084 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13085 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13086
f12ab1e0 13087 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13088 int i;
13089 /* check whether the digital-mic has to be supported */
13090 for (i = 0; i < spec->input_mux->num_items; i++) {
13091 if (spec->input_mux->items[i].index >= 9)
13092 break;
13093 }
13094 if (i < spec->input_mux->num_items) {
13095 /* use only ADC0 */
13096 spec->adc_nids = alc262_dmic_adc_nids;
13097 spec->num_adc_nids = 1;
13098 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13099 } else {
8c927b4a
TI
13100 /* all analog inputs */
13101 /* check whether NID 0x07 is valid */
13102 unsigned int wcap = get_wcaps(codec, 0x07);
13103
13104 /* get type */
a22d543a 13105 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13106 if (wcap != AC_WID_AUD_IN) {
13107 spec->adc_nids = alc262_adc_nids_alt;
13108 spec->num_adc_nids =
13109 ARRAY_SIZE(alc262_adc_nids_alt);
13110 spec->capsrc_nids = alc262_capsrc_nids_alt;
13111 } else {
13112 spec->adc_nids = alc262_adc_nids;
13113 spec->num_adc_nids =
13114 ARRAY_SIZE(alc262_adc_nids);
13115 spec->capsrc_nids = alc262_capsrc_nids;
13116 }
df694daa
KY
13117 }
13118 }
e64f14f4 13119 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13120 set_capture_mixer(codec);
dc1eae25 13121 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13122 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13123
b5bfbc67 13124 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13125
2134ea4f
TI
13126 spec->vmaster_nid = 0x0c;
13127
df694daa
KY
13128 codec->patch_ops = alc_patch_ops;
13129 if (board_config == ALC262_AUTO)
ae6b813a 13130 spec->init_hook = alc262_auto_init;
1c716153 13131 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13132
13133 alc_init_jacks(codec);
cb53c626
TI
13134#ifdef CONFIG_SND_HDA_POWER_SAVE
13135 if (!spec->loopback.amplist)
13136 spec->loopback.amplist = alc262_loopbacks;
13137#endif
ea1fb29a 13138
df694daa
KY
13139 return 0;
13140}
13141
a361d84b
KY
13142/*
13143 * ALC268 channel source setting (2 channel)
13144 */
13145#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13146#define alc268_modes alc260_modes
ea1fb29a 13147
4c6d72d1 13148static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13149 /* front, hp */
13150 0x02, 0x03
13151};
13152
4c6d72d1 13153static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13154 /* ADC0-1 */
13155 0x08, 0x07
13156};
13157
4c6d72d1 13158static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13159 /* ADC0 */
13160 0x08
13161};
13162
4c6d72d1 13163static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13164
a9111321 13165static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13166 /* output mixer control */
13167 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13174 { }
13175};
13176
a9111321 13177static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13178 /* output mixer control */
13179 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13180 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13181 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13182 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13183 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13184 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13185 { }
13186};
13187
aef9d318 13188/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13189static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13190 .ops = &snd_hda_bind_sw,
13191 .values = {
13192 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13193 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13194 0
13195 },
13196};
13197
a9111321 13198static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13199 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13200 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13201 { }
13202};
13203
a9111321 13204static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13205 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13206 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13207 { }
13208};
13209
d273809e 13210/* Toshiba specific */
a9111321 13211static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13213 { } /* end */
13214};
13215
13216/* Acer specific */
889c4395 13217/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13218static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13219 .ops = &snd_hda_bind_vol,
13220 .values = {
13221 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13222 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13223 0
13224 },
13225};
13226
0f0f391c 13227static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13228{
13229 struct alc_spec *spec = codec->spec;
889c4395 13230
0f0f391c
TI
13231 spec->autocfg.hp_pins[0] = 0x14;
13232 spec->autocfg.speaker_pins[0] = 0x15;
13233 spec->automute = 1;
13234 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13235}
13236
0f0f391c
TI
13237#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13238#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13239
a9111321 13240static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13241 /* output mixer control */
13242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13243 {
13244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13245 .name = "Master Playback Switch",
0f0f391c
TI
13246 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13247 .info = snd_ctl_boolean_mono_info,
13248 .get = alc268_acer_master_sw_get,
8ef355da 13249 .put = alc268_acer_master_sw_put,
8ef355da
KY
13250 },
13251 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13252 { }
13253};
13254
a9111321 13255static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13256 /* output mixer control */
13257 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13258 {
13259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13260 .name = "Master Playback Switch",
0f0f391c
TI
13261 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13262 .info = snd_ctl_boolean_mono_info,
13263 .get = alc268_acer_master_sw_get,
d273809e 13264 .put = alc268_acer_master_sw_put,
d273809e 13265 },
5f99f86a
DH
13266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13267 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13269 { }
13270};
13271
a9111321 13272static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13273 /* output mixer control */
13274 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13275 {
13276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13277 .name = "Master Playback Switch",
0f0f391c
TI
13278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13279 .info = snd_ctl_boolean_mono_info,
13280 .get = alc268_acer_master_sw_get,
c238b4f4 13281 .put = alc268_acer_master_sw_put,
c238b4f4 13282 },
5f99f86a
DH
13283 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13284 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13285 { }
13286};
13287
a9111321 13288static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13289 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13293 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13295 { }
13296};
13297
a9111321 13298static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13299 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13300 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13302 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13305 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13306 { }
13307};
13308
13309/* unsolicited event for HP jack sensing */
4f5d1706 13310#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13311
4f5d1706
TI
13312static void alc268_acer_lc_setup(struct hda_codec *codec)
13313{
13314 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13315 spec->autocfg.hp_pins[0] = 0x15;
13316 spec->autocfg.speaker_pins[0] = 0x14;
13317 spec->automute_mixer_nid[0] = 0x0f;
13318 spec->automute = 1;
13319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
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),
b875bf3a 13874 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13875 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13876 {}
13877};
13878
3abf2f36 13879/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13880static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13881 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13882 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13883 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13884 ALC268_TOSHIBA),
13885 {}
13886};
13887
a9111321 13888static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13889 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13890 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13891 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13892 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13893 alc267_quanta_il1_verbs },
13894 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13895 .dac_nids = alc268_dac_nids,
13896 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13897 .adc_nids = alc268_adc_nids_alt,
13898 .hp_nid = 0x03,
13899 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13900 .channel_mode = alc268_modes,
4f5d1706
TI
13901 .unsol_event = alc_sku_unsol_event,
13902 .setup = alc267_quanta_il1_setup,
13903 .init_hook = alc_inithook,
eb5a6621 13904 },
a361d84b 13905 [ALC268_3ST] = {
aef9d318
TI
13906 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13907 alc268_beep_mixer },
a361d84b
KY
13908 .init_verbs = { alc268_base_init_verbs },
13909 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13910 .dac_nids = alc268_dac_nids,
13911 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13912 .adc_nids = alc268_adc_nids_alt,
e1406348 13913 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13914 .hp_nid = 0x03,
13915 .dig_out_nid = ALC268_DIGOUT_NID,
13916 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13917 .channel_mode = alc268_modes,
13918 .input_mux = &alc268_capture_source,
13919 },
d1a991a6 13920 [ALC268_TOSHIBA] = {
42171c17 13921 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13922 alc268_beep_mixer },
d273809e
TI
13923 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13924 alc268_toshiba_verbs },
d1a991a6
KY
13925 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13926 .dac_nids = alc268_dac_nids,
13927 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13928 .adc_nids = alc268_adc_nids_alt,
e1406348 13929 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13930 .hp_nid = 0x03,
13931 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13932 .channel_mode = alc268_modes,
13933 .input_mux = &alc268_capture_source,
e9427969 13934 .unsol_event = alc_sku_unsol_event,
4f5d1706 13935 .setup = alc268_toshiba_setup,
e9427969 13936 .init_hook = alc_inithook,
d273809e
TI
13937 },
13938 [ALC268_ACER] = {
432fd133 13939 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13940 alc268_beep_mixer },
d273809e
TI
13941 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13942 alc268_acer_verbs },
13943 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13944 .dac_nids = alc268_dac_nids,
13945 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13946 .adc_nids = alc268_adc_nids_alt,
e1406348 13947 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13948 .hp_nid = 0x02,
13949 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13950 .channel_mode = alc268_modes,
0ccb541c 13951 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13952 .unsol_event = alc_sku_unsol_event,
13953 .setup = alc268_acer_setup,
13954 .init_hook = alc_inithook,
d1a991a6 13955 },
c238b4f4
TI
13956 [ALC268_ACER_DMIC] = {
13957 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13958 alc268_beep_mixer },
13959 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13960 alc268_acer_verbs },
13961 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13962 .dac_nids = alc268_dac_nids,
13963 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13964 .adc_nids = alc268_adc_nids_alt,
13965 .capsrc_nids = alc268_capsrc_nids,
13966 .hp_nid = 0x02,
13967 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13968 .channel_mode = alc268_modes,
13969 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13970 .unsol_event = alc_sku_unsol_event,
13971 .setup = alc268_acer_setup,
13972 .init_hook = alc_inithook,
c238b4f4 13973 },
8ef355da
KY
13974 [ALC268_ACER_ASPIRE_ONE] = {
13975 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13976 alc268_beep_mixer,
fdbc6626 13977 alc268_capture_nosrc_mixer },
8ef355da
KY
13978 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13979 alc268_acer_aspire_one_verbs },
13980 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13981 .dac_nids = alc268_dac_nids,
13982 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13983 .adc_nids = alc268_adc_nids_alt,
13984 .capsrc_nids = alc268_capsrc_nids,
13985 .hp_nid = 0x03,
13986 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13987 .channel_mode = alc268_modes,
3b8510ce 13988 .unsol_event = alc_sku_unsol_event,
4f5d1706 13989 .setup = alc268_acer_lc_setup,
3b8510ce 13990 .init_hook = alc_inithook,
8ef355da 13991 },
3866f0b0 13992 [ALC268_DELL] = {
fdbc6626
TI
13993 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13994 alc268_capture_nosrc_mixer },
3866f0b0
TI
13995 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13996 alc268_dell_verbs },
13997 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13998 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13999 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14000 .adc_nids = alc268_adc_nids_alt,
14001 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
14002 .hp_nid = 0x02,
14003 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14004 .channel_mode = alc268_modes,
a9fd4f3f 14005 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
14006 .setup = alc268_dell_setup,
14007 .init_hook = alc_inithook,
3866f0b0 14008 },
f12462c5 14009 [ALC268_ZEPTO] = {
aef9d318
TI
14010 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14011 alc268_beep_mixer },
f12462c5
MT
14012 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14013 alc268_toshiba_verbs },
14014 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14015 .dac_nids = alc268_dac_nids,
14016 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14017 .adc_nids = alc268_adc_nids_alt,
e1406348 14018 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
14019 .hp_nid = 0x03,
14020 .dig_out_nid = ALC268_DIGOUT_NID,
14021 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14022 .channel_mode = alc268_modes,
14023 .input_mux = &alc268_capture_source,
e9427969 14024 .unsol_event = alc_sku_unsol_event,
4f5d1706 14025 .setup = alc268_toshiba_setup,
e9427969 14026 .init_hook = alc_inithook,
f12462c5 14027 },
86c53bd2
JW
14028#ifdef CONFIG_SND_DEBUG
14029 [ALC268_TEST] = {
14030 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14031 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14032 alc268_volume_init_verbs },
14033 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14034 .dac_nids = alc268_dac_nids,
14035 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14036 .adc_nids = alc268_adc_nids_alt,
e1406348 14037 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
14038 .hp_nid = 0x03,
14039 .dig_out_nid = ALC268_DIGOUT_NID,
14040 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14041 .channel_mode = alc268_modes,
14042 .input_mux = &alc268_capture_source,
14043 },
14044#endif
a361d84b
KY
14045};
14046
14047static int patch_alc268(struct hda_codec *codec)
14048{
14049 struct alc_spec *spec;
14050 int board_config;
22971e3a 14051 int i, has_beep, err;
a361d84b 14052
ef86f581 14053 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14054 if (spec == NULL)
14055 return -ENOMEM;
14056
14057 codec->spec = spec;
14058
14059 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14060 alc268_models,
14061 alc268_cfg_tbl);
14062
3abf2f36
TI
14063 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14064 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14065 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14066
a361d84b 14067 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14068 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14069 codec->chip_name);
a361d84b
KY
14070 board_config = ALC268_AUTO;
14071 }
14072
14073 if (board_config == ALC268_AUTO) {
14074 /* automatic parse from the BIOS config */
14075 err = alc268_parse_auto_config(codec);
14076 if (err < 0) {
14077 alc_free(codec);
14078 return err;
14079 } else if (!err) {
14080 printk(KERN_INFO
14081 "hda_codec: Cannot set up configuration "
14082 "from BIOS. Using base mode...\n");
14083 board_config = ALC268_3ST;
14084 }
14085 }
14086
14087 if (board_config != ALC268_AUTO)
e9c364c0 14088 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14089
a361d84b
KY
14090 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14091 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14092 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14093
a361d84b
KY
14094 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14095
22971e3a
TI
14096 has_beep = 0;
14097 for (i = 0; i < spec->num_mixers; i++) {
14098 if (spec->mixers[i] == alc268_beep_mixer) {
14099 has_beep = 1;
14100 break;
14101 }
14102 }
14103
14104 if (has_beep) {
14105 err = snd_hda_attach_beep_device(codec, 0x1);
14106 if (err < 0) {
14107 alc_free(codec);
14108 return err;
14109 }
14110 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14111 /* override the amp caps for beep generator */
14112 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14113 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14114 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14115 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14116 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14117 }
aef9d318 14118
7e0e44d4 14119 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14120 /* check whether NID 0x07 is valid */
14121 unsigned int wcap = get_wcaps(codec, 0x07);
14122
defb5ab2 14123 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14124 /* get type */
a22d543a 14125 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14126 if (spec->auto_mic ||
14127 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14128 spec->adc_nids = alc268_adc_nids_alt;
14129 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14130 if (spec->auto_mic)
14131 fixup_automic_adc(codec);
fdbc6626
TI
14132 if (spec->auto_mic || spec->input_mux->num_items == 1)
14133 add_mixer(spec, alc268_capture_nosrc_mixer);
14134 else
14135 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14136 } else {
14137 spec->adc_nids = alc268_adc_nids;
14138 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14139 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14140 }
14141 }
2134ea4f
TI
14142
14143 spec->vmaster_nid = 0x02;
14144
a361d84b
KY
14145 codec->patch_ops = alc_patch_ops;
14146 if (board_config == ALC268_AUTO)
14147 spec->init_hook = alc268_auto_init;
1c716153 14148 spec->shutup = alc_eapd_shutup;
ea1fb29a 14149
bf1b0225
KY
14150 alc_init_jacks(codec);
14151
a361d84b
KY
14152 return 0;
14153}
14154
f6a92248
KY
14155/*
14156 * ALC269 channel source setting (2 channel)
14157 */
14158#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14159
14160#define alc269_dac_nids alc260_dac_nids
14161
4c6d72d1 14162static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14163 /* ADC1 */
f53281e6
KY
14164 0x08,
14165};
14166
4c6d72d1 14167static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14168 0x23,
14169};
14170
4c6d72d1 14171static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14172 /* ADC1 */
14173 0x09,
14174};
14175
4c6d72d1 14176static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14177 0x22,
14178};
14179
4c6d72d1 14180static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14181 0x08, 0x09, 0x07, 0x11,
6694635d 14182};
e01bf509 14183
f6a92248
KY
14184#define alc269_modes alc260_modes
14185#define alc269_capture_source alc880_lg_lw_capture_source
14186
a9111321 14187static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14188 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14193 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14194 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14195 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14196 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14197 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14198 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14199 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14200 { } /* end */
14201};
14202
a9111321 14203static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14204 /* output mixer control */
14205 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14206 {
14207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14208 .name = "Master Playback Switch",
5e26dfd0 14209 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14210 .info = snd_hda_mixer_amp_switch_info,
14211 .get = snd_hda_mixer_amp_switch_get,
14212 .put = alc268_acer_master_sw_put,
14213 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14214 },
14215 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14216 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14218 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14219 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14220 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14221 { }
14222};
14223
a9111321 14224static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14225 /* output mixer control */
14226 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14227 {
14228 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14229 .name = "Master Playback Switch",
5e26dfd0 14230 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14231 .info = snd_hda_mixer_amp_switch_info,
14232 .get = snd_hda_mixer_amp_switch_get,
14233 .put = alc268_acer_master_sw_put,
14234 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14235 },
14236 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14239 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14240 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14241 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14242 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14243 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14244 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14245 { }
14246};
14247
a9111321 14248static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14249 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14250 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14252 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14253 { } /* end */
14254};
14255
a9111321 14256static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14257 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14259 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14261 { } /* end */
14262};
14263
a9111321 14264static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14265 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14266 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14267 { } /* end */
14268};
14269
f53281e6 14270/* capture mixer elements */
a9111321 14271static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14272 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14273 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14274 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14275 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14276 { } /* end */
14277};
14278
a9111321 14279static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14280 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14281 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14282 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14283 { } /* end */
14284};
14285
a9111321 14286static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14287 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14288 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14289 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14290 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14291 { } /* end */
14292};
14293
a9111321 14294static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14295 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14296 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14298 { } /* end */
14299};
14300
26f5df26 14301/* FSC amilo */
84898e87 14302#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14303
a9111321 14304static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14305 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14306 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14307 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14308 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14309 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14310 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14311 { }
14312};
f6a92248 14313
a9111321 14314static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14315 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14316 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14317 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14318 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14320 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14321 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14322 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14323 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14324 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14325 { }
14326};
14327
60db6b53
KY
14328/* toggle speaker-output according to the hp-jack state */
14329static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14330{
3b8510ce 14331 alc_hp_automute(codec);
f6a92248 14332
60db6b53
KY
14333 snd_hda_codec_write(codec, 0x20, 0,
14334 AC_VERB_SET_COEF_INDEX, 0x0c);
14335 snd_hda_codec_write(codec, 0x20, 0,
14336 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14337
60db6b53
KY
14338 snd_hda_codec_write(codec, 0x20, 0,
14339 AC_VERB_SET_COEF_INDEX, 0x0c);
14340 snd_hda_codec_write(codec, 0x20, 0,
14341 AC_VERB_SET_PROC_COEF, 0x480);
14342}
f6a92248 14343
3b8510ce
TI
14344#define alc269_lifebook_speaker_automute \
14345 alc269_quanta_fl1_speaker_automute
64154835 14346
64154835
TV
14347static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14348{
14349 unsigned int present_laptop;
14350 unsigned int present_dock;
14351
864f92be
WF
14352 present_laptop = snd_hda_jack_detect(codec, 0x18);
14353 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14354
14355 /* Laptop mic port overrides dock mic port, design decision */
14356 if (present_dock)
14357 snd_hda_codec_write(codec, 0x23, 0,
14358 AC_VERB_SET_CONNECT_SEL, 0x3);
14359 if (present_laptop)
14360 snd_hda_codec_write(codec, 0x23, 0,
14361 AC_VERB_SET_CONNECT_SEL, 0x0);
14362 if (!present_dock && !present_laptop)
14363 snd_hda_codec_write(codec, 0x23, 0,
14364 AC_VERB_SET_CONNECT_SEL, 0x1);
14365}
14366
60db6b53
KY
14367static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14368 unsigned int res)
14369{
4f5d1706
TI
14370 switch (res >> 26) {
14371 case ALC880_HP_EVENT:
60db6b53 14372 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14373 break;
14374 case ALC880_MIC_EVENT:
14375 alc_mic_automute(codec);
14376 break;
14377 }
60db6b53 14378}
f6a92248 14379
64154835
TV
14380static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14381 unsigned int res)
14382{
14383 if ((res >> 26) == ALC880_HP_EVENT)
14384 alc269_lifebook_speaker_automute(codec);
14385 if ((res >> 26) == ALC880_MIC_EVENT)
14386 alc269_lifebook_mic_autoswitch(codec);
14387}
14388
4f5d1706
TI
14389static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14390{
14391 struct alc_spec *spec = codec->spec;
20645d70
TI
14392 spec->autocfg.hp_pins[0] = 0x15;
14393 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14394 spec->automute_mixer_nid[0] = 0x0c;
14395 spec->automute = 1;
14396 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14397 spec->ext_mic.pin = 0x18;
14398 spec->ext_mic.mux_idx = 0;
14399 spec->int_mic.pin = 0x19;
14400 spec->int_mic.mux_idx = 1;
14401 spec->auto_mic = 1;
14402}
14403
60db6b53
KY
14404static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14405{
14406 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14407 alc_mic_automute(codec);
60db6b53 14408}
f6a92248 14409
3b8510ce
TI
14410static void alc269_lifebook_setup(struct hda_codec *codec)
14411{
14412 struct alc_spec *spec = codec->spec;
14413 spec->autocfg.hp_pins[0] = 0x15;
14414 spec->autocfg.hp_pins[1] = 0x1a;
14415 spec->autocfg.speaker_pins[0] = 0x14;
14416 spec->automute_mixer_nid[0] = 0x0c;
14417 spec->automute = 1;
14418 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14419}
14420
64154835
TV
14421static void alc269_lifebook_init_hook(struct hda_codec *codec)
14422{
14423 alc269_lifebook_speaker_automute(codec);
14424 alc269_lifebook_mic_autoswitch(codec);
14425}
14426
a9111321 14427static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14428 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14429 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14430 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14431 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14432 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14434 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14435 {}
14436};
14437
a9111321 14438static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14439 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14441 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14443 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14444 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14445 {}
14446};
14447
a9111321 14448static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14449 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14450 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14451 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14452 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14453 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14454 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14455 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14456 {}
14457};
14458
a9111321 14459static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14460 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14462 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14464 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14465 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14466 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14467 {}
14468};
14469
a9111321 14470static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14471 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14472 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14473 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14474 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14475 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14476 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14477 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14478 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14479 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14480 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14481 { }
14482};
14483
226b1ec8 14484static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14485{
4f5d1706 14486 struct alc_spec *spec = codec->spec;
20645d70
TI
14487 spec->autocfg.hp_pins[0] = 0x15;
14488 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14489 spec->automute_mixer_nid[0] = 0x0c;
14490 spec->automute = 1;
14491 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14492 spec->ext_mic.pin = 0x18;
14493 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14494 spec->int_mic.pin = 0x19;
14495 spec->int_mic.mux_idx = 1;
4f5d1706 14496 spec->auto_mic = 1;
f53281e6
KY
14497}
14498
226b1ec8 14499static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14500{
14501 struct alc_spec *spec = codec->spec;
20645d70
TI
14502 spec->autocfg.hp_pins[0] = 0x15;
14503 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14504 spec->automute_mixer_nid[0] = 0x0c;
14505 spec->automute = 1;
14506 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14507 spec->ext_mic.pin = 0x18;
14508 spec->ext_mic.mux_idx = 0;
14509 spec->int_mic.pin = 0x12;
226b1ec8 14510 spec->int_mic.mux_idx = 5;
84898e87
KY
14511 spec->auto_mic = 1;
14512}
14513
226b1ec8 14514static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14515{
4f5d1706 14516 struct alc_spec *spec = codec->spec;
226b1ec8 14517 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14518 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14519 spec->automute_mixer_nid[0] = 0x0c;
14520 spec->automute = 1;
14521 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14522 spec->ext_mic.pin = 0x18;
14523 spec->ext_mic.mux_idx = 0;
14524 spec->int_mic.pin = 0x19;
14525 spec->int_mic.mux_idx = 1;
14526 spec->auto_mic = 1;
f53281e6
KY
14527}
14528
226b1ec8
KY
14529static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14530{
14531 struct alc_spec *spec = codec->spec;
14532 spec->autocfg.hp_pins[0] = 0x21;
14533 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14534 spec->automute_mixer_nid[0] = 0x0c;
14535 spec->automute = 1;
14536 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14537 spec->ext_mic.pin = 0x18;
14538 spec->ext_mic.mux_idx = 0;
14539 spec->int_mic.pin = 0x12;
14540 spec->int_mic.mux_idx = 6;
14541 spec->auto_mic = 1;
14542}
14543
60db6b53
KY
14544/*
14545 * generic initialization of ADC, input mixers and output mixers
14546 */
a9111321 14547static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14548 /*
14549 * Unmute ADC0 and set the default input to mic-in
14550 */
84898e87 14551 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14552
14553 /*
84898e87 14554 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14555 */
14556 /* set vol=0 to output mixers */
14557 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14559
14560 /* set up input amps for analog loopback */
14561 /* Amp Indices: DAC = 0, mixer = 1 */
14562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14565 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14567 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14568
14569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14571 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14572 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14573 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14574 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14576
14577 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14579
84898e87
KY
14580 /* FIXME: use Mux-type input source selection */
14581 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14582 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14583 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14584
84898e87
KY
14585 /* set EAPD */
14586 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14587 { }
14588};
14589
a9111321 14590static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14591 /*
14592 * Unmute ADC0 and set the default input to mic-in
14593 */
14594 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14595
14596 /*
14597 * Set up output mixers (0x02 - 0x03)
14598 */
14599 /* set vol=0 to output mixers */
14600 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14602
14603 /* set up input amps for analog loopback */
14604 /* Amp Indices: DAC = 0, mixer = 1 */
14605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14610 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14611
14612 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14613 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14614 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14615 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14616 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14617 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14619
14620 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14622
14623 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14624 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14625 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14626 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14627
14628 /* set EAPD */
14629 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14630 { }
14631};
14632
9d0b71b1
TI
14633#define alc269_auto_create_multi_out_ctls \
14634 alc268_auto_create_multi_out_ctls
05f5f477
TI
14635#define alc269_auto_create_input_ctls \
14636 alc268_auto_create_input_ctls
f6a92248
KY
14637
14638#ifdef CONFIG_SND_HDA_POWER_SAVE
14639#define alc269_loopbacks alc880_loopbacks
14640#endif
14641
def319f9 14642/* pcm configuration: identical with ALC880 */
f6a92248
KY
14643#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14644#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14645#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14646#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14647
a9111321 14648static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14649 .substreams = 1,
14650 .channels_min = 2,
14651 .channels_max = 8,
14652 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14653 /* NID is set in alc_build_pcms */
14654 .ops = {
14655 .open = alc880_playback_pcm_open,
14656 .prepare = alc880_playback_pcm_prepare,
14657 .cleanup = alc880_playback_pcm_cleanup
14658 },
14659};
14660
a9111321 14661static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14662 .substreams = 1,
14663 .channels_min = 2,
14664 .channels_max = 2,
14665 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14666 /* NID is set in alc_build_pcms */
14667};
14668
ad35879a
TI
14669#ifdef CONFIG_SND_HDA_POWER_SAVE
14670static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14671{
14672 switch (codec->subsystem_id) {
14673 case 0x103c1586:
14674 return 1;
14675 }
14676 return 0;
14677}
14678
14679static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14680{
14681 /* update mute-LED according to the speaker mute state */
14682 if (nid == 0x01 || nid == 0x14) {
14683 int pinval;
14684 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14685 HDA_AMP_MUTE)
14686 pinval = 0x24;
14687 else
14688 pinval = 0x20;
14689 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14690 snd_hda_codec_update_cache(codec, 0x19, 0,
14691 AC_VERB_SET_PIN_WIDGET_CONTROL,
14692 pinval);
ad35879a
TI
14693 }
14694 return alc_check_power_status(codec, nid);
14695}
14696#endif /* CONFIG_SND_HDA_POWER_SAVE */
14697
840b64c0
TI
14698static int alc275_setup_dual_adc(struct hda_codec *codec)
14699{
14700 struct alc_spec *spec = codec->spec;
14701
14702 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14703 return 0;
14704 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14705 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14706 if (spec->ext_mic.pin <= 0x12) {
14707 spec->private_adc_nids[0] = 0x08;
14708 spec->private_adc_nids[1] = 0x11;
14709 spec->private_capsrc_nids[0] = 0x23;
14710 spec->private_capsrc_nids[1] = 0x22;
14711 } else {
14712 spec->private_adc_nids[0] = 0x11;
14713 spec->private_adc_nids[1] = 0x08;
14714 spec->private_capsrc_nids[0] = 0x22;
14715 spec->private_capsrc_nids[1] = 0x23;
14716 }
14717 spec->adc_nids = spec->private_adc_nids;
14718 spec->capsrc_nids = spec->private_capsrc_nids;
14719 spec->num_adc_nids = 2;
14720 spec->dual_adc_switch = 1;
14721 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14722 spec->adc_nids[0], spec->adc_nids[1]);
14723 return 1;
14724 }
14725 return 0;
14726}
14727
d433a678
TI
14728/* different alc269-variants */
14729enum {
14730 ALC269_TYPE_NORMAL,
48c88e82 14731 ALC269_TYPE_ALC258,
d433a678 14732 ALC269_TYPE_ALC259,
48c88e82
KY
14733 ALC269_TYPE_ALC269VB,
14734 ALC269_TYPE_ALC270,
d433a678
TI
14735 ALC269_TYPE_ALC271X,
14736};
14737
f6a92248
KY
14738/*
14739 * BIOS auto configuration
14740 */
14741static int alc269_parse_auto_config(struct hda_codec *codec)
14742{
14743 struct alc_spec *spec = codec->spec;
cfb9fb55 14744 int err;
4c6d72d1 14745 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14746
14747 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14748 alc269_ignore);
14749 if (err < 0)
14750 return err;
14751
14752 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14753 if (err < 0)
14754 return err;
f3550d1b
TI
14755 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14756 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14757 else
14758 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14759 0x22, 0);
f6a92248
KY
14760 if (err < 0)
14761 return err;
14762
14763 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14764
757899ac 14765 alc_auto_parse_digital(codec);
f6a92248 14766
603c4019 14767 if (spec->kctls.list)
d88897ea 14768 add_mixer(spec, spec->kctls.list);
f6a92248 14769
d433a678 14770 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14771 add_verb(spec, alc269vb_init_verbs);
6227cdce 14772 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14773 } else {
14774 add_verb(spec, alc269_init_verbs);
6227cdce 14775 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14776 }
14777
f6a92248 14778 spec->num_mux_defs = 1;
61b9b9b1 14779 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14780
14781 if (!alc275_setup_dual_adc(codec))
14782 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14783 sizeof(alc269_adc_candidates));
6694635d 14784
f6a92248
KY
14785 err = alc_auto_add_mic_boost(codec);
14786 if (err < 0)
14787 return err;
14788
7e0e44d4 14789 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14790 set_capture_mixer(codec);
f53281e6 14791
f6a92248
KY
14792 return 1;
14793}
14794
e9af4f36
TI
14795#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14796#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14797#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14798#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14799
14800
14801/* init callback for auto-configuration model -- overriding the default init */
14802static void alc269_auto_init(struct hda_codec *codec)
14803{
f6c7e546 14804 struct alc_spec *spec = codec->spec;
f6a92248
KY
14805 alc269_auto_init_multi_out(codec);
14806 alc269_auto_init_hp_out(codec);
14807 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14808 if (!spec->dual_adc_switch)
14809 alc269_auto_init_input_src(codec);
757899ac 14810 alc_auto_init_digital(codec);
f6c7e546 14811 if (spec->unsol_event)
7fb0d78f 14812 alc_inithook(codec);
f6a92248
KY
14813}
14814
0ec33d1f
TI
14815static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14816{
14817 int val = alc_read_coef_idx(codec, 0x04);
14818 if (power_up)
14819 val |= 1 << 11;
14820 else
14821 val &= ~(1 << 11);
14822 alc_write_coef_idx(codec, 0x04, val);
14823}
14824
5402e4cb 14825static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14826{
0ec33d1f
TI
14827 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14828 alc269_toggle_power_output(codec, 0);
977ddd6b 14829 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14830 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14831 msleep(150);
14832 }
977ddd6b 14833}
0ec33d1f 14834
5402e4cb 14835#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14836static int alc269_resume(struct hda_codec *codec)
14837{
977ddd6b 14838 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14839 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14840 msleep(150);
14841 }
14842
14843 codec->patch_ops.init(codec);
14844
14845 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14846 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14847 msleep(200);
14848 }
14849
0ec33d1f
TI
14850 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14851 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14852
14853 snd_hda_codec_resume_amp(codec);
14854 snd_hda_codec_resume_cache(codec);
9e5341b9 14855 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14856 return 0;
14857}
0ec33d1f 14858#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14859
1a99d4a4 14860static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14861 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14862{
14863 int coef;
14864
58701120 14865 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14866 return;
1a99d4a4
KY
14867 coef = alc_read_coef_idx(codec, 0x1e);
14868 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14869}
14870
6981d184
TI
14871static void alc271_fixup_dmic(struct hda_codec *codec,
14872 const struct alc_fixup *fix, int action)
14873{
a9111321 14874 static const struct hda_verb verbs[] = {
6981d184
TI
14875 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14876 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14877 {}
14878 };
14879 unsigned int cfg;
14880
14881 if (strcmp(codec->chip_name, "ALC271X"))
14882 return;
14883 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14884 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14885 snd_hda_sequence_write(codec, verbs);
14886}
14887
ff818c24
TI
14888enum {
14889 ALC269_FIXUP_SONY_VAIO,
74dc8909 14890 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14891 ALC269_FIXUP_DELL_M101Z,
022c92be 14892 ALC269_FIXUP_SKU_IGNORE,
ac612407 14893 ALC269_FIXUP_ASUS_G73JW,
357f915e 14894 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14895 ALC275_FIXUP_SONY_HWEQ,
6981d184 14896 ALC271_FIXUP_DMIC,
ff818c24
TI
14897};
14898
ff818c24
TI
14899static const struct alc_fixup alc269_fixups[] = {
14900 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14901 .type = ALC_FIXUP_VERBS,
14902 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14903 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14904 {}
14905 }
ff818c24 14906 },
74dc8909 14907 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14908 .type = ALC_FIXUP_VERBS,
14909 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14910 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14911 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14912 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14913 { }
b5bfbc67
TI
14914 },
14915 .chained = true,
14916 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14917 },
145a902b 14918 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14919 .type = ALC_FIXUP_VERBS,
14920 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14921 /* Enables internal speaker */
14922 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14923 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14924 {}
14925 }
14926 },
022c92be 14927 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14928 .type = ALC_FIXUP_SKU,
14929 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14930 },
ac612407 14931 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14932 .type = ALC_FIXUP_PINS,
14933 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14934 { 0x17, 0x99130111 }, /* subwoofer */
14935 { }
14936 }
14937 },
357f915e 14938 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14939 .type = ALC_FIXUP_VERBS,
14940 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14941 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14942 {}
14943 }
14944 },
1a99d4a4 14945 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14946 .type = ALC_FIXUP_FUNC,
14947 .v.func = alc269_fixup_hweq,
14948 .chained = true,
14949 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14950 },
14951 [ALC271_FIXUP_DMIC] = {
14952 .type = ALC_FIXUP_FUNC,
14953 .v.func = alc271_fixup_dmic,
14954 },
ff818c24
TI
14955};
14956
a9111321 14957static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14958 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14959 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14960 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14961 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14962 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14963 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14964 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14965 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14968 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14969 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14970 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14971 {}
14972};
14973
14974
f6a92248
KY
14975/*
14976 * configuration and preset
14977 */
ea734963 14978static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14979 [ALC269_BASIC] = "basic",
2922c9af 14980 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14981 [ALC269_AMIC] = "laptop-amic",
14982 [ALC269_DMIC] = "laptop-dmic",
64154835 14983 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14984 [ALC269_LIFEBOOK] = "lifebook",
14985 [ALC269_AUTO] = "auto",
f6a92248
KY
14986};
14987
a9111321 14988static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14989 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14990 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14991 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14992 ALC269_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 15002 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
15003 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15024 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15025 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15029 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15030 ALC269_DMIC),
60db6b53 15031 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15032 ALC269_DMIC),
15033 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15034 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15035 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15036 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15037 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15038 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15039 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15041 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15042 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15043 {}
15044};
15045
a9111321 15046static const struct alc_config_preset alc269_presets[] = {
f6a92248 15047 [ALC269_BASIC] = {
f9e336f6 15048 .mixers = { alc269_base_mixer },
f6a92248
KY
15049 .init_verbs = { alc269_init_verbs },
15050 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15051 .dac_nids = alc269_dac_nids,
15052 .hp_nid = 0x03,
15053 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15054 .channel_mode = alc269_modes,
15055 .input_mux = &alc269_capture_source,
15056 },
60db6b53
KY
15057 [ALC269_QUANTA_FL1] = {
15058 .mixers = { alc269_quanta_fl1_mixer },
15059 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15060 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15061 .dac_nids = alc269_dac_nids,
15062 .hp_nid = 0x03,
15063 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15064 .channel_mode = alc269_modes,
15065 .input_mux = &alc269_capture_source,
15066 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15067 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15068 .init_hook = alc269_quanta_fl1_init_hook,
15069 },
84898e87
KY
15070 [ALC269_AMIC] = {
15071 .mixers = { alc269_laptop_mixer },
15072 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15073 .init_verbs = { alc269_init_verbs,
84898e87 15074 alc269_laptop_amic_init_verbs },
f53281e6
KY
15075 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15076 .dac_nids = alc269_dac_nids,
15077 .hp_nid = 0x03,
15078 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15079 .channel_mode = alc269_modes,
3b8510ce 15080 .unsol_event = alc_sku_unsol_event,
84898e87 15081 .setup = alc269_laptop_amic_setup,
3b8510ce 15082 .init_hook = alc_inithook,
f53281e6 15083 },
84898e87
KY
15084 [ALC269_DMIC] = {
15085 .mixers = { alc269_laptop_mixer },
15086 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15087 .init_verbs = { alc269_init_verbs,
84898e87
KY
15088 alc269_laptop_dmic_init_verbs },
15089 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15090 .dac_nids = alc269_dac_nids,
15091 .hp_nid = 0x03,
15092 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15093 .channel_mode = alc269_modes,
3b8510ce 15094 .unsol_event = alc_sku_unsol_event,
84898e87 15095 .setup = alc269_laptop_dmic_setup,
3b8510ce 15096 .init_hook = alc_inithook,
84898e87
KY
15097 },
15098 [ALC269VB_AMIC] = {
15099 .mixers = { alc269vb_laptop_mixer },
15100 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15101 .init_verbs = { alc269vb_init_verbs,
15102 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15103 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15104 .dac_nids = alc269_dac_nids,
15105 .hp_nid = 0x03,
15106 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15107 .channel_mode = alc269_modes,
3b8510ce 15108 .unsol_event = alc_sku_unsol_event,
226b1ec8 15109 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15110 .init_hook = alc_inithook,
84898e87
KY
15111 },
15112 [ALC269VB_DMIC] = {
15113 .mixers = { alc269vb_laptop_mixer },
15114 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15115 .init_verbs = { alc269vb_init_verbs,
15116 alc269vb_laptop_dmic_init_verbs },
15117 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15118 .dac_nids = alc269_dac_nids,
15119 .hp_nid = 0x03,
15120 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15121 .channel_mode = alc269_modes,
3b8510ce 15122 .unsol_event = alc_sku_unsol_event,
84898e87 15123 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15124 .init_hook = alc_inithook,
f53281e6 15125 },
26f5df26 15126 [ALC269_FUJITSU] = {
45bdd1c1 15127 .mixers = { alc269_fujitsu_mixer },
84898e87 15128 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15129 .init_verbs = { alc269_init_verbs,
84898e87 15130 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15131 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15132 .dac_nids = alc269_dac_nids,
15133 .hp_nid = 0x03,
15134 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15135 .channel_mode = alc269_modes,
3b8510ce 15136 .unsol_event = alc_sku_unsol_event,
84898e87 15137 .setup = alc269_laptop_dmic_setup,
3b8510ce 15138 .init_hook = alc_inithook,
26f5df26 15139 },
64154835
TV
15140 [ALC269_LIFEBOOK] = {
15141 .mixers = { alc269_lifebook_mixer },
15142 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15143 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15144 .dac_nids = alc269_dac_nids,
15145 .hp_nid = 0x03,
15146 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15147 .channel_mode = alc269_modes,
15148 .input_mux = &alc269_capture_source,
15149 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15150 .setup = alc269_lifebook_setup,
64154835
TV
15151 .init_hook = alc269_lifebook_init_hook,
15152 },
fe3eb0a7
KY
15153 [ALC271_ACER] = {
15154 .mixers = { alc269_asus_mixer },
15155 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15156 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15157 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15158 .dac_nids = alc269_dac_nids,
15159 .adc_nids = alc262_dmic_adc_nids,
15160 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15161 .capsrc_nids = alc262_dmic_capsrc_nids,
15162 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15163 .channel_mode = alc269_modes,
15164 .input_mux = &alc269_capture_source,
15165 .dig_out_nid = ALC880_DIGOUT_NID,
15166 .unsol_event = alc_sku_unsol_event,
15167 .setup = alc269vb_laptop_dmic_setup,
15168 .init_hook = alc_inithook,
15169 },
f6a92248
KY
15170};
15171
977ddd6b
KY
15172static int alc269_fill_coef(struct hda_codec *codec)
15173{
15174 int val;
15175
15176 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15177 alc_write_coef_idx(codec, 0xf, 0x960b);
15178 alc_write_coef_idx(codec, 0xe, 0x8817);
15179 }
15180
15181 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15182 alc_write_coef_idx(codec, 0xf, 0x960b);
15183 alc_write_coef_idx(codec, 0xe, 0x8814);
15184 }
15185
15186 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15187 val = alc_read_coef_idx(codec, 0x04);
15188 /* Power up output pin */
15189 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15190 }
15191
15192 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15193 val = alc_read_coef_idx(codec, 0xd);
15194 if ((val & 0x0c00) >> 10 != 0x1) {
15195 /* Capless ramp up clock control */
b896b4eb 15196 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
15197 }
15198 val = alc_read_coef_idx(codec, 0x17);
15199 if ((val & 0x01c0) >> 6 != 0x4) {
15200 /* Class D power on reset */
b896b4eb 15201 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
15202 }
15203 }
b896b4eb
KY
15204
15205 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15206 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15207
15208 val = alc_read_coef_idx(codec, 0x4); /* HP */
15209 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15210
977ddd6b
KY
15211 return 0;
15212}
15213
f6a92248
KY
15214static int patch_alc269(struct hda_codec *codec)
15215{
15216 struct alc_spec *spec;
48c88e82 15217 int board_config, coef;
f6a92248
KY
15218 int err;
15219
15220 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15221 if (spec == NULL)
15222 return -ENOMEM;
15223
15224 codec->spec = spec;
15225
da00c244
KY
15226 alc_auto_parse_customize_define(codec);
15227
c793bec5
KY
15228 if (codec->vendor_id == 0x10ec0269) {
15229 coef = alc_read_coef_idx(codec, 0);
15230 if ((coef & 0x00f0) == 0x0010) {
15231 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15232 spec->cdefine.platform_type == 1) {
15233 alc_codec_rename(codec, "ALC271X");
15234 spec->codec_variant = ALC269_TYPE_ALC271X;
15235 } else if ((coef & 0xf000) == 0x1000) {
15236 spec->codec_variant = ALC269_TYPE_ALC270;
15237 } else if ((coef & 0xf000) == 0x2000) {
15238 alc_codec_rename(codec, "ALC259");
15239 spec->codec_variant = ALC269_TYPE_ALC259;
15240 } else if ((coef & 0xf000) == 0x3000) {
15241 alc_codec_rename(codec, "ALC258");
15242 spec->codec_variant = ALC269_TYPE_ALC258;
15243 } else {
15244 alc_codec_rename(codec, "ALC269VB");
15245 spec->codec_variant = ALC269_TYPE_ALC269VB;
15246 }
15247 } else
15248 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15249 alc269_fill_coef(codec);
15250 }
977ddd6b 15251
f6a92248
KY
15252 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15253 alc269_models,
15254 alc269_cfg_tbl);
15255
15256 if (board_config < 0) {
9a11f1aa
TI
15257 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15258 codec->chip_name);
f6a92248
KY
15259 board_config = ALC269_AUTO;
15260 }
15261
b5bfbc67
TI
15262 if (board_config == ALC269_AUTO) {
15263 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15264 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15265 }
ff818c24 15266
f6a92248
KY
15267 if (board_config == ALC269_AUTO) {
15268 /* automatic parse from the BIOS config */
15269 err = alc269_parse_auto_config(codec);
15270 if (err < 0) {
15271 alc_free(codec);
15272 return err;
15273 } else if (!err) {
15274 printk(KERN_INFO
15275 "hda_codec: Cannot set up configuration "
15276 "from BIOS. Using base mode...\n");
15277 board_config = ALC269_BASIC;
15278 }
15279 }
15280
dc1eae25 15281 if (has_cdefine_beep(codec)) {
8af2591d
TI
15282 err = snd_hda_attach_beep_device(codec, 0x1);
15283 if (err < 0) {
15284 alc_free(codec);
15285 return err;
15286 }
680cd536
KK
15287 }
15288
f6a92248 15289 if (board_config != ALC269_AUTO)
e9c364c0 15290 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15291
84898e87 15292 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15293 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15294 * fix the sample rate of analog I/O to 44.1kHz
15295 */
15296 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15297 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15298 } else if (spec->dual_adc_switch) {
15299 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15300 /* switch ADC dynamically */
15301 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15302 } else {
15303 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15304 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15305 }
f6a92248
KY
15306 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15307 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15308
6694635d 15309 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15310 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15311 spec->adc_nids = alc269_adc_nids;
15312 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15313 spec->capsrc_nids = alc269_capsrc_nids;
15314 } else {
15315 spec->adc_nids = alc269vb_adc_nids;
15316 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15317 spec->capsrc_nids = alc269vb_capsrc_nids;
15318 }
84898e87
KY
15319 }
15320
f9e336f6 15321 if (!spec->cap_mixer)
b59bdf3b 15322 set_capture_mixer(codec);
dc1eae25 15323 if (has_cdefine_beep(codec))
da00c244 15324 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15325
b5bfbc67 15326 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15327
100d5eb3
TI
15328 spec->vmaster_nid = 0x02;
15329
f6a92248 15330 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15331#ifdef SND_HDA_NEEDS_RESUME
15332 codec->patch_ops.resume = alc269_resume;
15333#endif
f6a92248
KY
15334 if (board_config == ALC269_AUTO)
15335 spec->init_hook = alc269_auto_init;
5402e4cb 15336 spec->shutup = alc269_shutup;
bf1b0225
KY
15337
15338 alc_init_jacks(codec);
f6a92248
KY
15339#ifdef CONFIG_SND_HDA_POWER_SAVE
15340 if (!spec->loopback.amplist)
15341 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15342 if (alc269_mic2_for_mute_led(codec))
15343 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15344#endif
15345
15346 return 0;
15347}
15348
df694daa
KY
15349/*
15350 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15351 */
15352
15353/*
15354 * set the path ways for 2 channel output
15355 * need to set the codec line out and mic 1 pin widgets to inputs
15356 */
a9111321 15357static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15358 /* set pin widget 1Ah (line in) for input */
15359 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15360 /* set pin widget 18h (mic1/2) for input, for mic also enable
15361 * the vref
15362 */
df694daa
KY
15363 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15364
9c7f852e
TI
15365 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15366#if 0
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15368 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15369#endif
df694daa
KY
15370 { } /* end */
15371};
15372/*
15373 * 6ch mode
15374 * need to set the codec line out and mic 1 pin widgets to outputs
15375 */
a9111321 15376static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15377 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15378 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15379 /* set pin widget 18h (mic1) for output (CLFE)*/
15380 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15381
15382 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15383 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15384
9c7f852e
TI
15385 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15386#if 0
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15388 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15389#endif
df694daa
KY
15390 { } /* end */
15391};
15392
a9111321 15393static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15394 { 2, alc861_threestack_ch2_init },
15395 { 6, alc861_threestack_ch6_init },
15396};
22309c3e 15397/* Set mic1 as input and unmute the mixer */
a9111321 15398static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15399 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15400 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15401 { } /* end */
15402};
15403/* Set mic1 as output and mute mixer */
a9111321 15404static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15405 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15406 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15407 { } /* end */
15408};
15409
a9111321 15410static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15411 { 2, alc861_uniwill_m31_ch2_init },
15412 { 4, alc861_uniwill_m31_ch4_init },
15413};
df694daa 15414
7cdbff94 15415/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15416static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15417 /* set pin widget 1Ah (line in) for input */
15418 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15419 /* set pin widget 18h (mic1/2) for input, for mic also enable
15420 * the vref
15421 */
7cdbff94
MD
15422 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15423
15424 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15425#if 0
15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15427 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15428#endif
15429 { } /* end */
15430};
15431/* Set mic1 nad line-in as output and mute mixer */
a9111321 15432static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15433 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15434 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15435 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15436 /* set pin widget 18h (mic1) for output (CLFE)*/
15437 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15438 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15439 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15440 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15441
15442 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15443#if 0
15444 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15445 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15446#endif
15447 { } /* end */
15448};
15449
a9111321 15450static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15451 { 2, alc861_asus_ch2_init },
15452 { 6, alc861_asus_ch6_init },
15453};
15454
df694daa
KY
15455/* patch-ALC861 */
15456
a9111321 15457static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15458 /* output mixer control */
15459 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15463 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15464
15465 /*Input mixer control */
15466 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15467 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15468 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15470 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15474 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15476
df694daa
KY
15477 { } /* end */
15478};
15479
a9111321 15480static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15481 /* output mixer control */
15482 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15485 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15486 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15487
15488 /* Input mixer control */
15489 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15490 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15491 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15493 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15495 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15497 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15498 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15499
df694daa
KY
15500 {
15501 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15502 .name = "Channel Mode",
15503 .info = alc_ch_mode_info,
15504 .get = alc_ch_mode_get,
15505 .put = alc_ch_mode_put,
15506 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15507 },
15508 { } /* end */
a53d1aec
TD
15509};
15510
a9111321 15511static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15512 /* output mixer control */
15513 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15514 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15515 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15516
a53d1aec 15517 { } /* end */
f12ab1e0 15518};
a53d1aec 15519
a9111321 15520static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15521 /* output mixer control */
15522 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15525 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15526 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15527
15528 /* Input mixer control */
15529 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15530 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15531 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15533 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15537 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15538 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15539
22309c3e
TI
15540 {
15541 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15542 .name = "Channel Mode",
15543 .info = alc_ch_mode_info,
15544 .get = alc_ch_mode_get,
15545 .put = alc_ch_mode_put,
15546 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15547 },
15548 { } /* end */
f12ab1e0 15549};
7cdbff94 15550
a9111321 15551static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15552 /* output mixer control */
15553 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15557 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15558
15559 /* Input mixer control */
15560 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15562 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15563 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15564 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15565 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15566 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15567 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15568 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15569 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15570
7cdbff94
MD
15571 {
15572 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15573 .name = "Channel Mode",
15574 .info = alc_ch_mode_info,
15575 .get = alc_ch_mode_get,
15576 .put = alc_ch_mode_put,
15577 .private_value = ARRAY_SIZE(alc861_asus_modes),
15578 },
15579 { }
56bb0cab
TI
15580};
15581
15582/* additional mixer */
a9111321 15583static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15584 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15585 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15586 { }
15587};
7cdbff94 15588
df694daa
KY
15589/*
15590 * generic initialization of ADC, input mixers and output mixers
15591 */
a9111321 15592static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15593 /*
15594 * Unmute ADC0 and set the default input to mic-in
15595 */
15596 /* port-A for surround (rear panel) */
15597 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15598 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15599 /* port-B for mic-in (rear panel) with vref */
15600 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15601 /* port-C for line-in (rear panel) */
15602 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15603 /* port-D for Front */
15604 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15605 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15606 /* port-E for HP out (front panel) */
15607 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15608 /* route front PCM to HP */
9dece1d7 15609 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15610 /* port-F for mic-in (front panel) with vref */
15611 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15612 /* port-G for CLFE (rear panel) */
15613 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15614 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15615 /* port-H for side (rear panel) */
15616 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15617 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15618 /* CD-in */
15619 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15620 /* route front mic to ADC1*/
15621 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15622 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15623
df694daa
KY
15624 /* Unmute DAC0~3 & spdif out*/
15625 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15628 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15629 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15630
df694daa
KY
15631 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15632 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15635 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15636
df694daa
KY
15637 /* Unmute Stereo Mixer 15 */
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15641 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15642
15643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15648 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15650 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15651 /* hp used DAC 3 (Front) */
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15653 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15654
15655 { }
15656};
15657
a9111321 15658static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15659 /*
15660 * Unmute ADC0 and set the default input to mic-in
15661 */
15662 /* port-A for surround (rear panel) */
15663 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15664 /* port-B for mic-in (rear panel) with vref */
15665 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15666 /* port-C for line-in (rear panel) */
15667 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15668 /* port-D for Front */
15669 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15670 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15671 /* port-E for HP out (front panel) */
15672 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15673 /* route front PCM to HP */
9dece1d7 15674 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15675 /* port-F for mic-in (front panel) with vref */
15676 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15677 /* port-G for CLFE (rear panel) */
15678 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15679 /* port-H for side (rear panel) */
15680 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15681 /* CD-in */
15682 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15683 /* route front mic to ADC1*/
15684 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15685 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15686 /* Unmute DAC0~3 & spdif out*/
15687 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15690 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15692
df694daa
KY
15693 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15694 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15695 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15696 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15697 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15698
df694daa
KY
15699 /* Unmute Stereo Mixer 15 */
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15704
15705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15710 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15711 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15713 /* hp used DAC 3 (Front) */
15714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15715 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15716 { }
15717};
22309c3e 15718
a9111321 15719static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15720 /*
15721 * Unmute ADC0 and set the default input to mic-in
15722 */
15723 /* port-A for surround (rear panel) */
15724 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15725 /* port-B for mic-in (rear panel) with vref */
15726 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15727 /* port-C for line-in (rear panel) */
15728 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15729 /* port-D for Front */
15730 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15731 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15732 /* port-E for HP out (front panel) */
f12ab1e0
TI
15733 /* this has to be set to VREF80 */
15734 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15735 /* route front PCM to HP */
9dece1d7 15736 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15737 /* port-F for mic-in (front panel) with vref */
15738 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15739 /* port-G for CLFE (rear panel) */
15740 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15741 /* port-H for side (rear panel) */
15742 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15743 /* CD-in */
15744 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15745 /* route front mic to ADC1*/
15746 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15747 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15748 /* Unmute DAC0~3 & spdif out*/
15749 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15754
22309c3e
TI
15755 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15756 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15757 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15758 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15760
22309c3e
TI
15761 /* Unmute Stereo Mixer 15 */
15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15766
15767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15768 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15772 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15775 /* hp used DAC 3 (Front) */
15776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15778 { }
15779};
15780
a9111321 15781static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15782 /*
15783 * Unmute ADC0 and set the default input to mic-in
15784 */
f12ab1e0
TI
15785 /* port-A for surround (rear panel)
15786 * according to codec#0 this is the HP jack
15787 */
7cdbff94
MD
15788 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15789 /* route front PCM to HP */
15790 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15791 /* port-B for mic-in (rear panel) with vref */
15792 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15793 /* port-C for line-in (rear panel) */
15794 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15795 /* port-D for Front */
15796 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15797 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15798 /* port-E for HP out (front panel) */
f12ab1e0
TI
15799 /* this has to be set to VREF80 */
15800 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15801 /* route front PCM to HP */
9dece1d7 15802 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15803 /* port-F for mic-in (front panel) with vref */
15804 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15805 /* port-G for CLFE (rear panel) */
15806 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15807 /* port-H for side (rear panel) */
15808 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15809 /* CD-in */
15810 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15811 /* route front mic to ADC1*/
15812 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15813 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15814 /* Unmute DAC0~3 & spdif out*/
15815 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15816 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15820 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15821 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15822 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15823 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15824 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15825
7cdbff94
MD
15826 /* Unmute Stereo Mixer 15 */
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15830 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15831
15832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15833 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15835 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15837 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15839 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15840 /* hp used DAC 3 (Front) */
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15842 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15843 { }
15844};
15845
56bb0cab 15846/* additional init verbs for ASUS laptops */
a9111321 15847static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15848 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15849 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15850 { }
15851};
7cdbff94 15852
df694daa
KY
15853/*
15854 * generic initialization of ADC, input mixers and output mixers
15855 */
a9111321 15856static const struct hda_verb alc861_auto_init_verbs[] = {
df694daa
KY
15857 /*
15858 * Unmute ADC0 and set the default input to mic-in
15859 */
f12ab1e0 15860 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15861 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15862
df694daa
KY
15863 /* Unmute DAC0~3 & spdif out*/
15864 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15865 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15866 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15867 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15868 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15869
df694daa
KY
15870 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15871 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15872 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15873 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15874 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15875
df694daa
KY
15876 /* Unmute Stereo Mixer 15 */
15877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15880 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15881
1c20930a
TI
15882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15883 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15885 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15887 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15889 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15890
15891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15894 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15896 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15897 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15898 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15899
f12ab1e0 15900 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15901
15902 { }
15903};
15904
a9111321 15905static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15906 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15907
a53d1aec
TD
15908 { }
15909};
15910
15911/* toggle speaker-output according to the hp-jack state */
15912static void alc861_toshiba_automute(struct hda_codec *codec)
15913{
864f92be 15914 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15915
47fd830a
TI
15916 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15917 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15918 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15919 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15920}
15921
15922static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15923 unsigned int res)
15924{
a53d1aec
TD
15925 if ((res >> 26) == ALC880_HP_EVENT)
15926 alc861_toshiba_automute(codec);
15927}
15928
def319f9 15929/* pcm configuration: identical with ALC880 */
df694daa
KY
15930#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15931#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15932#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15933#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15934
15935
15936#define ALC861_DIGOUT_NID 0x07
15937
a9111321 15938static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15939 { 8, NULL }
15940};
15941
4c6d72d1 15942static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15943 /* front, surround, clfe, side */
15944 0x03, 0x06, 0x05, 0x04
15945};
15946
4c6d72d1 15947static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15948 /* front, clfe, surround */
15949 0x03, 0x05, 0x06
15950};
15951
4c6d72d1 15952static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15953 /* ADC0-2 */
15954 0x08,
15955};
15956
a9111321 15957static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15958 .num_items = 5,
15959 .items = {
15960 { "Mic", 0x0 },
15961 { "Front Mic", 0x3 },
15962 { "Line", 0x1 },
15963 { "CD", 0x4 },
15964 { "Mixer", 0x5 },
15965 },
15966};
15967
1c20930a
TI
15968static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15969{
15970 struct alc_spec *spec = codec->spec;
15971 hda_nid_t mix, srcs[5];
15972 int i, j, num;
15973
15974 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15975 return 0;
15976 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15977 if (num < 0)
15978 return 0;
15979 for (i = 0; i < num; i++) {
15980 unsigned int type;
a22d543a 15981 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15982 if (type != AC_WID_AUD_OUT)
15983 continue;
15984 for (j = 0; j < spec->multiout.num_dacs; j++)
15985 if (spec->multiout.dac_nids[j] == srcs[i])
15986 break;
15987 if (j >= spec->multiout.num_dacs)
15988 return srcs[i];
15989 }
15990 return 0;
15991}
15992
df694daa 15993/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15994static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15995 const struct auto_pin_cfg *cfg)
df694daa 15996{
1c20930a 15997 struct alc_spec *spec = codec->spec;
df694daa 15998 int i;
1c20930a 15999 hda_nid_t nid, dac;
df694daa
KY
16000
16001 spec->multiout.dac_nids = spec->private_dac_nids;
16002 for (i = 0; i < cfg->line_outs; i++) {
16003 nid = cfg->line_out_pins[i];
1c20930a
TI
16004 dac = alc861_look_for_dac(codec, nid);
16005 if (!dac)
16006 continue;
dda14410 16007 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 16008 }
df694daa
KY
16009 return 0;
16010}
16011
bcb2f0f5
TI
16012static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16013 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 16014{
bcb2f0f5 16015 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
16016 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16017}
16018
bcb2f0f5
TI
16019#define alc861_create_out_sw(codec, pfx, nid, chs) \
16020 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16021
df694daa 16022/* add playback controls from the parsed DAC table */
1c20930a 16023static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
16024 const struct auto_pin_cfg *cfg)
16025{
1c20930a 16026 struct alc_spec *spec = codec->spec;
ea734963 16027 static const char * const chname[4] = {
f12ab1e0
TI
16028 "Front", "Surround", NULL /*CLFE*/, "Side"
16029 };
ce764ab2 16030 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 16031 hda_nid_t nid;
ce764ab2 16032 int i, err, noutputs;
1c20930a 16033
ce764ab2
TI
16034 noutputs = cfg->line_outs;
16035 if (spec->multi_ios > 0)
16036 noutputs += spec->multi_ios;
16037
16038 for (i = 0; i < noutputs; i++) {
df694daa 16039 nid = spec->multiout.dac_nids[i];
f12ab1e0 16040 if (!nid)
df694daa 16041 continue;
bcb2f0f5 16042 if (!pfx && i == 2) {
df694daa 16043 /* Center/LFE */
1c20930a 16044 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16045 if (err < 0)
df694daa 16046 return err;
1c20930a 16047 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16048 if (err < 0)
df694daa
KY
16049 return err;
16050 } else {
bcb2f0f5 16051 const char *name = pfx;
5a882646
DH
16052 int index = i;
16053 if (!name) {
bcb2f0f5 16054 name = chname[i];
5a882646
DH
16055 index = 0;
16056 }
16057 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16058 if (err < 0)
df694daa
KY
16059 return err;
16060 }
16061 }
16062 return 0;
16063}
16064
1c20930a 16065static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16066{
1c20930a 16067 struct alc_spec *spec = codec->spec;
df694daa
KY
16068 int err;
16069 hda_nid_t nid;
16070
f12ab1e0 16071 if (!pin)
df694daa
KY
16072 return 0;
16073
16074 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16075 nid = alc861_look_for_dac(codec, pin);
16076 if (nid) {
16077 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16078 if (err < 0)
16079 return err;
16080 spec->multiout.hp_nid = nid;
16081 }
df694daa
KY
16082 }
16083 return 0;
16084}
16085
16086/* create playback/capture controls for input pins */
05f5f477 16087static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16088 const struct auto_pin_cfg *cfg)
df694daa 16089{
05f5f477 16090 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16091}
16092
f12ab1e0
TI
16093static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16094 hda_nid_t nid,
1c20930a 16095 int pin_type, hda_nid_t dac)
df694daa 16096{
1c20930a
TI
16097 hda_nid_t mix, srcs[5];
16098 int i, num;
16099
564c5bea
JL
16100 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16101 pin_type);
1c20930a 16102 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16103 AMP_OUT_UNMUTE);
1c20930a
TI
16104 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16105 return;
16106 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16107 if (num < 0)
16108 return;
16109 for (i = 0; i < num; i++) {
16110 unsigned int mute;
16111 if (srcs[i] == dac || srcs[i] == 0x15)
16112 mute = AMP_IN_UNMUTE(i);
16113 else
16114 mute = AMP_IN_MUTE(i);
16115 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16116 mute);
16117 }
df694daa
KY
16118}
16119
16120static void alc861_auto_init_multi_out(struct hda_codec *codec)
16121{
16122 struct alc_spec *spec = codec->spec;
16123 int i;
16124
16125 for (i = 0; i < spec->autocfg.line_outs; i++) {
16126 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16127 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16128 if (nid)
baba8ee9 16129 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16130 spec->multiout.dac_nids[i]);
df694daa
KY
16131 }
16132}
16133
16134static void alc861_auto_init_hp_out(struct hda_codec *codec)
16135{
16136 struct alc_spec *spec = codec->spec;
df694daa 16137
15870f05
TI
16138 if (spec->autocfg.hp_outs)
16139 alc861_auto_set_output_and_unmute(codec,
16140 spec->autocfg.hp_pins[0],
16141 PIN_HP,
1c20930a 16142 spec->multiout.hp_nid);
15870f05
TI
16143 if (spec->autocfg.speaker_outs)
16144 alc861_auto_set_output_and_unmute(codec,
16145 spec->autocfg.speaker_pins[0],
16146 PIN_OUT,
1c20930a 16147 spec->multiout.dac_nids[0]);
df694daa
KY
16148}
16149
16150static void alc861_auto_init_analog_input(struct hda_codec *codec)
16151{
16152 struct alc_spec *spec = codec->spec;
66ceeb6b 16153 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16154 int i;
16155
66ceeb6b
TI
16156 for (i = 0; i < cfg->num_inputs; i++) {
16157 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16158 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16159 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16160 }
16161}
16162
16163/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16164/* return 1 if successful, 0 if the proper config is not found,
16165 * or a negative error code
16166 */
df694daa
KY
16167static int alc861_parse_auto_config(struct hda_codec *codec)
16168{
16169 struct alc_spec *spec = codec->spec;
16170 int err;
4c6d72d1 16171 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16172
f12ab1e0
TI
16173 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16174 alc861_ignore);
16175 if (err < 0)
df694daa 16176 return err;
f12ab1e0 16177 if (!spec->autocfg.line_outs)
df694daa
KY
16178 return 0; /* can't find valid BIOS pin config */
16179
1c20930a 16180 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16181 if (err < 0)
16182 return err;
16183 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16184 if (err < 0)
16185 return err;
1c20930a 16186 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16187 if (err < 0)
16188 return err;
1c20930a 16189 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16190 if (err < 0)
16191 return err;
05f5f477 16192 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16193 if (err < 0)
df694daa
KY
16194 return err;
16195
16196 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16197
757899ac 16198 alc_auto_parse_digital(codec);
df694daa 16199
603c4019 16200 if (spec->kctls.list)
d88897ea 16201 add_mixer(spec, spec->kctls.list);
df694daa 16202
d88897ea 16203 add_verb(spec, alc861_auto_init_verbs);
df694daa 16204
a1e8d2da 16205 spec->num_mux_defs = 1;
61b9b9b1 16206 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16207
16208 spec->adc_nids = alc861_adc_nids;
16209 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16210 set_capture_mixer(codec);
df694daa 16211
6227cdce 16212 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16213
df694daa
KY
16214 return 1;
16215}
16216
ae6b813a
TI
16217/* additional initialization for auto-configuration model */
16218static void alc861_auto_init(struct hda_codec *codec)
df694daa 16219{
f6c7e546 16220 struct alc_spec *spec = codec->spec;
df694daa
KY
16221 alc861_auto_init_multi_out(codec);
16222 alc861_auto_init_hp_out(codec);
16223 alc861_auto_init_analog_input(codec);
757899ac 16224 alc_auto_init_digital(codec);
f6c7e546 16225 if (spec->unsol_event)
7fb0d78f 16226 alc_inithook(codec);
df694daa
KY
16227}
16228
cb53c626 16229#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16230static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16231 { 0x15, HDA_INPUT, 0 },
16232 { 0x15, HDA_INPUT, 1 },
16233 { 0x15, HDA_INPUT, 2 },
16234 { 0x15, HDA_INPUT, 3 },
16235 { } /* end */
16236};
16237#endif
16238
df694daa
KY
16239
16240/*
16241 * configuration and preset
16242 */
ea734963 16243static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16244 [ALC861_3ST] = "3stack",
16245 [ALC660_3ST] = "3stack-660",
16246 [ALC861_3ST_DIG] = "3stack-dig",
16247 [ALC861_6ST_DIG] = "6stack-dig",
16248 [ALC861_UNIWILL_M31] = "uniwill-m31",
16249 [ALC861_TOSHIBA] = "toshiba",
16250 [ALC861_ASUS] = "asus",
16251 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16252 [ALC861_AUTO] = "auto",
16253};
16254
a9111321 16255static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16256 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16257 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16258 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16259 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16260 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16261 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16262 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16263 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16264 * Any other models that need this preset?
16265 */
16266 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16267 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16268 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16269 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16270 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16271 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16272 /* FIXME: the below seems conflict */
16273 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16274 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16275 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16276 {}
16277};
16278
a9111321 16279static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16280 [ALC861_3ST] = {
16281 .mixers = { alc861_3ST_mixer },
16282 .init_verbs = { alc861_threestack_init_verbs },
16283 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16284 .dac_nids = alc861_dac_nids,
16285 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16286 .channel_mode = alc861_threestack_modes,
4e195a7b 16287 .need_dac_fix = 1,
df694daa
KY
16288 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16289 .adc_nids = alc861_adc_nids,
16290 .input_mux = &alc861_capture_source,
16291 },
16292 [ALC861_3ST_DIG] = {
16293 .mixers = { alc861_base_mixer },
16294 .init_verbs = { alc861_threestack_init_verbs },
16295 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16296 .dac_nids = alc861_dac_nids,
16297 .dig_out_nid = ALC861_DIGOUT_NID,
16298 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16299 .channel_mode = alc861_threestack_modes,
4e195a7b 16300 .need_dac_fix = 1,
df694daa
KY
16301 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16302 .adc_nids = alc861_adc_nids,
16303 .input_mux = &alc861_capture_source,
16304 },
16305 [ALC861_6ST_DIG] = {
16306 .mixers = { alc861_base_mixer },
16307 .init_verbs = { alc861_base_init_verbs },
16308 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16309 .dac_nids = alc861_dac_nids,
16310 .dig_out_nid = ALC861_DIGOUT_NID,
16311 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16312 .channel_mode = alc861_8ch_modes,
16313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16314 .adc_nids = alc861_adc_nids,
16315 .input_mux = &alc861_capture_source,
16316 },
9c7f852e
TI
16317 [ALC660_3ST] = {
16318 .mixers = { alc861_3ST_mixer },
16319 .init_verbs = { alc861_threestack_init_verbs },
16320 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16321 .dac_nids = alc660_dac_nids,
16322 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16323 .channel_mode = alc861_threestack_modes,
4e195a7b 16324 .need_dac_fix = 1,
9c7f852e
TI
16325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16326 .adc_nids = alc861_adc_nids,
16327 .input_mux = &alc861_capture_source,
16328 },
22309c3e
TI
16329 [ALC861_UNIWILL_M31] = {
16330 .mixers = { alc861_uniwill_m31_mixer },
16331 .init_verbs = { alc861_uniwill_m31_init_verbs },
16332 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16333 .dac_nids = alc861_dac_nids,
16334 .dig_out_nid = ALC861_DIGOUT_NID,
16335 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16336 .channel_mode = alc861_uniwill_m31_modes,
16337 .need_dac_fix = 1,
16338 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16339 .adc_nids = alc861_adc_nids,
16340 .input_mux = &alc861_capture_source,
16341 },
a53d1aec
TD
16342 [ALC861_TOSHIBA] = {
16343 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16344 .init_verbs = { alc861_base_init_verbs,
16345 alc861_toshiba_init_verbs },
a53d1aec
TD
16346 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16347 .dac_nids = alc861_dac_nids,
16348 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16349 .channel_mode = alc883_3ST_2ch_modes,
16350 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16351 .adc_nids = alc861_adc_nids,
16352 .input_mux = &alc861_capture_source,
16353 .unsol_event = alc861_toshiba_unsol_event,
16354 .init_hook = alc861_toshiba_automute,
16355 },
7cdbff94
MD
16356 [ALC861_ASUS] = {
16357 .mixers = { alc861_asus_mixer },
16358 .init_verbs = { alc861_asus_init_verbs },
16359 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16360 .dac_nids = alc861_dac_nids,
16361 .dig_out_nid = ALC861_DIGOUT_NID,
16362 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16363 .channel_mode = alc861_asus_modes,
16364 .need_dac_fix = 1,
16365 .hp_nid = 0x06,
16366 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16367 .adc_nids = alc861_adc_nids,
16368 .input_mux = &alc861_capture_source,
16369 },
56bb0cab
TI
16370 [ALC861_ASUS_LAPTOP] = {
16371 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16372 .init_verbs = { alc861_asus_init_verbs,
16373 alc861_asus_laptop_init_verbs },
16374 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16375 .dac_nids = alc861_dac_nids,
16376 .dig_out_nid = ALC861_DIGOUT_NID,
16377 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16378 .channel_mode = alc883_3ST_2ch_modes,
16379 .need_dac_fix = 1,
16380 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16381 .adc_nids = alc861_adc_nids,
16382 .input_mux = &alc861_capture_source,
16383 },
16384};
df694daa 16385
cfc9b06f
TI
16386/* Pin config fixes */
16387enum {
16388 PINFIX_FSC_AMILO_PI1505,
16389};
16390
cfc9b06f
TI
16391static const struct alc_fixup alc861_fixups[] = {
16392 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16393 .type = ALC_FIXUP_PINS,
16394 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16395 { 0x0b, 0x0221101f }, /* HP */
16396 { 0x0f, 0x90170310 }, /* speaker */
16397 { }
16398 }
cfc9b06f
TI
16399 },
16400};
16401
a9111321 16402static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16403 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16404 {}
16405};
df694daa
KY
16406
16407static int patch_alc861(struct hda_codec *codec)
16408{
16409 struct alc_spec *spec;
16410 int board_config;
16411 int err;
16412
dc041e0b 16413 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16414 if (spec == NULL)
16415 return -ENOMEM;
16416
f12ab1e0 16417 codec->spec = spec;
df694daa 16418
f5fcc13c
TI
16419 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16420 alc861_models,
16421 alc861_cfg_tbl);
9c7f852e 16422
f5fcc13c 16423 if (board_config < 0) {
9a11f1aa
TI
16424 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16425 codec->chip_name);
df694daa
KY
16426 board_config = ALC861_AUTO;
16427 }
16428
b5bfbc67
TI
16429 if (board_config == ALC861_AUTO) {
16430 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16431 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16432 }
cfc9b06f 16433
df694daa
KY
16434 if (board_config == ALC861_AUTO) {
16435 /* automatic parse from the BIOS config */
16436 err = alc861_parse_auto_config(codec);
16437 if (err < 0) {
16438 alc_free(codec);
16439 return err;
f12ab1e0 16440 } else if (!err) {
9c7f852e
TI
16441 printk(KERN_INFO
16442 "hda_codec: Cannot set up configuration "
16443 "from BIOS. Using base mode...\n");
df694daa
KY
16444 board_config = ALC861_3ST_DIG;
16445 }
16446 }
16447
680cd536
KK
16448 err = snd_hda_attach_beep_device(codec, 0x23);
16449 if (err < 0) {
16450 alc_free(codec);
16451 return err;
16452 }
16453
df694daa 16454 if (board_config != ALC861_AUTO)
e9c364c0 16455 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16456
df694daa
KY
16457 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16458 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16459
df694daa
KY
16460 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16461 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16462
c7a8eb10
TI
16463 if (!spec->cap_mixer)
16464 set_capture_mixer(codec);
45bdd1c1
TI
16465 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16466
2134ea4f
TI
16467 spec->vmaster_nid = 0x03;
16468
b5bfbc67 16469 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16470
df694daa 16471 codec->patch_ops = alc_patch_ops;
c97259df 16472 if (board_config == ALC861_AUTO) {
ae6b813a 16473 spec->init_hook = alc861_auto_init;
c97259df
DC
16474#ifdef CONFIG_SND_HDA_POWER_SAVE
16475 spec->power_hook = alc_power_eapd;
16476#endif
16477 }
cb53c626
TI
16478#ifdef CONFIG_SND_HDA_POWER_SAVE
16479 if (!spec->loopback.amplist)
16480 spec->loopback.amplist = alc861_loopbacks;
16481#endif
ea1fb29a 16482
1da177e4
LT
16483 return 0;
16484}
16485
f32610ed
JS
16486/*
16487 * ALC861-VD support
16488 *
16489 * Based on ALC882
16490 *
16491 * In addition, an independent DAC
16492 */
16493#define ALC861VD_DIGOUT_NID 0x06
16494
4c6d72d1 16495static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16496 /* front, surr, clfe, side surr */
16497 0x02, 0x03, 0x04, 0x05
16498};
16499
16500/* dac_nids for ALC660vd are in a different order - according to
16501 * Realtek's driver.
def319f9 16502 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16503 * of ALC660vd codecs, but for now there is only 3stack mixer
16504 * - and it is the same as in 861vd.
16505 * adc_nids in ALC660vd are (is) the same as in 861vd
16506 */
4c6d72d1 16507static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16508 /* front, rear, clfe, rear_surr */
16509 0x02, 0x04, 0x03
16510};
16511
4c6d72d1 16512static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16513 /* ADC0 */
16514 0x09,
16515};
16516
4c6d72d1 16517static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16518
f32610ed
JS
16519/* input MUX */
16520/* FIXME: should be a matrix-type input source selection */
a9111321 16521static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16522 .num_items = 4,
16523 .items = {
16524 { "Mic", 0x0 },
16525 { "Front Mic", 0x1 },
16526 { "Line", 0x2 },
16527 { "CD", 0x4 },
16528 },
16529};
16530
a9111321 16531static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16532 .num_items = 2,
272a527c 16533 .items = {
8607f7c4 16534 { "Mic", 0x0 },
28c4edb7 16535 { "Internal Mic", 0x1 },
272a527c
KY
16536 },
16537};
16538
a9111321 16539static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16540 .num_items = 2,
16541 .items = {
16542 { "Front Mic", 0x0 },
16543 { "ATAPI Mic", 0x1 },
16544 },
16545};
16546
f32610ed
JS
16547/*
16548 * 2ch mode
16549 */
a9111321 16550static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16551 { 2, NULL }
16552};
16553
16554/*
16555 * 6ch mode
16556 */
a9111321 16557static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16558 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16559 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16560 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16561 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16562 { } /* end */
16563};
16564
16565/*
16566 * 8ch mode
16567 */
a9111321 16568static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16569 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16571 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16572 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16573 { } /* end */
16574};
16575
a9111321 16576static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16577 { 6, alc861vd_6stack_ch6_init },
16578 { 8, alc861vd_6stack_ch8_init },
16579};
16580
a9111321 16581static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16582 {
16583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16584 .name = "Channel Mode",
16585 .info = alc_ch_mode_info,
16586 .get = alc_ch_mode_get,
16587 .put = alc_ch_mode_put,
16588 },
16589 { } /* end */
16590};
16591
f32610ed
JS
16592/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16593 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16594 */
a9111321 16595static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16597 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16598
16599 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16600 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16601
16602 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16603 HDA_OUTPUT),
16604 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16605 HDA_OUTPUT),
16606 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16607 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16608
16609 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16610 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16611
16612 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16613
5f99f86a 16614 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16615 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16616 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16617
5f99f86a 16618 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16619 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16620 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16621
16622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16624
16625 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16626 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16627
f32610ed
JS
16628 { } /* end */
16629};
16630
a9111321 16631static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16632 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16633 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16634
16635 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16636
5f99f86a 16637 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16640
5f99f86a 16641 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16644
16645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16647
16648 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16649 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16650
f32610ed
JS
16651 { } /* end */
16652};
16653
a9111321 16654static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16655 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16656 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16657 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16658
16659 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16660
5f99f86a 16661 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16664
5f99f86a 16665 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16666 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16667 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16668
16669 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16670 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16671
16672 { } /* end */
16673};
16674
b419f346 16675/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16676 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16677 */
a9111321 16678static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16679 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16680 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16681 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16682 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16683 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16684 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16685 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16686 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16687 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16688 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16689 { } /* end */
16690};
16691
d1a991a6
KY
16692/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16693 * Front Mic=0x18, ATAPI Mic = 0x19,
16694 */
a9111321 16695static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16696 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16697 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16698 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16699 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16700 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16701 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16702 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16703 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16704
d1a991a6
KY
16705 { } /* end */
16706};
16707
f32610ed
JS
16708/*
16709 * generic initialization of ADC, input mixers and output mixers
16710 */
a9111321 16711static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16712 /*
16713 * Unmute ADC0 and set the default input to mic-in
16714 */
16715 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16716 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16717
16718 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16719 * the analog-loopback mixer widget
16720 */
16721 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16727
16728 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16732 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16733
16734 /*
16735 * Set up output mixers (0x02 - 0x05)
16736 */
16737 /* set vol=0 to output mixers */
16738 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16740 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16741 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16742
16743 /* set up input amps for analog loopback */
16744 /* Amp Indices: DAC = 0, mixer = 1 */
16745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16746 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16748 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16750 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16752 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16753
16754 { }
16755};
16756
16757/*
16758 * 3-stack pin configuration:
16759 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16760 */
a9111321 16761static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16762 /*
16763 * Set pin mode and muting
16764 */
16765 /* set front pin widgets 0x14 for output */
16766 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16768 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16769
16770 /* Mic (rear) pin: input vref at 80% */
16771 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16772 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16773 /* Front Mic pin: input vref at 80% */
16774 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16776 /* Line In pin: input */
16777 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16778 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16779 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16780 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16781 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16782 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16783 /* CD pin widget for input */
16784 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16785
16786 { }
16787};
16788
16789/*
16790 * 6-stack pin configuration:
16791 */
a9111321 16792static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16793 /*
16794 * Set pin mode and muting
16795 */
16796 /* set front pin widgets 0x14 for output */
16797 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16798 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16799 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16800
16801 /* Rear Pin: output 1 (0x0d) */
16802 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16803 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16804 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16805 /* CLFE Pin: output 2 (0x0e) */
16806 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16808 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16809 /* Side Pin: output 3 (0x0f) */
16810 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16811 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16812 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16813
16814 /* Mic (rear) pin: input vref at 80% */
16815 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16817 /* Front Mic pin: input vref at 80% */
16818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16820 /* Line In pin: input */
16821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16822 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16823 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16826 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16827 /* CD pin widget for input */
16828 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16829
16830 { }
16831};
16832
a9111321 16833static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16834 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16835 { }
16836};
16837
a9111321 16838static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16839 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16840 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16841 { }
16842};
16843
a9111321 16844static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16846 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16847 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16848 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16849 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16850 {}
16851};
16852
4f5d1706 16853static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16854{
a9fd4f3f 16855 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16856 spec->autocfg.hp_pins[0] = 0x1b;
16857 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16858 spec->automute = 1;
16859 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16860}
16861
16862static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16863{
d922b51d 16864 alc_hp_automute(codec);
eeb43387 16865 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16866}
16867
16868static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16869 unsigned int res)
16870{
16871 switch (res >> 26) {
bdd148a3 16872 case ALC880_MIC_EVENT:
eeb43387 16873 alc88x_simple_mic_automute(codec);
bdd148a3 16874 break;
a9fd4f3f 16875 default:
d922b51d 16876 alc_sku_unsol_event(codec, res);
a9fd4f3f 16877 break;
bdd148a3
KY
16878 }
16879}
16880
a9111321 16881static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16882 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16883 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16884 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16885 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16886
16887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16888 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16890 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16892 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16894 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16895
272a527c
KY
16896 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16897 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16898 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16899 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16900 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16901 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16902 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16903 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16904
16905 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16906 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16907 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16909 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16910 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16911 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16912 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16913
16914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16918
16919 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16920 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16921 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16922
16923 { } /* end */
16924};
16925
16926/* toggle speaker-output according to the hp-jack state */
4f5d1706 16927static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16928{
a9fd4f3f 16929 struct alc_spec *spec = codec->spec;
272a527c 16930
a9fd4f3f
TI
16931 spec->autocfg.hp_pins[0] = 0x15;
16932 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16933 spec->automute = 1;
16934 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16935}
16936
cb53c626
TI
16937#ifdef CONFIG_SND_HDA_POWER_SAVE
16938#define alc861vd_loopbacks alc880_loopbacks
16939#endif
16940
def319f9 16941/* pcm configuration: identical with ALC880 */
f32610ed
JS
16942#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16943#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16944#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16945#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16946
16947/*
16948 * configuration and preset
16949 */
ea734963 16950static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16951 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16952 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16953 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16954 [ALC861VD_3ST] = "3stack",
16955 [ALC861VD_3ST_DIG] = "3stack-digout",
16956 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16957 [ALC861VD_LENOVO] = "lenovo",
272a527c 16958 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16959 [ALC861VD_HP] = "hp",
f32610ed
JS
16960 [ALC861VD_AUTO] = "auto",
16961};
16962
a9111321 16963static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16964 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16965 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16966 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16967 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16968 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16969 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16970 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16971 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16972 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16973 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16974 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16975 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16976 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16977 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16978 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16979 {}
16980};
16981
a9111321 16982static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16983 [ALC660VD_3ST] = {
16984 .mixers = { alc861vd_3st_mixer },
16985 .init_verbs = { alc861vd_volume_init_verbs,
16986 alc861vd_3stack_init_verbs },
16987 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16988 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16989 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16990 .channel_mode = alc861vd_3stack_2ch_modes,
16991 .input_mux = &alc861vd_capture_source,
16992 },
6963f84c
MC
16993 [ALC660VD_3ST_DIG] = {
16994 .mixers = { alc861vd_3st_mixer },
16995 .init_verbs = { alc861vd_volume_init_verbs,
16996 alc861vd_3stack_init_verbs },
16997 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16998 .dac_nids = alc660vd_dac_nids,
16999 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
17000 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17001 .channel_mode = alc861vd_3stack_2ch_modes,
17002 .input_mux = &alc861vd_capture_source,
17003 },
f32610ed
JS
17004 [ALC861VD_3ST] = {
17005 .mixers = { alc861vd_3st_mixer },
17006 .init_verbs = { alc861vd_volume_init_verbs,
17007 alc861vd_3stack_init_verbs },
17008 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17009 .dac_nids = alc861vd_dac_nids,
17010 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17011 .channel_mode = alc861vd_3stack_2ch_modes,
17012 .input_mux = &alc861vd_capture_source,
17013 },
17014 [ALC861VD_3ST_DIG] = {
17015 .mixers = { alc861vd_3st_mixer },
17016 .init_verbs = { alc861vd_volume_init_verbs,
17017 alc861vd_3stack_init_verbs },
17018 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17019 .dac_nids = alc861vd_dac_nids,
17020 .dig_out_nid = ALC861VD_DIGOUT_NID,
17021 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17022 .channel_mode = alc861vd_3stack_2ch_modes,
17023 .input_mux = &alc861vd_capture_source,
17024 },
17025 [ALC861VD_6ST_DIG] = {
17026 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17027 .init_verbs = { alc861vd_volume_init_verbs,
17028 alc861vd_6stack_init_verbs },
17029 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17030 .dac_nids = alc861vd_dac_nids,
17031 .dig_out_nid = ALC861VD_DIGOUT_NID,
17032 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17033 .channel_mode = alc861vd_6stack_modes,
17034 .input_mux = &alc861vd_capture_source,
17035 },
bdd148a3
KY
17036 [ALC861VD_LENOVO] = {
17037 .mixers = { alc861vd_lenovo_mixer },
17038 .init_verbs = { alc861vd_volume_init_verbs,
17039 alc861vd_3stack_init_verbs,
17040 alc861vd_eapd_verbs,
17041 alc861vd_lenovo_unsol_verbs },
17042 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17043 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
17044 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17045 .channel_mode = alc861vd_3stack_2ch_modes,
17046 .input_mux = &alc861vd_capture_source,
17047 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17048 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17049 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17050 },
272a527c
KY
17051 [ALC861VD_DALLAS] = {
17052 .mixers = { alc861vd_dallas_mixer },
17053 .init_verbs = { alc861vd_dallas_verbs },
17054 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17055 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17056 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17057 .channel_mode = alc861vd_3stack_2ch_modes,
17058 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 17059 .unsol_event = alc_sku_unsol_event,
4f5d1706 17060 .setup = alc861vd_dallas_setup,
d922b51d 17061 .init_hook = alc_hp_automute,
d1a991a6
KY
17062 },
17063 [ALC861VD_HP] = {
17064 .mixers = { alc861vd_hp_mixer },
17065 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17066 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17067 .dac_nids = alc861vd_dac_nids,
d1a991a6 17068 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17069 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17070 .channel_mode = alc861vd_3stack_2ch_modes,
17071 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17072 .unsol_event = alc_sku_unsol_event,
4f5d1706 17073 .setup = alc861vd_dallas_setup,
d922b51d 17074 .init_hook = alc_hp_automute,
ea1fb29a 17075 },
13c94744
TI
17076 [ALC660VD_ASUS_V1S] = {
17077 .mixers = { alc861vd_lenovo_mixer },
17078 .init_verbs = { alc861vd_volume_init_verbs,
17079 alc861vd_3stack_init_verbs,
17080 alc861vd_eapd_verbs,
17081 alc861vd_lenovo_unsol_verbs },
17082 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17083 .dac_nids = alc660vd_dac_nids,
17084 .dig_out_nid = ALC861VD_DIGOUT_NID,
17085 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17086 .channel_mode = alc861vd_3stack_2ch_modes,
17087 .input_mux = &alc861vd_capture_source,
17088 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17089 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17090 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17091 },
f32610ed
JS
17092};
17093
17094/*
17095 * BIOS auto configuration
17096 */
05f5f477
TI
17097static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17098 const struct auto_pin_cfg *cfg)
17099{
7167594a 17100 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17101}
17102
17103
f32610ed
JS
17104static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17105 hda_nid_t nid, int pin_type, int dac_idx)
17106{
f6c7e546 17107 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17108}
17109
17110static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17111{
17112 struct alc_spec *spec = codec->spec;
17113 int i;
17114
17115 for (i = 0; i <= HDA_SIDE; i++) {
17116 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17117 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17118 if (nid)
17119 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17120 pin_type, i);
f32610ed
JS
17121 }
17122}
17123
17124
17125static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17126{
17127 struct alc_spec *spec = codec->spec;
17128 hda_nid_t pin;
17129
17130 pin = spec->autocfg.hp_pins[0];
def319f9 17131 if (pin) /* connect to front and use dac 0 */
f32610ed 17132 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17133 pin = spec->autocfg.speaker_pins[0];
17134 if (pin)
17135 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17136}
17137
f32610ed
JS
17138#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17139
17140static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17141{
17142 struct alc_spec *spec = codec->spec;
66ceeb6b 17143 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17144 int i;
17145
66ceeb6b
TI
17146 for (i = 0; i < cfg->num_inputs; i++) {
17147 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17148 if (alc_is_input_pin(codec, nid)) {
30ea098f 17149 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17150 if (nid != ALC861VD_PIN_CD_NID &&
17151 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17152 snd_hda_codec_write(codec, nid, 0,
17153 AC_VERB_SET_AMP_GAIN_MUTE,
17154 AMP_OUT_MUTE);
17155 }
17156 }
17157}
17158
f511b01c
TI
17159#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17160
f32610ed
JS
17161#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17162#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17163
17164/* add playback controls from the parsed DAC table */
569ed348 17165/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17166 * different NIDs for mute/unmute switch and volume control */
17167static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17168 const struct auto_pin_cfg *cfg)
17169{
ea734963
TI
17170 static const char * const chname[4] = {
17171 "Front", "Surround", "CLFE", "Side"
17172 };
ce764ab2 17173 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17174 hda_nid_t nid_v, nid_s;
ce764ab2 17175 int i, err, noutputs;
f32610ed 17176
ce764ab2
TI
17177 noutputs = cfg->line_outs;
17178 if (spec->multi_ios > 0)
17179 noutputs += spec->multi_ios;
17180
17181 for (i = 0; i < noutputs; i++) {
f12ab1e0 17182 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17183 continue;
17184 nid_v = alc861vd_idx_to_mixer_vol(
17185 alc880_dac_to_idx(
17186 spec->multiout.dac_nids[i]));
17187 nid_s = alc861vd_idx_to_mixer_switch(
17188 alc880_dac_to_idx(
17189 spec->multiout.dac_nids[i]));
17190
bcb2f0f5 17191 if (!pfx && i == 2) {
f32610ed 17192 /* Center/LFE */
0afe5f89
TI
17193 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17194 "Center",
f12ab1e0
TI
17195 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17196 HDA_OUTPUT));
17197 if (err < 0)
f32610ed 17198 return err;
0afe5f89
TI
17199 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17200 "LFE",
f12ab1e0
TI
17201 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17202 HDA_OUTPUT));
17203 if (err < 0)
f32610ed 17204 return err;
0afe5f89
TI
17205 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17206 "Center",
f12ab1e0
TI
17207 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17208 HDA_INPUT));
17209 if (err < 0)
f32610ed 17210 return err;
0afe5f89
TI
17211 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17212 "LFE",
f12ab1e0
TI
17213 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17214 HDA_INPUT));
17215 if (err < 0)
f32610ed
JS
17216 return err;
17217 } else {
bcb2f0f5 17218 const char *name = pfx;
5a882646
DH
17219 int index = i;
17220 if (!name) {
bcb2f0f5 17221 name = chname[i];
5a882646
DH
17222 index = 0;
17223 }
bcb2f0f5 17224 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17225 name, index,
f12ab1e0
TI
17226 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17227 HDA_OUTPUT));
17228 if (err < 0)
f32610ed 17229 return err;
bcb2f0f5 17230 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17231 name, index,
bdd148a3 17232 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17233 HDA_INPUT));
17234 if (err < 0)
f32610ed
JS
17235 return err;
17236 }
17237 }
17238 return 0;
17239}
17240
17241/* add playback controls for speaker and HP outputs */
17242/* Based on ALC880 version. But ALC861VD has separate,
17243 * different NIDs for mute/unmute switch and volume control */
17244static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17245 hda_nid_t pin, const char *pfx)
17246{
17247 hda_nid_t nid_v, nid_s;
17248 int err;
f32610ed 17249
f12ab1e0 17250 if (!pin)
f32610ed
JS
17251 return 0;
17252
17253 if (alc880_is_fixed_pin(pin)) {
17254 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17255 /* specify the DAC as the extra output */
f12ab1e0 17256 if (!spec->multiout.hp_nid)
f32610ed
JS
17257 spec->multiout.hp_nid = nid_v;
17258 else
17259 spec->multiout.extra_out_nid[0] = nid_v;
17260 /* control HP volume/switch on the output mixer amp */
17261 nid_v = alc861vd_idx_to_mixer_vol(
17262 alc880_fixed_pin_idx(pin));
17263 nid_s = alc861vd_idx_to_mixer_switch(
17264 alc880_fixed_pin_idx(pin));
17265
0afe5f89 17266 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17267 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17268 if (err < 0)
f32610ed 17269 return err;
0afe5f89 17270 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17271 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17272 if (err < 0)
f32610ed
JS
17273 return err;
17274 } else if (alc880_is_multi_pin(pin)) {
17275 /* set manual connection */
17276 /* we have only a switch on HP-out PIN */
0afe5f89 17277 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17278 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17279 if (err < 0)
f32610ed
JS
17280 return err;
17281 }
17282 return 0;
17283}
17284
17285/* parse the BIOS configuration and set up the alc_spec
17286 * return 1 if successful, 0 if the proper config is not found,
17287 * or a negative error code
17288 * Based on ALC880 version - had to change it to override
17289 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17290static int alc861vd_parse_auto_config(struct hda_codec *codec)
17291{
17292 struct alc_spec *spec = codec->spec;
17293 int err;
4c6d72d1 17294 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17295
f12ab1e0
TI
17296 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17297 alc861vd_ignore);
17298 if (err < 0)
f32610ed 17299 return err;
f12ab1e0 17300 if (!spec->autocfg.line_outs)
f32610ed
JS
17301 return 0; /* can't find valid BIOS pin config */
17302
f12ab1e0 17303 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17304 if (err < 0)
17305 return err;
17306 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17307 if (err < 0)
17308 return err;
17309 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17310 if (err < 0)
17311 return err;
17312 err = alc861vd_auto_create_extra_out(spec,
17313 spec->autocfg.speaker_pins[0],
17314 "Speaker");
17315 if (err < 0)
17316 return err;
17317 err = alc861vd_auto_create_extra_out(spec,
17318 spec->autocfg.hp_pins[0],
17319 "Headphone");
17320 if (err < 0)
17321 return err;
05f5f477 17322 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17323 if (err < 0)
f32610ed
JS
17324 return err;
17325
17326 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17327
757899ac 17328 alc_auto_parse_digital(codec);
f32610ed 17329
603c4019 17330 if (spec->kctls.list)
d88897ea 17331 add_mixer(spec, spec->kctls.list);
f32610ed 17332
d88897ea 17333 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17334
17335 spec->num_mux_defs = 1;
61b9b9b1 17336 spec->input_mux = &spec->private_imux[0];
f32610ed 17337
776e184e
TI
17338 err = alc_auto_add_mic_boost(codec);
17339 if (err < 0)
17340 return err;
17341
6227cdce 17342 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17343
f32610ed
JS
17344 return 1;
17345}
17346
17347/* additional initialization for auto-configuration model */
17348static void alc861vd_auto_init(struct hda_codec *codec)
17349{
f6c7e546 17350 struct alc_spec *spec = codec->spec;
f32610ed
JS
17351 alc861vd_auto_init_multi_out(codec);
17352 alc861vd_auto_init_hp_out(codec);
17353 alc861vd_auto_init_analog_input(codec);
f511b01c 17354 alc861vd_auto_init_input_src(codec);
757899ac 17355 alc_auto_init_digital(codec);
f6c7e546 17356 if (spec->unsol_event)
7fb0d78f 17357 alc_inithook(codec);
f32610ed
JS
17358}
17359
f8f25ba3
TI
17360enum {
17361 ALC660VD_FIX_ASUS_GPIO1
17362};
17363
17364/* reset GPIO1 */
f8f25ba3
TI
17365static const struct alc_fixup alc861vd_fixups[] = {
17366 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17367 .type = ALC_FIXUP_VERBS,
17368 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17369 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17370 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17371 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17372 { }
17373 }
f8f25ba3
TI
17374 },
17375};
17376
a9111321 17377static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17378 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17379 {}
17380};
17381
f32610ed
JS
17382static int patch_alc861vd(struct hda_codec *codec)
17383{
17384 struct alc_spec *spec;
17385 int err, board_config;
17386
17387 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17388 if (spec == NULL)
17389 return -ENOMEM;
17390
17391 codec->spec = spec;
17392
17393 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17394 alc861vd_models,
17395 alc861vd_cfg_tbl);
17396
17397 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17398 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17399 codec->chip_name);
f32610ed
JS
17400 board_config = ALC861VD_AUTO;
17401 }
17402
b5bfbc67
TI
17403 if (board_config == ALC861VD_AUTO) {
17404 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17405 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17406 }
f8f25ba3 17407
f32610ed
JS
17408 if (board_config == ALC861VD_AUTO) {
17409 /* automatic parse from the BIOS config */
17410 err = alc861vd_parse_auto_config(codec);
17411 if (err < 0) {
17412 alc_free(codec);
17413 return err;
f12ab1e0 17414 } else if (!err) {
f32610ed
JS
17415 printk(KERN_INFO
17416 "hda_codec: Cannot set up configuration "
17417 "from BIOS. Using base mode...\n");
17418 board_config = ALC861VD_3ST;
17419 }
17420 }
17421
680cd536
KK
17422 err = snd_hda_attach_beep_device(codec, 0x23);
17423 if (err < 0) {
17424 alc_free(codec);
17425 return err;
17426 }
17427
f32610ed 17428 if (board_config != ALC861VD_AUTO)
e9c364c0 17429 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17430
2f893286 17431 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17432 /* always turn on EAPD */
d88897ea 17433 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17434 }
17435
f32610ed
JS
17436 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17437 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17438
f32610ed
JS
17439 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17440 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17441
dd704698
TI
17442 if (!spec->adc_nids) {
17443 spec->adc_nids = alc861vd_adc_nids;
17444 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17445 }
17446 if (!spec->capsrc_nids)
17447 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17448
b59bdf3b 17449 set_capture_mixer(codec);
45bdd1c1 17450 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17451
2134ea4f
TI
17452 spec->vmaster_nid = 0x02;
17453
b5bfbc67 17454 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17455
f32610ed
JS
17456 codec->patch_ops = alc_patch_ops;
17457
17458 if (board_config == ALC861VD_AUTO)
17459 spec->init_hook = alc861vd_auto_init;
1c716153 17460 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17461#ifdef CONFIG_SND_HDA_POWER_SAVE
17462 if (!spec->loopback.amplist)
17463 spec->loopback.amplist = alc861vd_loopbacks;
17464#endif
f32610ed
JS
17465
17466 return 0;
17467}
17468
bc9f98a9
KY
17469/*
17470 * ALC662 support
17471 *
17472 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17473 * configuration. Each pin widget can choose any input DACs and a mixer.
17474 * Each ADC is connected from a mixer of all inputs. This makes possible
17475 * 6-channel independent captures.
17476 *
17477 * In addition, an independent DAC for the multi-playback (not used in this
17478 * driver yet).
17479 */
17480#define ALC662_DIGOUT_NID 0x06
17481#define ALC662_DIGIN_NID 0x0a
17482
4c6d72d1 17483static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17484 /* front, rear, clfe */
bc9f98a9
KY
17485 0x02, 0x03, 0x04
17486};
17487
4c6d72d1 17488static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17489 0x02, 0x03
17490};
17491
4c6d72d1 17492static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17493 /* ADC1-2 */
b59bdf3b 17494 0x09, 0x08
bc9f98a9 17495};
e1406348 17496
4c6d72d1 17497static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17498 /* ADC1-2 */
17499 0x08,
17500};
17501
4c6d72d1
TI
17502static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17503static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17504
e1406348 17505
bc9f98a9
KY
17506/* input MUX */
17507/* FIXME: should be a matrix-type input source selection */
a9111321 17508static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17509 .num_items = 4,
17510 .items = {
17511 { "Mic", 0x0 },
17512 { "Front Mic", 0x1 },
17513 { "Line", 0x2 },
17514 { "CD", 0x4 },
17515 },
17516};
17517
a9111321 17518static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17519 .num_items = 2,
17520 .items = {
17521 { "Mic", 0x1 },
17522 { "Line", 0x2 },
17523 },
17524};
291702f0 17525
a9111321 17526static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17527 .num_items = 3,
17528 .items = {
17529 { "Mic", 0x0 },
17530 { "Front Mic", 0x1 },
17531 { "Line", 0x2 },
17532 },
17533};
17534
4f5d1706 17535#if 0 /* set to 1 for testing other input sources below */
a9111321 17536static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17537 .num_items = 16,
17538 .items = {
17539 { "Autoselect Mic", 0x0 },
17540 { "Internal Mic", 0x1 },
17541 { "In-0x02", 0x2 },
17542 { "In-0x03", 0x3 },
17543 { "In-0x04", 0x4 },
17544 { "In-0x05", 0x5 },
17545 { "In-0x06", 0x6 },
17546 { "In-0x07", 0x7 },
17547 { "In-0x08", 0x8 },
17548 { "In-0x09", 0x9 },
17549 { "In-0x0a", 0x0a },
17550 { "In-0x0b", 0x0b },
17551 { "In-0x0c", 0x0c },
17552 { "In-0x0d", 0x0d },
17553 { "In-0x0e", 0x0e },
17554 { "In-0x0f", 0x0f },
17555 },
17556};
17557#endif
17558
bc9f98a9
KY
17559/*
17560 * 2ch mode
17561 */
a9111321 17562static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17563 { 2, NULL }
17564};
17565
17566/*
17567 * 2ch mode
17568 */
a9111321 17569static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17570 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17571 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17572 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17573 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17574 { } /* end */
17575};
17576
17577/*
17578 * 6ch mode
17579 */
a9111321 17580static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17581 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17582 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17583 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17586 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17587 { } /* end */
17588};
17589
a9111321 17590static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17591 { 2, alc662_3ST_ch2_init },
17592 { 6, alc662_3ST_ch6_init },
17593};
17594
17595/*
17596 * 2ch mode
17597 */
a9111321 17598static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17599 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17600 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17601 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17602 { } /* end */
17603};
17604
17605/*
17606 * 6ch mode
17607 */
a9111321 17608static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17609 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17610 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17611 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17612 { } /* end */
17613};
17614
a9111321 17615static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17616 { 2, alc662_sixstack_ch6_init },
17617 { 6, alc662_sixstack_ch8_init },
17618};
17619
17620/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17621 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17622 */
17623
a9111321 17624static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17625 /* output mixer control */
17626 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17627 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17628 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17629 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17630 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17631 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17632 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17633 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17635
17636 /*Input mixer control */
17637 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17638 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17639 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17640 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17641 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17642 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17643 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17644 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17645 { } /* end */
17646};
17647
a9111321 17648static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17649 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17650 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17652 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17653 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17654 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17655 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17656 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17658 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17659 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17660 { } /* end */
17661};
17662
a9111321 17663static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17664 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17665 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17666 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17667 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17668 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17669 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17670 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17671 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17673 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17674 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17675 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17676 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17677 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17679 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17680 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17681 { } /* end */
17682};
17683
a9111321 17684static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17685 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17686 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17687 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17688 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17689 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17690 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17691 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17694 { } /* end */
17695};
17696
a9111321 17697static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17698 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17699 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17700
5f99f86a 17701 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17702 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17703 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17704
5f99f86a 17705 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17706 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17707 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17708 { } /* end */
17709};
17710
a9111321 17711static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17712 ALC262_HIPPO_MASTER_SWITCH,
17713 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17714 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17715 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17716 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17717 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17718 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17719 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17720 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17721 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17722 { } /* end */
17723};
17724
a9111321 17725static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17726 .ops = &snd_hda_bind_vol,
17727 .values = {
17728 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17729 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17730 0
17731 },
17732};
17733
a9111321 17734static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17735 .ops = &snd_hda_bind_sw,
17736 .values = {
17737 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17738 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17739 0
17740 },
17741};
17742
a9111321 17743static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17744 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17745 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17748 { } /* end */
17749};
17750
a9111321 17751static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17752 .ops = &snd_hda_bind_sw,
17753 .values = {
17754 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17755 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17756 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17757 0
17758 },
17759};
17760
a9111321 17761static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17762 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17763 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17765 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17766 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17767 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17768
17769 { } /* end */
17770};
17771
a9111321 17772static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17773 .ops = &snd_hda_bind_sw,
17774 .values = {
17775 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17777 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17778 0
17779 },
17780};
17781
a9111321 17782static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17783 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17784 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17785 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17786 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17787 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17788 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17789 { } /* end */
17790};
17791
a9111321 17792static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17793 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17794 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17795 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17798 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17799 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17800 { } /* end */
17801};
17802
a9111321 17803static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17804 .ops = &snd_hda_bind_vol,
17805 .values = {
17806 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17807 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17808 0
17809 },
17810};
17811
a9111321 17812static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17813 .ops = &snd_hda_bind_sw,
17814 .values = {
17815 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17816 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17817 0
17818 },
17819};
17820
a9111321 17821static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17822 HDA_BIND_VOL("Master Playback Volume",
17823 &alc663_asus_two_bind_master_vol),
17824 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17825 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17826 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17827 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17828 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17829 { } /* end */
17830};
17831
a9111321 17832static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17833 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17834 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17835 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17837 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17838 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17839 { } /* end */
17840};
17841
a9111321 17842static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17843 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17845 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17847 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17848
17849 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17850 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17851 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17852 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17853 { } /* end */
17854};
17855
a9111321 17856static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17857 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17858 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17859 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17860
17861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17863 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17864 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17865 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17866 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17867 { } /* end */
17868};
17869
a9111321 17870static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17871 .ops = &snd_hda_bind_sw,
17872 .values = {
17873 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17874 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17875 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17876 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17877 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17878 0
17879 },
17880};
17881
a9111321 17882static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17883 .ops = &snd_hda_bind_sw,
17884 .values = {
17885 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17886 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17887 0
17888 },
17889};
17890
a9111321 17891static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17892 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17893 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17894 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17895 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17896 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17897 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17899 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17900 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17901 { } /* end */
17902};
17903
a9111321 17904static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17905 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17906 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17907 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17908 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17910 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17911 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17912 { } /* end */
17913};
17914
17915
a9111321 17916static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17917 {
17918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17919 .name = "Channel Mode",
17920 .info = alc_ch_mode_info,
17921 .get = alc_ch_mode_get,
17922 .put = alc_ch_mode_put,
17923 },
17924 { } /* end */
17925};
17926
a9111321 17927static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17928 /* ADC: mute amp left and right */
17929 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17930 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17931
b60dd394
KY
17932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17933 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17935 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17937 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17938
17939 /* Front Pin: output 0 (0x0c) */
17940 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17941 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17942
17943 /* Rear Pin: output 1 (0x0d) */
17944 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17945 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17946
17947 /* CLFE Pin: output 2 (0x0e) */
17948 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17949 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17950
17951 /* Mic (rear) pin: input vref at 80% */
17952 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17953 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17954 /* Front Mic pin: input vref at 80% */
17955 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17956 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17957 /* Line In pin: input */
17958 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17959 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17960 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17961 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17962 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17963 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17964 /* CD pin widget for input */
17965 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17966
17967 /* FIXME: use matrix-type input source selection */
17968 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17969 /* Input mixer */
17970 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17971 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17972
a7f2371f
TI
17973 { }
17974};
17975
a9111321 17976static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17977 /* always trun on EAPD */
17978 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17979 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17980 { }
17981};
17982
a9111321 17983static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17984 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17985 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17986 {}
17987};
17988
a9111321 17989static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17990 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17991 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17992 {}
bc9f98a9
KY
17993};
17994
8c427226 17995/* Set Unsolicited Event*/
a9111321 17996static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17998 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17999 {}
18000};
18001
a9111321 18002static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
18003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18004 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
18005 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18006 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
18007 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18009 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18010 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18011 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18012 {}
18013};
18014
a9111321 18015static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
18016 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18017 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18018 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18021 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18022 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18023 {}
18024};
18025
a9111321 18026static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
18027 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18029 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18030 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18033 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18035 {}
18036};
6dda9f4a 18037
a9111321 18038static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
18039 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18040 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18041 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18043 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18044 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18045 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18046 {}
18047};
6dda9f4a 18048
a9111321 18049static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
18050 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18051 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18052 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18053 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18055 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18059 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18060 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18061 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18062 {}
18063};
18064
a9111321 18065static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
18066 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18067 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18068 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18069 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18070 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18075 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18076 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18077 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18078 {}
18079};
18080
a9111321 18081static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
18082 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18083 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18084 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18085
18086 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18087 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18088 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18089
18090 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18091 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18092 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18093 {}
18094};
18095
a9111321 18096static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
18097 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18098 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18100
18101 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18102 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18103 {}
18104};
18105
a9111321 18106static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
18107 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18108 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18109 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18110 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18111 {}
18112};
18113
a9111321 18114static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
18115 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18120 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18121 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18124 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18125 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18126 {}
18127};
18128
a9111321 18129static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
18130 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18131 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18134 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18135 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18136 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18138 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18139 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18140 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18141 {}
18142};
18143
a9111321 18144static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
18145 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18147 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18148 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18149 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18150 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18151 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18152 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18153 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18154 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18157 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18158 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18159 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18160 {}
18161};
18162
a9111321 18163static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
18164 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18166 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18168 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18169 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18170 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18171 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18172 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18173 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18174 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18176 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18177 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18178 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18179 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18180 {}
18181};
18182
a9111321 18183static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
18184 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18185 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18186 { } /* end */
18187};
18188
a9111321 18189static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
18190 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18191 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18192 { } /* end */
18193};
18194
e6a5e1b7 18195static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18196{
e6a5e1b7 18197 struct alc_spec *spec = codec->spec;
bc9f98a9 18198
e6a5e1b7
TI
18199 spec->autocfg.hp_pins[0] = 0x1b;
18200 spec->autocfg.line_out_pins[0] = 0x14;
18201 spec->autocfg.speaker_pins[0] = 0x15;
18202 spec->automute = 1;
18203 spec->detect_line = 1;
18204 spec->automute_lines = 1;
18205 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18206}
18207
4f5d1706
TI
18208static void alc662_eeepc_setup(struct hda_codec *codec)
18209{
18210 struct alc_spec *spec = codec->spec;
18211
18212 alc262_hippo1_setup(codec);
18213 spec->ext_mic.pin = 0x18;
18214 spec->ext_mic.mux_idx = 0;
18215 spec->int_mic.pin = 0x19;
18216 spec->int_mic.mux_idx = 1;
18217 spec->auto_mic = 1;
18218}
18219
4f5d1706 18220static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18221{
42171c17
TI
18222 struct alc_spec *spec = codec->spec;
18223
18224 spec->autocfg.hp_pins[0] = 0x14;
18225 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18226 spec->automute = 1;
18227 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18228}
18229
4f5d1706
TI
18230static void alc663_m51va_setup(struct hda_codec *codec)
18231{
18232 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18233 spec->autocfg.hp_pins[0] = 0x21;
18234 spec->autocfg.speaker_pins[0] = 0x14;
18235 spec->automute_mixer_nid[0] = 0x0c;
18236 spec->automute = 1;
18237 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18238 spec->ext_mic.pin = 0x18;
18239 spec->ext_mic.mux_idx = 0;
18240 spec->int_mic.pin = 0x12;
ebb83eeb 18241 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18242 spec->auto_mic = 1;
18243}
18244
f1d4e28b 18245/* ***************** Mode1 ******************************/
ebb83eeb
KY
18246static void alc663_mode1_setup(struct hda_codec *codec)
18247{
18248 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18249 spec->autocfg.hp_pins[0] = 0x21;
18250 spec->autocfg.speaker_pins[0] = 0x14;
18251 spec->automute_mixer_nid[0] = 0x0c;
18252 spec->automute = 1;
18253 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18254 spec->ext_mic.pin = 0x18;
18255 spec->ext_mic.mux_idx = 0;
18256 spec->int_mic.pin = 0x19;
18257 spec->int_mic.mux_idx = 1;
18258 spec->auto_mic = 1;
18259}
18260
f1d4e28b 18261/* ***************** Mode2 ******************************/
3b8510ce 18262static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18263{
3b8510ce
TI
18264 struct alc_spec *spec = codec->spec;
18265 spec->autocfg.hp_pins[0] = 0x1b;
18266 spec->autocfg.speaker_pins[0] = 0x14;
18267 spec->automute = 1;
18268 spec->automute_mode = ALC_AUTOMUTE_PIN;
18269 spec->ext_mic.pin = 0x18;
18270 spec->ext_mic.mux_idx = 0;
18271 spec->int_mic.pin = 0x19;
18272 spec->int_mic.mux_idx = 1;
18273 spec->auto_mic = 1;
f1d4e28b
KY
18274}
18275
f1d4e28b 18276/* ***************** Mode3 ******************************/
3b8510ce 18277static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18278{
3b8510ce
TI
18279 struct alc_spec *spec = codec->spec;
18280 spec->autocfg.hp_pins[0] = 0x21;
18281 spec->autocfg.hp_pins[0] = 0x15;
18282 spec->autocfg.speaker_pins[0] = 0x14;
18283 spec->automute = 1;
18284 spec->automute_mode = ALC_AUTOMUTE_PIN;
18285 spec->ext_mic.pin = 0x18;
18286 spec->ext_mic.mux_idx = 0;
18287 spec->int_mic.pin = 0x19;
18288 spec->int_mic.mux_idx = 1;
18289 spec->auto_mic = 1;
f1d4e28b
KY
18290}
18291
f1d4e28b 18292/* ***************** Mode4 ******************************/
3b8510ce 18293static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18294{
3b8510ce
TI
18295 struct alc_spec *spec = codec->spec;
18296 spec->autocfg.hp_pins[0] = 0x21;
18297 spec->autocfg.speaker_pins[0] = 0x14;
18298 spec->autocfg.speaker_pins[1] = 0x16;
18299 spec->automute_mixer_nid[0] = 0x0c;
18300 spec->automute_mixer_nid[1] = 0x0e;
18301 spec->automute = 1;
18302 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18303 spec->ext_mic.pin = 0x18;
18304 spec->ext_mic.mux_idx = 0;
18305 spec->int_mic.pin = 0x19;
18306 spec->int_mic.mux_idx = 1;
18307 spec->auto_mic = 1;
f1d4e28b
KY
18308}
18309
f1d4e28b 18310/* ***************** Mode5 ******************************/
3b8510ce 18311static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18312{
3b8510ce
TI
18313 struct alc_spec *spec = codec->spec;
18314 spec->autocfg.hp_pins[0] = 0x15;
18315 spec->autocfg.speaker_pins[0] = 0x14;
18316 spec->autocfg.speaker_pins[1] = 0x16;
18317 spec->automute_mixer_nid[0] = 0x0c;
18318 spec->automute_mixer_nid[1] = 0x0e;
18319 spec->automute = 1;
18320 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18321 spec->ext_mic.pin = 0x18;
18322 spec->ext_mic.mux_idx = 0;
18323 spec->int_mic.pin = 0x19;
18324 spec->int_mic.mux_idx = 1;
18325 spec->auto_mic = 1;
f1d4e28b
KY
18326}
18327
f1d4e28b 18328/* ***************** Mode6 ******************************/
3b8510ce 18329static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18330{
3b8510ce
TI
18331 struct alc_spec *spec = codec->spec;
18332 spec->autocfg.hp_pins[0] = 0x1b;
18333 spec->autocfg.hp_pins[0] = 0x15;
18334 spec->autocfg.speaker_pins[0] = 0x14;
18335 spec->automute_mixer_nid[0] = 0x0c;
18336 spec->automute = 1;
18337 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18338 spec->ext_mic.pin = 0x18;
18339 spec->ext_mic.mux_idx = 0;
18340 spec->int_mic.pin = 0x19;
18341 spec->int_mic.mux_idx = 1;
18342 spec->auto_mic = 1;
f1d4e28b
KY
18343}
18344
ebb83eeb 18345/* ***************** Mode7 ******************************/
3b8510ce 18346static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18347{
3b8510ce
TI
18348 struct alc_spec *spec = codec->spec;
18349 spec->autocfg.hp_pins[0] = 0x1b;
18350 spec->autocfg.hp_pins[0] = 0x21;
18351 spec->autocfg.speaker_pins[0] = 0x14;
18352 spec->autocfg.speaker_pins[0] = 0x17;
18353 spec->automute = 1;
18354 spec->automute_mode = ALC_AUTOMUTE_PIN;
18355 spec->ext_mic.pin = 0x18;
18356 spec->ext_mic.mux_idx = 0;
18357 spec->int_mic.pin = 0x19;
18358 spec->int_mic.mux_idx = 1;
18359 spec->auto_mic = 1;
ebb83eeb
KY
18360}
18361
18362/* ***************** Mode8 ******************************/
3b8510ce 18363static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18364{
3b8510ce
TI
18365 struct alc_spec *spec = codec->spec;
18366 spec->autocfg.hp_pins[0] = 0x21;
18367 spec->autocfg.hp_pins[1] = 0x15;
18368 spec->autocfg.speaker_pins[0] = 0x14;
18369 spec->autocfg.speaker_pins[0] = 0x17;
18370 spec->automute = 1;
18371 spec->automute_mode = ALC_AUTOMUTE_PIN;
18372 spec->ext_mic.pin = 0x18;
18373 spec->ext_mic.mux_idx = 0;
18374 spec->int_mic.pin = 0x12;
18375 spec->int_mic.mux_idx = 9;
18376 spec->auto_mic = 1;
ebb83eeb
KY
18377}
18378
e6a5e1b7 18379static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18380{
e6a5e1b7
TI
18381 struct alc_spec *spec = codec->spec;
18382 spec->autocfg.hp_pins[0] = 0x21;
18383 spec->autocfg.line_out_pins[0] = 0x15;
18384 spec->autocfg.speaker_pins[0] = 0x14;
18385 spec->automute = 1;
18386 spec->automute_mode = ALC_AUTOMUTE_AMP;
18387 spec->detect_line = 1;
18388 spec->automute_lines = 1;
18389 spec->ext_mic.pin = 0x18;
18390 spec->ext_mic.mux_idx = 0;
18391 spec->int_mic.pin = 0x12;
18392 spec->int_mic.mux_idx = 9;
18393 spec->auto_mic = 1;
6dda9f4a
KY
18394}
18395
4f5d1706
TI
18396#define alc663_g50v_setup alc663_m51va_setup
18397
a9111321 18398static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18399 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18400 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18401
5f99f86a 18402 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18403 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18404 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18405
5f99f86a 18406 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18407 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18408 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18409 { } /* end */
18410};
18411
a9111321 18412static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18413 /* Master Playback automatically created from Speaker and Headphone */
18414 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18415 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18416 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18417 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18418
8607f7c4
DH
18419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18421 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18422
28c4edb7
DH
18423 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18424 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18425 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18426 { } /* end */
18427};
18428
cb53c626
TI
18429#ifdef CONFIG_SND_HDA_POWER_SAVE
18430#define alc662_loopbacks alc880_loopbacks
18431#endif
18432
bc9f98a9 18433
def319f9 18434/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18435#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18436#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18437#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18438#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18439
18440/*
18441 * configuration and preset
18442 */
ea734963 18443static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18444 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18445 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18446 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18447 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18448 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18449 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18450 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18451 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18452 [ALC663_ASUS_M51VA] = "m51va",
18453 [ALC663_ASUS_G71V] = "g71v",
18454 [ALC663_ASUS_H13] = "h13",
18455 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18456 [ALC663_ASUS_MODE1] = "asus-mode1",
18457 [ALC662_ASUS_MODE2] = "asus-mode2",
18458 [ALC663_ASUS_MODE3] = "asus-mode3",
18459 [ALC663_ASUS_MODE4] = "asus-mode4",
18460 [ALC663_ASUS_MODE5] = "asus-mode5",
18461 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18462 [ALC663_ASUS_MODE7] = "asus-mode7",
18463 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18464 [ALC272_DELL] = "dell",
18465 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18466 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18467 [ALC662_AUTO] = "auto",
18468};
18469
a9111321 18470static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18471 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18472 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18473 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18474 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18475 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18476 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18477 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18478 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18479 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18480 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18481 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18482 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18483 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18484 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18485 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18486 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18487 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18488 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18489 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18490 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18491 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18492 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18493 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18494 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18495 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18496 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18497 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18498 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18499 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18500 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18501 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18502 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18503 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18504 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18505 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18506 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18507 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18508 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18509 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18510 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18511 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18512 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18513 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18514 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18515 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18516 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18517 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18518 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18519 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18520 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18521 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18522 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18523 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18524 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18525 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18526 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18527 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18528 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18529 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18530 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18531 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18532 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18533 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18534 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18535 ALC662_3ST_6ch_DIG),
4dee8baa 18536 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18537 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18538 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18539 ALC662_3ST_6ch_DIG),
6227cdce 18540 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18541 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18542 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18543 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18544 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18545 ALC662_3ST_6ch_DIG),
dea0a509
TI
18546 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18547 ALC663_ASUS_H13),
965b76d2 18548 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18549 {}
18550};
18551
a9111321 18552static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18553 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18554 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18555 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18556 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18557 .dac_nids = alc662_dac_nids,
18558 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18559 .dig_in_nid = ALC662_DIGIN_NID,
18560 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18561 .channel_mode = alc662_3ST_2ch_modes,
18562 .input_mux = &alc662_capture_source,
18563 },
18564 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18565 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18566 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18567 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18568 .dac_nids = alc662_dac_nids,
18569 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18570 .dig_in_nid = ALC662_DIGIN_NID,
18571 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18572 .channel_mode = alc662_3ST_6ch_modes,
18573 .need_dac_fix = 1,
18574 .input_mux = &alc662_capture_source,
f12ab1e0 18575 },
bc9f98a9 18576 [ALC662_3ST_6ch] = {
f9e336f6 18577 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18578 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18579 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18580 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18581 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18582 .channel_mode = alc662_3ST_6ch_modes,
18583 .need_dac_fix = 1,
18584 .input_mux = &alc662_capture_source,
f12ab1e0 18585 },
bc9f98a9 18586 [ALC662_5ST_DIG] = {
f9e336f6 18587 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18588 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18589 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18590 .dac_nids = alc662_dac_nids,
18591 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18592 .dig_in_nid = ALC662_DIGIN_NID,
18593 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18594 .channel_mode = alc662_5stack_modes,
18595 .input_mux = &alc662_capture_source,
18596 },
18597 [ALC662_LENOVO_101E] = {
f9e336f6 18598 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18599 .init_verbs = { alc662_init_verbs,
18600 alc662_eapd_init_verbs,
18601 alc662_sue_init_verbs },
bc9f98a9
KY
18602 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18603 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18604 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18605 .channel_mode = alc662_3ST_2ch_modes,
18606 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18607 .unsol_event = alc_sku_unsol_event,
18608 .setup = alc662_lenovo_101e_setup,
18609 .init_hook = alc_inithook,
bc9f98a9 18610 },
291702f0 18611 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18612 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18613 .init_verbs = { alc662_init_verbs,
a7f2371f 18614 alc662_eapd_init_verbs,
291702f0
KY
18615 alc662_eeepc_sue_init_verbs },
18616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18617 .dac_nids = alc662_dac_nids,
291702f0
KY
18618 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18619 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18620 .unsol_event = alc_sku_unsol_event,
4f5d1706 18621 .setup = alc662_eeepc_setup,
e9427969 18622 .init_hook = alc_inithook,
291702f0 18623 },
8c427226 18624 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18625 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18626 alc662_chmode_mixer },
18627 .init_verbs = { alc662_init_verbs,
a7f2371f 18628 alc662_eapd_init_verbs,
8c427226
KY
18629 alc662_eeepc_ep20_sue_init_verbs },
18630 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18631 .dac_nids = alc662_dac_nids,
8c427226
KY
18632 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18633 .channel_mode = alc662_3ST_6ch_modes,
18634 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18635 .unsol_event = alc_sku_unsol_event,
4f5d1706 18636 .setup = alc662_eeepc_ep20_setup,
e9427969 18637 .init_hook = alc_inithook,
8c427226 18638 },
f1d4e28b 18639 [ALC662_ECS] = {
f9e336f6 18640 .mixers = { alc662_ecs_mixer },
f1d4e28b 18641 .init_verbs = { alc662_init_verbs,
a7f2371f 18642 alc662_eapd_init_verbs,
f1d4e28b
KY
18643 alc662_ecs_init_verbs },
18644 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18645 .dac_nids = alc662_dac_nids,
18646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18647 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18648 .unsol_event = alc_sku_unsol_event,
4f5d1706 18649 .setup = alc662_eeepc_setup,
e9427969 18650 .init_hook = alc_inithook,
f1d4e28b 18651 },
6dda9f4a 18652 [ALC663_ASUS_M51VA] = {
f9e336f6 18653 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18654 .init_verbs = { alc662_init_verbs,
18655 alc662_eapd_init_verbs,
18656 alc663_m51va_init_verbs },
6dda9f4a
KY
18657 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18658 .dac_nids = alc662_dac_nids,
18659 .dig_out_nid = ALC662_DIGOUT_NID,
18660 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18661 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18662 .unsol_event = alc_sku_unsol_event,
4f5d1706 18663 .setup = alc663_m51va_setup,
3b8510ce 18664 .init_hook = alc_inithook,
6dda9f4a
KY
18665 },
18666 [ALC663_ASUS_G71V] = {
f9e336f6 18667 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18668 .init_verbs = { alc662_init_verbs,
18669 alc662_eapd_init_verbs,
18670 alc663_g71v_init_verbs },
6dda9f4a
KY
18671 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18672 .dac_nids = alc662_dac_nids,
18673 .dig_out_nid = ALC662_DIGOUT_NID,
18674 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18675 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18676 .unsol_event = alc_sku_unsol_event,
4f5d1706 18677 .setup = alc663_g71v_setup,
e6a5e1b7 18678 .init_hook = alc_inithook,
6dda9f4a
KY
18679 },
18680 [ALC663_ASUS_H13] = {
f9e336f6 18681 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18682 .init_verbs = { alc662_init_verbs,
18683 alc662_eapd_init_verbs,
18684 alc663_m51va_init_verbs },
6dda9f4a
KY
18685 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18686 .dac_nids = alc662_dac_nids,
18687 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18688 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18689 .setup = alc663_m51va_setup,
18690 .unsol_event = alc_sku_unsol_event,
18691 .init_hook = alc_inithook,
6dda9f4a
KY
18692 },
18693 [ALC663_ASUS_G50V] = {
f9e336f6 18694 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18695 .init_verbs = { alc662_init_verbs,
18696 alc662_eapd_init_verbs,
18697 alc663_g50v_init_verbs },
6dda9f4a
KY
18698 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18699 .dac_nids = alc662_dac_nids,
18700 .dig_out_nid = ALC662_DIGOUT_NID,
18701 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18702 .channel_mode = alc662_3ST_6ch_modes,
18703 .input_mux = &alc663_capture_source,
3b8510ce 18704 .unsol_event = alc_sku_unsol_event,
4f5d1706 18705 .setup = alc663_g50v_setup,
3b8510ce 18706 .init_hook = alc_inithook,
6dda9f4a 18707 },
f1d4e28b 18708 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18709 .mixers = { alc663_m51va_mixer },
18710 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18711 .init_verbs = { alc662_init_verbs,
a7f2371f 18712 alc662_eapd_init_verbs,
f1d4e28b
KY
18713 alc663_21jd_amic_init_verbs },
18714 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18715 .hp_nid = 0x03,
18716 .dac_nids = alc662_dac_nids,
18717 .dig_out_nid = ALC662_DIGOUT_NID,
18718 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18719 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18720 .unsol_event = alc_sku_unsol_event,
4f5d1706 18721 .setup = alc663_mode1_setup,
3b8510ce 18722 .init_hook = alc_inithook,
f1d4e28b
KY
18723 },
18724 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18725 .mixers = { alc662_1bjd_mixer },
18726 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18727 .init_verbs = { alc662_init_verbs,
a7f2371f 18728 alc662_eapd_init_verbs,
f1d4e28b
KY
18729 alc662_1bjd_amic_init_verbs },
18730 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18731 .dac_nids = alc662_dac_nids,
18732 .dig_out_nid = ALC662_DIGOUT_NID,
18733 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18734 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18735 .unsol_event = alc_sku_unsol_event,
4f5d1706 18736 .setup = alc662_mode2_setup,
3b8510ce 18737 .init_hook = alc_inithook,
f1d4e28b
KY
18738 },
18739 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18740 .mixers = { alc663_two_hp_m1_mixer },
18741 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18742 .init_verbs = { alc662_init_verbs,
a7f2371f 18743 alc662_eapd_init_verbs,
f1d4e28b
KY
18744 alc663_two_hp_amic_m1_init_verbs },
18745 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18746 .hp_nid = 0x03,
18747 .dac_nids = alc662_dac_nids,
18748 .dig_out_nid = ALC662_DIGOUT_NID,
18749 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18750 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18751 .unsol_event = alc_sku_unsol_event,
4f5d1706 18752 .setup = alc663_mode3_setup,
3b8510ce 18753 .init_hook = alc_inithook,
f1d4e28b
KY
18754 },
18755 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18756 .mixers = { alc663_asus_21jd_clfe_mixer },
18757 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18758 .init_verbs = { alc662_init_verbs,
a7f2371f 18759 alc662_eapd_init_verbs,
f1d4e28b
KY
18760 alc663_21jd_amic_init_verbs},
18761 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18762 .hp_nid = 0x03,
18763 .dac_nids = alc662_dac_nids,
18764 .dig_out_nid = ALC662_DIGOUT_NID,
18765 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18766 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18767 .unsol_event = alc_sku_unsol_event,
4f5d1706 18768 .setup = alc663_mode4_setup,
3b8510ce 18769 .init_hook = alc_inithook,
f1d4e28b
KY
18770 },
18771 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18772 .mixers = { alc663_asus_15jd_clfe_mixer },
18773 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18774 .init_verbs = { alc662_init_verbs,
a7f2371f 18775 alc662_eapd_init_verbs,
f1d4e28b
KY
18776 alc663_15jd_amic_init_verbs },
18777 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18778 .hp_nid = 0x03,
18779 .dac_nids = alc662_dac_nids,
18780 .dig_out_nid = ALC662_DIGOUT_NID,
18781 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18782 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18783 .unsol_event = alc_sku_unsol_event,
4f5d1706 18784 .setup = alc663_mode5_setup,
3b8510ce 18785 .init_hook = alc_inithook,
f1d4e28b
KY
18786 },
18787 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18788 .mixers = { alc663_two_hp_m2_mixer },
18789 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18790 .init_verbs = { alc662_init_verbs,
a7f2371f 18791 alc662_eapd_init_verbs,
f1d4e28b
KY
18792 alc663_two_hp_amic_m2_init_verbs },
18793 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18794 .hp_nid = 0x03,
18795 .dac_nids = alc662_dac_nids,
18796 .dig_out_nid = ALC662_DIGOUT_NID,
18797 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18798 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18799 .unsol_event = alc_sku_unsol_event,
4f5d1706 18800 .setup = alc663_mode6_setup,
3b8510ce 18801 .init_hook = alc_inithook,
f1d4e28b 18802 },
ebb83eeb
KY
18803 [ALC663_ASUS_MODE7] = {
18804 .mixers = { alc663_mode7_mixer },
18805 .cap_mixer = alc662_auto_capture_mixer,
18806 .init_verbs = { alc662_init_verbs,
a7f2371f 18807 alc662_eapd_init_verbs,
ebb83eeb
KY
18808 alc663_mode7_init_verbs },
18809 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18810 .hp_nid = 0x03,
18811 .dac_nids = alc662_dac_nids,
18812 .dig_out_nid = ALC662_DIGOUT_NID,
18813 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18814 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18815 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18816 .setup = alc663_mode7_setup,
3b8510ce 18817 .init_hook = alc_inithook,
ebb83eeb
KY
18818 },
18819 [ALC663_ASUS_MODE8] = {
18820 .mixers = { alc663_mode8_mixer },
18821 .cap_mixer = alc662_auto_capture_mixer,
18822 .init_verbs = { alc662_init_verbs,
a7f2371f 18823 alc662_eapd_init_verbs,
ebb83eeb
KY
18824 alc663_mode8_init_verbs },
18825 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18826 .hp_nid = 0x03,
18827 .dac_nids = alc662_dac_nids,
18828 .dig_out_nid = ALC662_DIGOUT_NID,
18829 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18830 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18831 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18832 .setup = alc663_mode8_setup,
3b8510ce 18833 .init_hook = alc_inithook,
ebb83eeb 18834 },
622e84cd
KY
18835 [ALC272_DELL] = {
18836 .mixers = { alc663_m51va_mixer },
18837 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18838 .init_verbs = { alc662_init_verbs,
18839 alc662_eapd_init_verbs,
18840 alc272_dell_init_verbs },
622e84cd 18841 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18842 .dac_nids = alc272_dac_nids,
622e84cd
KY
18843 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18844 .adc_nids = alc272_adc_nids,
18845 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18846 .capsrc_nids = alc272_capsrc_nids,
18847 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18848 .unsol_event = alc_sku_unsol_event,
4f5d1706 18849 .setup = alc663_m51va_setup,
3b8510ce 18850 .init_hook = alc_inithook,
622e84cd
KY
18851 },
18852 [ALC272_DELL_ZM1] = {
18853 .mixers = { alc663_m51va_mixer },
18854 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18855 .init_verbs = { alc662_init_verbs,
18856 alc662_eapd_init_verbs,
18857 alc272_dell_zm1_init_verbs },
622e84cd 18858 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18859 .dac_nids = alc272_dac_nids,
622e84cd
KY
18860 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18861 .adc_nids = alc662_adc_nids,
b59bdf3b 18862 .num_adc_nids = 1,
622e84cd
KY
18863 .capsrc_nids = alc662_capsrc_nids,
18864 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18865 .unsol_event = alc_sku_unsol_event,
4f5d1706 18866 .setup = alc663_m51va_setup,
3b8510ce 18867 .init_hook = alc_inithook,
622e84cd 18868 },
9541ba1d
CP
18869 [ALC272_SAMSUNG_NC10] = {
18870 .mixers = { alc272_nc10_mixer },
18871 .init_verbs = { alc662_init_verbs,
a7f2371f 18872 alc662_eapd_init_verbs,
9541ba1d
CP
18873 alc663_21jd_amic_init_verbs },
18874 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18875 .dac_nids = alc272_dac_nids,
18876 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18877 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18878 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18879 .unsol_event = alc_sku_unsol_event,
4f5d1706 18880 .setup = alc663_mode4_setup,
3b8510ce 18881 .init_hook = alc_inithook,
9541ba1d 18882 },
bc9f98a9
KY
18883};
18884
18885
18886/*
18887 * BIOS auto configuration
18888 */
18889
7085ec12 18890/* convert from MIX nid to DAC */
604401a9 18891static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18892{
604401a9 18893 hda_nid_t list[5];
1304ac89
TI
18894 int i, num;
18895
18896 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18897 for (i = 0; i < num; i++) {
18898 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18899 return list[i];
18900 }
18901 return 0;
7085ec12
TI
18902}
18903
604401a9
TI
18904/* go down to the selector widget before the mixer */
18905static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18906{
18907 hda_nid_t srcs[5];
18908 int num = snd_hda_get_connections(codec, pin, srcs,
18909 ARRAY_SIZE(srcs));
18910 if (num != 1 ||
18911 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18912 return pin;
18913 return srcs[0];
18914}
18915
7085ec12 18916/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18917static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18918 hda_nid_t dac)
18919{
cc1c452e 18920 hda_nid_t mix[5];
7085ec12
TI
18921 int i, num;
18922
604401a9 18923 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18924 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18925 for (i = 0; i < num; i++) {
604401a9 18926 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18927 return mix[i];
18928 }
18929 return 0;
18930}
18931
ce764ab2
TI
18932/* select the connection from pin to DAC if needed */
18933static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18934 hda_nid_t dac)
18935{
18936 hda_nid_t mix[5];
18937 int i, num;
18938
18939 pin = alc_go_down_to_selector(codec, pin);
18940 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18941 if (num < 2)
18942 return 0;
18943 for (i = 0; i < num; i++) {
18944 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18945 snd_hda_codec_update_cache(codec, pin, 0,
18946 AC_VERB_SET_CONNECT_SEL, i);
18947 return 0;
18948 }
18949 }
18950 return 0;
18951}
18952
7085ec12 18953/* look for an empty DAC slot */
604401a9 18954static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18955{
18956 struct alc_spec *spec = codec->spec;
18957 hda_nid_t srcs[5];
18958 int i, j, num;
18959
604401a9 18960 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18961 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18962 for (i = 0; i < num; i++) {
604401a9 18963 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18964 if (!nid)
18965 continue;
18966 for (j = 0; j < spec->multiout.num_dacs; j++)
18967 if (spec->multiout.dac_nids[j] == nid)
18968 break;
18969 if (j >= spec->multiout.num_dacs)
18970 return nid;
18971 }
18972 return 0;
18973}
18974
18975/* fill in the dac_nids table from the parsed pin configuration */
18976static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18977 const struct auto_pin_cfg *cfg)
18978{
18979 struct alc_spec *spec = codec->spec;
18980 int i;
18981 hda_nid_t dac;
18982
18983 spec->multiout.dac_nids = spec->private_dac_nids;
18984 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18985 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18986 if (!dac)
18987 continue;
dda14410 18988 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
7085ec12
TI
18989 }
18990 return 0;
18991}
18992
bcb2f0f5
TI
18993static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18994 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18995{
bcb2f0f5 18996 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18997 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18998}
18999
bcb2f0f5
TI
19000static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19001 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19002{
bcb2f0f5 19003 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19004 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19005}
19006
bcb2f0f5
TI
19007#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19008 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19009#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19010 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19011#define alc662_add_stereo_vol(spec, pfx, nid) \
19012 alc662_add_vol_ctl(spec, pfx, nid, 3)
19013#define alc662_add_stereo_sw(spec, pfx, nid) \
19014 alc662_add_sw_ctl(spec, pfx, nid, 3)
19015
bc9f98a9 19016/* add playback controls from the parsed DAC table */
7085ec12 19017static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19018 const struct auto_pin_cfg *cfg)
19019{
7085ec12 19020 struct alc_spec *spec = codec->spec;
ea734963 19021 static const char * const chname[4] = {
bc9f98a9
KY
19022 "Front", "Surround", NULL /*CLFE*/, "Side"
19023 };
ce764ab2
TI
19024 const char *pfx = alc_get_line_out_pfx(spec, true);
19025 hda_nid_t nid, mix, pin;
19026 int i, err, noutputs;
bc9f98a9 19027
ce764ab2
TI
19028 noutputs = cfg->line_outs;
19029 if (spec->multi_ios > 0)
19030 noutputs += spec->multi_ios;
19031
19032 for (i = 0; i < noutputs; i++) {
7085ec12
TI
19033 nid = spec->multiout.dac_nids[i];
19034 if (!nid)
19035 continue;
ce764ab2
TI
19036 if (i >= cfg->line_outs)
19037 pin = spec->multi_io[i - 1].pin;
19038 else
19039 pin = cfg->line_out_pins[i];
19040 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 19041 if (!mix)
bc9f98a9 19042 continue;
bcb2f0f5 19043 if (!pfx && i == 2) {
bc9f98a9 19044 /* Center/LFE */
7085ec12 19045 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19046 if (err < 0)
19047 return err;
7085ec12 19048 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19049 if (err < 0)
19050 return err;
7085ec12 19051 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19052 if (err < 0)
19053 return err;
7085ec12 19054 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19055 if (err < 0)
19056 return err;
19057 } else {
bcb2f0f5 19058 const char *name = pfx;
5a882646
DH
19059 int index = i;
19060 if (!name) {
bcb2f0f5 19061 name = chname[i];
5a882646
DH
19062 index = 0;
19063 }
19064 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19065 if (err < 0)
19066 return err;
5a882646 19067 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19068 if (err < 0)
19069 return err;
19070 }
19071 }
19072 return 0;
19073}
19074
19075/* add playback controls for speaker and HP outputs */
7085ec12
TI
19076/* return DAC nid if any new DAC is assigned */
19077static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19078 const char *pfx)
19079{
7085ec12
TI
19080 struct alc_spec *spec = codec->spec;
19081 hda_nid_t nid, mix;
bc9f98a9 19082 int err;
bc9f98a9
KY
19083
19084 if (!pin)
19085 return 0;
604401a9 19086 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19087 if (!nid) {
7085ec12
TI
19088 /* the corresponding DAC is already occupied */
19089 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19090 return 0; /* no way */
19091 /* create a switch only */
0afe5f89 19092 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19093 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19094 }
19095
604401a9 19096 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19097 if (!mix)
19098 return 0;
19099 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19100 if (err < 0)
19101 return err;
19102 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19103 if (err < 0)
19104 return err;
19105 return nid;
bc9f98a9
KY
19106}
19107
19108/* create playback/capture controls for input pins */
05f5f477 19109#define alc662_auto_create_input_ctls \
4b7348a1 19110 alc882_auto_create_input_ctls
bc9f98a9
KY
19111
19112static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19113 hda_nid_t nid, int pin_type,
7085ec12 19114 hda_nid_t dac)
bc9f98a9 19115{
7085ec12 19116 int i, num;
ce503f38 19117 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19118
f6c7e546 19119 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19120 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19121 for (i = 0; i < num; i++) {
604401a9 19122 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19123 continue;
0e53f344
TI
19124 /* need the manual connection? */
19125 if (num > 1)
19126 snd_hda_codec_write(codec, nid, 0,
19127 AC_VERB_SET_CONNECT_SEL, i);
19128 /* unmute mixer widget inputs */
19129 snd_hda_codec_write(codec, srcs[i], 0,
19130 AC_VERB_SET_AMP_GAIN_MUTE,
19131 AMP_IN_UNMUTE(0));
19132 snd_hda_codec_write(codec, srcs[i], 0,
19133 AC_VERB_SET_AMP_GAIN_MUTE,
19134 AMP_IN_UNMUTE(1));
7085ec12 19135 return;
bc9f98a9
KY
19136 }
19137}
19138
19139static void alc662_auto_init_multi_out(struct hda_codec *codec)
19140{
19141 struct alc_spec *spec = codec->spec;
7085ec12 19142 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19143 int i;
19144
19145 for (i = 0; i <= HDA_SIDE; i++) {
19146 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19147 if (nid)
baba8ee9 19148 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19149 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19150 }
19151}
19152
19153static void alc662_auto_init_hp_out(struct hda_codec *codec)
19154{
19155 struct alc_spec *spec = codec->spec;
19156 hda_nid_t pin;
19157
19158 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19159 if (pin)
19160 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19161 spec->multiout.hp_nid);
f6c7e546
TI
19162 pin = spec->autocfg.speaker_pins[0];
19163 if (pin)
7085ec12
TI
19164 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19165 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19166}
19167
bc9f98a9
KY
19168#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19169
19170static void alc662_auto_init_analog_input(struct hda_codec *codec)
19171{
19172 struct alc_spec *spec = codec->spec;
66ceeb6b 19173 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19174 int i;
19175
66ceeb6b
TI
19176 for (i = 0; i < cfg->num_inputs; i++) {
19177 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19178 if (alc_is_input_pin(codec, nid)) {
30ea098f 19179 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19180 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19181 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19182 snd_hda_codec_write(codec, nid, 0,
19183 AC_VERB_SET_AMP_GAIN_MUTE,
19184 AMP_OUT_MUTE);
19185 }
19186 }
19187}
19188
f511b01c
TI
19189#define alc662_auto_init_input_src alc882_auto_init_input_src
19190
ce764ab2
TI
19191/*
19192 * multi-io helper
19193 */
19194static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19195 unsigned int location)
19196{
19197 struct alc_spec *spec = codec->spec;
19198 struct auto_pin_cfg *cfg = &spec->autocfg;
19199 int type, i, num_pins = 0;
19200
19201 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19202 for (i = 0; i < cfg->num_inputs; i++) {
19203 hda_nid_t nid = cfg->inputs[i].pin;
19204 hda_nid_t dac;
19205 unsigned int defcfg, caps;
19206 if (cfg->inputs[i].type != type)
19207 continue;
19208 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19209 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19210 continue;
19211 if (location && get_defcfg_location(defcfg) != location)
19212 continue;
19213 caps = snd_hda_query_pin_caps(codec, nid);
19214 if (!(caps & AC_PINCAP_OUT))
19215 continue;
19216 dac = alc_auto_look_for_dac(codec, nid);
19217 if (!dac)
19218 continue;
19219 spec->multi_io[num_pins].pin = nid;
19220 spec->multi_io[num_pins].dac = dac;
19221 num_pins++;
dda14410 19222 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19223 }
19224 }
19225 spec->multiout.num_dacs = 1;
19226 if (num_pins < 2)
19227 return 0;
19228 return num_pins;
19229}
19230
19231static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19232 struct snd_ctl_elem_info *uinfo)
19233{
19234 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19235 struct alc_spec *spec = codec->spec;
19236
19237 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19238 uinfo->count = 1;
19239 uinfo->value.enumerated.items = spec->multi_ios + 1;
19240 if (uinfo->value.enumerated.item > spec->multi_ios)
19241 uinfo->value.enumerated.item = spec->multi_ios;
19242 sprintf(uinfo->value.enumerated.name, "%dch",
19243 (uinfo->value.enumerated.item + 1) * 2);
19244 return 0;
19245}
19246
19247static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19248 struct snd_ctl_elem_value *ucontrol)
19249{
19250 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19251 struct alc_spec *spec = codec->spec;
19252 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19253 return 0;
19254}
19255
19256static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19257{
19258 struct alc_spec *spec = codec->spec;
19259 hda_nid_t nid = spec->multi_io[idx].pin;
19260
19261 if (!spec->multi_io[idx].ctl_in)
19262 spec->multi_io[idx].ctl_in =
19263 snd_hda_codec_read(codec, nid, 0,
19264 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19265 if (output) {
19266 snd_hda_codec_update_cache(codec, nid, 0,
19267 AC_VERB_SET_PIN_WIDGET_CONTROL,
19268 PIN_OUT);
19269 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19270 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19271 HDA_AMP_MUTE, 0);
19272 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19273 } else {
19274 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19275 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19276 HDA_AMP_MUTE, HDA_AMP_MUTE);
19277 snd_hda_codec_update_cache(codec, nid, 0,
19278 AC_VERB_SET_PIN_WIDGET_CONTROL,
19279 spec->multi_io[idx].ctl_in);
19280 }
19281 return 0;
19282}
19283
19284static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19285 struct snd_ctl_elem_value *ucontrol)
19286{
19287 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19288 struct alc_spec *spec = codec->spec;
19289 int i, ch;
19290
19291 ch = ucontrol->value.enumerated.item[0];
19292 if (ch < 0 || ch > spec->multi_ios)
19293 return -EINVAL;
19294 if (ch == (spec->ext_channel_count - 1) / 2)
19295 return 0;
19296 spec->ext_channel_count = (ch + 1) * 2;
19297 for (i = 0; i < spec->multi_ios; i++)
19298 alc_set_multi_io(codec, i, i < ch);
19299 spec->multiout.max_channels = spec->ext_channel_count;
19300 return 1;
19301}
19302
a9111321 19303static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19304 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19305 .name = "Channel Mode",
19306 .info = alc_auto_ch_mode_info,
19307 .get = alc_auto_ch_mode_get,
19308 .put = alc_auto_ch_mode_put,
19309};
19310
19311static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19312{
19313 struct alc_spec *spec = codec->spec;
19314 struct auto_pin_cfg *cfg = &spec->autocfg;
19315 unsigned int location, defcfg;
19316 int num_pins;
19317
19318 if (cfg->line_outs != 1 ||
19319 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19320 return 0;
19321
19322 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19323 location = get_defcfg_location(defcfg);
19324
19325 num_pins = alc_auto_fill_multi_ios(codec, location);
19326 if (num_pins > 0) {
19327 struct snd_kcontrol_new *knew;
19328
19329 knew = alc_kcontrol_new(spec);
19330 if (!knew)
19331 return -ENOMEM;
19332 *knew = alc_auto_channel_mode_enum;
19333 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19334 if (!knew->name)
19335 return -ENOMEM;
19336
19337 spec->multi_ios = num_pins;
19338 spec->ext_channel_count = 2;
19339 spec->multiout.num_dacs = num_pins + 1;
19340 }
19341 return 0;
19342}
19343
bc9f98a9
KY
19344static int alc662_parse_auto_config(struct hda_codec *codec)
19345{
19346 struct alc_spec *spec = codec->spec;
19347 int err;
4c6d72d1 19348 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19349
19350 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19351 alc662_ignore);
19352 if (err < 0)
19353 return err;
19354 if (!spec->autocfg.line_outs)
19355 return 0; /* can't find valid BIOS pin config */
19356
7085ec12 19357 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19358 if (err < 0)
19359 return err;
19360 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19361 if (err < 0)
19362 return err;
7085ec12 19363 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19364 if (err < 0)
19365 return err;
7085ec12 19366 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19367 spec->autocfg.speaker_pins[0],
19368 "Speaker");
19369 if (err < 0)
19370 return err;
7085ec12
TI
19371 if (err)
19372 spec->multiout.extra_out_nid[0] = err;
19373 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19374 "Headphone");
19375 if (err < 0)
19376 return err;
7085ec12
TI
19377 if (err)
19378 spec->multiout.hp_nid = err;
05f5f477 19379 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19380 if (err < 0)
bc9f98a9
KY
19381 return err;
19382
19383 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19384
757899ac 19385 alc_auto_parse_digital(codec);
bc9f98a9 19386
603c4019 19387 if (spec->kctls.list)
d88897ea 19388 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19389
19390 spec->num_mux_defs = 1;
61b9b9b1 19391 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19392
ee979a14
TI
19393 err = alc_auto_add_mic_boost(codec);
19394 if (err < 0)
19395 return err;
19396
6227cdce
KY
19397 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19398 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19399 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19400 else
19401 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19402
8c87286f 19403 return 1;
bc9f98a9
KY
19404}
19405
19406/* additional initialization for auto-configuration model */
19407static void alc662_auto_init(struct hda_codec *codec)
19408{
f6c7e546 19409 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19410 alc662_auto_init_multi_out(codec);
19411 alc662_auto_init_hp_out(codec);
19412 alc662_auto_init_analog_input(codec);
f511b01c 19413 alc662_auto_init_input_src(codec);
757899ac 19414 alc_auto_init_digital(codec);
f6c7e546 19415 if (spec->unsol_event)
7fb0d78f 19416 alc_inithook(codec);
bc9f98a9
KY
19417}
19418
6be7948f 19419static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19420 const struct alc_fixup *fix, int action)
6fc398cb 19421{
b5bfbc67 19422 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19423 return;
6be7948f
TB
19424 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19425 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19426 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19427 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19428 (0 << AC_AMPCAP_MUTE_SHIFT)))
19429 printk(KERN_WARNING
19430 "hda_codec: failed to override amp caps for NID 0x2\n");
19431}
19432
6cb3b707 19433enum {
2df03514 19434 ALC662_FIXUP_ASPIRE,
6cb3b707 19435 ALC662_FIXUP_IDEAPAD,
6be7948f 19436 ALC272_FIXUP_MARIO,
d2ebd479 19437 ALC662_FIXUP_CZC_P10T,
94024cd1 19438 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19439};
19440
19441static const struct alc_fixup alc662_fixups[] = {
2df03514 19442 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19443 .type = ALC_FIXUP_PINS,
19444 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19445 { 0x15, 0x99130112 }, /* subwoofer */
19446 { }
19447 }
19448 },
6cb3b707 19449 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19450 .type = ALC_FIXUP_PINS,
19451 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19452 { 0x17, 0x99130112 }, /* subwoofer */
19453 { }
19454 }
19455 },
6be7948f 19456 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19457 .type = ALC_FIXUP_FUNC,
19458 .v.func = alc272_fixup_mario,
d2ebd479
AA
19459 },
19460 [ALC662_FIXUP_CZC_P10T] = {
19461 .type = ALC_FIXUP_VERBS,
19462 .v.verbs = (const struct hda_verb[]) {
19463 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19464 {}
19465 }
19466 },
94024cd1
DH
19467 [ALC662_FIXUP_SKU_IGNORE] = {
19468 .type = ALC_FIXUP_SKU,
19469 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19470 },
6cb3b707
DH
19471};
19472
a9111321 19473static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19474 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19475 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19476 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19477 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19478 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19479 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19480 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19481 {}
19482};
19483
6be7948f
TB
19484static const struct alc_model_fixup alc662_fixup_models[] = {
19485 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19486 {}
19487};
6cb3b707
DH
19488
19489
bc9f98a9
KY
19490static int patch_alc662(struct hda_codec *codec)
19491{
19492 struct alc_spec *spec;
19493 int err, board_config;
693194f3 19494 int coef;
bc9f98a9
KY
19495
19496 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19497 if (!spec)
19498 return -ENOMEM;
19499
19500 codec->spec = spec;
19501
da00c244
KY
19502 alc_auto_parse_customize_define(codec);
19503
2c3bf9ab
TI
19504 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19505
693194f3
KY
19506 coef = alc_read_coef_idx(codec, 0);
19507 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19508 alc_codec_rename(codec, "ALC661");
693194f3
KY
19509 else if (coef & (1 << 14) &&
19510 codec->bus->pci->subsystem_vendor == 0x1025 &&
19511 spec->cdefine.platform_type == 1)
c027ddcd 19512 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19513 else if (coef == 0x4011)
19514 alc_codec_rename(codec, "ALC656");
274693f3 19515
bc9f98a9
KY
19516 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19517 alc662_models,
19518 alc662_cfg_tbl);
19519 if (board_config < 0) {
9a11f1aa
TI
19520 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19521 codec->chip_name);
bc9f98a9
KY
19522 board_config = ALC662_AUTO;
19523 }
19524
19525 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19526 alc_pick_fixup(codec, alc662_fixup_models,
19527 alc662_fixup_tbl, alc662_fixups);
19528 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19529 /* automatic parse from the BIOS config */
19530 err = alc662_parse_auto_config(codec);
19531 if (err < 0) {
19532 alc_free(codec);
19533 return err;
8c87286f 19534 } else if (!err) {
bc9f98a9
KY
19535 printk(KERN_INFO
19536 "hda_codec: Cannot set up configuration "
19537 "from BIOS. Using base mode...\n");
19538 board_config = ALC662_3ST_2ch_DIG;
19539 }
19540 }
19541
dc1eae25 19542 if (has_cdefine_beep(codec)) {
8af2591d
TI
19543 err = snd_hda_attach_beep_device(codec, 0x1);
19544 if (err < 0) {
19545 alc_free(codec);
19546 return err;
19547 }
680cd536
KK
19548 }
19549
bc9f98a9 19550 if (board_config != ALC662_AUTO)
e9c364c0 19551 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19552
bc9f98a9
KY
19553 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19554 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19555
bc9f98a9
KY
19556 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19557 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19558
dd704698
TI
19559 if (!spec->adc_nids) {
19560 spec->adc_nids = alc662_adc_nids;
19561 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19562 }
19563 if (!spec->capsrc_nids)
19564 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19565
f9e336f6 19566 if (!spec->cap_mixer)
b59bdf3b 19567 set_capture_mixer(codec);
cec27c89 19568
dc1eae25 19569 if (has_cdefine_beep(codec)) {
da00c244
KY
19570 switch (codec->vendor_id) {
19571 case 0x10ec0662:
19572 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19573 break;
19574 case 0x10ec0272:
19575 case 0x10ec0663:
19576 case 0x10ec0665:
19577 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19578 break;
19579 case 0x10ec0273:
19580 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19581 break;
19582 }
cec27c89 19583 }
2134ea4f
TI
19584 spec->vmaster_nid = 0x02;
19585
b5bfbc67
TI
19586 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19587
bc9f98a9 19588 codec->patch_ops = alc_patch_ops;
b5bfbc67 19589 if (board_config == ALC662_AUTO)
bc9f98a9 19590 spec->init_hook = alc662_auto_init;
1c716153 19591 spec->shutup = alc_eapd_shutup;
6cb3b707 19592
bf1b0225
KY
19593 alc_init_jacks(codec);
19594
cb53c626
TI
19595#ifdef CONFIG_SND_HDA_POWER_SAVE
19596 if (!spec->loopback.amplist)
19597 spec->loopback.amplist = alc662_loopbacks;
19598#endif
bc9f98a9
KY
19599
19600 return 0;
19601}
19602
274693f3
KY
19603static int patch_alc888(struct hda_codec *codec)
19604{
19605 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19606 kfree(codec->chip_name);
01e0f137
KY
19607 if (codec->vendor_id == 0x10ec0887)
19608 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19609 else
19610 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19611 if (!codec->chip_name) {
19612 alc_free(codec);
274693f3 19613 return -ENOMEM;
ac2c92e0
TI
19614 }
19615 return patch_alc662(codec);
274693f3 19616 }
ac2c92e0 19617 return patch_alc882(codec);
274693f3
KY
19618}
19619
b478b998
KY
19620static int patch_alc899(struct hda_codec *codec)
19621{
19622 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19623 kfree(codec->chip_name);
19624 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19625 }
19626 return patch_alc882(codec);
19627}
19628
d1eb57f4
KY
19629/*
19630 * ALC680 support
19631 */
c69aefab 19632#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19633#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19634#define alc680_modes alc260_modes
19635
4c6d72d1 19636static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19637 /* Lout1, Lout2, hp */
19638 0x02, 0x03, 0x04
19639};
19640
4c6d72d1 19641static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19642 /* ADC0-2 */
19643 /* DMIC, MIC, Line-in*/
19644 0x07, 0x08, 0x09
19645};
19646
c69aefab
KY
19647/*
19648 * Analog capture ADC cgange
19649 */
66ceeb6b
TI
19650static void alc680_rec_autoswitch(struct hda_codec *codec)
19651{
19652 struct alc_spec *spec = codec->spec;
19653 struct auto_pin_cfg *cfg = &spec->autocfg;
19654 int pin_found = 0;
19655 int type_found = AUTO_PIN_LAST;
19656 hda_nid_t nid;
19657 int i;
19658
19659 for (i = 0; i < cfg->num_inputs; i++) {
19660 nid = cfg->inputs[i].pin;
06dec228 19661 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19662 continue;
19663 if (snd_hda_jack_detect(codec, nid)) {
19664 if (cfg->inputs[i].type < type_found) {
19665 type_found = cfg->inputs[i].type;
19666 pin_found = nid;
19667 }
19668 }
19669 }
19670
19671 nid = 0x07;
19672 if (pin_found)
19673 snd_hda_get_connections(codec, pin_found, &nid, 1);
19674
19675 if (nid != spec->cur_adc)
19676 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19677 spec->cur_adc = nid;
19678 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19679 spec->cur_adc_format);
19680}
19681
c69aefab
KY
19682static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19683 struct hda_codec *codec,
19684 unsigned int stream_tag,
19685 unsigned int format,
19686 struct snd_pcm_substream *substream)
19687{
19688 struct alc_spec *spec = codec->spec;
c69aefab 19689
66ceeb6b 19690 spec->cur_adc = 0x07;
c69aefab
KY
19691 spec->cur_adc_stream_tag = stream_tag;
19692 spec->cur_adc_format = format;
19693
66ceeb6b 19694 alc680_rec_autoswitch(codec);
c69aefab
KY
19695 return 0;
19696}
19697
19698static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19699 struct hda_codec *codec,
19700 struct snd_pcm_substream *substream)
19701{
19702 snd_hda_codec_cleanup_stream(codec, 0x07);
19703 snd_hda_codec_cleanup_stream(codec, 0x08);
19704 snd_hda_codec_cleanup_stream(codec, 0x09);
19705 return 0;
19706}
19707
a9111321 19708static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19709 .substreams = 1, /* can be overridden */
19710 .channels_min = 2,
19711 .channels_max = 2,
19712 /* NID is set in alc_build_pcms */
19713 .ops = {
19714 .prepare = alc680_capture_pcm_prepare,
19715 .cleanup = alc680_capture_pcm_cleanup
19716 },
19717};
19718
a9111321 19719static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19720 /* output mixer control */
19721 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19722 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19723 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19724 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19725 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19726 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19727 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19728 { }
19729};
19730
a9111321 19731static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19732 .ops = &snd_hda_bind_vol,
19733 .values = {
19734 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19735 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19736 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19737 0
19738 },
19739};
19740
a9111321 19741static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19742 .ops = &snd_hda_bind_sw,
19743 .values = {
19744 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19746 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19747 0
19748 },
19749};
19750
a9111321 19751static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19752 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19753 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19754 { } /* end */
19755};
19756
19757/*
19758 * generic initialization of ADC, input mixers and output mixers
19759 */
a9111321 19760static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19761 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19762 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19763 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19764
c69aefab
KY
19765 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19766 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19767 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19768 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19770 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19771
19772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19773 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19774 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19775 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19776 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19777
19778 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19779 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19780 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19781
d1eb57f4
KY
19782 { }
19783};
19784
c69aefab
KY
19785/* toggle speaker-output according to the hp-jack state */
19786static void alc680_base_setup(struct hda_codec *codec)
19787{
19788 struct alc_spec *spec = codec->spec;
19789
19790 spec->autocfg.hp_pins[0] = 0x16;
19791 spec->autocfg.speaker_pins[0] = 0x14;
19792 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19793 spec->autocfg.num_inputs = 2;
19794 spec->autocfg.inputs[0].pin = 0x18;
19795 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19796 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19797 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19798 spec->automute = 1;
19799 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19800}
19801
19802static void alc680_unsol_event(struct hda_codec *codec,
19803 unsigned int res)
19804{
19805 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19806 alc_hp_automute(codec);
c69aefab
KY
19807 if ((res >> 26) == ALC880_MIC_EVENT)
19808 alc680_rec_autoswitch(codec);
19809}
19810
19811static void alc680_inithook(struct hda_codec *codec)
19812{
d922b51d 19813 alc_hp_automute(codec);
c69aefab
KY
19814 alc680_rec_autoswitch(codec);
19815}
19816
d1eb57f4
KY
19817/* create input playback/capture controls for the given pin */
19818static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19819 const char *ctlname, int idx)
19820{
19821 hda_nid_t dac;
19822 int err;
19823
19824 switch (nid) {
19825 case 0x14:
19826 dac = 0x02;
19827 break;
19828 case 0x15:
19829 dac = 0x03;
19830 break;
19831 case 0x16:
19832 dac = 0x04;
19833 break;
19834 default:
19835 return 0;
19836 }
19837 if (spec->multiout.dac_nids[0] != dac &&
19838 spec->multiout.dac_nids[1] != dac) {
19839 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19840 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19841 HDA_OUTPUT));
19842 if (err < 0)
19843 return err;
19844
19845 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19846 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19847
19848 if (err < 0)
19849 return err;
dda14410 19850 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19851 }
19852
19853 return 0;
19854}
19855
19856/* add playback controls from the parsed DAC table */
19857static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19858 const struct auto_pin_cfg *cfg)
19859{
19860 hda_nid_t nid;
19861 int err;
19862
19863 spec->multiout.dac_nids = spec->private_dac_nids;
19864
19865 nid = cfg->line_out_pins[0];
19866 if (nid) {
19867 const char *name;
19868 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19869 name = "Speaker";
19870 else
19871 name = "Front";
19872 err = alc680_new_analog_output(spec, nid, name, 0);
19873 if (err < 0)
19874 return err;
19875 }
19876
19877 nid = cfg->speaker_pins[0];
19878 if (nid) {
19879 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19880 if (err < 0)
19881 return err;
19882 }
19883 nid = cfg->hp_pins[0];
19884 if (nid) {
19885 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19886 if (err < 0)
19887 return err;
19888 }
19889
19890 return 0;
19891}
19892
19893static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19894 hda_nid_t nid, int pin_type)
19895{
19896 alc_set_pin_output(codec, nid, pin_type);
19897}
19898
19899static void alc680_auto_init_multi_out(struct hda_codec *codec)
19900{
19901 struct alc_spec *spec = codec->spec;
19902 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19903 if (nid) {
19904 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19905 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19906 }
19907}
19908
19909static void alc680_auto_init_hp_out(struct hda_codec *codec)
19910{
19911 struct alc_spec *spec = codec->spec;
19912 hda_nid_t pin;
19913
19914 pin = spec->autocfg.hp_pins[0];
19915 if (pin)
19916 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19917 pin = spec->autocfg.speaker_pins[0];
19918 if (pin)
19919 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19920}
19921
19922/* pcm configuration: identical with ALC880 */
19923#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19924#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19925#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19926#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19927#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19928
19929/*
19930 * BIOS auto configuration
19931 */
19932static int alc680_parse_auto_config(struct hda_codec *codec)
19933{
19934 struct alc_spec *spec = codec->spec;
19935 int err;
4c6d72d1 19936 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19937
19938 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19939 alc680_ignore);
19940 if (err < 0)
19941 return err;
c69aefab 19942
d1eb57f4
KY
19943 if (!spec->autocfg.line_outs) {
19944 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19945 spec->multiout.max_channels = 2;
19946 spec->no_analog = 1;
19947 goto dig_only;
19948 }
19949 return 0; /* can't find valid BIOS pin config */
19950 }
19951 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19952 if (err < 0)
19953 return err;
19954
19955 spec->multiout.max_channels = 2;
19956
19957 dig_only:
19958 /* digital only support output */
757899ac 19959 alc_auto_parse_digital(codec);
d1eb57f4
KY
19960 if (spec->kctls.list)
19961 add_mixer(spec, spec->kctls.list);
19962
19963 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19964
19965 err = alc_auto_add_mic_boost(codec);
19966 if (err < 0)
19967 return err;
19968
19969 return 1;
19970}
19971
19972#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19973
19974/* init callback for auto-configuration model -- overriding the default init */
19975static void alc680_auto_init(struct hda_codec *codec)
19976{
19977 struct alc_spec *spec = codec->spec;
19978 alc680_auto_init_multi_out(codec);
19979 alc680_auto_init_hp_out(codec);
19980 alc680_auto_init_analog_input(codec);
757899ac 19981 alc_auto_init_digital(codec);
d1eb57f4
KY
19982 if (spec->unsol_event)
19983 alc_inithook(codec);
19984}
19985
19986/*
19987 * configuration and preset
19988 */
ea734963 19989static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19990 [ALC680_BASE] = "base",
19991 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19992};
19993
a9111321 19994static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19995 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19996 {}
19997};
19998
a9111321 19999static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
20000 [ALC680_BASE] = {
20001 .mixers = { alc680_base_mixer },
c69aefab 20002 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
20003 .init_verbs = { alc680_init_verbs },
20004 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20005 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20006 .dig_out_nid = ALC680_DIGOUT_NID,
20007 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20008 .channel_mode = alc680_modes,
c69aefab
KY
20009 .unsol_event = alc680_unsol_event,
20010 .setup = alc680_base_setup,
20011 .init_hook = alc680_inithook,
20012
d1eb57f4
KY
20013 },
20014};
20015
20016static int patch_alc680(struct hda_codec *codec)
20017{
20018 struct alc_spec *spec;
20019 int board_config;
20020 int err;
20021
20022 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20023 if (spec == NULL)
20024 return -ENOMEM;
20025
20026 codec->spec = spec;
20027
20028 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20029 alc680_models,
20030 alc680_cfg_tbl);
20031
20032 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20033 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20034 codec->chip_name);
20035 board_config = ALC680_AUTO;
20036 }
20037
20038 if (board_config == ALC680_AUTO) {
20039 /* automatic parse from the BIOS config */
20040 err = alc680_parse_auto_config(codec);
20041 if (err < 0) {
20042 alc_free(codec);
20043 return err;
20044 } else if (!err) {
20045 printk(KERN_INFO
20046 "hda_codec: Cannot set up configuration "
20047 "from BIOS. Using base mode...\n");
20048 board_config = ALC680_BASE;
20049 }
20050 }
20051
20052 if (board_config != ALC680_AUTO)
20053 setup_preset(codec, &alc680_presets[board_config]);
20054
20055 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20056 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20057 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20058 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20059
20060 if (!spec->adc_nids) {
20061 spec->adc_nids = alc680_adc_nids;
20062 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20063 }
20064
20065 if (!spec->cap_mixer)
20066 set_capture_mixer(codec);
20067
20068 spec->vmaster_nid = 0x02;
20069
20070 codec->patch_ops = alc_patch_ops;
20071 if (board_config == ALC680_AUTO)
20072 spec->init_hook = alc680_auto_init;
20073
20074 return 0;
20075}
20076
1da177e4
LT
20077/*
20078 * patch entries
20079 */
a9111321 20080static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 20081 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 20082 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20083 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20084 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20085 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20086 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20087 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20088 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20089 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 20090 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 20091 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20092 .patch = patch_alc861 },
f32610ed
JS
20093 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20094 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20095 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20096 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20097 .patch = patch_alc882 },
bc9f98a9
KY
20098 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20099 .patch = patch_alc662 },
6dda9f4a 20100 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20101 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20102 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20103 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20104 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20105 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20106 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20107 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20108 .patch = patch_alc882 },
cb308f97 20109 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20110 .patch = patch_alc882 },
df694daa 20111 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20112 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20113 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20114 .patch = patch_alc882 },
274693f3 20115 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20116 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20117 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 20118 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
20119 {} /* terminator */
20120};
1289e9e8
TI
20121
20122MODULE_ALIAS("snd-hda-codec-id:10ec*");
20123
20124MODULE_LICENSE("GPL");
20125MODULE_DESCRIPTION("Realtek HD-audio codec");
20126
20127static struct hda_codec_preset_list realtek_list = {
20128 .preset = snd_hda_preset_realtek,
20129 .owner = THIS_MODULE,
20130};
20131
20132static int __init patch_realtek_init(void)
20133{
20134 return snd_hda_add_codec_preset(&realtek_list);
20135}
20136
20137static void __exit patch_realtek_exit(void)
20138{
20139 snd_hda_delete_codec_preset(&realtek_list);
20140}
20141
20142module_init(patch_realtek_init)
20143module_exit(patch_realtek_exit)