]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - More flexible dynamic-ADC switching for Realtek codecs
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
da00c244
KY
279struct alc_customize_define {
280 unsigned int sku_cfg;
281 unsigned char port_connectivity;
282 unsigned char check_sum;
283 unsigned char customization;
284 unsigned char external_amp;
285 unsigned int enable_pcbeep:1;
286 unsigned int platform_type:1;
287 unsigned int swap:1;
288 unsigned int override:1;
90622917 289 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
290};
291
b5bfbc67
TI
292struct alc_fixup;
293
ce764ab2
TI
294struct alc_multi_io {
295 hda_nid_t pin; /* multi-io widget pin NID */
296 hda_nid_t dac; /* DAC to be connected */
297 unsigned int ctl_in; /* cached input-pin control value */
298};
299
d922b51d 300enum {
3b8510ce
TI
301 ALC_AUTOMUTE_PIN, /* change the pin control */
302 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
303 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
304};
305
1da177e4
LT
306struct alc_spec {
307 /* codec parameterization */
a9111321 308 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 309 unsigned int num_mixers;
a9111321 310 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 311 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 312
2d9c6482 313 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
314 * don't forget NULL
315 * termination!
e9edcee0
TI
316 */
317 unsigned int num_init_verbs;
1da177e4 318
aa563af7 319 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
320 const struct hda_pcm_stream *stream_analog_playback;
321 const struct hda_pcm_stream *stream_analog_capture;
322 const struct hda_pcm_stream *stream_analog_alt_playback;
323 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 324
aa563af7 325 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
326 const struct hda_pcm_stream *stream_digital_playback;
327 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
328
329 /* playback */
16ded525
TI
330 struct hda_multi_out multiout; /* playback set-up
331 * max_channels, dacs must be set
332 * dig_out_nid and hp_nid are optional
333 */
6330079f 334 hda_nid_t alt_dac_nid;
6a05ac4a 335 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 336 int dig_out_type;
1da177e4
LT
337
338 /* capture */
339 unsigned int num_adc_nids;
4c6d72d1
TI
340 const hda_nid_t *adc_nids;
341 const hda_nid_t *capsrc_nids;
16ded525 342 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1f0f4b80 343 hda_nid_t mixer_nid; /* analog-mixer NID */
1da177e4 344
840b64c0 345 /* capture setup for dynamic dual-adc switch */
840b64c0
TI
346 hda_nid_t cur_adc;
347 unsigned int cur_adc_stream_tag;
348 unsigned int cur_adc_format;
349
1da177e4 350 /* capture source */
a1e8d2da 351 unsigned int num_mux_defs;
1da177e4
LT
352 const struct hda_input_mux *input_mux;
353 unsigned int cur_mux[3];
21268961
TI
354 hda_nid_t ext_mic_pin;
355 hda_nid_t dock_mic_pin;
356 hda_nid_t int_mic_pin;
1da177e4
LT
357
358 /* channel model */
d2a6d7dc 359 const struct hda_channel_mode *channel_mode;
1da177e4 360 int num_channel_mode;
4e195a7b 361 int need_dac_fix;
3b315d70
HM
362 int const_channel_count;
363 int ext_channel_count;
1da177e4
LT
364
365 /* PCM information */
4c5186ed 366 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 367
e9edcee0
TI
368 /* dynamic controls, init_verbs and input_mux */
369 struct auto_pin_cfg autocfg;
da00c244 370 struct alc_customize_define cdefine;
603c4019 371 struct snd_array kctls;
61b9b9b1 372 struct hda_input_mux private_imux[3];
41923e44 373 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
374 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
375 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
21268961
TI
376 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
377 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
378 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
834be88d 379
ae6b813a
TI
380 /* hooks */
381 void (*init_hook)(struct hda_codec *codec);
382 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 383#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 384 void (*power_hook)(struct hda_codec *codec);
f5de24b0 385#endif
1c716153 386 void (*shutup)(struct hda_codec *codec);
ae6b813a 387
834be88d 388 /* for pin sensing */
834be88d 389 unsigned int jack_present: 1;
e6a5e1b7 390 unsigned int line_jack_present:1;
e9427969 391 unsigned int master_mute:1;
6c819492 392 unsigned int auto_mic:1;
21268961 393 unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */
d922b51d 394 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
395 unsigned int detect_line:1; /* Line-out detection enabled */
396 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 397 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 398
e64f14f4
TI
399 /* other flags */
400 unsigned int no_analog :1; /* digital I/O only */
21268961 401 unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 402 unsigned int single_input_src:1;
d6cc9fab 403 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
d922b51d
TI
404
405 /* auto-mute control */
406 int automute_mode;
3b8510ce 407 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 408
4a79ba34 409 int init_amp;
d433a678 410 int codec_variant; /* flag for other variants */
e64f14f4 411
2134ea4f
TI
412 /* for virtual master */
413 hda_nid_t vmaster_nid;
cb53c626
TI
414#ifdef CONFIG_SND_HDA_POWER_SAVE
415 struct hda_loopback_check loopback;
416#endif
2c3bf9ab
TI
417
418 /* for PLL fix */
419 hda_nid_t pll_nid;
420 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
421
422 /* fix-up list */
423 int fixup_id;
424 const struct alc_fixup *fixup_list;
425 const char *fixup_name;
ce764ab2
TI
426
427 /* multi-io */
428 int multi_ios;
429 struct alc_multi_io multi_io[4];
df694daa
KY
430};
431
432/*
433 * configuration template - to be copied to the spec instance
434 */
435struct alc_config_preset {
a9111321 436 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
437 * with spec
438 */
a9111321 439 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
440 const struct hda_verb *init_verbs[5];
441 unsigned int num_dacs;
4c6d72d1 442 const hda_nid_t *dac_nids;
df694daa
KY
443 hda_nid_t dig_out_nid; /* optional */
444 hda_nid_t hp_nid; /* optional */
4c6d72d1 445 const hda_nid_t *slave_dig_outs;
df694daa 446 unsigned int num_adc_nids;
4c6d72d1
TI
447 const hda_nid_t *adc_nids;
448 const hda_nid_t *capsrc_nids;
df694daa
KY
449 hda_nid_t dig_in_nid;
450 unsigned int num_channel_mode;
451 const struct hda_channel_mode *channel_mode;
4e195a7b 452 int need_dac_fix;
3b315d70 453 int const_channel_count;
a1e8d2da 454 unsigned int num_mux_defs;
df694daa 455 const struct hda_input_mux *input_mux;
ae6b813a 456 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 457 void (*setup)(struct hda_codec *);
ae6b813a 458 void (*init_hook)(struct hda_codec *);
cb53c626 459#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 460 const struct hda_amp_list *loopbacks;
c97259df 461 void (*power_hook)(struct hda_codec *codec);
cb53c626 462#endif
1da177e4
LT
463};
464
1da177e4
LT
465
466/*
467 * input MUX handling
468 */
9c7f852e
TI
469static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
471{
472 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
473 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
474 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
475 if (mux_idx >= spec->num_mux_defs)
476 mux_idx = 0;
5311114d
TI
477 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
478 mux_idx = 0;
a1e8d2da 479 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
480}
481
9c7f852e
TI
482static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
483 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
484{
485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
486 struct alc_spec *spec = codec->spec;
487 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
488
489 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
490 return 0;
491}
492
21268961
TI
493static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
494{
495 struct alc_spec *spec = codec->spec;
496 hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
497
498 if (spec->cur_adc && spec->cur_adc != new_adc) {
499 /* stream is running, let's swap the current ADC */
500 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
501 spec->cur_adc = new_adc;
502 snd_hda_codec_setup_stream(codec, new_adc,
503 spec->cur_adc_stream_tag, 0,
504 spec->cur_adc_format);
505 return true;
506 }
507 return false;
508}
509
510/* select the given imux item; either unmute exclusively or select the route */
511static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
512 unsigned int idx, bool force)
1da177e4 513{
1da177e4 514 struct alc_spec *spec = codec->spec;
cd896c33 515 const struct hda_input_mux *imux;
cd896c33 516 unsigned int mux_idx;
21268961
TI
517 int i, type;
518 hda_nid_t nid;
1da177e4 519
cd896c33
TI
520 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
521 imux = &spec->input_mux[mux_idx];
5311114d
TI
522 if (!imux->num_items && mux_idx > 0)
523 imux = &spec->input_mux[0];
cd896c33 524
21268961
TI
525 if (idx >= imux->num_items)
526 idx = imux->num_items - 1;
527 if (spec->cur_mux[adc_idx] == idx && !force)
528 return 0;
529 spec->cur_mux[adc_idx] = idx;
530
531 if (spec->dyn_adc_switch) {
532 alc_dyn_adc_pcm_resetup(codec, idx);
533 adc_idx = spec->dyn_adc_idx[idx];
534 }
535
536 nid = spec->capsrc_nids ?
537 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
538
539 /* no selection? */
540 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
541 return 1;
542
a22d543a 543 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 544 if (type == AC_WID_AUD_MIX) {
54cbc9ab 545 /* Matrix-mixer style (e.g. ALC882) */
54cbc9ab
TI
546 for (i = 0; i < imux->num_items; i++) {
547 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
548 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
549 imux->items[i].index,
550 HDA_AMP_MUTE, v);
551 }
54cbc9ab
TI
552 } else {
553 /* MUX style (e.g. ALC880) */
21268961
TI
554 snd_hda_codec_write_cache(codec, nid, 0,
555 AC_VERB_SET_CONNECT_SEL,
556 imux->items[idx].index);
54cbc9ab 557 }
21268961
TI
558 return 1;
559}
560
561static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563{
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
566 return alc_mux_select(codec, adc_idx,
567 ucontrol->value.enumerated.item[0], false);
54cbc9ab 568}
e9edcee0 569
1da177e4
LT
570/*
571 * channel mode setting
572 */
9c7f852e
TI
573static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
575{
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
578 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
579 spec->num_channel_mode);
1da177e4
LT
580}
581
9c7f852e
TI
582static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
584{
585 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
586 struct alc_spec *spec = codec->spec;
d2a6d7dc 587 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 588 spec->num_channel_mode,
3b315d70 589 spec->ext_channel_count);
1da177e4
LT
590}
591
9c7f852e
TI
592static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
594{
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 struct alc_spec *spec = codec->spec;
4e195a7b
TI
597 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
598 spec->num_channel_mode,
3b315d70
HM
599 &spec->ext_channel_count);
600 if (err >= 0 && !spec->const_channel_count) {
601 spec->multiout.max_channels = spec->ext_channel_count;
602 if (spec->need_dac_fix)
603 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
604 }
4e195a7b 605 return err;
1da177e4
LT
606}
607
a9430dd8 608/*
4c5186ed 609 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 610 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
611 * being part of a format specifier. Maximum allowed length of a value is
612 * 63 characters plus NULL terminator.
7cf51e48
JW
613 *
614 * Note: some retasking pin complexes seem to ignore requests for input
615 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
616 * are requested. Therefore order this list so that this behaviour will not
617 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
618 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
619 * March 2006.
4c5186ed 620 */
a9111321 621static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
622 "Mic 50pc bias", "Mic 80pc bias",
623 "Line in", "Line out", "Headphone out",
4c5186ed 624};
a9111321 625static const unsigned char alc_pin_mode_values[] = {
7cf51e48 626 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
627};
628/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
629 * in the pin being assumed to be exclusively an input or an output pin. In
630 * addition, "input" pins may or may not process the mic bias option
631 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
632 * accept requests for bias as of chip versions up to March 2006) and/or
633 * wiring in the computer.
a9430dd8 634 */
a1e8d2da
JW
635#define ALC_PIN_DIR_IN 0x00
636#define ALC_PIN_DIR_OUT 0x01
637#define ALC_PIN_DIR_INOUT 0x02
638#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
639#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 640
ea1fb29a 641/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
642 * For each direction the minimum and maximum values are given.
643 */
a9111321 644static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
645 { 0, 2 }, /* ALC_PIN_DIR_IN */
646 { 3, 4 }, /* ALC_PIN_DIR_OUT */
647 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
648 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
649 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
650};
651#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
652#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
653#define alc_pin_mode_n_items(_dir) \
654 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
655
9c7f852e
TI
656static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
657 struct snd_ctl_elem_info *uinfo)
a9430dd8 658{
4c5186ed
JW
659 unsigned int item_num = uinfo->value.enumerated.item;
660 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
661
662 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 663 uinfo->count = 1;
4c5186ed
JW
664 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
665
666 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
667 item_num = alc_pin_mode_min(dir);
668 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
669 return 0;
670}
671
9c7f852e
TI
672static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
a9430dd8 674{
4c5186ed 675 unsigned int i;
a9430dd8
JW
676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
677 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 678 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 679 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
680 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
681 AC_VERB_GET_PIN_WIDGET_CONTROL,
682 0x00);
a9430dd8 683
4c5186ed
JW
684 /* Find enumerated value for current pinctl setting */
685 i = alc_pin_mode_min(dir);
4b35d2ca 686 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 687 i++;
9c7f852e 688 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
689 return 0;
690}
691
9c7f852e
TI
692static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
a9430dd8 694{
4c5186ed 695 signed int change;
a9430dd8
JW
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
698 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
699 long val = *ucontrol->value.integer.value;
9c7f852e
TI
700 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
701 AC_VERB_GET_PIN_WIDGET_CONTROL,
702 0x00);
a9430dd8 703
f12ab1e0 704 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
705 val = alc_pin_mode_min(dir);
706
707 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
708 if (change) {
709 /* Set pin mode to that requested */
82beb8fd
TI
710 snd_hda_codec_write_cache(codec, nid, 0,
711 AC_VERB_SET_PIN_WIDGET_CONTROL,
712 alc_pin_mode_values[val]);
cdcd9268 713
ea1fb29a 714 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
715 * for the requested pin mode. Enum values of 2 or less are
716 * input modes.
717 *
718 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
719 * reduces noise slightly (particularly on input) so we'll
720 * do it. However, having both input and output buffers
721 * enabled simultaneously doesn't seem to be problematic if
722 * this turns out to be necessary in the future.
cdcd9268
JW
723 */
724 if (val <= 2) {
47fd830a
TI
725 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
726 HDA_AMP_MUTE, HDA_AMP_MUTE);
727 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
728 HDA_AMP_MUTE, 0);
cdcd9268 729 } else {
47fd830a
TI
730 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
731 HDA_AMP_MUTE, HDA_AMP_MUTE);
732 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
733 HDA_AMP_MUTE, 0);
cdcd9268
JW
734 }
735 }
a9430dd8
JW
736 return change;
737}
738
4c5186ed 739#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 741 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
742 .info = alc_pin_mode_info, \
743 .get = alc_pin_mode_get, \
744 .put = alc_pin_mode_put, \
745 .private_value = nid | (dir<<16) }
df694daa 746
5c8f858d
JW
747/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
748 * together using a mask with more than one bit set. This control is
749 * currently used only by the ALC260 test model. At this stage they are not
750 * needed for any "production" models.
751 */
752#ifdef CONFIG_SND_DEBUG
a5ce8890 753#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 754
9c7f852e
TI
755static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
756 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
757{
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
762 unsigned int val = snd_hda_codec_read(codec, nid, 0,
763 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
764
765 *valp = (val & mask) != 0;
766 return 0;
767}
9c7f852e
TI
768static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
769 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
770{
771 signed int change;
772 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
773 hda_nid_t nid = kcontrol->private_value & 0xffff;
774 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
775 long val = *ucontrol->value.integer.value;
9c7f852e
TI
776 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
777 AC_VERB_GET_GPIO_DATA,
778 0x00);
5c8f858d
JW
779
780 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
781 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
782 if (val == 0)
5c8f858d
JW
783 gpio_data &= ~mask;
784 else
785 gpio_data |= mask;
82beb8fd
TI
786 snd_hda_codec_write_cache(codec, nid, 0,
787 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
788
789 return change;
790}
791#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
792 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 793 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
794 .info = alc_gpio_data_info, \
795 .get = alc_gpio_data_get, \
796 .put = alc_gpio_data_put, \
797 .private_value = nid | (mask<<16) }
798#endif /* CONFIG_SND_DEBUG */
799
92621f13
JW
800/* A switch control to allow the enabling of the digital IO pins on the
801 * ALC260. This is incredibly simplistic; the intention of this control is
802 * to provide something in the test model allowing digital outputs to be
803 * identified if present. If models are found which can utilise these
804 * outputs a more complete mixer control can be devised for those models if
805 * necessary.
806 */
807#ifdef CONFIG_SND_DEBUG
a5ce8890 808#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 809
9c7f852e
TI
810static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
812{
813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
814 hda_nid_t nid = kcontrol->private_value & 0xffff;
815 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
816 long *valp = ucontrol->value.integer.value;
9c7f852e 817 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 818 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
819
820 *valp = (val & mask) != 0;
821 return 0;
822}
9c7f852e
TI
823static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
824 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
825{
826 signed int change;
827 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
828 hda_nid_t nid = kcontrol->private_value & 0xffff;
829 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
830 long val = *ucontrol->value.integer.value;
9c7f852e 831 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 832 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 833 0x00);
92621f13
JW
834
835 /* Set/unset the masked control bit(s) as needed */
9c7f852e 836 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
837 if (val==0)
838 ctrl_data &= ~mask;
839 else
840 ctrl_data |= mask;
82beb8fd
TI
841 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
842 ctrl_data);
92621f13
JW
843
844 return change;
845}
846#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
847 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 848 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
849 .info = alc_spdif_ctrl_info, \
850 .get = alc_spdif_ctrl_get, \
851 .put = alc_spdif_ctrl_put, \
852 .private_value = nid | (mask<<16) }
853#endif /* CONFIG_SND_DEBUG */
854
f8225f6d
JW
855/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
856 * Again, this is only used in the ALC26x test models to help identify when
857 * the EAPD line must be asserted for features to work.
858 */
859#ifdef CONFIG_SND_DEBUG
860#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
861
862static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
863 struct snd_ctl_elem_value *ucontrol)
864{
865 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
866 hda_nid_t nid = kcontrol->private_value & 0xffff;
867 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
868 long *valp = ucontrol->value.integer.value;
869 unsigned int val = snd_hda_codec_read(codec, nid, 0,
870 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
871
872 *valp = (val & mask) != 0;
873 return 0;
874}
875
876static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
877 struct snd_ctl_elem_value *ucontrol)
878{
879 int change;
880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
881 hda_nid_t nid = kcontrol->private_value & 0xffff;
882 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
883 long val = *ucontrol->value.integer.value;
884 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
885 AC_VERB_GET_EAPD_BTLENABLE,
886 0x00);
887
888 /* Set/unset the masked control bit(s) as needed */
889 change = (!val ? 0 : mask) != (ctrl_data & mask);
890 if (!val)
891 ctrl_data &= ~mask;
892 else
893 ctrl_data |= mask;
894 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
895 ctrl_data);
896
897 return change;
898}
899
900#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
901 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 902 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
903 .info = alc_eapd_ctrl_info, \
904 .get = alc_eapd_ctrl_get, \
905 .put = alc_eapd_ctrl_put, \
906 .private_value = nid | (mask<<16) }
907#endif /* CONFIG_SND_DEBUG */
908
23f0c048
TI
909/*
910 * set up the input pin config (depending on the given auto-pin type)
911 */
912static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
913 int auto_pin_type)
914{
915 unsigned int val = PIN_IN;
916
86e2959a 917 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 918 unsigned int pincap;
954a29c8
TI
919 unsigned int oldval;
920 oldval = snd_hda_codec_read(codec, nid, 0,
921 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 922 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 923 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
924 /* if the default pin setup is vref50, we give it priority */
925 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 926 val = PIN_VREF80;
461c6c3a
TI
927 else if (pincap & AC_PINCAP_VREF_50)
928 val = PIN_VREF50;
929 else if (pincap & AC_PINCAP_VREF_100)
930 val = PIN_VREF100;
931 else if (pincap & AC_PINCAP_VREF_GRD)
932 val = PIN_VREFGRD;
23f0c048
TI
933 }
934 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
935}
936
f6837bbd
TI
937static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
938{
939 struct alc_spec *spec = codec->spec;
940 struct auto_pin_cfg *cfg = &spec->autocfg;
941
942 if (!cfg->line_outs) {
943 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
944 cfg->line_out_pins[cfg->line_outs])
945 cfg->line_outs++;
946 }
947 if (!cfg->speaker_outs) {
948 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
949 cfg->speaker_pins[cfg->speaker_outs])
950 cfg->speaker_outs++;
951 }
952 if (!cfg->hp_outs) {
953 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
954 cfg->hp_pins[cfg->hp_outs])
955 cfg->hp_outs++;
956 }
957}
958
d88897ea
TI
959/*
960 */
a9111321 961static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
962{
963 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
964 return;
965 spec->mixers[spec->num_mixers++] = mix;
966}
967
968static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
969{
970 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
971 return;
972 spec->init_verbs[spec->num_init_verbs++] = verb;
973}
974
df694daa
KY
975/*
976 * set up from the preset table
977 */
e9c364c0 978static void setup_preset(struct hda_codec *codec,
9c7f852e 979 const struct alc_config_preset *preset)
df694daa 980{
e9c364c0 981 struct alc_spec *spec = codec->spec;
df694daa
KY
982 int i;
983
984 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 985 add_mixer(spec, preset->mixers[i]);
f9e336f6 986 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
987 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
988 i++)
d88897ea 989 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 990
df694daa
KY
991 spec->channel_mode = preset->channel_mode;
992 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 993 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 994 spec->const_channel_count = preset->const_channel_count;
df694daa 995
3b315d70
HM
996 if (preset->const_channel_count)
997 spec->multiout.max_channels = preset->const_channel_count;
998 else
999 spec->multiout.max_channels = spec->channel_mode[0].channels;
1000 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
1001
1002 spec->multiout.num_dacs = preset->num_dacs;
1003 spec->multiout.dac_nids = preset->dac_nids;
1004 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 1005 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 1006 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 1007
a1e8d2da 1008 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 1009 if (!spec->num_mux_defs)
a1e8d2da 1010 spec->num_mux_defs = 1;
df694daa
KY
1011 spec->input_mux = preset->input_mux;
1012
1013 spec->num_adc_nids = preset->num_adc_nids;
1014 spec->adc_nids = preset->adc_nids;
e1406348 1015 spec->capsrc_nids = preset->capsrc_nids;
df694daa 1016 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
1017
1018 spec->unsol_event = preset->unsol_event;
1019 spec->init_hook = preset->init_hook;
cb53c626 1020#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 1021 spec->power_hook = preset->power_hook;
cb53c626
TI
1022 spec->loopback.amplist = preset->loopbacks;
1023#endif
e9c364c0
TI
1024
1025 if (preset->setup)
1026 preset->setup(codec);
f6837bbd
TI
1027
1028 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
1029}
1030
bc9f98a9 1031/* Enable GPIO mask and set output */
a9111321 1032static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1033 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1034 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1035 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1036 { }
1037};
1038
a9111321 1039static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1040 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1041 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1042 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1043 { }
1044};
1045
a9111321 1046static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1047 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1048 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1049 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1050 { }
1051};
1052
2c3bf9ab
TI
1053/*
1054 * Fix hardware PLL issue
1055 * On some codecs, the analog PLL gating control must be off while
1056 * the default value is 1.
1057 */
1058static void alc_fix_pll(struct hda_codec *codec)
1059{
1060 struct alc_spec *spec = codec->spec;
1061 unsigned int val;
1062
1063 if (!spec->pll_nid)
1064 return;
1065 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1066 spec->pll_coef_idx);
1067 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1068 AC_VERB_GET_PROC_COEF, 0);
1069 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1070 spec->pll_coef_idx);
1071 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1072 val & ~(1 << spec->pll_coef_bit));
1073}
1074
1075static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1076 unsigned int coef_idx, unsigned int coef_bit)
1077{
1078 struct alc_spec *spec = codec->spec;
1079 spec->pll_nid = nid;
1080 spec->pll_coef_idx = coef_idx;
1081 spec->pll_coef_bit = coef_bit;
1082 alc_fix_pll(codec);
1083}
1084
9ad0e496
KY
1085static int alc_init_jacks(struct hda_codec *codec)
1086{
cd372fb3 1087#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1088 struct alc_spec *spec = codec->spec;
1089 int err;
1090 unsigned int hp_nid = spec->autocfg.hp_pins[0];
21268961
TI
1091 unsigned int mic_nid = spec->ext_mic_pin;
1092 unsigned int dock_nid = spec->dock_mic_pin;
9ad0e496 1093
265a0247 1094 if (hp_nid) {
cd372fb3
TI
1095 err = snd_hda_input_jack_add(codec, hp_nid,
1096 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1097 if (err < 0)
1098 return err;
cd372fb3 1099 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1100 }
9ad0e496 1101
265a0247 1102 if (mic_nid) {
cd372fb3
TI
1103 err = snd_hda_input_jack_add(codec, mic_nid,
1104 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1105 if (err < 0)
1106 return err;
cd372fb3 1107 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1108 }
8ed99d97
TI
1109 if (dock_nid) {
1110 err = snd_hda_input_jack_add(codec, dock_nid,
1111 SND_JACK_MICROPHONE, NULL);
1112 if (err < 0)
1113 return err;
1114 snd_hda_input_jack_report(codec, dock_nid);
1115 }
cd372fb3 1116#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1117 return 0;
1118}
9ad0e496 1119
e6a5e1b7 1120static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1121{
e6a5e1b7 1122 int i, present = 0;
c9b58006 1123
e6a5e1b7
TI
1124 for (i = 0; i < num_pins; i++) {
1125 hda_nid_t nid = pins[i];
bb35febd
TI
1126 if (!nid)
1127 break;
cd372fb3 1128 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1129 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1130 }
e6a5e1b7
TI
1131 return present;
1132}
bb35febd 1133
e6a5e1b7 1134static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1135 bool mute, bool hp_out)
e6a5e1b7
TI
1136{
1137 struct alc_spec *spec = codec->spec;
1138 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1139 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1140 int i;
1141
1142 for (i = 0; i < num_pins; i++) {
1143 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1144 if (!nid)
1145 break;
3b8510ce
TI
1146 switch (spec->automute_mode) {
1147 case ALC_AUTOMUTE_PIN:
bb35febd 1148 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1149 AC_VERB_SET_PIN_WIDGET_CONTROL,
1150 pin_bits);
3b8510ce
TI
1151 break;
1152 case ALC_AUTOMUTE_AMP:
bb35febd 1153 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1154 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1155 break;
1156 case ALC_AUTOMUTE_MIXER:
1157 nid = spec->automute_mixer_nid[i];
1158 if (!nid)
1159 break;
1160 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1161 HDA_AMP_MUTE, mute_bits);
3b8510ce 1162 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1163 HDA_AMP_MUTE, mute_bits);
3b8510ce 1164 break;
bb35febd 1165 }
a9fd4f3f 1166 }
c9b58006
KY
1167}
1168
e6a5e1b7
TI
1169/* Toggle internal speakers muting */
1170static void update_speakers(struct hda_codec *codec)
1171{
1172 struct alc_spec *spec = codec->spec;
1a1455de 1173 int on;
e6a5e1b7 1174
c0a20263
TI
1175 /* Control HP pins/amps depending on master_mute state;
1176 * in general, HP pins/amps control should be enabled in all cases,
1177 * but currently set only for master_mute, just to be safe
1178 */
1179 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1180 spec->autocfg.hp_pins, spec->master_mute, true);
1181
1a1455de
TI
1182 if (!spec->automute)
1183 on = 0;
1184 else
1185 on = spec->jack_present | spec->line_jack_present;
1186 on |= spec->master_mute;
e6a5e1b7 1187 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1188 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1189
1190 /* toggle line-out mutes if needed, too */
1a1455de
TI
1191 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1192 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1193 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1194 return;
1a1455de
TI
1195 if (!spec->automute_lines || !spec->automute)
1196 on = 0;
1197 else
1198 on = spec->jack_present;
1199 on |= spec->master_mute;
e6a5e1b7 1200 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1201 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1202}
1203
1204static void alc_hp_automute(struct hda_codec *codec)
1205{
1206 struct alc_spec *spec = codec->spec;
1207
1208 if (!spec->automute)
1209 return;
1210 spec->jack_present =
1211 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1212 spec->autocfg.hp_pins);
1213 update_speakers(codec);
1214}
1215
1216static void alc_line_automute(struct hda_codec *codec)
1217{
1218 struct alc_spec *spec = codec->spec;
1219
1220 if (!spec->automute || !spec->detect_line)
1221 return;
1222 spec->line_jack_present =
1223 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1224 spec->autocfg.line_out_pins);
1225 update_speakers(codec);
1226}
1227
8d087c76
TI
1228#define get_connection_index(codec, mux, nid) \
1229 snd_hda_get_conn_index(codec, mux, nid, 0)
6c819492 1230
7fb0d78f
KY
1231static void alc_mic_automute(struct hda_codec *codec)
1232{
1233 struct alc_spec *spec = codec->spec;
21268961 1234 hda_nid_t *pins = spec->imux_pins;
6c819492 1235
21268961 1236 if (!spec->auto_mic || !spec->auto_mic_valid_imux)
6c819492
TI
1237 return;
1238 if (snd_BUG_ON(!spec->adc_nids))
1239 return;
21268961 1240 if (snd_BUG_ON(spec->int_mic_idx < 0 || spec->ext_mic_idx < 0))
840b64c0 1241 return;
6c819492 1242
21268961
TI
1243 if (snd_hda_jack_detect(codec, pins[spec->ext_mic_idx]))
1244 alc_mux_select(codec, 0, spec->ext_mic_idx, false);
1245 else if (spec->dock_mic_idx >= 0 &&
1246 snd_hda_jack_detect(codec, pins[spec->dock_mic_idx]))
1247 alc_mux_select(codec, 0, spec->dock_mic_idx, false);
1248 else
1249 alc_mux_select(codec, 0, spec->int_mic_idx, false);
6c819492 1250
21268961
TI
1251 snd_hda_input_jack_report(codec, pins[spec->ext_mic_idx]);
1252 if (spec->dock_mic_idx >= 0)
1253 snd_hda_input_jack_report(codec, pins[spec->dock_mic_idx]);
7fb0d78f
KY
1254}
1255
c9b58006
KY
1256/* unsolicited event for HP jack sensing */
1257static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1258{
1259 if (codec->vendor_id == 0x10ec0880)
1260 res >>= 28;
1261 else
1262 res >>= 26;
a9fd4f3f
TI
1263 switch (res) {
1264 case ALC880_HP_EVENT:
d922b51d 1265 alc_hp_automute(codec);
a9fd4f3f 1266 break;
e6a5e1b7
TI
1267 case ALC880_FRONT_EVENT:
1268 alc_line_automute(codec);
1269 break;
a9fd4f3f 1270 case ALC880_MIC_EVENT:
7fb0d78f 1271 alc_mic_automute(codec);
a9fd4f3f
TI
1272 break;
1273 }
7fb0d78f
KY
1274}
1275
1276static void alc_inithook(struct hda_codec *codec)
1277{
d922b51d 1278 alc_hp_automute(codec);
e6a5e1b7 1279 alc_line_automute(codec);
7fb0d78f 1280 alc_mic_automute(codec);
c9b58006
KY
1281}
1282
f9423e7a
KY
1283/* additional initialization for ALC888 variants */
1284static void alc888_coef_init(struct hda_codec *codec)
1285{
1286 unsigned int tmp;
1287
1288 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1289 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1290 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1291 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1292 /* alc888S-VC */
1293 snd_hda_codec_read(codec, 0x20, 0,
1294 AC_VERB_SET_PROC_COEF, 0x830);
1295 else
1296 /* alc888-VB */
1297 snd_hda_codec_read(codec, 0x20, 0,
1298 AC_VERB_SET_PROC_COEF, 0x3030);
1299}
1300
87a8c370
JK
1301static void alc889_coef_init(struct hda_codec *codec)
1302{
1303 unsigned int tmp;
1304
1305 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1306 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1307 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1308 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1309}
1310
3fb4a508
TI
1311/* turn on/off EAPD control (only if available) */
1312static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1313{
1314 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1315 return;
1316 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1317 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1318 on ? 2 : 0);
1319}
1320
691f1fcc
TI
1321/* turn on/off EAPD controls of the codec */
1322static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1323{
1324 /* We currently only handle front, HP */
39fa84e9
TI
1325 static hda_nid_t pins[] = {
1326 0x0f, 0x10, 0x14, 0x15, 0
1327 };
1328 hda_nid_t *p;
1329 for (p = pins; *p; p++)
1330 set_eapd(codec, *p, on);
691f1fcc
TI
1331}
1332
1c716153
TI
1333/* generic shutup callback;
1334 * just turning off EPAD and a little pause for avoiding pop-noise
1335 */
1336static void alc_eapd_shutup(struct hda_codec *codec)
1337{
1338 alc_auto_setup_eapd(codec, false);
1339 msleep(200);
1340}
1341
4a79ba34 1342static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1343{
4a79ba34 1344 unsigned int tmp;
bc9f98a9 1345
39fa84e9 1346 alc_auto_setup_eapd(codec, true);
4a79ba34
TI
1347 switch (type) {
1348 case ALC_INIT_GPIO1:
bc9f98a9
KY
1349 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1350 break;
4a79ba34 1351 case ALC_INIT_GPIO2:
bc9f98a9
KY
1352 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1353 break;
4a79ba34 1354 case ALC_INIT_GPIO3:
bdd148a3
KY
1355 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1356 break;
4a79ba34 1357 case ALC_INIT_DEFAULT:
c9b58006
KY
1358 switch (codec->vendor_id) {
1359 case 0x10ec0260:
1360 snd_hda_codec_write(codec, 0x1a, 0,
1361 AC_VERB_SET_COEF_INDEX, 7);
1362 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1363 AC_VERB_GET_PROC_COEF, 0);
1364 snd_hda_codec_write(codec, 0x1a, 0,
1365 AC_VERB_SET_COEF_INDEX, 7);
1366 snd_hda_codec_write(codec, 0x1a, 0,
1367 AC_VERB_SET_PROC_COEF,
1368 tmp | 0x2010);
1369 break;
1370 case 0x10ec0262:
1371 case 0x10ec0880:
1372 case 0x10ec0882:
1373 case 0x10ec0883:
1374 case 0x10ec0885:
4a5a4c56 1375 case 0x10ec0887:
20b67ddd 1376 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1377 alc889_coef_init(codec);
c9b58006 1378 break;
f9423e7a 1379 case 0x10ec0888:
4a79ba34 1380 alc888_coef_init(codec);
f9423e7a 1381 break;
0aea778e 1382#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1383 case 0x10ec0267:
1384 case 0x10ec0268:
1385 snd_hda_codec_write(codec, 0x20, 0,
1386 AC_VERB_SET_COEF_INDEX, 7);
1387 tmp = snd_hda_codec_read(codec, 0x20, 0,
1388 AC_VERB_GET_PROC_COEF, 0);
1389 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1390 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1391 snd_hda_codec_write(codec, 0x20, 0,
1392 AC_VERB_SET_PROC_COEF,
1393 tmp | 0x3000);
1394 break;
0aea778e 1395#endif /* XXX */
bc9f98a9 1396 }
4a79ba34
TI
1397 break;
1398 }
1399}
1400
1a1455de
TI
1401static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1402 struct snd_ctl_elem_info *uinfo)
1403{
ae8a60a5
TI
1404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1405 struct alc_spec *spec = codec->spec;
1406 static const char * const texts2[] = {
1407 "Disabled", "Enabled"
1408 };
1409 static const char * const texts3[] = {
1a1455de
TI
1410 "Disabled", "Speaker Only", "Line-Out+Speaker"
1411 };
ae8a60a5 1412 const char * const *texts;
1a1455de
TI
1413
1414 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1415 uinfo->count = 1;
ae8a60a5
TI
1416 if (spec->automute_hp_lo) {
1417 uinfo->value.enumerated.items = 3;
1418 texts = texts3;
1419 } else {
1420 uinfo->value.enumerated.items = 2;
1421 texts = texts2;
1422 }
1423 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1424 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1425 strcpy(uinfo->value.enumerated.name,
1426 texts[uinfo->value.enumerated.item]);
1427 return 0;
1428}
1429
1430static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1431 struct snd_ctl_elem_value *ucontrol)
1432{
1433 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1434 struct alc_spec *spec = codec->spec;
1435 unsigned int val;
1436 if (!spec->automute)
1437 val = 0;
1438 else if (!spec->automute_lines)
1439 val = 1;
1440 else
1441 val = 2;
1442 ucontrol->value.enumerated.item[0] = val;
1443 return 0;
1444}
1445
1446static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1447 struct snd_ctl_elem_value *ucontrol)
1448{
1449 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1450 struct alc_spec *spec = codec->spec;
1451
1452 switch (ucontrol->value.enumerated.item[0]) {
1453 case 0:
1454 if (!spec->automute)
1455 return 0;
1456 spec->automute = 0;
1457 break;
1458 case 1:
1459 if (spec->automute && !spec->automute_lines)
1460 return 0;
1461 spec->automute = 1;
1462 spec->automute_lines = 0;
1463 break;
1464 case 2:
ae8a60a5
TI
1465 if (!spec->automute_hp_lo)
1466 return -EINVAL;
1a1455de
TI
1467 if (spec->automute && spec->automute_lines)
1468 return 0;
1469 spec->automute = 1;
1470 spec->automute_lines = 1;
1471 break;
1472 default:
1473 return -EINVAL;
1474 }
1475 update_speakers(codec);
1476 return 1;
1477}
1478
a9111321 1479static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1480 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1481 .name = "Auto-Mute Mode",
1482 .info = alc_automute_mode_info,
1483 .get = alc_automute_mode_get,
1484 .put = alc_automute_mode_put,
1485};
1486
1487static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1488
1489static int alc_add_automute_mode_enum(struct hda_codec *codec)
1490{
1491 struct alc_spec *spec = codec->spec;
1492 struct snd_kcontrol_new *knew;
1493
1494 knew = alc_kcontrol_new(spec);
1495 if (!knew)
1496 return -ENOMEM;
1497 *knew = alc_automute_mode_enum;
1498 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1499 if (!knew->name)
1500 return -ENOMEM;
1501 return 0;
1502}
1503
4a79ba34
TI
1504static void alc_init_auto_hp(struct hda_codec *codec)
1505{
1506 struct alc_spec *spec = codec->spec;
bb35febd 1507 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1508 int present = 0;
bb35febd 1509 int i;
4a79ba34 1510
1daf5f46
TI
1511 if (cfg->hp_pins[0])
1512 present++;
1513 if (cfg->line_out_pins[0])
1514 present++;
1515 if (cfg->speaker_pins[0])
1516 present++;
1517 if (present < 2) /* need two different output types */
1518 return;
ae8a60a5
TI
1519 if (present == 3)
1520 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1521
bb35febd 1522 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1523 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1524 sizeof(cfg->speaker_pins));
1525 cfg->speaker_outs = cfg->line_outs;
1526 }
1527
1528 if (!cfg->hp_pins[0]) {
1529 memcpy(cfg->hp_pins, cfg->line_out_pins,
1530 sizeof(cfg->hp_pins));
1531 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1532 }
1533
bb35febd 1534 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1535 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1536 if (!is_jack_detectable(codec, nid))
1a1455de 1537 continue;
bb35febd 1538 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1539 nid);
1540 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1541 AC_VERB_SET_UNSOLICITED_ENABLE,
1542 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1543 spec->automute = 1;
1544 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1545 }
1a1455de
TI
1546 if (spec->automute && cfg->line_out_pins[0] &&
1547 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1548 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1549 for (i = 0; i < cfg->line_outs; i++) {
1550 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1551 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1552 continue;
1553 snd_printdd("realtek: Enable Line-Out auto-muting "
1554 "on NID 0x%x\n", nid);
1555 snd_hda_codec_write_cache(codec, nid, 0,
1556 AC_VERB_SET_UNSOLICITED_ENABLE,
1557 AC_USRSP_EN | ALC880_FRONT_EVENT);
1558 spec->detect_line = 1;
1559 }
52d3cb88 1560 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1561 }
1562
1563 if (spec->automute) {
1a1455de
TI
1564 /* create a control for automute mode */
1565 alc_add_automute_mode_enum(codec);
ae8a60a5 1566 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1567 }
4a79ba34
TI
1568}
1569
21268961
TI
1570static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1571{
1572 int i;
1573 for (i = 0; i < nums; i++)
1574 if (list[i] == nid)
1575 return i;
1576 return -1;
1577}
1578
1579static bool alc_check_dyn_adc_switch(struct hda_codec *codec);
1580
1581/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1582static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
1583{
1584 struct alc_spec *spec = codec->spec;
1585 struct hda_input_mux *imux;
1586 static char * const texts[3] = {
1587 "Mic", "Internal Mic", "Dock Mic"
1588 };
1589 int i;
1590
1591 if (!spec->auto_mic)
1592 return false;
1593 imux = &spec->private_imux[0];
1594 if (spec->input_mux == imux)
1595 return true;
1596 spec->imux_pins[0] = spec->ext_mic_pin;
1597 spec->imux_pins[1] = spec->int_mic_pin;
1598 spec->imux_pins[2] = spec->dock_mic_pin;
1599 for (i = 0; i < 3; i++) {
1600 strcpy(imux->items[i].label, texts[i]);
1601 if (spec->imux_pins[i])
1602 imux->num_items = i + 1;
1603 }
1604 spec->num_mux_defs = 1;
1605 spec->input_mux = imux;
1606 return true;
1607}
1608
1609/* check whether all auto-mic pins are valid; setup indices if OK */
1610static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1611{
1612 struct alc_spec *spec = codec->spec;
1613 const struct hda_input_mux *imux;
1614
1615 if (!spec->auto_mic)
1616 return false;
1617 if (spec->auto_mic_valid_imux)
1618 return true; /* already checked */
1619
1620 /* fill up imux indices */
1621 if (!alc_check_dyn_adc_switch(codec)) {
1622 spec->auto_mic = 0;
1623 return false;
1624 }
1625
1626 imux = spec->input_mux;
1627 spec->ext_mic_idx = find_idx_in_nid_list(spec->ext_mic_pin,
1628 spec->imux_pins, imux->num_items);
1629 spec->int_mic_idx = find_idx_in_nid_list(spec->int_mic_pin,
1630 spec->imux_pins, imux->num_items);
1631 spec->dock_mic_idx = find_idx_in_nid_list(spec->dock_mic_pin,
1632 spec->imux_pins, imux->num_items);
1633 if (spec->ext_mic_idx < 0 || spec->int_mic_idx < 0) {
1634 spec->auto_mic = 0;
1635 return false; /* no corresponding imux */
1636 }
1637
1638 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1639 AC_VERB_SET_UNSOLICITED_ENABLE,
1640 AC_USRSP_EN | ALC880_MIC_EVENT);
1641 if (spec->dock_mic_pin)
1642 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1643 AC_VERB_SET_UNSOLICITED_ENABLE,
1644 AC_USRSP_EN | ALC880_MIC_EVENT);
1645
1646 spec->auto_mic_valid_imux = 1;
1647 spec->auto_mic = 1;
1648 return true;
1649}
1650
6c819492
TI
1651static void alc_init_auto_mic(struct hda_codec *codec)
1652{
1653 struct alc_spec *spec = codec->spec;
1654 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1655 hda_nid_t fixed, ext, dock;
6c819492
TI
1656 int i;
1657
21268961
TI
1658 spec->ext_mic_idx = spec->int_mic_idx = spec->dock_mic_idx = -1;
1659
8ed99d97 1660 fixed = ext = dock = 0;
66ceeb6b
TI
1661 for (i = 0; i < cfg->num_inputs; i++) {
1662 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1663 unsigned int defcfg;
6c819492 1664 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1665 switch (snd_hda_get_input_pin_attr(defcfg)) {
1666 case INPUT_PIN_ATTR_INT:
6c819492
TI
1667 if (fixed)
1668 return; /* already occupied */
8ed99d97
TI
1669 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1670 return; /* invalid type */
6c819492
TI
1671 fixed = nid;
1672 break;
99ae28be
TI
1673 case INPUT_PIN_ATTR_UNUSED:
1674 return; /* invalid entry */
8ed99d97
TI
1675 case INPUT_PIN_ATTR_DOCK:
1676 if (dock)
1677 return; /* already occupied */
1678 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1679 return; /* invalid type */
1680 dock = nid;
1681 break;
99ae28be 1682 default:
6c819492
TI
1683 if (ext)
1684 return; /* already occupied */
8ed99d97
TI
1685 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1686 return; /* invalid type */
6c819492
TI
1687 ext = nid;
1688 break;
6c819492
TI
1689 }
1690 }
8ed99d97
TI
1691 if (!ext && dock) {
1692 ext = dock;
1693 dock = 0;
1694 }
eaa9b3a7
TI
1695 if (!ext || !fixed)
1696 return;
e35d9d6a 1697 if (!is_jack_detectable(codec, ext))
6c819492 1698 return; /* no unsol support */
8ed99d97
TI
1699 if (dock && !is_jack_detectable(codec, dock))
1700 return; /* no unsol support */
21268961
TI
1701
1702 /* check imux indices */
1703 spec->ext_mic_pin = ext;
1704 spec->int_mic_pin = fixed;
1705 spec->dock_mic_pin = dock;
1706
1707 spec->auto_mic = 1;
1708 if (!alc_auto_mic_check_imux(codec))
1709 return;
1710
8ed99d97
TI
1711 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1712 ext, fixed, dock);
6c819492
TI
1713 spec->unsol_event = alc_sku_unsol_event;
1714}
1715
90622917
DH
1716/* Could be any non-zero and even value. When used as fixup, tells
1717 * the driver to ignore any present sku defines.
1718 */
1719#define ALC_FIXUP_SKU_IGNORE (2)
1720
da00c244
KY
1721static int alc_auto_parse_customize_define(struct hda_codec *codec)
1722{
1723 unsigned int ass, tmp, i;
7fb56223 1724 unsigned nid = 0;
da00c244
KY
1725 struct alc_spec *spec = codec->spec;
1726
b6cbe517
TI
1727 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1728
90622917
DH
1729 if (spec->cdefine.fixup) {
1730 ass = spec->cdefine.sku_cfg;
1731 if (ass == ALC_FIXUP_SKU_IGNORE)
1732 return -1;
1733 goto do_sku;
1734 }
1735
da00c244 1736 ass = codec->subsystem_id & 0xffff;
b6cbe517 1737 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1738 goto do_sku;
1739
1740 nid = 0x1d;
1741 if (codec->vendor_id == 0x10ec0260)
1742 nid = 0x17;
1743 ass = snd_hda_codec_get_pincfg(codec, nid);
1744
1745 if (!(ass & 1)) {
1746 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1747 codec->chip_name, ass);
1748 return -1;
1749 }
1750
1751 /* check sum */
1752 tmp = 0;
1753 for (i = 1; i < 16; i++) {
1754 if ((ass >> i) & 1)
1755 tmp++;
1756 }
1757 if (((ass >> 16) & 0xf) != tmp)
1758 return -1;
1759
1760 spec->cdefine.port_connectivity = ass >> 30;
1761 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1762 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1763 spec->cdefine.customization = ass >> 8;
1764do_sku:
1765 spec->cdefine.sku_cfg = ass;
1766 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1767 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1768 spec->cdefine.swap = (ass & 0x2) >> 1;
1769 spec->cdefine.override = ass & 0x1;
1770
1771 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1772 nid, spec->cdefine.sku_cfg);
1773 snd_printd("SKU: port_connectivity=0x%x\n",
1774 spec->cdefine.port_connectivity);
1775 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1776 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1777 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1778 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1779 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1780 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1781 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1782
1783 return 0;
1784}
1785
3af9ee6b
TI
1786static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1787{
21268961 1788 return find_idx_in_nid_list(nid, list, nums) >= 0;
3af9ee6b
TI
1789}
1790
4a79ba34
TI
1791/* check subsystem ID and set up device-specific initialization;
1792 * return 1 if initialized, 0 if invalid SSID
1793 */
1794/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1795 * 31 ~ 16 : Manufacture ID
1796 * 15 ~ 8 : SKU ID
1797 * 7 ~ 0 : Assembly ID
1798 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1799 */
1800static int alc_subsystem_id(struct hda_codec *codec,
1801 hda_nid_t porta, hda_nid_t porte,
6227cdce 1802 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1803{
1804 unsigned int ass, tmp, i;
1805 unsigned nid;
1806 struct alc_spec *spec = codec->spec;
1807
90622917
DH
1808 if (spec->cdefine.fixup) {
1809 ass = spec->cdefine.sku_cfg;
1810 if (ass == ALC_FIXUP_SKU_IGNORE)
1811 return 0;
1812 goto do_sku;
1813 }
1814
4a79ba34
TI
1815 ass = codec->subsystem_id & 0xffff;
1816 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1817 goto do_sku;
1818
1819 /* invalid SSID, check the special NID pin defcfg instead */
1820 /*
def319f9 1821 * 31~30 : port connectivity
4a79ba34
TI
1822 * 29~21 : reserve
1823 * 20 : PCBEEP input
1824 * 19~16 : Check sum (15:1)
1825 * 15~1 : Custom
1826 * 0 : override
1827 */
1828 nid = 0x1d;
1829 if (codec->vendor_id == 0x10ec0260)
1830 nid = 0x17;
1831 ass = snd_hda_codec_get_pincfg(codec, nid);
1832 snd_printd("realtek: No valid SSID, "
1833 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1834 ass, nid);
6227cdce 1835 if (!(ass & 1))
4a79ba34
TI
1836 return 0;
1837 if ((ass >> 30) != 1) /* no physical connection */
1838 return 0;
1839
1840 /* check sum */
1841 tmp = 0;
1842 for (i = 1; i < 16; i++) {
1843 if ((ass >> i) & 1)
1844 tmp++;
1845 }
1846 if (((ass >> 16) & 0xf) != tmp)
1847 return 0;
1848do_sku:
1849 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1850 ass & 0xffff, codec->vendor_id);
1851 /*
1852 * 0 : override
1853 * 1 : Swap Jack
1854 * 2 : 0 --> Desktop, 1 --> Laptop
1855 * 3~5 : External Amplifier control
1856 * 7~6 : Reserved
1857 */
1858 tmp = (ass & 0x38) >> 3; /* external Amp control */
1859 switch (tmp) {
1860 case 1:
1861 spec->init_amp = ALC_INIT_GPIO1;
1862 break;
1863 case 3:
1864 spec->init_amp = ALC_INIT_GPIO2;
1865 break;
1866 case 7:
1867 spec->init_amp = ALC_INIT_GPIO3;
1868 break;
1869 case 5:
5a8cfb4e 1870 default:
4a79ba34 1871 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1872 break;
1873 }
ea1fb29a 1874
8c427226 1875 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1876 * when the external headphone out jack is plugged"
1877 */
8c427226 1878 if (!(ass & 0x8000))
4a79ba34 1879 return 1;
c9b58006
KY
1880 /*
1881 * 10~8 : Jack location
1882 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1883 * 14~13: Resvered
1884 * 15 : 1 --> enable the function "Mute internal speaker
1885 * when the external headphone out jack is plugged"
1886 */
c9b58006 1887 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1888 hda_nid_t nid;
c9b58006
KY
1889 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1890 if (tmp == 0)
01d4825d 1891 nid = porta;
c9b58006 1892 else if (tmp == 1)
01d4825d 1893 nid = porte;
c9b58006 1894 else if (tmp == 2)
01d4825d 1895 nid = portd;
6227cdce
KY
1896 else if (tmp == 3)
1897 nid = porti;
c9b58006 1898 else
4a79ba34 1899 return 1;
3af9ee6b
TI
1900 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1901 spec->autocfg.line_outs))
1902 return 1;
01d4825d 1903 spec->autocfg.hp_pins[0] = nid;
c9b58006 1904 }
4a79ba34
TI
1905 return 1;
1906}
ea1fb29a 1907
4a79ba34 1908static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1909 hda_nid_t porta, hda_nid_t porte,
1910 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1911{
6227cdce 1912 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1913 struct alc_spec *spec = codec->spec;
1914 snd_printd("realtek: "
1915 "Enable default setup for auto mode as fallback\n");
1916 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1917 }
21268961 1918}
1a1455de 1919
21268961
TI
1920/* check the availabilities of auto-mute and auto-mic switches */
1921static void alc_auto_check_switches(struct hda_codec *codec)
1922{
1a1455de
TI
1923 alc_init_auto_hp(codec);
1924 alc_init_auto_mic(codec);
bc9f98a9
KY
1925}
1926
f95474ec 1927/*
f8f25ba3 1928 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1929 */
1930
1931struct alc_pincfg {
1932 hda_nid_t nid;
1933 u32 val;
1934};
1935
e1eb5f10
TB
1936struct alc_model_fixup {
1937 const int id;
1938 const char *name;
1939};
1940
f8f25ba3 1941struct alc_fixup {
b5bfbc67 1942 int type;
361fe6e9
TI
1943 bool chained;
1944 int chain_id;
b5bfbc67
TI
1945 union {
1946 unsigned int sku;
1947 const struct alc_pincfg *pins;
1948 const struct hda_verb *verbs;
1949 void (*func)(struct hda_codec *codec,
1950 const struct alc_fixup *fix,
1951 int action);
1952 } v;
f8f25ba3
TI
1953};
1954
b5bfbc67
TI
1955enum {
1956 ALC_FIXUP_INVALID,
1957 ALC_FIXUP_SKU,
1958 ALC_FIXUP_PINS,
1959 ALC_FIXUP_VERBS,
1960 ALC_FIXUP_FUNC,
1961};
1962
1963enum {
1964 ALC_FIXUP_ACT_PRE_PROBE,
1965 ALC_FIXUP_ACT_PROBE,
58701120 1966 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1967};
1968
1969static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1970{
b5bfbc67
TI
1971 struct alc_spec *spec = codec->spec;
1972 int id = spec->fixup_id;
aa1d0c52 1973#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1974 const char *modelname = spec->fixup_name;
aa1d0c52 1975#endif
b5bfbc67 1976 int depth = 0;
f95474ec 1977
b5bfbc67
TI
1978 if (!spec->fixup_list)
1979 return;
1980
1981 while (id >= 0) {
1982 const struct alc_fixup *fix = spec->fixup_list + id;
1983 const struct alc_pincfg *cfg;
1984
1985 switch (fix->type) {
1986 case ALC_FIXUP_SKU:
1987 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1988 break;;
1989 snd_printdd(KERN_INFO "hda_codec: %s: "
1990 "Apply sku override for %s\n",
1991 codec->chip_name, modelname);
1992 spec->cdefine.sku_cfg = fix->v.sku;
1993 spec->cdefine.fixup = 1;
1994 break;
1995 case ALC_FIXUP_PINS:
1996 cfg = fix->v.pins;
1997 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1998 break;
1999 snd_printdd(KERN_INFO "hda_codec: %s: "
2000 "Apply pincfg for %s\n",
2001 codec->chip_name, modelname);
2002 for (; cfg->nid; cfg++)
2003 snd_hda_codec_set_pincfg(codec, cfg->nid,
2004 cfg->val);
2005 break;
2006 case ALC_FIXUP_VERBS:
2007 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
2008 break;
2009 snd_printdd(KERN_INFO "hda_codec: %s: "
2010 "Apply fix-verbs for %s\n",
2011 codec->chip_name, modelname);
2012 add_verb(codec->spec, fix->v.verbs);
2013 break;
2014 case ALC_FIXUP_FUNC:
2015 if (!fix->v.func)
2016 break;
2017 snd_printdd(KERN_INFO "hda_codec: %s: "
2018 "Apply fix-func for %s\n",
2019 codec->chip_name, modelname);
2020 fix->v.func(codec, fix, action);
2021 break;
2022 default:
2023 snd_printk(KERN_ERR "hda_codec: %s: "
2024 "Invalid fixup type %d\n",
2025 codec->chip_name, fix->type);
2026 break;
2027 }
24af2b1c 2028 if (!fix->chained)
b5bfbc67
TI
2029 break;
2030 if (++depth > 10)
2031 break;
24af2b1c 2032 id = fix->chain_id;
9d57883f 2033 }
f95474ec
TI
2034}
2035
e1eb5f10 2036static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
2037 const struct alc_model_fixup *models,
2038 const struct snd_pci_quirk *quirk,
2039 const struct alc_fixup *fixlist)
e1eb5f10 2040{
b5bfbc67
TI
2041 struct alc_spec *spec = codec->spec;
2042 int id = -1;
2043 const char *name = NULL;
e1eb5f10 2044
e1eb5f10
TB
2045 if (codec->modelname && models) {
2046 while (models->name) {
2047 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2048 id = models->id;
2049 name = models->name;
e1eb5f10
TB
2050 break;
2051 }
2052 models++;
2053 }
b5bfbc67
TI
2054 }
2055 if (id < 0) {
2056 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2057 if (quirk) {
2058 id = quirk->value;
2059#ifdef CONFIG_SND_DEBUG_VERBOSE
2060 name = quirk->name;
2061#endif
2062 }
2063 }
2064
2065 spec->fixup_id = id;
2066 if (id >= 0) {
2067 spec->fixup_list = fixlist;
2068 spec->fixup_name = name;
e1eb5f10 2069 }
f95474ec
TI
2070}
2071
274693f3
KY
2072static int alc_read_coef_idx(struct hda_codec *codec,
2073 unsigned int coef_idx)
2074{
2075 unsigned int val;
2076 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2077 coef_idx);
2078 val = snd_hda_codec_read(codec, 0x20, 0,
2079 AC_VERB_GET_PROC_COEF, 0);
2080 return val;
2081}
2082
977ddd6b
KY
2083static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2084 unsigned int coef_val)
2085{
2086 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2087 coef_idx);
2088 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2089 coef_val);
2090}
2091
757899ac
TI
2092/* set right pin controls for digital I/O */
2093static void alc_auto_init_digital(struct hda_codec *codec)
2094{
2095 struct alc_spec *spec = codec->spec;
2096 int i;
1f0f4b80 2097 hda_nid_t pin, dac;
757899ac
TI
2098
2099 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2100 pin = spec->autocfg.dig_out_pins[i];
1f0f4b80
TI
2101 if (!pin)
2102 continue;
2103 snd_hda_codec_write(codec, pin, 0,
2104 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2105 if (!i)
2106 dac = spec->multiout.dig_out_nid;
2107 else
2108 dac = spec->slave_dig_outs[i - 1];
2109 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2110 continue;
2111 snd_hda_codec_write(codec, dac, 0,
2112 AC_VERB_SET_AMP_GAIN_MUTE,
2113 AMP_OUT_UNMUTE);
757899ac
TI
2114 }
2115 pin = spec->autocfg.dig_in_pin;
2116 if (pin)
2117 snd_hda_codec_write(codec, pin, 0,
2118 AC_VERB_SET_PIN_WIDGET_CONTROL,
2119 PIN_IN);
2120}
2121
2122/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2123static void alc_auto_parse_digital(struct hda_codec *codec)
2124{
2125 struct alc_spec *spec = codec->spec;
2126 int i, err;
2127 hda_nid_t dig_nid;
2128
2129 /* support multiple SPDIFs; the secondary is set up as a slave */
2130 for (i = 0; i < spec->autocfg.dig_outs; i++) {
a926757f 2131 hda_nid_t conn[4];
757899ac
TI
2132 err = snd_hda_get_connections(codec,
2133 spec->autocfg.dig_out_pins[i],
a926757f 2134 conn, ARRAY_SIZE(conn));
757899ac
TI
2135 if (err < 0)
2136 continue;
a926757f 2137 dig_nid = conn[0]; /* assume the first element is audio-out */
757899ac
TI
2138 if (!i) {
2139 spec->multiout.dig_out_nid = dig_nid;
2140 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2141 } else {
2142 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2143 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2144 break;
2145 spec->slave_dig_outs[i - 1] = dig_nid;
2146 }
2147 }
2148
2149 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2150 dig_nid = codec->start_nid;
2151 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2152 unsigned int wcaps = get_wcaps(codec, dig_nid);
2153 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2154 continue;
2155 if (!(wcaps & AC_WCAP_DIGITAL))
2156 continue;
2157 if (!(wcaps & AC_WCAP_CONN_LIST))
2158 continue;
2159 err = get_connection_index(codec, dig_nid,
2160 spec->autocfg.dig_in_pin);
2161 if (err >= 0) {
2162 spec->dig_in_nid = dig_nid;
2163 break;
2164 }
2165 }
757899ac
TI
2166 }
2167}
2168
ef8ef5fb
VP
2169/*
2170 * ALC888
2171 */
2172
2173/*
2174 * 2ch mode
2175 */
a9111321 2176static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2177/* Mic-in jack as mic in */
2178 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2179 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2180/* Line-in jack as Line in */
2181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2182 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2183/* Line-Out as Front */
2184 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2185 { } /* end */
2186};
2187
2188/*
2189 * 4ch mode
2190 */
a9111321 2191static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2192/* Mic-in jack as mic in */
2193 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2194 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2195/* Line-in jack as Surround */
2196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2198/* Line-Out as Front */
2199 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2200 { } /* end */
2201};
2202
2203/*
2204 * 6ch mode
2205 */
a9111321 2206static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2207/* Mic-in jack as CLFE */
2208 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2209 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2210/* Line-in jack as Surround */
2211 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2212 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2213/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2214 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2215 { } /* end */
2216};
2217
2218/*
2219 * 8ch mode
2220 */
a9111321 2221static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2222/* Mic-in jack as CLFE */
2223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2225/* Line-in jack as Surround */
2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2228/* Line-Out as Side */
2229 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2230 { } /* end */
2231};
2232
a9111321 2233static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2234 { 2, alc888_4ST_ch2_intel_init },
2235 { 4, alc888_4ST_ch4_intel_init },
2236 { 6, alc888_4ST_ch6_intel_init },
2237 { 8, alc888_4ST_ch8_intel_init },
2238};
2239
2240/*
2241 * ALC888 Fujitsu Siemens Amillo xa3530
2242 */
2243
a9111321 2244static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2245/* Front Mic: set to PIN_IN (empty by default) */
2246 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247/* Connect Internal HP to Front */
2248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2251/* Connect Bass HP to Front */
2252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2255/* Connect Line-Out side jack (SPDIF) to Side */
2256 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2259/* Connect Mic jack to CLFE */
2260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2263/* Connect Line-in jack to Surround */
2264 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2267/* Connect HP out jack to Front */
2268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2269 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2270 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2271/* Enable unsolicited event for HP jack and Line-out jack */
2272 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2273 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2274 {}
2275};
2276
4f5d1706 2277static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2278{
2279 struct alc_spec *spec = codec->spec;
2280
2281 spec->autocfg.hp_pins[0] = 0x15;
2282 spec->autocfg.speaker_pins[0] = 0x14;
2283 spec->autocfg.speaker_pins[1] = 0x16;
2284 spec->autocfg.speaker_pins[2] = 0x17;
2285 spec->autocfg.speaker_pins[3] = 0x19;
2286 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2287 spec->automute = 1;
2288 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2289}
2290
2291static void alc889_intel_init_hook(struct hda_codec *codec)
2292{
2293 alc889_coef_init(codec);
d922b51d 2294 alc_hp_automute(codec);
6732bd0d
WF
2295}
2296
4f5d1706 2297static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2298{
2299 struct alc_spec *spec = codec->spec;
2300
2301 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2302 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2303 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2304 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2305 spec->automute = 1;
2306 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2307}
ef8ef5fb 2308
5b2d1eca
VP
2309/*
2310 * ALC888 Acer Aspire 4930G model
2311 */
2312
a9111321 2313static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2314/* Front Mic: set to PIN_IN (empty by default) */
2315 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2316/* Unselect Front Mic by default in input mixer 3 */
2317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2318/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2320/* Connect Internal HP to front */
2321 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2324/* Connect HP out to front */
2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2328 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2329 { }
2330};
2331
d2fd4b09
TV
2332/*
2333 * ALC888 Acer Aspire 6530G model
2334 */
2335
a9111321 2336static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2337/* Route to built-in subwoofer as well as speakers */
2338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2342/* Bias voltage on for external mic port */
2343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2344/* Front Mic: set to PIN_IN (empty by default) */
2345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2346/* Unselect Front Mic by default in input mixer 3 */
2347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2348/* Enable unsolicited event for HP jack */
2349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2350/* Enable speaker output */
2351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2353 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2354/* Enable headphone output */
2355 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2356 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2358 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2359 { }
2360};
2361
d9477207
DK
2362/*
2363 *ALC888 Acer Aspire 7730G model
2364 */
2365
a9111321 2366static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2367/* Bias voltage on for external mic port */
2368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2369/* Front Mic: set to PIN_IN (empty by default) */
2370 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2371/* Unselect Front Mic by default in input mixer 3 */
2372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2373/* Enable unsolicited event for HP jack */
2374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2375/* Enable speaker output */
2376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2379/* Enable headphone output */
2380 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2383 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2384/*Enable internal subwoofer */
2385 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2387 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2388 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2389 { }
2390};
2391
3b315d70 2392/*
018df418 2393 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2394 */
2395
a9111321 2396static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2397/* Front Mic: set to PIN_IN (empty by default) */
2398 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2399/* Unselect Front Mic by default in input mixer 3 */
2400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2401/* Enable unsolicited event for HP jack */
2402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2403/* Connect Internal Front to Front */
2404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2405 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2406 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2407/* Connect Internal Rear to Rear */
2408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2411/* Connect Internal CLFE to CLFE */
2412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2413 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2414 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2415/* Connect HP out to Front */
018df418 2416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2417 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2419/* Enable all DACs */
2420/* DAC DISABLE/MUTE 1? */
2421/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2422 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2423 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2424/* DAC DISABLE/MUTE 2? */
2425/* some bit here disables the other DACs. Init=0x4900 */
2426 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2427 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2428/* DMIC fix
2429 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2430 * which makes the stereo useless. However, either the mic or the ALC889
2431 * makes the signal become a difference/sum signal instead of standard
2432 * stereo, which is annoying. So instead we flip this bit which makes the
2433 * codec replicate the sum signal to both channels, turning it into a
2434 * normal mono mic.
2435 */
2436/* DMIC_CONTROL? Init value = 0x0001 */
2437 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2438 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2439 { }
2440};
2441
a9111321 2442static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2443 /* Front mic only available on one ADC */
2444 {
2445 .num_items = 4,
2446 .items = {
2447 { "Mic", 0x0 },
2448 { "Line", 0x2 },
2449 { "CD", 0x4 },
2450 { "Front Mic", 0xb },
2451 },
2452 },
2453 {
2454 .num_items = 3,
2455 .items = {
2456 { "Mic", 0x0 },
2457 { "Line", 0x2 },
2458 { "CD", 0x4 },
2459 },
2460 }
2461};
2462
a9111321 2463static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2464 /* Interal mic only available on one ADC */
2465 {
684a8842 2466 .num_items = 5,
d2fd4b09 2467 .items = {
8607f7c4 2468 { "Mic", 0x0 },
684a8842 2469 { "Line In", 0x2 },
d2fd4b09 2470 { "CD", 0x4 },
684a8842 2471 { "Input Mix", 0xa },
28c4edb7 2472 { "Internal Mic", 0xb },
d2fd4b09
TV
2473 },
2474 },
2475 {
684a8842 2476 .num_items = 4,
d2fd4b09 2477 .items = {
8607f7c4 2478 { "Mic", 0x0 },
684a8842 2479 { "Line In", 0x2 },
d2fd4b09 2480 { "CD", 0x4 },
684a8842 2481 { "Input Mix", 0xa },
d2fd4b09
TV
2482 },
2483 }
2484};
2485
a9111321 2486static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2487 /* Digital mic only available on first "ADC" */
2488 {
2489 .num_items = 5,
2490 .items = {
2491 { "Mic", 0x0 },
2492 { "Line", 0x2 },
2493 { "CD", 0x4 },
2494 { "Front Mic", 0xb },
2495 { "Input Mix", 0xa },
2496 },
2497 },
2498 {
2499 .num_items = 4,
2500 .items = {
2501 { "Mic", 0x0 },
2502 { "Line", 0x2 },
2503 { "CD", 0x4 },
2504 { "Input Mix", 0xa },
2505 },
2506 },
2507 {
2508 .num_items = 4,
2509 .items = {
2510 { "Mic", 0x0 },
2511 { "Line", 0x2 },
2512 { "CD", 0x4 },
2513 { "Input Mix", 0xa },
2514 },
2515 }
2516};
2517
a9111321 2518static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2521 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2522 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2523 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2524 HDA_OUTPUT),
2525 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2526 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2527 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2528 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2535 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2537 { } /* end */
2538};
2539
a9111321 2540static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2543 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2544 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2546 HDA_OUTPUT),
786c51f9
ŁW
2547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2548 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2551 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2552 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2553 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2555 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2557 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2559 { } /* end */
2560};
2561
a9111321 2562static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2563 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2565 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2566 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2567 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2568 HDA_OUTPUT),
2569 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2571 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 { } /* end */
2578};
2579
2580
4f5d1706 2581static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2582{
a9fd4f3f 2583 struct alc_spec *spec = codec->spec;
5b2d1eca 2584
a9fd4f3f
TI
2585 spec->autocfg.hp_pins[0] = 0x15;
2586 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2587 spec->autocfg.speaker_pins[1] = 0x16;
2588 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2589 spec->automute = 1;
2590 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2591}
2592
4f5d1706 2593static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2594{
2595 struct alc_spec *spec = codec->spec;
2596
2597 spec->autocfg.hp_pins[0] = 0x15;
2598 spec->autocfg.speaker_pins[0] = 0x14;
2599 spec->autocfg.speaker_pins[1] = 0x16;
2600 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2601 spec->automute = 1;
2602 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2603}
2604
d9477207
DK
2605static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2606{
2607 struct alc_spec *spec = codec->spec;
2608
2609 spec->autocfg.hp_pins[0] = 0x15;
2610 spec->autocfg.speaker_pins[0] = 0x14;
2611 spec->autocfg.speaker_pins[1] = 0x16;
2612 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2613 spec->automute = 1;
2614 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2615}
2616
4f5d1706 2617static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2618{
2619 struct alc_spec *spec = codec->spec;
2620
2621 spec->autocfg.hp_pins[0] = 0x15;
2622 spec->autocfg.speaker_pins[0] = 0x14;
2623 spec->autocfg.speaker_pins[1] = 0x16;
2624 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2625 spec->automute = 1;
2626 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2627}
2628
1da177e4 2629/*
e9edcee0
TI
2630 * ALC880 3-stack model
2631 *
2632 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2633 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2634 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2635 */
2636
4c6d72d1 2637static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2638 /* front, rear, clfe, rear_surr */
2639 0x02, 0x05, 0x04, 0x03
2640};
2641
4c6d72d1 2642static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2643 /* ADC0-2 */
2644 0x07, 0x08, 0x09,
2645};
2646
2647/* The datasheet says the node 0x07 is connected from inputs,
2648 * but it shows zero connection in the real implementation on some devices.
df694daa 2649 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2650 */
4c6d72d1 2651static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2652 /* ADC1-2 */
2653 0x08, 0x09,
2654};
2655
2656#define ALC880_DIGOUT_NID 0x06
2657#define ALC880_DIGIN_NID 0x0a
2658
a9111321 2659static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2660 .num_items = 4,
2661 .items = {
2662 { "Mic", 0x0 },
2663 { "Front Mic", 0x3 },
2664 { "Line", 0x2 },
2665 { "CD", 0x4 },
2666 },
2667};
2668
2669/* channel source setting (2/6 channel selection for 3-stack) */
2670/* 2ch mode */
a9111321 2671static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2672 /* set line-in to input, mute it */
2673 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2674 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2675 /* set mic-in to input vref 80%, mute it */
2676 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2677 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2678 { } /* end */
2679};
2680
2681/* 6ch mode */
a9111321 2682static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2683 /* set line-in to output, unmute it */
2684 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2685 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2686 /* set mic-in to output, unmute it */
2687 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2688 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2689 { } /* end */
2690};
2691
a9111321 2692static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2693 { 2, alc880_threestack_ch2_init },
2694 { 6, alc880_threestack_ch6_init },
2695};
2696
a9111321 2697static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2700 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2701 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2702 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2703 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2704 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2705 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2712 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2713 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2715 {
2716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2717 .name = "Channel Mode",
df694daa
KY
2718 .info = alc_ch_mode_info,
2719 .get = alc_ch_mode_get,
2720 .put = alc_ch_mode_put,
e9edcee0
TI
2721 },
2722 { } /* end */
2723};
2724
2725/* capture mixer elements */
f9e336f6
TI
2726static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_info *uinfo)
2728{
2729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2730 struct alc_spec *spec = codec->spec;
d6cc9fab 2731 unsigned long val;
f9e336f6 2732 int err;
1da177e4 2733
5a9e02e9 2734 mutex_lock(&codec->control_mutex);
d6cc9fab
TI
2735 if (spec->vol_in_capsrc)
2736 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2737 else
2738 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2739 kcontrol->private_value = val;
f9e336f6 2740 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2741 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2742 return err;
2743}
2744
2745static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2746 unsigned int size, unsigned int __user *tlv)
2747{
2748 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2749 struct alc_spec *spec = codec->spec;
d6cc9fab 2750 unsigned long val;
f9e336f6 2751 int err;
1da177e4 2752
5a9e02e9 2753 mutex_lock(&codec->control_mutex);
d6cc9fab
TI
2754 if (spec->vol_in_capsrc)
2755 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2756 else
2757 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2758 kcontrol->private_value = val;
f9e336f6 2759 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2760 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2761 return err;
2762}
2763
2764typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2765 struct snd_ctl_elem_value *ucontrol);
2766
2767static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2768 struct snd_ctl_elem_value *ucontrol,
9c7a083d 2769 getput_call_t func, bool check_adc_switch)
f9e336f6
TI
2770{
2771 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2772 struct alc_spec *spec = codec->spec;
21268961 2773 int i, err = 0;
f9e336f6 2774
5a9e02e9 2775 mutex_lock(&codec->control_mutex);
21268961 2776 if (check_adc_switch && spec->dyn_adc_switch) {
9c7a083d
TI
2777 for (i = 0; i < spec->num_adc_nids; i++) {
2778 kcontrol->private_value =
2779 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2780 3, 0, HDA_INPUT);
2781 err = func(kcontrol, ucontrol);
2782 if (err < 0)
2783 goto error;
2784 }
2785 } else {
2786 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
d6cc9fab
TI
2787 if (spec->vol_in_capsrc)
2788 kcontrol->private_value =
2789 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
2790 3, 0, HDA_OUTPUT);
2791 else
2792 kcontrol->private_value =
21268961
TI
2793 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2794 3, 0, HDA_INPUT);
9c7a083d
TI
2795 err = func(kcontrol, ucontrol);
2796 }
2797 error:
5a9e02e9 2798 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2799 return err;
2800}
2801
2802static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2803 struct snd_ctl_elem_value *ucontrol)
2804{
2805 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2806 snd_hda_mixer_amp_volume_get, false);
f9e336f6
TI
2807}
2808
2809static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2810 struct snd_ctl_elem_value *ucontrol)
2811{
2812 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2813 snd_hda_mixer_amp_volume_put, true);
f9e336f6
TI
2814}
2815
2816/* capture mixer elements */
2817#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2818
2819static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2820 struct snd_ctl_elem_value *ucontrol)
2821{
2822 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2823 snd_hda_mixer_amp_switch_get, false);
f9e336f6
TI
2824}
2825
2826static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2827 struct snd_ctl_elem_value *ucontrol)
2828{
2829 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2830 snd_hda_mixer_amp_switch_put, true);
f9e336f6
TI
2831}
2832
a23b688f 2833#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2834 { \
2835 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2836 .name = "Capture Switch", \
2837 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2838 .count = num, \
2839 .info = alc_cap_sw_info, \
2840 .get = alc_cap_sw_get, \
2841 .put = alc_cap_sw_put, \
2842 }, \
2843 { \
2844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2845 .name = "Capture Volume", \
2846 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2847 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2848 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2849 .count = num, \
2850 .info = alc_cap_vol_info, \
2851 .get = alc_cap_vol_get, \
2852 .put = alc_cap_vol_put, \
2853 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2854 }
2855
2856#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2857 { \
2858 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2859 /* .name = "Capture Source", */ \
2860 .name = "Input Source", \
2861 .count = num, \
2862 .info = alc_mux_enum_info, \
2863 .get = alc_mux_enum_get, \
2864 .put = alc_mux_enum_put, \
a23b688f
TI
2865 }
2866
2867#define DEFINE_CAPMIX(num) \
a9111321 2868static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2869 _DEFINE_CAPMIX(num), \
2870 _DEFINE_CAPSRC(num), \
2871 { } /* end */ \
2872}
2873
2874#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2875static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2876 _DEFINE_CAPMIX(num), \
2877 { } /* end */ \
f9e336f6
TI
2878}
2879
2880/* up to three ADCs */
2881DEFINE_CAPMIX(1);
2882DEFINE_CAPMIX(2);
2883DEFINE_CAPMIX(3);
a23b688f
TI
2884DEFINE_CAPMIX_NOSRC(1);
2885DEFINE_CAPMIX_NOSRC(2);
2886DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2887
2888/*
2889 * ALC880 5-stack model
2890 *
9c7f852e
TI
2891 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2892 * Side = 0x02 (0xd)
e9edcee0
TI
2893 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2894 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2895 */
2896
2897/* additional mixers to alc880_three_stack_mixer */
a9111321 2898static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2899 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2900 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2901 { } /* end */
2902};
2903
e9edcee0
TI
2904/* channel source setting (6/8 channel selection for 5-stack) */
2905/* 6ch mode */
a9111321 2906static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2907 /* set line-in to input, mute it */
2908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2910 { } /* end */
2911};
2912
e9edcee0 2913/* 8ch mode */
a9111321 2914static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2915 /* set line-in to output, unmute it */
2916 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2917 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2918 { } /* end */
2919};
2920
a9111321 2921static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2922 { 6, alc880_fivestack_ch6_init },
2923 { 8, alc880_fivestack_ch8_init },
2924};
2925
2926
2927/*
2928 * ALC880 6-stack model
2929 *
9c7f852e
TI
2930 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2931 * Side = 0x05 (0x0f)
e9edcee0
TI
2932 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2933 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2934 */
2935
4c6d72d1 2936static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2937 /* front, rear, clfe, rear_surr */
2938 0x02, 0x03, 0x04, 0x05
f12ab1e0 2939};
e9edcee0 2940
a9111321 2941static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2942 .num_items = 4,
2943 .items = {
2944 { "Mic", 0x0 },
2945 { "Front Mic", 0x1 },
2946 { "Line", 0x2 },
2947 { "CD", 0x4 },
2948 },
2949};
2950
2951/* fixed 8-channels */
a9111321 2952static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2953 { 8, NULL },
2954};
2955
a9111321 2956static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2965 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2975 {
2976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2977 .name = "Channel Mode",
df694daa
KY
2978 .info = alc_ch_mode_info,
2979 .get = alc_ch_mode_get,
2980 .put = alc_ch_mode_put,
16ded525
TI
2981 },
2982 { } /* end */
2983};
2984
e9edcee0
TI
2985
2986/*
2987 * ALC880 W810 model
2988 *
2989 * W810 has rear IO for:
2990 * Front (DAC 02)
2991 * Surround (DAC 03)
2992 * Center/LFE (DAC 04)
2993 * Digital out (06)
2994 *
2995 * The system also has a pair of internal speakers, and a headphone jack.
2996 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2997 *
e9edcee0
TI
2998 * There is a variable resistor to control the speaker or headphone
2999 * volume. This is a hardware-only device without a software API.
3000 *
3001 * Plugging headphones in will disable the internal speakers. This is
3002 * implemented in hardware, not via the driver using jack sense. In
3003 * a similar fashion, plugging into the rear socket marked "front" will
3004 * disable both the speakers and headphones.
3005 *
3006 * For input, there's a microphone jack, and an "audio in" jack.
3007 * These may not do anything useful with this driver yet, because I
3008 * haven't setup any initialization verbs for these yet...
3009 */
3010
4c6d72d1 3011static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
3012 /* front, rear/surround, clfe */
3013 0x02, 0x03, 0x04
16ded525
TI
3014};
3015
e9edcee0 3016/* fixed 6 channels */
a9111321 3017static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
3018 { 6, NULL }
3019};
3020
3021/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 3022static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 3023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3024 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3026 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
3031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3032 { } /* end */
3033};
3034
3035
3036/*
3037 * Z710V model
3038 *
3039 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
3040 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
3041 * Line = 0x1a
e9edcee0
TI
3042 */
3043
4c6d72d1 3044static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
3045 0x02
3046};
3047#define ALC880_Z71V_HP_DAC 0x03
3048
3049/* fixed 2 channels */
a9111321 3050static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
3051 { 2, NULL }
3052};
3053
a9111321 3054static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 3055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 3057 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3058 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
3061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3063 { } /* end */
3064};
3065
e9edcee0 3066
e9edcee0
TI
3067/*
3068 * ALC880 F1734 model
3069 *
3070 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3071 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3072 */
3073
4c6d72d1 3074static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
3075 0x03
3076};
3077#define ALC880_F1734_HP_DAC 0x02
3078
a9111321 3079static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3081 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3082 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3083 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3084 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3085 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3088 { } /* end */
3089};
3090
a9111321 3091static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3092 .num_items = 2,
3093 .items = {
3094 { "Mic", 0x1 },
3095 { "CD", 0x4 },
3096 },
3097};
3098
e9edcee0 3099
e9edcee0
TI
3100/*
3101 * ALC880 ASUS model
3102 *
3103 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3104 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3105 * Mic = 0x18, Line = 0x1a
3106 */
3107
3108#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3109#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3110
a9111321 3111static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3117 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3118 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3119 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3120 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3121 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3126 {
3127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3128 .name = "Channel Mode",
df694daa
KY
3129 .info = alc_ch_mode_info,
3130 .get = alc_ch_mode_get,
3131 .put = alc_ch_mode_put,
16ded525
TI
3132 },
3133 { } /* end */
3134};
e9edcee0 3135
e9edcee0
TI
3136/*
3137 * ALC880 ASUS W1V model
3138 *
3139 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3140 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3141 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3142 */
3143
3144/* additional mixers to alc880_asus_mixer */
a9111321 3145static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3146 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3147 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3148 { } /* end */
3149};
3150
df694daa 3151/* TCL S700 */
a9111321 3152static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3153 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3154 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3156 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3157 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3160 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3161 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3162 { } /* end */
3163};
3164
ccc656ce 3165/* Uniwill */
a9111321 3166static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3167 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3168 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3169 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3170 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3172 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3174 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3183 {
3184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3185 .name = "Channel Mode",
3186 .info = alc_ch_mode_info,
3187 .get = alc_ch_mode_get,
3188 .put = alc_ch_mode_put,
3189 },
3190 { } /* end */
3191};
3192
a9111321 3193static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3195 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3197 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3202 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3203 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3204 { } /* end */
3205};
3206
a9111321 3207static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3209 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3211 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3214 { } /* end */
3215};
3216
2134ea4f
TI
3217/*
3218 * virtual master controls
3219 */
3220
3221/*
3222 * slave controls for virtual master
3223 */
ea734963 3224static const char * const alc_slave_vols[] = {
2134ea4f
TI
3225 "Front Playback Volume",
3226 "Surround Playback Volume",
3227 "Center Playback Volume",
3228 "LFE Playback Volume",
3229 "Side Playback Volume",
3230 "Headphone Playback Volume",
3231 "Speaker Playback Volume",
3232 "Mono Playback Volume",
2134ea4f
TI
3233 "Line-Out Playback Volume",
3234 NULL,
3235};
3236
ea734963 3237static const char * const alc_slave_sws[] = {
2134ea4f
TI
3238 "Front Playback Switch",
3239 "Surround Playback Switch",
3240 "Center Playback Switch",
3241 "LFE Playback Switch",
3242 "Side Playback Switch",
3243 "Headphone Playback Switch",
3244 "Speaker Playback Switch",
3245 "Mono Playback Switch",
edb54a55 3246 "IEC958 Playback Switch",
23033b2b 3247 "Line-Out Playback Switch",
2134ea4f
TI
3248 NULL,
3249};
3250
1da177e4 3251/*
e9edcee0 3252 * build control elements
1da177e4 3253 */
603c4019 3254
5b0cb1d8
JK
3255#define NID_MAPPING (-1)
3256
3257#define SUBDEV_SPEAKER_ (0 << 6)
3258#define SUBDEV_HP_ (1 << 6)
3259#define SUBDEV_LINE_ (2 << 6)
3260#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3261#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3262#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3263
603c4019
TI
3264static void alc_free_kctls(struct hda_codec *codec);
3265
67d634c0 3266#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3267/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3268static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3269 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3270 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3271 { } /* end */
3272};
67d634c0 3273#endif
45bdd1c1 3274
1da177e4
LT
3275static int alc_build_controls(struct hda_codec *codec)
3276{
3277 struct alc_spec *spec = codec->spec;
2f44f847 3278 struct snd_kcontrol *kctl = NULL;
a9111321 3279 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3280 int i, j, err;
3281 unsigned int u;
3282 hda_nid_t nid;
1da177e4
LT
3283
3284 for (i = 0; i < spec->num_mixers; i++) {
3285 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3286 if (err < 0)
3287 return err;
3288 }
f9e336f6
TI
3289 if (spec->cap_mixer) {
3290 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3291 if (err < 0)
3292 return err;
3293 }
1da177e4 3294 if (spec->multiout.dig_out_nid) {
9c7f852e 3295 err = snd_hda_create_spdif_out_ctls(codec,
74b654c9 3296 spec->multiout.dig_out_nid,
9c7f852e 3297 spec->multiout.dig_out_nid);
1da177e4
LT
3298 if (err < 0)
3299 return err;
e64f14f4
TI
3300 if (!spec->no_analog) {
3301 err = snd_hda_create_spdif_share_sw(codec,
3302 &spec->multiout);
3303 if (err < 0)
3304 return err;
3305 spec->multiout.share_spdif = 1;
3306 }
1da177e4
LT
3307 }
3308 if (spec->dig_in_nid) {
3309 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3310 if (err < 0)
3311 return err;
3312 }
2134ea4f 3313
67d634c0 3314#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3315 /* create beep controls if needed */
3316 if (spec->beep_amp) {
a9111321 3317 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3318 for (knew = alc_beep_mixer; knew->name; knew++) {
3319 struct snd_kcontrol *kctl;
3320 kctl = snd_ctl_new1(knew, codec);
3321 if (!kctl)
3322 return -ENOMEM;
3323 kctl->private_value = spec->beep_amp;
5e26dfd0 3324 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3325 if (err < 0)
3326 return err;
3327 }
3328 }
67d634c0 3329#endif
45bdd1c1 3330
2134ea4f 3331 /* if we have no master control, let's create it */
e64f14f4
TI
3332 if (!spec->no_analog &&
3333 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3334 unsigned int vmaster_tlv[4];
2134ea4f 3335 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3336 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3337 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3338 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3339 if (err < 0)
3340 return err;
3341 }
e64f14f4
TI
3342 if (!spec->no_analog &&
3343 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3344 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3345 NULL, alc_slave_sws);
3346 if (err < 0)
3347 return err;
3348 }
3349
5b0cb1d8 3350 /* assign Capture Source enums to NID */
fbe618f2
TI
3351 if (spec->capsrc_nids || spec->adc_nids) {
3352 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3353 if (!kctl)
3354 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3355 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3356 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3357 if (!nids)
3358 nids = spec->adc_nids;
3359 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3360 if (err < 0)
3361 return err;
3362 }
5b0cb1d8
JK
3363 }
3364 if (spec->cap_mixer) {
3365 const char *kname = kctl ? kctl->id.name : NULL;
3366 for (knew = spec->cap_mixer; knew->name; knew++) {
3367 if (kname && strcmp(knew->name, kname) == 0)
3368 continue;
3369 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3370 for (i = 0; kctl && i < kctl->count; i++) {
3371 err = snd_hda_add_nid(codec, kctl, i,
3372 spec->adc_nids[i]);
3373 if (err < 0)
3374 return err;
3375 }
3376 }
3377 }
3378
3379 /* other nid->control mapping */
3380 for (i = 0; i < spec->num_mixers; i++) {
3381 for (knew = spec->mixers[i]; knew->name; knew++) {
3382 if (knew->iface != NID_MAPPING)
3383 continue;
3384 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3385 if (kctl == NULL)
3386 continue;
3387 u = knew->subdevice;
3388 for (j = 0; j < 4; j++, u >>= 8) {
3389 nid = u & 0x3f;
3390 if (nid == 0)
3391 continue;
3392 switch (u & 0xc0) {
3393 case SUBDEV_SPEAKER_:
3394 nid = spec->autocfg.speaker_pins[nid];
3395 break;
3396 case SUBDEV_LINE_:
3397 nid = spec->autocfg.line_out_pins[nid];
3398 break;
3399 case SUBDEV_HP_:
3400 nid = spec->autocfg.hp_pins[nid];
3401 break;
3402 default:
3403 continue;
3404 }
3405 err = snd_hda_add_nid(codec, kctl, 0, nid);
3406 if (err < 0)
3407 return err;
3408 }
3409 u = knew->private_value;
3410 for (j = 0; j < 4; j++, u >>= 8) {
3411 nid = u & 0xff;
3412 if (nid == 0)
3413 continue;
3414 err = snd_hda_add_nid(codec, kctl, 0, nid);
3415 if (err < 0)
3416 return err;
3417 }
3418 }
3419 }
bae84e70
TI
3420
3421 alc_free_kctls(codec); /* no longer needed */
3422
1da177e4
LT
3423 return 0;
3424}
3425
e9edcee0 3426
1da177e4
LT
3427/*
3428 * initialize the codec volumes, etc
3429 */
3430
e9edcee0
TI
3431/*
3432 * generic initialization of ADC, input mixers and output mixers
3433 */
a9111321 3434static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3435 /*
3436 * Unmute ADC0-2 and set the default input to mic-in
3437 */
71fe7b82 3438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3444
e9edcee0
TI
3445 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3446 * mixer widget
9c7f852e
TI
3447 * Note: PASD motherboards uses the Line In 2 as the input for front
3448 * panel mic (mic 2)
1da177e4 3449 */
e9edcee0 3450 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3458
e9edcee0
TI
3459 /*
3460 * Set up output mixers (0x0c - 0x0f)
1da177e4 3461 */
e9edcee0
TI
3462 /* set vol=0 to output mixers */
3463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3466 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3467 /* set up input amps for analog loopback */
3468 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3477
3478 { }
3479};
3480
e9edcee0
TI
3481/*
3482 * 3-stack pin configuration:
3483 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3484 */
a9111321 3485static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3486 /*
3487 * preset connection lists of input pins
3488 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3489 */
3490 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3491 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3492 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3493
3494 /*
3495 * Set pin mode and muting
3496 */
3497 /* set front pin widgets 0x14 for output */
05acb863 3498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3503 /* Mic2 (as headphone out) for HP output */
3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3506 /* Line In pin widget for input */
05acb863 3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3509 /* Line2 (as front mic) pin widget for input and vref at 80% */
3510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3511 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3512 /* CD pin widget for input */
05acb863 3513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3514
e9edcee0
TI
3515 { }
3516};
1da177e4 3517
e9edcee0
TI
3518/*
3519 * 5-stack pin configuration:
3520 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3521 * line-in/side = 0x1a, f-mic = 0x1b
3522 */
a9111321 3523static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3524 /*
3525 * preset connection lists of input pins
3526 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3527 */
e9edcee0
TI
3528 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3529 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3530
e9edcee0
TI
3531 /*
3532 * Set pin mode and muting
1da177e4 3533 */
e9edcee0
TI
3534 /* set pin widgets 0x14-0x17 for output */
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 /* unmute pins for output (no gain on this amp) */
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544
3545 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3548 /* Mic2 (as headphone out) for HP output */
3549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551 /* Line In pin widget for input */
3552 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 /* Line2 (as front mic) pin widget for input and vref at 80% */
3555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 /* CD pin widget for input */
3558 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3559
3560 { }
3561};
3562
e9edcee0
TI
3563/*
3564 * W810 pin configuration:
3565 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3566 */
a9111321 3567static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3568 /* hphone/speaker input selector: front DAC */
3569 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3570
05acb863 3571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3575 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3577
e9edcee0 3578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3579 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3580
1da177e4
LT
3581 { }
3582};
3583
e9edcee0
TI
3584/*
3585 * Z71V pin configuration:
3586 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3587 */
a9111321 3588static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3593
16ded525 3594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3595 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3597 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3598
3599 { }
3600};
3601
e9edcee0
TI
3602/*
3603 * 6-stack pin configuration:
9c7f852e
TI
3604 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3605 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3606 */
a9111321 3607static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3608 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3609
16ded525 3610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3614 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3616 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3618
16ded525 3619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3623 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3626 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3627 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3628
e9edcee0
TI
3629 { }
3630};
3631
ccc656ce
KY
3632/*
3633 * Uniwill pin configuration:
3634 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3635 * line = 0x1a
3636 */
a9111321 3637static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3638 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3639
3640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3644 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3646 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3654
3655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3661 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3662 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3664
3665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3666 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3667
3668 { }
3669};
3670
3671/*
3672* Uniwill P53
ea1fb29a 3673* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3674 */
a9111321 3675static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3676 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3677
3678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3690
3691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3697
3698 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3699 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3700
3701 { }
3702};
3703
a9111321 3704static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3705 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3706 { }
3707};
3708
458a4fab 3709/* auto-toggle front mic */
eeb43387 3710static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3711{
3712 unsigned int present;
3713 unsigned char bits;
ccc656ce 3714
864f92be 3715 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3716 bits = present ? HDA_AMP_MUTE : 0;
3717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3718}
3719
4f5d1706 3720static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3721{
a9fd4f3f
TI
3722 struct alc_spec *spec = codec->spec;
3723
3724 spec->autocfg.hp_pins[0] = 0x14;
3725 spec->autocfg.speaker_pins[0] = 0x15;
3726 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3727 spec->automute = 1;
3728 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3729}
3730
3731static void alc880_uniwill_init_hook(struct hda_codec *codec)
3732{
d922b51d 3733 alc_hp_automute(codec);
eeb43387 3734 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3735}
3736
3737static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3738 unsigned int res)
3739{
3740 /* Looks like the unsol event is incompatible with the standard
3741 * definition. 4bit tag is placed at 28 bit!
3742 */
458a4fab 3743 switch (res >> 28) {
458a4fab 3744 case ALC880_MIC_EVENT:
eeb43387 3745 alc88x_simple_mic_automute(codec);
458a4fab 3746 break;
a9fd4f3f 3747 default:
d922b51d 3748 alc_sku_unsol_event(codec, res);
a9fd4f3f 3749 break;
458a4fab 3750 }
ccc656ce
KY
3751}
3752
4f5d1706 3753static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3754{
a9fd4f3f 3755 struct alc_spec *spec = codec->spec;
ccc656ce 3756
a9fd4f3f
TI
3757 spec->autocfg.hp_pins[0] = 0x14;
3758 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3759 spec->automute = 1;
3760 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3761}
3762
3763static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3764{
3765 unsigned int present;
ea1fb29a 3766
ccc656ce 3767 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3768 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3769 present &= HDA_AMP_VOLMASK;
3770 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3771 HDA_AMP_VOLMASK, present);
3772 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3773 HDA_AMP_VOLMASK, present);
ccc656ce 3774}
47fd830a 3775
ccc656ce
KY
3776static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3777 unsigned int res)
3778{
3779 /* Looks like the unsol event is incompatible with the standard
3780 * definition. 4bit tag is placed at 28 bit!
3781 */
f12ab1e0 3782 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3783 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3784 else
d922b51d 3785 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3786}
3787
e9edcee0
TI
3788/*
3789 * F1734 pin configuration:
3790 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3791 */
a9111321 3792static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3793 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3794 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3795 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3796 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3797 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3798
e9edcee0 3799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3800 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3803
e9edcee0
TI
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3806 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3807 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3813
937b4160
TI
3814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3815 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3816
dfc0ff62
TI
3817 { }
3818};
3819
e9edcee0
TI
3820/*
3821 * ASUS pin configuration:
3822 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3823 */
a9111321 3824static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3825 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3826 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3827 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3833 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3835 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3836 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3837 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3838
3839 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3848
e9edcee0
TI
3849 { }
3850};
16ded525 3851
e9edcee0 3852/* Enable GPIO mask and set output */
bc9f98a9
KY
3853#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3854#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3855#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3856
3857/* Clevo m520g init */
a9111321 3858static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3859 /* headphone output */
3860 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3861 /* line-out */
3862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864 /* Line-in */
3865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3867 /* CD */
3868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3869 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3870 /* Mic1 (rear panel) */
3871 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3873 /* Mic2 (front panel) */
3874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3876 /* headphone */
3877 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3879 /* change to EAPD mode */
3880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3881 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3882
3883 { }
16ded525
TI
3884};
3885
a9111321 3886static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3887 /* change to EAPD mode */
3888 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3889 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3890
df694daa
KY
3891 /* Headphone output */
3892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3893 /* Front output*/
3894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3895 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3896
3897 /* Line In pin widget for input */
3898 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3899 /* CD pin widget for input */
3900 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3901 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3903
3904 /* change to EAPD mode */
3905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3906 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3907
3908 { }
3909};
16ded525 3910
e9edcee0 3911/*
ae6b813a
TI
3912 * LG m1 express dual
3913 *
3914 * Pin assignment:
3915 * Rear Line-In/Out (blue): 0x14
3916 * Build-in Mic-In: 0x15
3917 * Speaker-out: 0x17
3918 * HP-Out (green): 0x1b
3919 * Mic-In/Out (red): 0x19
3920 * SPDIF-Out: 0x1e
3921 */
3922
3923/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3924static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3925 0x05, 0x02, 0x03
3926};
3927
3928/* seems analog CD is not working */
a9111321 3929static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3930 .num_items = 3,
3931 .items = {
3932 { "Mic", 0x1 },
3933 { "Line", 0x5 },
3934 { "Internal Mic", 0x6 },
3935 },
3936};
3937
3938/* 2,4,6 channel modes */
a9111321 3939static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3940 /* set line-in and mic-in to input */
3941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3942 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3943 { }
3944};
3945
a9111321 3946static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3947 /* set line-in to out and mic-in to input */
3948 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3950 { }
3951};
3952
a9111321 3953static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3954 /* set line-in and mic-in to output */
3955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3956 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3957 { }
3958};
3959
a9111321 3960static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3961 { 2, alc880_lg_ch2_init },
3962 { 4, alc880_lg_ch4_init },
3963 { 6, alc880_lg_ch6_init },
3964};
3965
a9111321 3966static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3968 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3970 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3977 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3978 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3980 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3981 {
3982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3983 .name = "Channel Mode",
3984 .info = alc_ch_mode_info,
3985 .get = alc_ch_mode_get,
3986 .put = alc_ch_mode_put,
3987 },
3988 { } /* end */
3989};
3990
a9111321 3991static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3992 /* set capture source to mic-in */
3993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3996 /* mute all amp mixer inputs */
3997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
4000 /* line-in to input */
4001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4003 /* built-in mic */
4004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4006 /* speaker-out */
4007 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4009 /* mic-in to input */
4010 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
4011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4013 /* HP-out */
4014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
4015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* jack sense */
a9fd4f3f 4018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
4019 { }
4020};
4021
4022/* toggle speaker-output according to the hp-jack state */
4f5d1706 4023static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 4024{
a9fd4f3f 4025 struct alc_spec *spec = codec->spec;
ae6b813a 4026
a9fd4f3f
TI
4027 spec->autocfg.hp_pins[0] = 0x1b;
4028 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
4029 spec->automute = 1;
4030 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
4031}
4032
d681518a
TI
4033/*
4034 * LG LW20
4035 *
4036 * Pin assignment:
4037 * Speaker-out: 0x14
4038 * Mic-In: 0x18
e4f41da9
CM
4039 * Built-in Mic-In: 0x19
4040 * Line-In: 0x1b
4041 * HP-Out: 0x1a
d681518a
TI
4042 * SPDIF-Out: 0x1e
4043 */
4044
a9111321 4045static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 4046 .num_items = 3,
d681518a
TI
4047 .items = {
4048 { "Mic", 0x0 },
4049 { "Internal Mic", 0x1 },
e4f41da9 4050 { "Line In", 0x2 },
d681518a
TI
4051 },
4052};
4053
0a8c5da3
CM
4054#define alc880_lg_lw_modes alc880_threestack_modes
4055
a9111321 4056static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
4057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4059 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4060 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4061 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4062 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4063 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4064 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
4067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4069 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4070 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
4071 {
4072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 .name = "Channel Mode",
4074 .info = alc_ch_mode_info,
4075 .get = alc_ch_mode_get,
4076 .put = alc_ch_mode_put,
4077 },
d681518a
TI
4078 { } /* end */
4079};
4080
a9111321 4081static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4082 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4083 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4084 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4085
d681518a
TI
4086 /* set capture source to mic-in */
4087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4091 /* speaker-out */
4092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4094 /* HP-out */
d681518a
TI
4095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4096 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4097 /* mic-in to input */
4098 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4100 /* built-in mic */
4101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4103 /* jack sense */
a9fd4f3f 4104 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4105 { }
4106};
4107
4108/* toggle speaker-output according to the hp-jack state */
4f5d1706 4109static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4110{
a9fd4f3f 4111 struct alc_spec *spec = codec->spec;
d681518a 4112
a9fd4f3f
TI
4113 spec->autocfg.hp_pins[0] = 0x1b;
4114 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4115 spec->automute = 1;
4116 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4117}
4118
a9111321 4119static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4120 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4121 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4124 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4125 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4126 { } /* end */
4127};
4128
a9111321 4129static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4130 .num_items = 2,
4131 .items = {
4132 { "Mic", 0x0 },
4133 { "Internal Mic", 0x1 },
4134 },
4135};
4136
a9111321 4137static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4138 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4139
4140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4142
4143 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4144 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4145 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4146 /* Mic2 (as headphone out) for HP output */
4147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4148 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4149 /* Internal Speaker */
4150 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4151 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4152
4153 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4154 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4155
4156 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4157 { }
4158};
4159
4160/* toggle speaker-output according to the hp-jack state */
4161static void alc880_medion_rim_automute(struct hda_codec *codec)
4162{
a9fd4f3f 4163 struct alc_spec *spec = codec->spec;
d922b51d 4164 alc_hp_automute(codec);
a9fd4f3f
TI
4165 /* toggle EAPD */
4166 if (spec->jack_present)
df99cd33
TI
4167 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4168 else
4169 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4170}
4171
4172static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4173 unsigned int res)
4174{
4175 /* Looks like the unsol event is incompatible with the standard
4176 * definition. 4bit tag is placed at 28 bit!
4177 */
4178 if ((res >> 28) == ALC880_HP_EVENT)
4179 alc880_medion_rim_automute(codec);
4180}
4181
4f5d1706 4182static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4183{
4184 struct alc_spec *spec = codec->spec;
4185
4186 spec->autocfg.hp_pins[0] = 0x14;
4187 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4188 spec->automute = 1;
4189 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4190}
4191
cb53c626 4192#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4193static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4194 { 0x0b, HDA_INPUT, 0 },
4195 { 0x0b, HDA_INPUT, 1 },
4196 { 0x0b, HDA_INPUT, 2 },
4197 { 0x0b, HDA_INPUT, 3 },
4198 { 0x0b, HDA_INPUT, 4 },
4199 { } /* end */
4200};
4201
a9111321 4202static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4203 { 0x0b, HDA_INPUT, 1 },
4204 { 0x0b, HDA_INPUT, 6 },
4205 { 0x0b, HDA_INPUT, 7 },
4206 { } /* end */
4207};
4208#endif
4209
ae6b813a
TI
4210/*
4211 * Common callbacks
e9edcee0
TI
4212 */
4213
584c0c4c
TI
4214static void alc_init_special_input_src(struct hda_codec *codec);
4215
1da177e4
LT
4216static int alc_init(struct hda_codec *codec)
4217{
4218 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4219 unsigned int i;
4220
2c3bf9ab 4221 alc_fix_pll(codec);
4a79ba34 4222 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4223
e9edcee0
TI
4224 for (i = 0; i < spec->num_init_verbs; i++)
4225 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4226 alc_init_special_input_src(codec);
ae6b813a
TI
4227
4228 if (spec->init_hook)
4229 spec->init_hook(codec);
4230
58701120
TI
4231 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4232
9e5341b9 4233 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4234 return 0;
4235}
4236
ae6b813a
TI
4237static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4238{
4239 struct alc_spec *spec = codec->spec;
4240
4241 if (spec->unsol_event)
4242 spec->unsol_event(codec, res);
4243}
4244
cb53c626
TI
4245#ifdef CONFIG_SND_HDA_POWER_SAVE
4246static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4247{
4248 struct alc_spec *spec = codec->spec;
4249 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4250}
4251#endif
4252
1da177e4
LT
4253/*
4254 * Analog playback callbacks
4255 */
c2d986b0 4256static int alc_playback_pcm_open(struct hda_pcm_stream *hinfo,
1da177e4 4257 struct hda_codec *codec,
c8b6bf9b 4258 struct snd_pcm_substream *substream)
1da177e4
LT
4259{
4260 struct alc_spec *spec = codec->spec;
9a08160b
TI
4261 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4262 hinfo);
1da177e4
LT
4263}
4264
c2d986b0 4265static int alc_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4266 struct hda_codec *codec,
4267 unsigned int stream_tag,
4268 unsigned int format,
c8b6bf9b 4269 struct snd_pcm_substream *substream)
1da177e4
LT
4270{
4271 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4272 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4273 stream_tag, format, substream);
1da177e4
LT
4274}
4275
c2d986b0 4276static int alc_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4277 struct hda_codec *codec,
c8b6bf9b 4278 struct snd_pcm_substream *substream)
1da177e4
LT
4279{
4280 struct alc_spec *spec = codec->spec;
4281 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4282}
4283
4284/*
4285 * Digital out
4286 */
c2d986b0 4287static int alc_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
1da177e4 4288 struct hda_codec *codec,
c8b6bf9b 4289 struct snd_pcm_substream *substream)
1da177e4
LT
4290{
4291 struct alc_spec *spec = codec->spec;
4292 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4293}
4294
c2d986b0 4295static int alc_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
6b97eb45
TI
4296 struct hda_codec *codec,
4297 unsigned int stream_tag,
4298 unsigned int format,
4299 struct snd_pcm_substream *substream)
4300{
4301 struct alc_spec *spec = codec->spec;
4302 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4303 stream_tag, format, substream);
4304}
4305
c2d986b0 4306static int alc_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
9b5f12e5
TI
4307 struct hda_codec *codec,
4308 struct snd_pcm_substream *substream)
4309{
4310 struct alc_spec *spec = codec->spec;
4311 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4312}
4313
c2d986b0 4314static int alc_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
1da177e4 4315 struct hda_codec *codec,
c8b6bf9b 4316 struct snd_pcm_substream *substream)
1da177e4
LT
4317{
4318 struct alc_spec *spec = codec->spec;
4319 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4320}
4321
4322/*
4323 * Analog capture
4324 */
c2d986b0 4325static int alc_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4326 struct hda_codec *codec,
4327 unsigned int stream_tag,
4328 unsigned int format,
c8b6bf9b 4329 struct snd_pcm_substream *substream)
1da177e4
LT
4330{
4331 struct alc_spec *spec = codec->spec;
4332
6330079f 4333 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4334 stream_tag, 0, format);
4335 return 0;
4336}
4337
c2d986b0 4338static int alc_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4339 struct hda_codec *codec,
c8b6bf9b 4340 struct snd_pcm_substream *substream)
1da177e4
LT
4341{
4342 struct alc_spec *spec = codec->spec;
4343
888afa15
TI
4344 snd_hda_codec_cleanup_stream(codec,
4345 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4346 return 0;
4347}
4348
840b64c0 4349/* analog capture with dynamic dual-adc changes */
21268961 4350static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
840b64c0
TI
4351 struct hda_codec *codec,
4352 unsigned int stream_tag,
4353 unsigned int format,
4354 struct snd_pcm_substream *substream)
4355{
4356 struct alc_spec *spec = codec->spec;
21268961 4357 spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
840b64c0
TI
4358 spec->cur_adc_stream_tag = stream_tag;
4359 spec->cur_adc_format = format;
4360 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4361 return 0;
4362}
4363
21268961 4364static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
840b64c0
TI
4365 struct hda_codec *codec,
4366 struct snd_pcm_substream *substream)
4367{
4368 struct alc_spec *spec = codec->spec;
4369 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4370 spec->cur_adc = 0;
4371 return 0;
4372}
4373
21268961 4374static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
840b64c0
TI
4375 .substreams = 1,
4376 .channels_min = 2,
4377 .channels_max = 2,
4378 .nid = 0, /* fill later */
4379 .ops = {
21268961
TI
4380 .prepare = dyn_adc_capture_pcm_prepare,
4381 .cleanup = dyn_adc_capture_pcm_cleanup
840b64c0
TI
4382 },
4383};
1da177e4
LT
4384
4385/*
4386 */
c2d986b0 4387static const struct hda_pcm_stream alc_pcm_analog_playback = {
1da177e4
LT
4388 .substreams = 1,
4389 .channels_min = 2,
4390 .channels_max = 8,
e9edcee0 4391 /* NID is set in alc_build_pcms */
1da177e4 4392 .ops = {
c2d986b0
TI
4393 .open = alc_playback_pcm_open,
4394 .prepare = alc_playback_pcm_prepare,
4395 .cleanup = alc_playback_pcm_cleanup
1da177e4
LT
4396 },
4397};
4398
c2d986b0 4399static const struct hda_pcm_stream alc_pcm_analog_capture = {
6330079f
TI
4400 .substreams = 1,
4401 .channels_min = 2,
4402 .channels_max = 2,
4403 /* NID is set in alc_build_pcms */
4404};
4405
c2d986b0 4406static const struct hda_pcm_stream alc_pcm_analog_alt_playback = {
6330079f
TI
4407 .substreams = 1,
4408 .channels_min = 2,
4409 .channels_max = 2,
4410 /* NID is set in alc_build_pcms */
4411};
4412
c2d986b0 4413static const struct hda_pcm_stream alc_pcm_analog_alt_capture = {
6330079f 4414 .substreams = 2, /* can be overridden */
1da177e4
LT
4415 .channels_min = 2,
4416 .channels_max = 2,
e9edcee0 4417 /* NID is set in alc_build_pcms */
1da177e4 4418 .ops = {
c2d986b0
TI
4419 .prepare = alc_alt_capture_pcm_prepare,
4420 .cleanup = alc_alt_capture_pcm_cleanup
1da177e4
LT
4421 },
4422};
4423
c2d986b0 4424static const struct hda_pcm_stream alc_pcm_digital_playback = {
1da177e4
LT
4425 .substreams = 1,
4426 .channels_min = 2,
4427 .channels_max = 2,
4428 /* NID is set in alc_build_pcms */
4429 .ops = {
c2d986b0
TI
4430 .open = alc_dig_playback_pcm_open,
4431 .close = alc_dig_playback_pcm_close,
4432 .prepare = alc_dig_playback_pcm_prepare,
4433 .cleanup = alc_dig_playback_pcm_cleanup
1da177e4
LT
4434 },
4435};
4436
c2d986b0 4437static const struct hda_pcm_stream alc_pcm_digital_capture = {
1da177e4
LT
4438 .substreams = 1,
4439 .channels_min = 2,
4440 .channels_max = 2,
4441 /* NID is set in alc_build_pcms */
4442};
4443
4c5186ed 4444/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4445static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4446 .substreams = 0,
4447 .channels_min = 0,
4448 .channels_max = 0,
4449};
4450
1da177e4
LT
4451static int alc_build_pcms(struct hda_codec *codec)
4452{
4453 struct alc_spec *spec = codec->spec;
4454 struct hda_pcm *info = spec->pcm_rec;
c2d986b0 4455 const struct hda_pcm_stream *p;
1da177e4
LT
4456 int i;
4457
4458 codec->num_pcms = 1;
4459 codec->pcm_info = info;
4460
e64f14f4
TI
4461 if (spec->no_analog)
4462 goto skip_analog;
4463
812a2cca
TI
4464 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4465 "%s Analog", codec->chip_name);
1da177e4 4466 info->name = spec->stream_name_analog;
274693f3 4467
c2d986b0
TI
4468 if (spec->multiout.dac_nids > 0) {
4469 p = spec->stream_analog_playback;
4470 if (!p)
4471 p = &alc_pcm_analog_playback;
4472 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4a471b7d
TI
4473 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4474 }
c2d986b0
TI
4475 if (spec->adc_nids) {
4476 p = spec->stream_analog_capture;
21268961
TI
4477 if (!p) {
4478 if (spec->dyn_adc_switch)
4479 p = &dyn_adc_pcm_analog_capture;
4480 else
4481 p = &alc_pcm_analog_capture;
4482 }
c2d986b0 4483 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4a471b7d
TI
4484 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4485 }
4486
4487 if (spec->channel_mode) {
4488 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4489 for (i = 0; i < spec->num_channel_mode; i++) {
4490 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4491 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4492 }
1da177e4
LT
4493 }
4494 }
4495
e64f14f4 4496 skip_analog:
e08a007d 4497 /* SPDIF for stream index #1 */
1da177e4 4498 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4499 snprintf(spec->stream_name_digital,
4500 sizeof(spec->stream_name_digital),
4501 "%s Digital", codec->chip_name);
e08a007d 4502 codec->num_pcms = 2;
b25c9da1 4503 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4504 info = spec->pcm_rec + 1;
1da177e4 4505 info->name = spec->stream_name_digital;
8c441982
TI
4506 if (spec->dig_out_type)
4507 info->pcm_type = spec->dig_out_type;
4508 else
4509 info->pcm_type = HDA_PCM_TYPE_SPDIF;
c2d986b0
TI
4510 if (spec->multiout.dig_out_nid) {
4511 p = spec->stream_digital_playback;
4512 if (!p)
4513 p = &alc_pcm_digital_playback;
4514 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
1da177e4
LT
4515 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4516 }
c2d986b0
TI
4517 if (spec->dig_in_nid) {
4518 p = spec->stream_digital_capture;
4519 if (!p)
4520 p = &alc_pcm_digital_capture;
4521 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
1da177e4
LT
4522 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4523 }
963f803f
TI
4524 /* FIXME: do we need this for all Realtek codec models? */
4525 codec->spdif_status_reset = 1;
1da177e4
LT
4526 }
4527
e64f14f4
TI
4528 if (spec->no_analog)
4529 return 0;
4530
e08a007d
TI
4531 /* If the use of more than one ADC is requested for the current
4532 * model, configure a second analog capture-only PCM.
4533 */
4534 /* Additional Analaog capture for index #2 */
c2d986b0 4535 if (spec->alt_dac_nid || spec->num_adc_nids > 1) {
e08a007d 4536 codec->num_pcms = 3;
c06134d7 4537 info = spec->pcm_rec + 2;
e08a007d 4538 info->name = spec->stream_name_analog;
6330079f 4539 if (spec->alt_dac_nid) {
c2d986b0
TI
4540 p = spec->stream_analog_alt_playback;
4541 if (!p)
4542 p = &alc_pcm_analog_alt_playback;
4543 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
6330079f
TI
4544 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4545 spec->alt_dac_nid;
4546 } else {
4547 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4548 alc_pcm_null_stream;
4549 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4550 }
c2d986b0
TI
4551 if (spec->num_adc_nids > 1) {
4552 p = spec->stream_analog_alt_capture;
4553 if (!p)
4554 p = &alc_pcm_analog_alt_capture;
4555 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
6330079f
TI
4556 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4557 spec->adc_nids[1];
4558 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4559 spec->num_adc_nids - 1;
4560 } else {
4561 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4562 alc_pcm_null_stream;
4563 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4564 }
4565 }
4566
1da177e4
LT
4567 return 0;
4568}
4569
a4e09aa3
TI
4570static inline void alc_shutup(struct hda_codec *codec)
4571{
1c716153
TI
4572 struct alc_spec *spec = codec->spec;
4573
4574 if (spec && spec->shutup)
4575 spec->shutup(codec);
a4e09aa3
TI
4576 snd_hda_shutup_pins(codec);
4577}
4578
603c4019
TI
4579static void alc_free_kctls(struct hda_codec *codec)
4580{
4581 struct alc_spec *spec = codec->spec;
4582
4583 if (spec->kctls.list) {
4584 struct snd_kcontrol_new *kctl = spec->kctls.list;
4585 int i;
4586 for (i = 0; i < spec->kctls.used; i++)
4587 kfree(kctl[i].name);
4588 }
4589 snd_array_free(&spec->kctls);
4590}
4591
1da177e4
LT
4592static void alc_free(struct hda_codec *codec)
4593{
e9edcee0 4594 struct alc_spec *spec = codec->spec;
e9edcee0 4595
f12ab1e0 4596 if (!spec)
e9edcee0
TI
4597 return;
4598
a4e09aa3 4599 alc_shutup(codec);
cd372fb3 4600 snd_hda_input_jack_free(codec);
603c4019 4601 alc_free_kctls(codec);
e9edcee0 4602 kfree(spec);
680cd536 4603 snd_hda_detach_beep_device(codec);
1da177e4
LT
4604}
4605
f5de24b0 4606#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4607static void alc_power_eapd(struct hda_codec *codec)
4608{
691f1fcc 4609 alc_auto_setup_eapd(codec, false);
c97259df
DC
4610}
4611
f5de24b0
HM
4612static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4613{
4614 struct alc_spec *spec = codec->spec;
a4e09aa3 4615 alc_shutup(codec);
f5de24b0 4616 if (spec && spec->power_hook)
c97259df 4617 spec->power_hook(codec);
f5de24b0
HM
4618 return 0;
4619}
4620#endif
4621
e044c39a 4622#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4623static int alc_resume(struct hda_codec *codec)
4624{
1c716153 4625 msleep(150); /* to avoid pop noise */
e044c39a
TI
4626 codec->patch_ops.init(codec);
4627 snd_hda_codec_resume_amp(codec);
4628 snd_hda_codec_resume_cache(codec);
9e5341b9 4629 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4630 return 0;
4631}
e044c39a
TI
4632#endif
4633
1da177e4
LT
4634/*
4635 */
a9111321 4636static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4637 .build_controls = alc_build_controls,
4638 .build_pcms = alc_build_pcms,
4639 .init = alc_init,
4640 .free = alc_free,
ae6b813a 4641 .unsol_event = alc_unsol_event,
e044c39a
TI
4642#ifdef SND_HDA_NEEDS_RESUME
4643 .resume = alc_resume,
4644#endif
cb53c626 4645#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4646 .suspend = alc_suspend,
cb53c626
TI
4647 .check_power_status = alc_check_power_status,
4648#endif
c97259df 4649 .reboot_notify = alc_shutup,
1da177e4
LT
4650};
4651
c027ddcd
KY
4652/* replace the codec chip_name with the given string */
4653static int alc_codec_rename(struct hda_codec *codec, const char *name)
4654{
4655 kfree(codec->chip_name);
4656 codec->chip_name = kstrdup(name, GFP_KERNEL);
4657 if (!codec->chip_name) {
4658 alc_free(codec);
4659 return -ENOMEM;
4660 }
4661 return 0;
4662}
4663
2fa522be
TI
4664/*
4665 * Test configuration for debugging
4666 *
4667 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4668 * enum controls.
4669 */
4670#ifdef CONFIG_SND_DEBUG
4c6d72d1 4671static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4672 0x02, 0x03, 0x04, 0x05
4673};
4674
a9111321 4675static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4676 .num_items = 7,
2fa522be
TI
4677 .items = {
4678 { "In-1", 0x0 },
4679 { "In-2", 0x1 },
4680 { "In-3", 0x2 },
4681 { "In-4", 0x3 },
4682 { "CD", 0x4 },
ae6b813a
TI
4683 { "Front", 0x5 },
4684 { "Surround", 0x6 },
2fa522be
TI
4685 },
4686};
4687
a9111321 4688static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4689 { 2, NULL },
fd2c326d 4690 { 4, NULL },
2fa522be 4691 { 6, NULL },
fd2c326d 4692 { 8, NULL },
2fa522be
TI
4693};
4694
9c7f852e
TI
4695static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4696 struct snd_ctl_elem_info *uinfo)
2fa522be 4697{
4c6d72d1 4698 static const char * const texts[] = {
2fa522be
TI
4699 "N/A", "Line Out", "HP Out",
4700 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4701 };
4702 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4703 uinfo->count = 1;
4704 uinfo->value.enumerated.items = 8;
4705 if (uinfo->value.enumerated.item >= 8)
4706 uinfo->value.enumerated.item = 7;
4707 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4708 return 0;
4709}
4710
9c7f852e
TI
4711static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4712 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4713{
4714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4715 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4716 unsigned int pin_ctl, item = 0;
4717
4718 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4719 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4720 if (pin_ctl & AC_PINCTL_OUT_EN) {
4721 if (pin_ctl & AC_PINCTL_HP_EN)
4722 item = 2;
4723 else
4724 item = 1;
4725 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4726 switch (pin_ctl & AC_PINCTL_VREFEN) {
4727 case AC_PINCTL_VREF_HIZ: item = 3; break;
4728 case AC_PINCTL_VREF_50: item = 4; break;
4729 case AC_PINCTL_VREF_GRD: item = 5; break;
4730 case AC_PINCTL_VREF_80: item = 6; break;
4731 case AC_PINCTL_VREF_100: item = 7; break;
4732 }
4733 }
4734 ucontrol->value.enumerated.item[0] = item;
4735 return 0;
4736}
4737
9c7f852e
TI
4738static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4739 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4740{
4741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4742 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4743 static const unsigned int ctls[] = {
2fa522be
TI
4744 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4745 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4746 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4747 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4748 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4749 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4750 };
4751 unsigned int old_ctl, new_ctl;
4752
4753 old_ctl = snd_hda_codec_read(codec, nid, 0,
4754 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4755 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4756 if (old_ctl != new_ctl) {
82beb8fd
TI
4757 int val;
4758 snd_hda_codec_write_cache(codec, nid, 0,
4759 AC_VERB_SET_PIN_WIDGET_CONTROL,
4760 new_ctl);
47fd830a
TI
4761 val = ucontrol->value.enumerated.item[0] >= 3 ?
4762 HDA_AMP_MUTE : 0;
4763 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4764 HDA_AMP_MUTE, val);
2fa522be
TI
4765 return 1;
4766 }
4767 return 0;
4768}
4769
9c7f852e
TI
4770static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4771 struct snd_ctl_elem_info *uinfo)
2fa522be 4772{
4c6d72d1 4773 static const char * const texts[] = {
2fa522be
TI
4774 "Front", "Surround", "CLFE", "Side"
4775 };
4776 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4777 uinfo->count = 1;
4778 uinfo->value.enumerated.items = 4;
4779 if (uinfo->value.enumerated.item >= 4)
4780 uinfo->value.enumerated.item = 3;
4781 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4782 return 0;
4783}
4784
9c7f852e
TI
4785static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4786 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4787{
4788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4789 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4790 unsigned int sel;
4791
4792 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4793 ucontrol->value.enumerated.item[0] = sel & 3;
4794 return 0;
4795}
4796
9c7f852e
TI
4797static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4798 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4799{
4800 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4801 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4802 unsigned int sel;
4803
4804 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4805 if (ucontrol->value.enumerated.item[0] != sel) {
4806 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4807 snd_hda_codec_write_cache(codec, nid, 0,
4808 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4809 return 1;
4810 }
4811 return 0;
4812}
4813
4814#define PIN_CTL_TEST(xname,nid) { \
4815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4816 .name = xname, \
5b0cb1d8 4817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4818 .info = alc_test_pin_ctl_info, \
4819 .get = alc_test_pin_ctl_get, \
4820 .put = alc_test_pin_ctl_put, \
4821 .private_value = nid \
4822 }
4823
4824#define PIN_SRC_TEST(xname,nid) { \
4825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4826 .name = xname, \
5b0cb1d8 4827 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4828 .info = alc_test_pin_src_info, \
4829 .get = alc_test_pin_src_get, \
4830 .put = alc_test_pin_src_put, \
4831 .private_value = nid \
4832 }
4833
a9111321 4834static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4836 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4837 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4838 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4840 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4841 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4842 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4843 PIN_CTL_TEST("Front Pin Mode", 0x14),
4844 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4845 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4846 PIN_CTL_TEST("Side Pin Mode", 0x17),
4847 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4848 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4849 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4850 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4851 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4852 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4853 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4854 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4855 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4856 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4857 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4858 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4859 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4860 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4861 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4862 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4865 {
4866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4867 .name = "Channel Mode",
df694daa
KY
4868 .info = alc_ch_mode_info,
4869 .get = alc_ch_mode_get,
4870 .put = alc_ch_mode_put,
2fa522be
TI
4871 },
4872 { } /* end */
4873};
4874
a9111321 4875static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4876 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4878 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4883 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4884 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4885 /* Vol output for 0x0c-0x0f */
05acb863
TI
4886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4888 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4889 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4890 /* Set output pins 0x14-0x17 */
05acb863
TI
4891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4893 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4894 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4895 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4900 /* Set input pins 0x18-0x1c */
16ded525
TI
4901 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4905 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4906 /* Mute input pins 0x18-0x1b */
05acb863
TI
4907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4910 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4911 /* ADC set up */
05acb863 4912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4913 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4914 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4915 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4917 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4918 /* Analog input/passthru */
4919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4924 { }
4925};
4926#endif
4927
1da177e4
LT
4928/*
4929 */
4930
ea734963 4931static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4932 [ALC880_3ST] = "3stack",
4933 [ALC880_TCL_S700] = "tcl",
4934 [ALC880_3ST_DIG] = "3stack-digout",
4935 [ALC880_CLEVO] = "clevo",
4936 [ALC880_5ST] = "5stack",
4937 [ALC880_5ST_DIG] = "5stack-digout",
4938 [ALC880_W810] = "w810",
4939 [ALC880_Z71V] = "z71v",
4940 [ALC880_6ST] = "6stack",
4941 [ALC880_6ST_DIG] = "6stack-digout",
4942 [ALC880_ASUS] = "asus",
4943 [ALC880_ASUS_W1V] = "asus-w1v",
4944 [ALC880_ASUS_DIG] = "asus-dig",
4945 [ALC880_ASUS_DIG2] = "asus-dig2",
4946 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4947 [ALC880_UNIWILL_P53] = "uniwill-p53",
4948 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4949 [ALC880_F1734] = "F1734",
4950 [ALC880_LG] = "lg",
4951 [ALC880_LG_LW] = "lg-lw",
df99cd33 4952 [ALC880_MEDION_RIM] = "medion",
2fa522be 4953#ifdef CONFIG_SND_DEBUG
f5fcc13c 4954 [ALC880_TEST] = "test",
2fa522be 4955#endif
f5fcc13c
TI
4956 [ALC880_AUTO] = "auto",
4957};
4958
a9111321 4959static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4960 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4961 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4962 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4963 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4964 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4965 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4966 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4967 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4968 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c 4969 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
f5fcc13c
TI
4970 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4971 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4972 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4973 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4974 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4975 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4976 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4977 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4978 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4979 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4980 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4981 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4982 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4983 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4984 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4985 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4986 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4987 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4988 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4989 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4990 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4991 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4992 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4993 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4994 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4995 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4996 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4997 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4998 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4999 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
5000 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
5001 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 5002 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 5003 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 5004 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 5005 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 5006 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 5007 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 5008 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 5009 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 5010 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 5011 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 5012 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 5013 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 5014 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
5015 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
5016 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
5017 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
5018 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
5019 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
5020 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 5021 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 5022 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
5023 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
5024 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
5025 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
5026 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
5027 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
5028 /* default Intel */
5029 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
5030 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
5031 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
5032 {}
5033};
5034
16ded525 5035/*
df694daa 5036 * ALC880 codec presets
16ded525 5037 */
a9111321 5038static const struct alc_config_preset alc880_presets[] = {
16ded525 5039 [ALC880_3ST] = {
e9edcee0 5040 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_3stack_init_verbs },
16ded525 5043 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 5044 .dac_nids = alc880_dac_nids,
16ded525
TI
5045 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5046 .channel_mode = alc880_threestack_modes,
4e195a7b 5047 .need_dac_fix = 1,
16ded525
TI
5048 .input_mux = &alc880_capture_source,
5049 },
5050 [ALC880_3ST_DIG] = {
e9edcee0 5051 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
5052 .init_verbs = { alc880_volume_init_verbs,
5053 alc880_pin_3stack_init_verbs },
16ded525 5054 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
5055 .dac_nids = alc880_dac_nids,
5056 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5057 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5058 .channel_mode = alc880_threestack_modes,
4e195a7b 5059 .need_dac_fix = 1,
16ded525
TI
5060 .input_mux = &alc880_capture_source,
5061 },
df694daa
KY
5062 [ALC880_TCL_S700] = {
5063 .mixers = { alc880_tcl_s700_mixer },
5064 .init_verbs = { alc880_volume_init_verbs,
5065 alc880_pin_tcl_S700_init_verbs,
5066 alc880_gpio2_init_verbs },
5067 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5068 .dac_nids = alc880_dac_nids,
f9e336f6
TI
5069 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5070 .num_adc_nids = 1, /* single ADC */
df694daa
KY
5071 .hp_nid = 0x03,
5072 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5073 .channel_mode = alc880_2_jack_modes,
5074 .input_mux = &alc880_capture_source,
5075 },
16ded525 5076 [ALC880_5ST] = {
f12ab1e0
TI
5077 .mixers = { alc880_three_stack_mixer,
5078 alc880_five_stack_mixer},
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_5stack_init_verbs },
16ded525
TI
5081 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5082 .dac_nids = alc880_dac_nids,
16ded525
TI
5083 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5084 .channel_mode = alc880_fivestack_modes,
5085 .input_mux = &alc880_capture_source,
5086 },
5087 [ALC880_5ST_DIG] = {
f12ab1e0
TI
5088 .mixers = { alc880_three_stack_mixer,
5089 alc880_five_stack_mixer },
5090 .init_verbs = { alc880_volume_init_verbs,
5091 alc880_pin_5stack_init_verbs },
16ded525
TI
5092 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5093 .dac_nids = alc880_dac_nids,
5094 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5095 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5096 .channel_mode = alc880_fivestack_modes,
5097 .input_mux = &alc880_capture_source,
5098 },
b6482d48
TI
5099 [ALC880_6ST] = {
5100 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_6stack_init_verbs },
b6482d48
TI
5103 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5104 .dac_nids = alc880_6st_dac_nids,
5105 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5106 .channel_mode = alc880_sixstack_modes,
5107 .input_mux = &alc880_6stack_capture_source,
5108 },
16ded525 5109 [ALC880_6ST_DIG] = {
e9edcee0 5110 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5111 .init_verbs = { alc880_volume_init_verbs,
5112 alc880_pin_6stack_init_verbs },
16ded525
TI
5113 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5114 .dac_nids = alc880_6st_dac_nids,
5115 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5116 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5117 .channel_mode = alc880_sixstack_modes,
5118 .input_mux = &alc880_6stack_capture_source,
5119 },
5120 [ALC880_W810] = {
e9edcee0 5121 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5122 .init_verbs = { alc880_volume_init_verbs,
5123 alc880_pin_w810_init_verbs,
b0af0de5 5124 alc880_gpio2_init_verbs },
16ded525
TI
5125 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5126 .dac_nids = alc880_w810_dac_nids,
5127 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5128 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5129 .channel_mode = alc880_w810_modes,
5130 .input_mux = &alc880_capture_source,
5131 },
5132 [ALC880_Z71V] = {
e9edcee0 5133 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5134 .init_verbs = { alc880_volume_init_verbs,
5135 alc880_pin_z71v_init_verbs },
16ded525
TI
5136 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5137 .dac_nids = alc880_z71v_dac_nids,
5138 .dig_out_nid = ALC880_DIGOUT_NID,
5139 .hp_nid = 0x03,
e9edcee0
TI
5140 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5141 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5142 .input_mux = &alc880_capture_source,
5143 },
5144 [ALC880_F1734] = {
e9edcee0 5145 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5146 .init_verbs = { alc880_volume_init_verbs,
5147 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5148 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5149 .dac_nids = alc880_f1734_dac_nids,
5150 .hp_nid = 0x02,
5151 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5152 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5153 .input_mux = &alc880_f1734_capture_source,
5154 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5155 .setup = alc880_uniwill_p53_setup,
d922b51d 5156 .init_hook = alc_hp_automute,
16ded525
TI
5157 },
5158 [ALC880_ASUS] = {
e9edcee0 5159 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5160 .init_verbs = { alc880_volume_init_verbs,
5161 alc880_pin_asus_init_verbs,
e9edcee0
TI
5162 alc880_gpio1_init_verbs },
5163 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5164 .dac_nids = alc880_asus_dac_nids,
5165 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5166 .channel_mode = alc880_asus_modes,
4e195a7b 5167 .need_dac_fix = 1,
16ded525
TI
5168 .input_mux = &alc880_capture_source,
5169 },
5170 [ALC880_ASUS_DIG] = {
e9edcee0 5171 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5172 .init_verbs = { alc880_volume_init_verbs,
5173 alc880_pin_asus_init_verbs,
e9edcee0
TI
5174 alc880_gpio1_init_verbs },
5175 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5176 .dac_nids = alc880_asus_dac_nids,
16ded525 5177 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5178 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5179 .channel_mode = alc880_asus_modes,
4e195a7b 5180 .need_dac_fix = 1,
16ded525
TI
5181 .input_mux = &alc880_capture_source,
5182 },
df694daa
KY
5183 [ALC880_ASUS_DIG2] = {
5184 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_asus_init_verbs,
df694daa
KY
5187 alc880_gpio2_init_verbs }, /* use GPIO2 */
5188 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5189 .dac_nids = alc880_asus_dac_nids,
5190 .dig_out_nid = ALC880_DIGOUT_NID,
5191 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5192 .channel_mode = alc880_asus_modes,
4e195a7b 5193 .need_dac_fix = 1,
df694daa
KY
5194 .input_mux = &alc880_capture_source,
5195 },
16ded525 5196 [ALC880_ASUS_W1V] = {
e9edcee0 5197 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5198 .init_verbs = { alc880_volume_init_verbs,
5199 alc880_pin_asus_init_verbs,
e9edcee0
TI
5200 alc880_gpio1_init_verbs },
5201 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5202 .dac_nids = alc880_asus_dac_nids,
16ded525 5203 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5204 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5205 .channel_mode = alc880_asus_modes,
4e195a7b 5206 .need_dac_fix = 1,
16ded525
TI
5207 .input_mux = &alc880_capture_source,
5208 },
5209 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5210 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5211 .init_verbs = { alc880_volume_init_verbs,
5212 alc880_pin_asus_init_verbs },
e9edcee0
TI
5213 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5214 .dac_nids = alc880_asus_dac_nids,
16ded525 5215 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5216 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5217 .channel_mode = alc880_asus_modes,
4e195a7b 5218 .need_dac_fix = 1,
16ded525
TI
5219 .input_mux = &alc880_capture_source,
5220 },
ccc656ce
KY
5221 [ALC880_UNIWILL] = {
5222 .mixers = { alc880_uniwill_mixer },
5223 .init_verbs = { alc880_volume_init_verbs,
5224 alc880_uniwill_init_verbs },
5225 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5226 .dac_nids = alc880_asus_dac_nids,
5227 .dig_out_nid = ALC880_DIGOUT_NID,
5228 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5229 .channel_mode = alc880_threestack_modes,
5230 .need_dac_fix = 1,
5231 .input_mux = &alc880_capture_source,
5232 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5233 .setup = alc880_uniwill_setup,
a9fd4f3f 5234 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5235 },
5236 [ALC880_UNIWILL_P53] = {
5237 .mixers = { alc880_uniwill_p53_mixer },
5238 .init_verbs = { alc880_volume_init_verbs,
5239 alc880_uniwill_p53_init_verbs },
5240 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5241 .dac_nids = alc880_asus_dac_nids,
5242 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5243 .channel_mode = alc880_threestack_modes,
5244 .input_mux = &alc880_capture_source,
5245 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5246 .setup = alc880_uniwill_p53_setup,
d922b51d 5247 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5248 },
5249 [ALC880_FUJITSU] = {
45bdd1c1 5250 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5251 .init_verbs = { alc880_volume_init_verbs,
5252 alc880_uniwill_p53_init_verbs,
5253 alc880_beep_init_verbs },
5254 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5255 .dac_nids = alc880_dac_nids,
d53d7d9e 5256 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5257 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5258 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5259 .input_mux = &alc880_capture_source,
5260 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5261 .setup = alc880_uniwill_p53_setup,
d922b51d 5262 .init_hook = alc_hp_automute,
ccc656ce 5263 },
df694daa
KY
5264 [ALC880_CLEVO] = {
5265 .mixers = { alc880_three_stack_mixer },
5266 .init_verbs = { alc880_volume_init_verbs,
5267 alc880_pin_clevo_init_verbs },
5268 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5269 .dac_nids = alc880_dac_nids,
5270 .hp_nid = 0x03,
5271 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5272 .channel_mode = alc880_threestack_modes,
4e195a7b 5273 .need_dac_fix = 1,
df694daa
KY
5274 .input_mux = &alc880_capture_source,
5275 },
ae6b813a
TI
5276 [ALC880_LG] = {
5277 .mixers = { alc880_lg_mixer },
5278 .init_verbs = { alc880_volume_init_verbs,
5279 alc880_lg_init_verbs },
5280 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5281 .dac_nids = alc880_lg_dac_nids,
5282 .dig_out_nid = ALC880_DIGOUT_NID,
5283 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5284 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5285 .need_dac_fix = 1,
ae6b813a 5286 .input_mux = &alc880_lg_capture_source,
d922b51d 5287 .unsol_event = alc_sku_unsol_event,
4f5d1706 5288 .setup = alc880_lg_setup,
d922b51d 5289 .init_hook = alc_hp_automute,
cb53c626
TI
5290#ifdef CONFIG_SND_HDA_POWER_SAVE
5291 .loopbacks = alc880_lg_loopbacks,
5292#endif
ae6b813a 5293 },
d681518a
TI
5294 [ALC880_LG_LW] = {
5295 .mixers = { alc880_lg_lw_mixer },
5296 .init_verbs = { alc880_volume_init_verbs,
5297 alc880_lg_lw_init_verbs },
0a8c5da3 5298 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5299 .dac_nids = alc880_dac_nids,
5300 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5301 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5302 .channel_mode = alc880_lg_lw_modes,
d681518a 5303 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5304 .unsol_event = alc_sku_unsol_event,
4f5d1706 5305 .setup = alc880_lg_lw_setup,
d922b51d 5306 .init_hook = alc_hp_automute,
d681518a 5307 },
df99cd33
TI
5308 [ALC880_MEDION_RIM] = {
5309 .mixers = { alc880_medion_rim_mixer },
5310 .init_verbs = { alc880_volume_init_verbs,
5311 alc880_medion_rim_init_verbs,
5312 alc_gpio2_init_verbs },
5313 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5314 .dac_nids = alc880_dac_nids,
5315 .dig_out_nid = ALC880_DIGOUT_NID,
5316 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5317 .channel_mode = alc880_2_jack_modes,
5318 .input_mux = &alc880_medion_rim_capture_source,
5319 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5320 .setup = alc880_medion_rim_setup,
5321 .init_hook = alc880_medion_rim_automute,
df99cd33 5322 },
16ded525
TI
5323#ifdef CONFIG_SND_DEBUG
5324 [ALC880_TEST] = {
e9edcee0
TI
5325 .mixers = { alc880_test_mixer },
5326 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5327 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5328 .dac_nids = alc880_test_dac_nids,
5329 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5330 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5331 .channel_mode = alc880_test_modes,
5332 .input_mux = &alc880_test_capture_source,
5333 },
5334#endif
5335};
5336
e9edcee0
TI
5337/*
5338 * Automatic parse of I/O pins from the BIOS configuration
5339 */
5340
e9edcee0
TI
5341enum {
5342 ALC_CTL_WIDGET_VOL,
5343 ALC_CTL_WIDGET_MUTE,
5344 ALC_CTL_BIND_MUTE,
5345};
a9111321 5346static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5347 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5348 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5349 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5350};
5351
ce764ab2
TI
5352static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5353{
5354 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5355 return snd_array_new(&spec->kctls);
5356}
5357
e9edcee0 5358/* add dynamic controls */
f12ab1e0 5359static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5360 int cidx, unsigned long val)
e9edcee0 5361{
c8b6bf9b 5362 struct snd_kcontrol_new *knew;
e9edcee0 5363
ce764ab2 5364 knew = alc_kcontrol_new(spec);
603c4019
TI
5365 if (!knew)
5366 return -ENOMEM;
e9edcee0 5367 *knew = alc880_control_templates[type];
543537bd 5368 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5369 if (!knew->name)
e9edcee0 5370 return -ENOMEM;
66ceeb6b 5371 knew->index = cidx;
4d02d1b6 5372 if (get_amp_nid_(val))
5e26dfd0 5373 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5374 knew->private_value = val;
e9edcee0
TI
5375 return 0;
5376}
5377
0afe5f89
TI
5378static int add_control_with_pfx(struct alc_spec *spec, int type,
5379 const char *pfx, const char *dir,
66ceeb6b 5380 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5381{
5382 char name[32];
5383 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5384 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5385}
5386
66ceeb6b
TI
5387#define add_pb_vol_ctrl(spec, type, pfx, val) \
5388 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5389#define add_pb_sw_ctrl(spec, type, pfx, val) \
5390 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5391#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5392 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5393#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5394 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5395
e9edcee0
TI
5396#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5397#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5398#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5399#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5400#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5401#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5402#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5403#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5404#define ALC880_PIN_CD_NID 0x1c
5405
6843ca16
TI
5406static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5407 bool can_be_master, int *index)
bcb2f0f5 5408{
ce764ab2 5409 struct auto_pin_cfg *cfg = &spec->autocfg;
6843ca16
TI
5410 static const char * const chname[4] = {
5411 "Front", "Surround", NULL /*CLFE*/, "Side"
5412 };
ce764ab2 5413
6843ca16 5414 *index = 0;
ce764ab2
TI
5415 if (cfg->line_outs == 1 && !spec->multi_ios &&
5416 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5417 return "Master";
5418
5419 switch (cfg->line_out_type) {
5420 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5421 if (cfg->line_outs == 1)
5422 return "Speaker";
5423 break;
bcb2f0f5 5424 case AUTO_PIN_HP_OUT:
6843ca16
TI
5425 /* for multi-io case, only the primary out */
5426 if (ch && spec->multi_ios)
5427 break;
5428 *index = ch;
bcb2f0f5
TI
5429 return "Headphone";
5430 default:
ce764ab2 5431 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5432 return "PCM";
5433 break;
5434 }
6843ca16 5435 return chname[ch];
bcb2f0f5
TI
5436}
5437
e9edcee0 5438/* create input playback/capture controls for the given pin */
f12ab1e0 5439static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5440 const char *ctlname, int ctlidx,
df694daa 5441 int idx, hda_nid_t mix_nid)
e9edcee0 5442{
df694daa 5443 int err;
e9edcee0 5444
66ceeb6b 5445 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5446 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5447 if (err < 0)
e9edcee0 5448 return err;
66ceeb6b 5449 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5450 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5451 if (err < 0)
e9edcee0
TI
5452 return err;
5453 return 0;
5454}
5455
05f5f477
TI
5456static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5457{
5458 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5459 return (pincap & AC_PINCAP_IN) != 0;
5460}
5461
d6cc9fab 5462static int alc_auto_fill_adc_caps(struct hda_codec *codec)
b7821709 5463{
d6cc9fab 5464 struct alc_spec *spec = codec->spec;
b7821709 5465 hda_nid_t nid;
d6cc9fab
TI
5466 hda_nid_t *adc_nids = spec->private_adc_nids;
5467 hda_nid_t *cap_nids = spec->private_capsrc_nids;
5468 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
5469 bool indep_capsrc = false;
b7821709
TI
5470 int i, nums = 0;
5471
5472 nid = codec->start_nid;
5473 for (i = 0; i < codec->num_nodes; i++, nid++) {
5474 hda_nid_t src;
5475 const hda_nid_t *list;
5476 unsigned int caps = get_wcaps(codec, nid);
5477 int type = get_wcaps_type(caps);
5478
5479 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
5480 continue;
5481 adc_nids[nums] = nid;
5482 cap_nids[nums] = nid;
5483 src = nid;
5484 for (;;) {
5485 int n;
5486 type = get_wcaps_type(get_wcaps(codec, src));
5487 if (type == AC_WID_PIN)
5488 break;
5489 if (type == AC_WID_AUD_SEL) {
5490 cap_nids[nums] = src;
d6cc9fab 5491 indep_capsrc = true;
b7821709
TI
5492 break;
5493 }
5494 n = snd_hda_get_conn_list(codec, src, &list);
5495 if (n > 1) {
5496 cap_nids[nums] = src;
d6cc9fab 5497 indep_capsrc = true;
b7821709
TI
5498 break;
5499 } else if (n != 1)
5500 break;
5501 src = *list;
5502 }
5503 if (++nums >= max_nums)
5504 break;
5505 }
d6cc9fab 5506 spec->adc_nids = spec->private_adc_nids;
21268961 5507 spec->capsrc_nids = spec->private_capsrc_nids;
d6cc9fab 5508 spec->num_adc_nids = nums;
b7821709
TI
5509 return nums;
5510}
5511
e9edcee0 5512/* create playback/capture controls for input pins */
b7821709 5513static int alc_auto_create_input_ctls(struct hda_codec *codec)
e9edcee0 5514{
05f5f477 5515 struct alc_spec *spec = codec->spec;
b7821709
TI
5516 const struct auto_pin_cfg *cfg = &spec->autocfg;
5517 hda_nid_t mixer = spec->mixer_nid;
61b9b9b1 5518 struct hda_input_mux *imux = &spec->private_imux[0];
b7821709 5519 int num_adcs;
b7821709 5520 int i, c, err, idx, type_idx = 0;
5322bf27 5521 const char *prev_label = NULL;
e9edcee0 5522
d6cc9fab 5523 num_adcs = alc_auto_fill_adc_caps(codec);
b7821709
TI
5524 if (num_adcs < 0)
5525 return 0;
5526
66ceeb6b 5527 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5528 hda_nid_t pin;
10a20af7 5529 const char *label;
05f5f477 5530
66ceeb6b 5531 pin = cfg->inputs[i].pin;
05f5f477
TI
5532 if (!alc_is_input_pin(codec, pin))
5533 continue;
5534
5322bf27
DH
5535 label = hda_get_autocfg_input_label(codec, cfg, i);
5536 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5537 type_idx++;
5538 else
5539 type_idx = 0;
5322bf27
DH
5540 prev_label = label;
5541
05f5f477
TI
5542 if (mixer) {
5543 idx = get_connection_index(codec, mixer, pin);
5544 if (idx >= 0) {
5545 err = new_analog_input(spec, pin,
10a20af7
TI
5546 label, type_idx,
5547 idx, mixer);
05f5f477
TI
5548 if (err < 0)
5549 return err;
5550 }
5551 }
5552
b7821709 5553 for (c = 0; c < num_adcs; c++) {
d6cc9fab
TI
5554 hda_nid_t cap = spec->capsrc_nids ?
5555 spec->capsrc_nids[c] : spec->adc_nids[c];
5556 idx = get_connection_index(codec, cap, pin);
b7821709 5557 if (idx >= 0) {
21268961 5558 spec->imux_pins[imux->num_items] = pin;
b7821709
TI
5559 snd_hda_add_imux_item(imux, label, idx, NULL);
5560 break;
5561 }
5562 }
e9edcee0 5563 }
21268961
TI
5564
5565 spec->num_mux_defs = 1;
5566 spec->input_mux = imux;
5567
e9edcee0
TI
5568 return 0;
5569}
5570
343a04be
TI
5571static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5572static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5573 const struct auto_pin_cfg *cfg);
5574static int alc_auto_create_hp_out(struct hda_codec *codec);
5575static int alc_auto_create_speaker_out(struct hda_codec *codec);
5576static void alc_auto_init_multi_out(struct hda_codec *codec);
5577static void alc_auto_init_extra_out(struct hda_codec *codec);
5578
f6c7e546
TI
5579static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5580 unsigned int pin_type)
5581{
5582 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5583 pin_type);
5584 /* unmute pin */
d260cdf6
TI
5585 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5586 AMP_OUT_UNMUTE);
f6c7e546
TI
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
0a7f5320 5597static void alc_auto_init_analog_input(struct hda_codec *codec)
e9edcee0
TI
5598{
5599 struct alc_spec *spec = codec->spec;
66ceeb6b 5600 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5601 int i;
5602
66ceeb6b
TI
5603 for (i = 0; i < cfg->num_inputs; i++) {
5604 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5605 if (alc_is_input_pin(codec, nid)) {
30ea098f 5606 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
1f0f4b80 5607 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
f12ab1e0
TI
5608 snd_hda_codec_write(codec, nid, 0,
5609 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5610 AMP_OUT_MUTE);
5611 }
5612 }
1f0f4b80
TI
5613
5614 /* mute all loopback inputs */
5615 if (spec->mixer_nid) {
5616 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5617 for (i = 0; i < nums; i++)
5618 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5619 AC_VERB_SET_AMP_GAIN_MUTE,
5620 AMP_IN_MUTE(i));
5621 }
e9edcee0
TI
5622}
5623
cb053a82
TI
5624static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5625 int (*fill_dac)(struct hda_codec *));
d6cc9fab 5626static void alc_remove_invalid_adc_nids(struct hda_codec *codec);
f970de25 5627static void alc_auto_init_input_src(struct hda_codec *codec);
ce764ab2 5628
e9edcee0 5629/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5630/* return 1 if successful, 0 if the proper config is not found,
5631 * or a negative error code
5632 */
e9edcee0
TI
5633static int alc880_parse_auto_config(struct hda_codec *codec)
5634{
5635 struct alc_spec *spec = codec->spec;
757899ac 5636 int err;
4c6d72d1 5637 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5638
f12ab1e0
TI
5639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5640 alc880_ignore);
5641 if (err < 0)
e9edcee0 5642 return err;
f12ab1e0 5643 if (!spec->autocfg.line_outs)
e9edcee0 5644 return 0; /* can't find valid BIOS pin config */
df694daa 5645
343a04be 5646 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
5647 if (err < 0)
5648 return err;
343a04be 5649 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
5650 if (err < 0)
5651 return err;
343a04be 5652 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
5653 if (err < 0)
5654 return err;
343a04be 5655 err = alc_auto_create_hp_out(codec);
f12ab1e0
TI
5656 if (err < 0)
5657 return err;
343a04be 5658 err = alc_auto_create_speaker_out(codec);
f12ab1e0
TI
5659 if (err < 0)
5660 return err;
b7821709 5661 err = alc_auto_create_input_ctls(codec);
f12ab1e0 5662 if (err < 0)
e9edcee0
TI
5663 return err;
5664
5665 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5666
757899ac 5667 alc_auto_parse_digital(codec);
e9edcee0 5668
603c4019 5669 if (spec->kctls.list)
d88897ea 5670 add_mixer(spec, spec->kctls.list);
e9edcee0 5671
21268961 5672 alc_remove_invalid_adc_nids(codec);
d6cc9fab 5673
6227cdce 5674 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
21268961 5675 alc_auto_check_switches(codec);
4a79ba34 5676
e9edcee0
TI
5677 return 1;
5678}
5679
ae6b813a
TI
5680/* additional initialization for auto-configuration model */
5681static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5682{
f6c7e546 5683 struct alc_spec *spec = codec->spec;
343a04be
TI
5684 alc_auto_init_multi_out(codec);
5685 alc_auto_init_extra_out(codec);
0a7f5320 5686 alc_auto_init_analog_input(codec);
f970de25 5687 alc_auto_init_input_src(codec);
757899ac 5688 alc_auto_init_digital(codec);
f6c7e546 5689 if (spec->unsol_event)
7fb0d78f 5690 alc_inithook(codec);
e9edcee0
TI
5691}
5692
748cce43
TI
5693/* select or unmute the given capsrc route */
5694static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5695 int idx)
5696{
5697 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5698 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5699 HDA_AMP_MUTE, 0);
21268961 5700 } else if (snd_hda_get_conn_list(codec, cap, NULL) > 1) {
748cce43
TI
5701 snd_hda_codec_write_cache(codec, cap, 0,
5702 AC_VERB_SET_CONNECT_SEL, idx);
5703 }
5704}
5705
840b64c0
TI
5706/* set the default connection to that pin */
5707static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5708{
5709 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5710 int i;
5711
8ed99d97
TI
5712 if (!pin)
5713 return 0;
eaa9b3a7
TI
5714 for (i = 0; i < spec->num_adc_nids; i++) {
5715 hda_nid_t cap = spec->capsrc_nids ?
5716 spec->capsrc_nids[i] : spec->adc_nids[i];
5717 int idx;
5718
5719 idx = get_connection_index(codec, cap, pin);
5720 if (idx < 0)
5721 continue;
748cce43 5722 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5723 return i; /* return the found index */
5724 }
5725 return -1; /* not found */
5726}
5727
584c0c4c
TI
5728/* initialize some special cases for input sources */
5729static void alc_init_special_input_src(struct hda_codec *codec)
5730{
5731 struct alc_spec *spec = codec->spec;
21268961
TI
5732 int i;
5733
5734 for (i = 0; i < spec->autocfg.num_inputs; i++)
5735 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
584c0c4c
TI
5736}
5737
b59bdf3b 5738static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5739{
b59bdf3b 5740 struct alc_spec *spec = codec->spec;
a9111321 5741 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5742 { alc_capture_mixer_nosrc1,
5743 alc_capture_mixer_nosrc2,
5744 alc_capture_mixer_nosrc3 },
5745 { alc_capture_mixer1,
5746 alc_capture_mixer2,
5747 alc_capture_mixer3 },
f9e336f6 5748 };
d6cc9fab
TI
5749
5750 /* check whether either of ADC or MUX has a volume control */
5751 if (!(query_amp_caps(codec, spec->adc_nids[0], HDA_INPUT) &
5752 AC_AMPCAP_NUM_STEPS)) {
5753 if (!spec->capsrc_nids)
5754 return; /* no volume */
5755 if (!(query_amp_caps(codec, spec->capsrc_nids[0], HDA_OUTPUT) &
5756 AC_AMPCAP_NUM_STEPS))
5757 return; /* no volume in capsrc, too */
5758 spec->vol_in_capsrc = 1;
5759 }
5760
5761 if (spec->num_adc_nids > 0) {
eaa9b3a7 5762 int mux = 0;
d6cc9fab 5763 int num_adcs = 0;
21268961
TI
5764
5765 if (spec->input_mux && spec->input_mux->num_items > 1)
5766 mux = 1;
5767 if (spec->auto_mic) {
5768 num_adcs = 1;
5769 mux = 0;
5770 } else if (spec->dyn_adc_switch)
584c0c4c 5771 num_adcs = 1;
d6cc9fab
TI
5772 if (!num_adcs) {
5773 if (spec->num_adc_nids > 3)
5774 spec->num_adc_nids = 3;
5775 else if (!spec->num_adc_nids)
5776 return;
5777 num_adcs = spec->num_adc_nids;
5778 }
840b64c0 5779 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5780 }
f9e336f6
TI
5781}
5782
21268961
TI
5783/* check whether dynamic ADC-switching is available */
5784static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
5785{
5786 struct alc_spec *spec = codec->spec;
5787 struct hda_input_mux *imux = &spec->private_imux[0];
5788 int i, n, idx;
5789 hda_nid_t cap, pin;
5790
5791 if (imux != spec->input_mux) /* no dynamic imux? */
5792 return false;
5793
5794 for (n = 0; n < spec->num_adc_nids; n++) {
5795 cap = spec->private_capsrc_nids[n];
5796 for (i = 0; i < imux->num_items; i++) {
5797 pin = spec->imux_pins[i];
5798 if (!pin)
5799 return false;
5800 if (get_connection_index(codec, cap, pin) < 0)
5801 break;
5802 }
5803 if (i >= imux->num_items)
5804 return false; /* no ADC-switch is needed */
5805 }
5806
5807 for (i = 0; i < imux->num_items; i++) {
5808 pin = spec->imux_pins[i];
5809 for (n = 0; n < spec->num_adc_nids; n++) {
5810 cap = spec->private_capsrc_nids[n];
5811 idx = get_connection_index(codec, cap, pin);
5812 if (idx >= 0) {
5813 imux->items[i].index = idx;
5814 spec->dyn_adc_idx[i] = n;
5815 break;
5816 }
5817 }
5818 }
5819
5820 snd_printdd("realtek: enabling ADC switching\n");
5821 spec->dyn_adc_switch = 1;
5822 return true;
5823}
5824
d6cc9fab
TI
5825/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5826 * active input pins
5827 */
5828static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
6694635d
TI
5829{
5830 struct alc_spec *spec = codec->spec;
21268961 5831 const struct hda_input_mux *imux;
d6cc9fab
TI
5832 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5833 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5834 int i, n, nums;
6694635d 5835
21268961
TI
5836 imux = spec->input_mux;
5837 if (!imux)
5838 return;
5839 if (spec->dyn_adc_switch)
5840 return;
5841
d6cc9fab
TI
5842 nums = 0;
5843 for (n = 0; n < spec->num_adc_nids; n++) {
5844 hda_nid_t cap = spec->private_capsrc_nids[n];
21268961
TI
5845 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5846 for (i = 0; i < imux->num_items; i++) {
5847 hda_nid_t pin = spec->imux_pins[i];
5848 if (pin) {
5849 if (get_connection_index(codec, cap, pin) < 0)
5850 break;
5851 } else if (num_conns <= imux->items[i].index)
6694635d
TI
5852 break;
5853 }
21268961 5854 if (i >= imux->num_items) {
d6cc9fab
TI
5855 adc_nids[nums] = spec->private_adc_nids[n];
5856 capsrc_nids[nums++] = cap;
6694635d
TI
5857 }
5858 }
d6cc9fab 5859 if (!nums) {
21268961
TI
5860 /* check whether ADC-switch is possible */
5861 if (!alc_check_dyn_adc_switch(codec)) {
5862 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5863 " using fallback 0x%x\n",
5864 codec->chip_name, spec->private_adc_nids[0]);
5865 spec->num_adc_nids = 1;
5866 spec->auto_mic = 0;
5867 return;
5868 }
d6cc9fab
TI
5869 } else if (nums != spec->num_adc_nids) {
5870 memcpy(spec->private_adc_nids, adc_nids,
5871 nums * sizeof(hda_nid_t));
5872 memcpy(spec->private_capsrc_nids, capsrc_nids,
5873 nums * sizeof(hda_nid_t));
5874 spec->num_adc_nids = nums;
6694635d 5875 }
21268961
TI
5876
5877 if (spec->auto_mic)
5878 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
5879 else if (spec->input_mux->num_items == 1)
5880 spec->num_adc_nids = 1; /* reduce to a single ADC */
6694635d
TI
5881}
5882
67d634c0 5883#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5884#define set_beep_amp(spec, nid, idx, dir) \
5885 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5886
a9111321 5887static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5888 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5889 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5890 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5891 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5892 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5893 {}
5894};
5895
5896static inline int has_cdefine_beep(struct hda_codec *codec)
5897{
5898 struct alc_spec *spec = codec->spec;
5899 const struct snd_pci_quirk *q;
5900 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5901 if (q)
5902 return q->value;
5903 return spec->cdefine.enable_pcbeep;
5904}
67d634c0
TI
5905#else
5906#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5907#define has_cdefine_beep(codec) 0
67d634c0 5908#endif
45bdd1c1
TI
5909
5910/*
5911 * OK, here we have finally the patch for ALC880
5912 */
5913
1da177e4
LT
5914static int patch_alc880(struct hda_codec *codec)
5915{
5916 struct alc_spec *spec;
5917 int board_config;
df694daa 5918 int err;
1da177e4 5919
e560d8d8 5920 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5921 if (spec == NULL)
5922 return -ENOMEM;
5923
5924 codec->spec = spec;
5925
1f0f4b80
TI
5926 spec->mixer_nid = 0x0b;
5927
f5fcc13c
TI
5928 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5929 alc880_models,
5930 alc880_cfg_tbl);
5931 if (board_config < 0) {
9a11f1aa
TI
5932 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5933 codec->chip_name);
e9edcee0 5934 board_config = ALC880_AUTO;
1da177e4 5935 }
1da177e4 5936
e9edcee0
TI
5937 if (board_config == ALC880_AUTO) {
5938 /* automatic parse from the BIOS config */
5939 err = alc880_parse_auto_config(codec);
5940 if (err < 0) {
5941 alc_free(codec);
5942 return err;
f12ab1e0 5943 } else if (!err) {
9c7f852e
TI
5944 printk(KERN_INFO
5945 "hda_codec: Cannot set up configuration "
5946 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5947 board_config = ALC880_3ST;
5948 }
1da177e4
LT
5949 }
5950
680cd536
KK
5951 err = snd_hda_attach_beep_device(codec, 0x1);
5952 if (err < 0) {
5953 alc_free(codec);
5954 return err;
5955 }
5956
df694daa 5957 if (board_config != ALC880_AUTO)
e9c364c0 5958 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5959
f12ab1e0 5960 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab 5961 alc_auto_fill_adc_caps(codec);
21268961 5962 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 5963 alc_remove_invalid_adc_nids(codec);
e9edcee0 5964 }
b59bdf3b 5965 set_capture_mixer(codec);
45bdd1c1 5966 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5967
2134ea4f
TI
5968 spec->vmaster_nid = 0x0c;
5969
1da177e4 5970 codec->patch_ops = alc_patch_ops;
e9edcee0 5971 if (board_config == ALC880_AUTO)
ae6b813a 5972 spec->init_hook = alc880_auto_init;
cb53c626
TI
5973#ifdef CONFIG_SND_HDA_POWER_SAVE
5974 if (!spec->loopback.amplist)
5975 spec->loopback.amplist = alc880_loopbacks;
5976#endif
1da177e4
LT
5977
5978 return 0;
5979}
5980
e9edcee0 5981
1da177e4
LT
5982/*
5983 * ALC260 support
5984 */
5985
4c6d72d1 5986static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
5987 /* front */
5988 0x02,
5989};
5990
4c6d72d1 5991static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
5992 /* ADC0 */
5993 0x04,
5994};
5995
4c6d72d1 5996static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5997 /* ADC1 */
5998 0x05,
5999};
6000
d57fdac0
JW
6001/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6002 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6003 */
4c6d72d1 6004static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6005 /* ADC0, ADC1 */
6006 0x04, 0x05
6007};
6008
e9edcee0
TI
6009#define ALC260_DIGOUT_NID 0x03
6010#define ALC260_DIGIN_NID 0x06
6011
a9111321 6012static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6013 .num_items = 4,
6014 .items = {
6015 { "Mic", 0x0 },
6016 { "Front Mic", 0x1 },
6017 { "Line", 0x2 },
6018 { "CD", 0x4 },
6019 },
6020};
6021
17e7aec6 6022/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6023 * headphone jack and the internal CD lines since these are the only pins at
6024 * which audio can appear. For flexibility, also allow the option of
6025 * recording the mixer output on the second ADC (ADC0 doesn't have a
6026 * connection to the mixer output).
a9430dd8 6027 */
a9111321 6028static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6029 {
6030 .num_items = 3,
6031 .items = {
6032 { "Mic/Line", 0x0 },
6033 { "CD", 0x4 },
6034 { "Headphone", 0x2 },
6035 },
a9430dd8 6036 },
a1e8d2da
JW
6037 {
6038 .num_items = 4,
6039 .items = {
6040 { "Mic/Line", 0x0 },
6041 { "CD", 0x4 },
6042 { "Headphone", 0x2 },
6043 { "Mixer", 0x5 },
6044 },
6045 },
6046
a9430dd8
JW
6047};
6048
a1e8d2da
JW
6049/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6050 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6051 */
a9111321 6052static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6053 {
6054 .num_items = 4,
6055 .items = {
6056 { "Mic", 0x0 },
6057 { "Line", 0x2 },
6058 { "CD", 0x4 },
6059 { "Headphone", 0x5 },
6060 },
6061 },
6062 {
6063 .num_items = 5,
6064 .items = {
6065 { "Mic", 0x0 },
6066 { "Line", 0x2 },
6067 { "CD", 0x4 },
6068 { "Headphone", 0x6 },
6069 { "Mixer", 0x5 },
6070 },
0bfc90e9
JW
6071 },
6072};
cc959489
MS
6073
6074/* Maxdata Favorit 100XS */
a9111321 6075static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6076 {
6077 .num_items = 2,
6078 .items = {
6079 { "Line/Mic", 0x0 },
6080 { "CD", 0x4 },
6081 },
6082 },
6083 {
6084 .num_items = 3,
6085 .items = {
6086 { "Line/Mic", 0x0 },
6087 { "CD", 0x4 },
6088 { "Mixer", 0x5 },
6089 },
6090 },
6091};
6092
1da177e4
LT
6093/*
6094 * This is just place-holder, so there's something for alc_build_pcms to look
6095 * at when it calculates the maximum number of channels. ALC260 has no mixer
6096 * element which allows changing the channel mode, so the verb list is
6097 * never used.
6098 */
a9111321 6099static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6100 { 2, NULL },
6101};
6102
df694daa
KY
6103
6104/* Mixer combinations
6105 *
6106 * basic: base_output + input + pc_beep + capture
6107 * HP: base_output + input + capture_alt
6108 * HP_3013: hp_3013 + input + capture
6109 * fujitsu: fujitsu + capture
0bfc90e9 6110 * acer: acer + capture
df694daa
KY
6111 */
6112
a9111321 6113static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6114 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6115 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6116 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6117 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6118 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6119 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6120 { } /* end */
f12ab1e0 6121};
1da177e4 6122
a9111321 6123static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6124 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6125 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6126 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6127 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6129 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6132 { } /* end */
6133};
6134
bec15c3a 6135/* update HP, line and mono out pins according to the master switch */
e9427969 6136static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a 6137{
e9427969 6138 update_speakers(codec);
bec15c3a
TI
6139}
6140
6141static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6142 struct snd_ctl_elem_value *ucontrol)
6143{
6144 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6145 struct alc_spec *spec = codec->spec;
e9427969 6146 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6147 return 0;
6148}
6149
6150static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6151 struct snd_ctl_elem_value *ucontrol)
6152{
6153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6154 struct alc_spec *spec = codec->spec;
e9427969 6155 int val = !*ucontrol->value.integer.value;
bec15c3a 6156
e9427969 6157 if (val == spec->master_mute)
bec15c3a 6158 return 0;
e9427969
TI
6159 spec->master_mute = val;
6160 alc260_hp_master_update(codec);
bec15c3a
TI
6161 return 1;
6162}
6163
a9111321 6164static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6165 {
6166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6167 .name = "Master Playback Switch",
5b0cb1d8 6168 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6169 .info = snd_ctl_boolean_mono_info,
6170 .get = alc260_hp_master_sw_get,
6171 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6172 },
6173 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6174 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6176 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6177 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6178 HDA_OUTPUT),
6179 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6180 { } /* end */
6181};
6182
a9111321 6183static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6184 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6185 {},
6186};
6187
e9427969 6188static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6189{
6190 struct alc_spec *spec = codec->spec;
bec15c3a 6191
e9427969
TI
6192 spec->autocfg.hp_pins[0] = 0x0f;
6193 spec->autocfg.speaker_pins[0] = 0x10;
6194 spec->autocfg.speaker_pins[1] = 0x11;
6195 spec->automute = 1;
6196 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6197}
6198
a9111321 6199static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6200 {
6201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6202 .name = "Master Playback Switch",
5b0cb1d8 6203 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6204 .info = snd_ctl_boolean_mono_info,
6205 .get = alc260_hp_master_sw_get,
6206 .put = alc260_hp_master_sw_put,
bec15c3a 6207 },
df694daa
KY
6208 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6209 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6210 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6211 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6214 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6215 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6216 { } /* end */
6217};
6218
e9427969
TI
6219static void alc260_hp_3013_setup(struct hda_codec *codec)
6220{
6221 struct alc_spec *spec = codec->spec;
6222
6223 spec->autocfg.hp_pins[0] = 0x15;
6224 spec->autocfg.speaker_pins[0] = 0x10;
6225 spec->autocfg.speaker_pins[1] = 0x11;
6226 spec->automute = 1;
6227 spec->automute_mode = ALC_AUTOMUTE_PIN;
6228}
6229
a9111321 6230static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6231 .ops = &snd_hda_bind_vol,
6232 .values = {
6233 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6234 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6235 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6236 0
6237 },
6238};
6239
a9111321 6240static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6241 .ops = &snd_hda_bind_sw,
6242 .values = {
6243 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6244 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6245 0
6246 },
6247};
6248
a9111321 6249static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6250 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6251 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6254 { } /* end */
6255};
6256
a9111321 6257static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6258 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6259 {},
6260};
6261
e9427969 6262static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6263{
6264 struct alc_spec *spec = codec->spec;
bec15c3a 6265
e9427969
TI
6266 spec->autocfg.hp_pins[0] = 0x10;
6267 spec->autocfg.speaker_pins[0] = 0x0f;
6268 spec->autocfg.speaker_pins[1] = 0x11;
6269 spec->autocfg.speaker_pins[2] = 0x15;
6270 spec->automute = 1;
6271 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6272}
6273
6274/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6275 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6276 */
a9111321 6277static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6279 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6280 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6281 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6282 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6284 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6285 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6287 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6288 { } /* end */
6289};
6290
a1e8d2da
JW
6291/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6292 * versions of the ALC260 don't act on requests to enable mic bias from NID
6293 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6294 * datasheet doesn't mention this restriction. At this stage it's not clear
6295 * whether this behaviour is intentional or is a hardware bug in chip
6296 * revisions available in early 2006. Therefore for now allow the
6297 * "Headphone Jack Mode" control to span all choices, but if it turns out
6298 * that the lack of mic bias for this NID is intentional we could change the
6299 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6300 *
6301 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6302 * don't appear to make the mic bias available from the "line" jack, even
6303 * though the NID used for this jack (0x14) can supply it. The theory is
6304 * that perhaps Acer have included blocking capacitors between the ALC260
6305 * and the output jack. If this turns out to be the case for all such
6306 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6307 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6308 *
6309 * The C20x Tablet series have a mono internal speaker which is controlled
6310 * via the chip's Mono sum widget and pin complex, so include the necessary
6311 * controls for such models. On models without a "mono speaker" the control
6312 * won't do anything.
a1e8d2da 6313 */
a9111321 6314static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6315 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6316 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6317 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6318 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6319 HDA_OUTPUT),
31bffaa9 6320 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6321 HDA_INPUT),
0bfc90e9
JW
6322 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6323 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6325 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6326 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6327 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6328 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6329 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6330 { } /* end */
6331};
6332
cc959489
MS
6333/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6334 */
a9111321 6335static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6336 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6337 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6338 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6339 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6340 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6341 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6342 { } /* end */
6343};
6344
bc9f98a9
KY
6345/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6346 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6347 */
a9111321 6348static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6349 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6350 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6352 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6353 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6354 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6355 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6356 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6357 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6358 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6359 { } /* end */
6360};
6361
6362/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6363 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6364 */
a9111321 6365static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6366 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6367 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6370 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6371 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6372 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6374 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6375 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6376 { } /* end */
6377};
6378
df694daa
KY
6379/*
6380 * initialization verbs
6381 */
a9111321 6382static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6383 /* Line In pin widget for input */
05acb863 6384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6385 /* CD pin widget for input */
05acb863 6386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6387 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6388 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6389 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6390 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6391 /* LINE-2 is used for line-out in rear */
05acb863 6392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6393 /* select line-out */
fd56f2db 6394 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6395 /* LINE-OUT pin */
05acb863 6396 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6397 /* enable HP */
05acb863 6398 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6399 /* enable Mono */
05acb863
TI
6400 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6401 /* mute capture amp left and right */
16ded525 6402 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6403 /* set connection select to line in (default select for this ADC) */
6404 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6405 /* mute capture amp left and right */
6406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407 /* set connection select to line in (default select for this ADC) */
6408 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6409 /* set vol=0 Line-Out mixer amp left and right */
6410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6411 /* unmute pin widget amp left and right (no gain on this amp) */
6412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6413 /* set vol=0 HP mixer amp left and right */
6414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6415 /* unmute pin widget amp left and right (no gain on this amp) */
6416 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6417 /* set vol=0 Mono mixer amp left and right */
6418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6419 /* unmute pin widget amp left and right (no gain on this amp) */
6420 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6421 /* unmute LINE-2 out pin */
6422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6423 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6424 * Line In 2 = 0x03
6425 */
cb53c626
TI
6426 /* mute analog inputs */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6432 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6433 /* mute Front out path */
6434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6436 /* mute Headphone out path */
6437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6439 /* mute Mono out path */
6440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6441 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6442 { }
6443};
6444
474167d6 6445#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6446static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6447 /* Headphone and output */
6448 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6449 /* mono output */
6450 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6453 /* Mic2 (front panel) pin widget for input and vref at 80% */
6454 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6455 /* Line In pin widget for input */
6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6457 /* Line-2 pin widget for output */
6458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6459 /* CD pin widget for input */
6460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6461 /* unmute amp left and right */
6462 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6463 /* set connection select to line in (default select for this ADC) */
6464 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6465 /* unmute Line-Out mixer amp left and right (volume = 0) */
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6467 /* mute pin widget amp left and right (no gain on this amp) */
6468 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6469 /* unmute HP mixer amp left and right (volume = 0) */
6470 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6471 /* mute pin widget amp left and right (no gain on this amp) */
6472 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6473 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6474 * Line In 2 = 0x03
6475 */
cb53c626
TI
6476 /* mute analog inputs */
6477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6482 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6483 /* Unmute Front out path */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6486 /* Unmute Headphone out path */
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6489 /* Unmute Mono out path */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6492 { }
6493};
474167d6 6494#endif
df694daa 6495
a9111321 6496static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6497 /* Line out and output */
6498 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6499 /* mono output */
6500 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6501 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6502 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6503 /* Mic2 (front panel) pin widget for input and vref at 80% */
6504 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6505 /* Line In pin widget for input */
6506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6507 /* Headphone pin widget for output */
6508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6509 /* CD pin widget for input */
6510 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6511 /* unmute amp left and right */
6512 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6513 /* set connection select to line in (default select for this ADC) */
6514 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6515 /* unmute Line-Out mixer amp left and right (volume = 0) */
6516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6517 /* mute pin widget amp left and right (no gain on this amp) */
6518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6519 /* unmute HP mixer amp left and right (volume = 0) */
6520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6521 /* mute pin widget amp left and right (no gain on this amp) */
6522 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6523 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6524 * Line In 2 = 0x03
6525 */
cb53c626
TI
6526 /* mute analog inputs */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6532 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6533 /* Unmute Front out path */
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6536 /* Unmute Headphone out path */
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6539 /* Unmute Mono out path */
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6542 { }
6543};
6544
a9430dd8 6545/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6546 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6547 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6548 */
a9111321 6549static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6550 /* Disable all GPIOs */
6551 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6552 /* Internal speaker is connected to headphone pin */
6553 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6554 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6555 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6556 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6557 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6558 /* Ensure all other unused pins are disabled and muted. */
6559 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6560 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6561 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6562 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6563 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6564 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567
6568 /* Disable digital (SPDIF) pins */
6569 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6570 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6571
ea1fb29a 6572 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6573 * when acting as an output.
6574 */
6575 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6576
f7ace40d 6577 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6584 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6587
f7ace40d
JW
6588 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6589 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6590 /* Unmute Line1 pin widget output buffer since it starts as an output.
6591 * If the pin mode is changed by the user the pin mode control will
6592 * take care of enabling the pin's input/output buffers as needed.
6593 * Therefore there's no need to enable the input buffer at this
6594 * stage.
cdcd9268 6595 */
f7ace40d 6596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6597 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6598 * mixer ctrl)
6599 */
f7ace40d
JW
6600 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6601
6602 /* Mute capture amp left and right */
6603 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6604 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6605 * in (on mic1 pin)
6606 */
6607 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6608
6609 /* Do the same for the second ADC: mute capture input amp and
6610 * set ADC connection to line in (on mic1 pin)
6611 */
6612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6613 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6614
6615 /* Mute all inputs to mixer widget (even unconnected ones) */
6616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6624
6625 { }
a9430dd8
JW
6626};
6627
0bfc90e9
JW
6628/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6629 * similar laptops (adapted from Fujitsu init verbs).
6630 */
a9111321 6631static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6632 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6633 * the headphone jack. Turn this on and rely on the standard mute
6634 * methods whenever the user wants to turn these outputs off.
6635 */
6636 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6637 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6638 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6639 /* Internal speaker/Headphone jack is connected to Line-out pin */
6640 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6641 /* Internal microphone/Mic jack is connected to Mic1 pin */
6642 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6643 /* Line In jack is connected to Line1 pin */
6644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6645 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6646 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6647 /* Ensure all other unused pins are disabled and muted. */
6648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6650 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 /* Disable digital (SPDIF) pins */
6655 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6656 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6657
ea1fb29a 6658 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6659 * bus when acting as outputs.
6660 */
6661 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6662 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6663
6664 /* Start with output sum widgets muted and their output gains at min */
6665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6672 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6673 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6674
f12ab1e0
TI
6675 /* Unmute Line-out pin widget amp left and right
6676 * (no equiv mixer ctrl)
6677 */
0bfc90e9 6678 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6679 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6680 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6681 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6682 * inputs. If the pin mode is changed by the user the pin mode control
6683 * will take care of enabling the pin's input/output buffers as needed.
6684 * Therefore there's no need to enable the input buffer at this
6685 * stage.
6686 */
6687 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6689
6690 /* Mute capture amp left and right */
6691 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6692 /* Set ADC connection select to match default mixer setting - mic
6693 * (on mic1 pin)
6694 */
6695 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6696
6697 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6698 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6699 */
6700 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6701 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6702
6703 /* Mute all inputs to mixer widget (even unconnected ones) */
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6712
6713 { }
6714};
6715
cc959489
MS
6716/* Initialisation sequence for Maxdata Favorit 100XS
6717 * (adapted from Acer init verbs).
6718 */
a9111321 6719static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6720 /* GPIO 0 enables the output jack.
6721 * Turn this on and rely on the standard mute
6722 * methods whenever the user wants to turn these outputs off.
6723 */
6724 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6726 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6727 /* Line/Mic input jack is connected to Mic1 pin */
6728 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6729 /* Ensure all other unused pins are disabled and muted. */
6730 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6731 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6732 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6733 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6735 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 /* Disable digital (SPDIF) pins */
6741 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6742 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6743
6744 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6745 * bus when acting as outputs.
6746 */
6747 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6748 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6749
6750 /* Start with output sum widgets muted and their output gains at min */
6751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6757 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760
6761 /* Unmute Line-out pin widget amp left and right
6762 * (no equiv mixer ctrl)
6763 */
6764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6765 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6766 * inputs. If the pin mode is changed by the user the pin mode control
6767 * will take care of enabling the pin's input/output buffers as needed.
6768 * Therefore there's no need to enable the input buffer at this
6769 * stage.
6770 */
6771 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772
6773 /* Mute capture amp left and right */
6774 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Set ADC connection select to match default mixer setting - mic
6776 * (on mic1 pin)
6777 */
6778 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6779
6780 /* Do similar with the second ADC: mute capture input amp and
6781 * set ADC connection to mic to match ALSA's default state.
6782 */
6783 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6785
6786 /* Mute all inputs to mixer widget (even unconnected ones) */
6787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6795
6796 { }
6797};
6798
a9111321 6799static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6800 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6801 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6802 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6803 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6804 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6805 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6806 {}
6807};
6808
a9111321 6809static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6810 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6811 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6812 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6813
6814 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6815 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6816 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6817
6818 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6819 {}
6820};
6821
6822/* toggle speaker-output according to the hp-jack state */
6823static void alc260_replacer_672v_automute(struct hda_codec *codec)
6824{
6825 unsigned int present;
6826
6827 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6828 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6829 if (present) {
82beb8fd
TI
6830 snd_hda_codec_write_cache(codec, 0x01, 0,
6831 AC_VERB_SET_GPIO_DATA, 1);
6832 snd_hda_codec_write_cache(codec, 0x0f, 0,
6833 AC_VERB_SET_PIN_WIDGET_CONTROL,
6834 PIN_HP);
bc9f98a9 6835 } else {
82beb8fd
TI
6836 snd_hda_codec_write_cache(codec, 0x01, 0,
6837 AC_VERB_SET_GPIO_DATA, 0);
6838 snd_hda_codec_write_cache(codec, 0x0f, 0,
6839 AC_VERB_SET_PIN_WIDGET_CONTROL,
6840 PIN_OUT);
bc9f98a9
KY
6841 }
6842}
6843
6844static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6845 unsigned int res)
6846{
6847 if ((res >> 26) == ALC880_HP_EVENT)
6848 alc260_replacer_672v_automute(codec);
6849}
6850
a9111321 6851static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6852 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6854 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6855 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6856 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6859 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6860 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6862 {}
6863};
6864
7cf51e48
JW
6865/* Test configuration for debugging, modelled after the ALC880 test
6866 * configuration.
6867 */
6868#ifdef CONFIG_SND_DEBUG
4c6d72d1 6869static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6870 0x02,
6871};
4c6d72d1 6872static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6873 0x04, 0x05,
6874};
a1e8d2da 6875/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6876 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6877 * is NID 0x04.
17e7aec6 6878 */
a9111321 6879static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6880 {
6881 .num_items = 7,
6882 .items = {
6883 { "MIC1 pin", 0x0 },
6884 { "MIC2 pin", 0x1 },
6885 { "LINE1 pin", 0x2 },
6886 { "LINE2 pin", 0x3 },
6887 { "CD pin", 0x4 },
6888 { "LINE-OUT pin", 0x5 },
6889 { "HP-OUT pin", 0x6 },
6890 },
6891 },
6892 {
6893 .num_items = 8,
6894 .items = {
6895 { "MIC1 pin", 0x0 },
6896 { "MIC2 pin", 0x1 },
6897 { "LINE1 pin", 0x2 },
6898 { "LINE2 pin", 0x3 },
6899 { "CD pin", 0x4 },
6900 { "Mixer", 0x5 },
6901 { "LINE-OUT pin", 0x6 },
6902 { "HP-OUT pin", 0x7 },
6903 },
7cf51e48
JW
6904 },
6905};
a9111321 6906static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6907 /* Output driver widgets */
6908 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6909 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6910 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6911 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6912 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6913 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6914
a1e8d2da
JW
6915 /* Modes for retasking pin widgets
6916 * Note: the ALC260 doesn't seem to act on requests to enable mic
6917 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6918 * mention this restriction. At this stage it's not clear whether
6919 * this behaviour is intentional or is a hardware bug in chip
6920 * revisions available at least up until early 2006. Therefore for
6921 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6922 * choices, but if it turns out that the lack of mic bias for these
6923 * NIDs is intentional we could change their modes from
6924 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6925 */
7cf51e48
JW
6926 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6927 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6928 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6929 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6930 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6931 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6932
6933 /* Loopback mixer controls */
6934 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6935 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6936 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6937 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6938 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6939 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6940 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6941 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6942 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6943 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6944 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6945 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6946 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6947 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6948
6949 /* Controls for GPIO pins, assuming they are configured as outputs */
6950 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6951 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6952 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6953 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6954
92621f13
JW
6955 /* Switches to allow the digital IO pins to be enabled. The datasheet
6956 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6957 * make this output available should provide clarification.
92621f13
JW
6958 */
6959 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6960 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6961
f8225f6d
JW
6962 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6963 * this output to turn on an external amplifier.
6964 */
6965 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6966 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6967
7cf51e48
JW
6968 { } /* end */
6969};
a9111321 6970static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6971 /* Enable all GPIOs as outputs with an initial value of 0 */
6972 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6973 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6974 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6975
7cf51e48
JW
6976 /* Enable retasking pins as output, initially without power amp */
6977 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6981 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6983
92621f13
JW
6984 /* Disable digital (SPDIF) pins initially, but users can enable
6985 * them via a mixer switch. In the case of SPDIF-out, this initverb
6986 * payload also sets the generation to 0, output to be in "consumer"
6987 * PCM format, copyright asserted, no pre-emphasis and no validity
6988 * control.
6989 */
7cf51e48
JW
6990 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6991 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6992
ea1fb29a 6993 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6994 * OUT1 sum bus when acting as an output.
6995 */
6996 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6997 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6998 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6999 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7000
7001 /* Start with output sum widgets muted and their output gains at min */
7002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7003 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7006 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011
cdcd9268
JW
7012 /* Unmute retasking pin widget output buffers since the default
7013 * state appears to be output. As the pin mode is changed by the
7014 * user the pin mode control will take care of enabling the pin's
7015 * input/output buffers as needed.
7016 */
7cf51e48
JW
7017 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7020 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7021 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7022 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7023 /* Also unmute the mono-out pin widget */
7024 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025
7cf51e48
JW
7026 /* Mute capture amp left and right */
7027 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7028 /* Set ADC connection select to match default mixer setting (mic1
7029 * pin)
7cf51e48
JW
7030 */
7031 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7032
7033 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7034 * set ADC connection to mic1 pin
7cf51e48
JW
7035 */
7036 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7037 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7038
7039 /* Mute all inputs to mixer widget (even unconnected ones) */
7040 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7041 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7043 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7044 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7048
7049 { }
7050};
7051#endif
7052
df694daa
KY
7053/*
7054 * for BIOS auto-configuration
7055 */
16ded525 7056
6d86b4fb
TI
7057/* convert from pin to volume-mixer widget */
7058static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7059{
7060 if (nid >= 0x0f && nid <= 0x11)
7061 return nid - 0x7;
7062 else if (nid >= 0x12 && nid <= 0x15)
7063 return 0x08;
7064 else
7065 return 0;
7066}
7067
df694daa 7068static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7069 const char *pfx, int *vol_bits)
df694daa
KY
7070{
7071 hda_nid_t nid_vol;
7072 unsigned long vol_val, sw_val;
6d86b4fb 7073 int chs, err;
df694daa 7074
6d86b4fb
TI
7075 nid_vol = alc260_pin_to_vol_mix(nid);
7076 if (!nid_vol)
df694daa 7077 return 0; /* N/A */
6d86b4fb
TI
7078 if (nid == 0x11)
7079 chs = 2;
7080 else
7081 chs = 3;
7082 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7083 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
ea1fb29a 7084
863b4518
TI
7085 if (!(*vol_bits & (1 << nid_vol))) {
7086 /* first control for the volume widget */
0afe5f89 7087 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7088 if (err < 0)
7089 return err;
7090 *vol_bits |= (1 << nid_vol);
7091 }
0afe5f89 7092 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7093 if (err < 0)
df694daa
KY
7094 return err;
7095 return 1;
7096}
7097
7098/* add playback controls from the parsed DAC table */
7099static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7100 const struct auto_pin_cfg *cfg)
7101{
7102 hda_nid_t nid;
7103 int err;
863b4518 7104 int vols = 0;
df694daa
KY
7105
7106 spec->multiout.num_dacs = 1;
7107 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7108 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7109
7110 nid = cfg->line_out_pins[0];
7111 if (nid) {
23112d6d 7112 const char *pfx;
2e925dde
TI
7113 int index;
7114 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
23112d6d 7115 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7116 if (err < 0)
7117 return err;
7118 }
7119
82bc955f 7120 nid = cfg->speaker_pins[0];
df694daa 7121 if (nid) {
863b4518 7122 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7123 if (err < 0)
7124 return err;
7125 }
7126
eb06ed8f 7127 nid = cfg->hp_pins[0];
df694daa 7128 if (nid) {
863b4518
TI
7129 err = alc260_add_playback_controls(spec, nid, "Headphone",
7130 &vols);
df694daa
KY
7131 if (err < 0)
7132 return err;
7133 }
f12ab1e0 7134 return 0;
df694daa
KY
7135}
7136
df694daa
KY
7137static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7138 hda_nid_t nid, int pin_type,
7139 int sel_idx)
7140{
6d86b4fb
TI
7141 hda_nid_t mix;
7142
f6c7e546 7143 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7144 /* need the manual connection? */
7145 if (nid >= 0x12) {
7146 int idx = nid - 0x12;
7147 snd_hda_codec_write(codec, idx + 0x0b, 0,
7148 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa 7149 }
df694daa 7150
6d86b4fb
TI
7151 mix = alc260_pin_to_vol_mix(nid);
7152 if (!mix)
1f0f4b80 7153 return;
6d86b4fb 7154 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1f0f4b80 7155 AMP_OUT_ZERO);
6d86b4fb
TI
7156 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7157 AMP_IN_UNMUTE(0));
7158 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7159 AMP_IN_UNMUTE(1));
1f0f4b80
TI
7160}
7161
df694daa
KY
7162static void alc260_auto_init_multi_out(struct hda_codec *codec)
7163{
7164 struct alc_spec *spec = codec->spec;
7165 hda_nid_t nid;
7166
f12ab1e0 7167 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7168 if (nid) {
7169 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7170 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7171 }
ea1fb29a 7172
82bc955f 7173 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7174 if (nid)
7175 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7176
eb06ed8f 7177 nid = spec->autocfg.hp_pins[0];
df694daa 7178 if (nid)
baba8ee9 7179 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
df694daa
KY
7180}
7181
df694daa
KY
7182static int alc260_parse_auto_config(struct hda_codec *codec)
7183{
7184 struct alc_spec *spec = codec->spec;
df694daa 7185 int err;
4c6d72d1 7186 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7187
f12ab1e0
TI
7188 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7189 alc260_ignore);
7190 if (err < 0)
df694daa 7191 return err;
f12ab1e0
TI
7192 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7193 if (err < 0)
4a471b7d 7194 return err;
603c4019 7195 if (!spec->kctls.list)
df694daa 7196 return 0; /* can't find valid BIOS pin config */
b7821709 7197 err = alc_auto_create_input_ctls(codec);
f12ab1e0 7198 if (err < 0)
df694daa
KY
7199 return err;
7200
7201 spec->multiout.max_channels = 2;
7202
0852d7a6 7203 if (spec->autocfg.dig_outs)
df694daa 7204 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7205 if (spec->kctls.list)
d88897ea 7206 add_mixer(spec, spec->kctls.list);
df694daa 7207
21268961 7208 alc_remove_invalid_adc_nids(codec);
d6cc9fab 7209
6227cdce 7210 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
21268961 7211 alc_auto_check_switches(codec);
4a79ba34 7212
df694daa
KY
7213 return 1;
7214}
7215
ae6b813a
TI
7216/* additional initialization for auto-configuration model */
7217static void alc260_auto_init(struct hda_codec *codec)
df694daa 7218{
f6c7e546 7219 struct alc_spec *spec = codec->spec;
df694daa 7220 alc260_auto_init_multi_out(codec);
0a7f5320 7221 alc_auto_init_analog_input(codec);
f970de25 7222 alc_auto_init_input_src(codec);
757899ac 7223 alc_auto_init_digital(codec);
f6c7e546 7224 if (spec->unsol_event)
7fb0d78f 7225 alc_inithook(codec);
df694daa
KY
7226}
7227
cb53c626 7228#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7229static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7230 { 0x07, HDA_INPUT, 0 },
7231 { 0x07, HDA_INPUT, 1 },
7232 { 0x07, HDA_INPUT, 2 },
7233 { 0x07, HDA_INPUT, 3 },
7234 { 0x07, HDA_INPUT, 4 },
7235 { } /* end */
7236};
7237#endif
7238
fc091769
TI
7239/*
7240 * Pin config fixes
7241 */
7242enum {
7243 PINFIX_HP_DC5750,
7244};
7245
fc091769
TI
7246static const struct alc_fixup alc260_fixups[] = {
7247 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7248 .type = ALC_FIXUP_PINS,
7249 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7250 { 0x11, 0x90130110 }, /* speaker */
7251 { }
7252 }
fc091769
TI
7253 },
7254};
7255
a9111321 7256static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7257 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7258 {}
7259};
7260
df694daa
KY
7261/*
7262 * ALC260 configurations
7263 */
ea734963 7264static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7265 [ALC260_BASIC] = "basic",
7266 [ALC260_HP] = "hp",
7267 [ALC260_HP_3013] = "hp-3013",
2922c9af 7268 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7269 [ALC260_FUJITSU_S702X] = "fujitsu",
7270 [ALC260_ACER] = "acer",
bc9f98a9
KY
7271 [ALC260_WILL] = "will",
7272 [ALC260_REPLACER_672V] = "replacer",
cc959489 7273 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7274#ifdef CONFIG_SND_DEBUG
f5fcc13c 7275 [ALC260_TEST] = "test",
7cf51e48 7276#endif
f5fcc13c
TI
7277 [ALC260_AUTO] = "auto",
7278};
7279
a9111321 7280static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7281 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7282 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7283 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7284 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7285 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7286 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7287 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7288 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7289 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7290 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7291 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7292 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7293 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7294 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7295 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7296 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7297 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7298 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7299 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7300 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7301 {}
7302};
7303
a9111321 7304static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7305 [ALC260_BASIC] = {
7306 .mixers = { alc260_base_output_mixer,
45bdd1c1 7307 alc260_input_mixer },
df694daa
KY
7308 .init_verbs = { alc260_init_verbs },
7309 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7310 .dac_nids = alc260_dac_nids,
f9e336f6 7311 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7312 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7313 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7314 .channel_mode = alc260_modes,
7315 .input_mux = &alc260_capture_source,
7316 },
7317 [ALC260_HP] = {
bec15c3a 7318 .mixers = { alc260_hp_output_mixer,
f9e336f6 7319 alc260_input_mixer },
bec15c3a
TI
7320 .init_verbs = { alc260_init_verbs,
7321 alc260_hp_unsol_verbs },
df694daa
KY
7322 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7323 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7324 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7325 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7326 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7327 .channel_mode = alc260_modes,
7328 .input_mux = &alc260_capture_source,
e9427969
TI
7329 .unsol_event = alc_sku_unsol_event,
7330 .setup = alc260_hp_setup,
7331 .init_hook = alc_inithook,
df694daa 7332 },
3f878308
KY
7333 [ALC260_HP_DC7600] = {
7334 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7335 alc260_input_mixer },
3f878308
KY
7336 .init_verbs = { alc260_init_verbs,
7337 alc260_hp_dc7600_verbs },
7338 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7339 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7340 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7341 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7342 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7343 .channel_mode = alc260_modes,
7344 .input_mux = &alc260_capture_source,
e9427969
TI
7345 .unsol_event = alc_sku_unsol_event,
7346 .setup = alc260_hp_3012_setup,
7347 .init_hook = alc_inithook,
3f878308 7348 },
df694daa
KY
7349 [ALC260_HP_3013] = {
7350 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7351 alc260_input_mixer },
bec15c3a
TI
7352 .init_verbs = { alc260_hp_3013_init_verbs,
7353 alc260_hp_3013_unsol_verbs },
df694daa
KY
7354 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7355 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7356 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7357 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7359 .channel_mode = alc260_modes,
7360 .input_mux = &alc260_capture_source,
e9427969
TI
7361 .unsol_event = alc_sku_unsol_event,
7362 .setup = alc260_hp_3013_setup,
7363 .init_hook = alc_inithook,
df694daa
KY
7364 },
7365 [ALC260_FUJITSU_S702X] = {
f9e336f6 7366 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7367 .init_verbs = { alc260_fujitsu_init_verbs },
7368 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7369 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7370 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7371 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7373 .channel_mode = alc260_modes,
a1e8d2da
JW
7374 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7375 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7376 },
0bfc90e9 7377 [ALC260_ACER] = {
f9e336f6 7378 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7379 .init_verbs = { alc260_acer_init_verbs },
7380 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7381 .dac_nids = alc260_dac_nids,
7382 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7383 .adc_nids = alc260_dual_adc_nids,
7384 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7385 .channel_mode = alc260_modes,
a1e8d2da
JW
7386 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7387 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7388 },
cc959489
MS
7389 [ALC260_FAVORIT100] = {
7390 .mixers = { alc260_favorit100_mixer },
7391 .init_verbs = { alc260_favorit100_init_verbs },
7392 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7393 .dac_nids = alc260_dac_nids,
7394 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7395 .adc_nids = alc260_dual_adc_nids,
7396 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7397 .channel_mode = alc260_modes,
7398 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7399 .input_mux = alc260_favorit100_capture_sources,
7400 },
bc9f98a9 7401 [ALC260_WILL] = {
f9e336f6 7402 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7403 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7405 .dac_nids = alc260_dac_nids,
7406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7407 .adc_nids = alc260_adc_nids,
7408 .dig_out_nid = ALC260_DIGOUT_NID,
7409 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7410 .channel_mode = alc260_modes,
7411 .input_mux = &alc260_capture_source,
7412 },
7413 [ALC260_REPLACER_672V] = {
f9e336f6 7414 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7415 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7416 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7417 .dac_nids = alc260_dac_nids,
7418 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7419 .adc_nids = alc260_adc_nids,
7420 .dig_out_nid = ALC260_DIGOUT_NID,
7421 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7422 .channel_mode = alc260_modes,
7423 .input_mux = &alc260_capture_source,
7424 .unsol_event = alc260_replacer_672v_unsol_event,
7425 .init_hook = alc260_replacer_672v_automute,
7426 },
7cf51e48
JW
7427#ifdef CONFIG_SND_DEBUG
7428 [ALC260_TEST] = {
f9e336f6 7429 .mixers = { alc260_test_mixer },
7cf51e48
JW
7430 .init_verbs = { alc260_test_init_verbs },
7431 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7432 .dac_nids = alc260_test_dac_nids,
7433 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7434 .adc_nids = alc260_test_adc_nids,
7435 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7436 .channel_mode = alc260_modes,
a1e8d2da
JW
7437 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7438 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7439 },
7440#endif
df694daa
KY
7441};
7442
7443static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7444{
7445 struct alc_spec *spec;
df694daa 7446 int err, board_config;
1da177e4 7447
e560d8d8 7448 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7449 if (spec == NULL)
7450 return -ENOMEM;
7451
7452 codec->spec = spec;
7453
1f0f4b80
TI
7454 spec->mixer_nid = 0x07;
7455
f5fcc13c
TI
7456 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7457 alc260_models,
7458 alc260_cfg_tbl);
7459 if (board_config < 0) {
9a11f1aa 7460 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7461 codec->chip_name);
df694daa 7462 board_config = ALC260_AUTO;
16ded525 7463 }
1da177e4 7464
b5bfbc67
TI
7465 if (board_config == ALC260_AUTO) {
7466 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7467 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7468 }
fc091769 7469
df694daa
KY
7470 if (board_config == ALC260_AUTO) {
7471 /* automatic parse from the BIOS config */
7472 err = alc260_parse_auto_config(codec);
7473 if (err < 0) {
7474 alc_free(codec);
7475 return err;
f12ab1e0 7476 } else if (!err) {
9c7f852e
TI
7477 printk(KERN_INFO
7478 "hda_codec: Cannot set up configuration "
7479 "from BIOS. Using base mode...\n");
df694daa
KY
7480 board_config = ALC260_BASIC;
7481 }
a9430dd8 7482 }
e9edcee0 7483
680cd536
KK
7484 err = snd_hda_attach_beep_device(codec, 0x1);
7485 if (err < 0) {
7486 alc_free(codec);
7487 return err;
7488 }
7489
df694daa 7490 if (board_config != ALC260_AUTO)
e9c364c0 7491 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7492
4ef0ef19 7493 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab 7494 alc_auto_fill_adc_caps(codec);
21268961 7495 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 7496 alc_remove_invalid_adc_nids(codec);
4ef0ef19 7497 }
b59bdf3b 7498 set_capture_mixer(codec);
45bdd1c1 7499 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7500
b5bfbc67 7501 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7502
2134ea4f
TI
7503 spec->vmaster_nid = 0x08;
7504
1da177e4 7505 codec->patch_ops = alc_patch_ops;
df694daa 7506 if (board_config == ALC260_AUTO)
ae6b813a 7507 spec->init_hook = alc260_auto_init;
1c716153 7508 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7509#ifdef CONFIG_SND_HDA_POWER_SAVE
7510 if (!spec->loopback.amplist)
7511 spec->loopback.amplist = alc260_loopbacks;
7512#endif
1da177e4
LT
7513
7514 return 0;
7515}
7516
e9edcee0 7517
1da177e4 7518/*
4953550a 7519 * ALC882/883/885/888/889 support
1da177e4
LT
7520 *
7521 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7522 * configuration. Each pin widget can choose any input DACs and a mixer.
7523 * Each ADC is connected from a mixer of all inputs. This makes possible
7524 * 6-channel independent captures.
7525 *
7526 * In addition, an independent DAC for the multi-playback (not used in this
7527 * driver yet).
7528 */
df694daa
KY
7529#define ALC882_DIGOUT_NID 0x06
7530#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7531#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7532#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7533#define ALC1200_DIGOUT_NID 0x10
7534
1da177e4 7535
a9111321 7536static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7537 { 8, NULL }
7538};
7539
4953550a 7540/* DACs */
4c6d72d1 7541static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7542 /* front, rear, clfe, rear_surr */
7543 0x02, 0x03, 0x04, 0x05
7544};
4953550a 7545#define alc883_dac_nids alc882_dac_nids
1da177e4 7546
4953550a 7547/* ADCs */
df694daa
KY
7548#define alc882_adc_nids alc880_adc_nids
7549#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7550#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7551static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7552static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7553#define alc889_adc_nids alc880_adc_nids
1da177e4 7554
4c6d72d1
TI
7555static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7556static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7557#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7558static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7559#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7560
1da177e4
LT
7561/* input MUX */
7562/* FIXME: should be a matrix-type input source selection */
7563
a9111321 7564static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7565 .num_items = 4,
7566 .items = {
7567 { "Mic", 0x0 },
7568 { "Front Mic", 0x1 },
7569 { "Line", 0x2 },
7570 { "CD", 0x4 },
7571 },
7572};
41d5545d 7573
4953550a
TI
7574#define alc883_capture_source alc882_capture_source
7575
a9111321 7576static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7577 .num_items = 3,
7578 .items = {
7579 { "Front Mic", 0x0 },
7580 { "Mic", 0x3 },
7581 { "Line", 0x2 },
7582 },
7583};
7584
a9111321 7585static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7586 .num_items = 3,
7587 .items = {
7588 { "Mic", 0x1 },
b8f171e7 7589 { "Line", 0x7 },
41d5545d
KS
7590 { "CD", 0x4 },
7591 },
7592};
7593
a9111321 7594static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7595 .num_items = 2,
7596 .items = {
7597 { "Line", 0x2 },
7598 { "CD", 0x4 },
7599 },
7600};
7601
a9111321 7602static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7603 .num_items = 4,
7604 .items = {
7605 { "Mic", 0x1 },
7606 { "Front Mic", 0x0 },
7607 { "Line", 0x2 },
7608 { "CD", 0x4 },
7609 },
7610};
7611
a9111321 7612static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7613 .num_items = 2,
7614 .items = {
7615 { "Mic", 0x1 },
7616 { "Line", 0x2 },
7617 },
7618};
7619
a9111321 7620static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7621 .num_items = 4,
7622 .items = {
7623 { "Mic", 0x0 },
28c4edb7 7624 { "Internal Mic", 0x1 },
4953550a
TI
7625 { "Line", 0x2 },
7626 { "CD", 0x4 },
7627 },
7628};
7629
a9111321 7630static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7631 .num_items = 2,
7632 .items = {
7633 { "Mic", 0x0 },
28c4edb7 7634 { "Internal Mic", 0x1 },
4953550a
TI
7635 },
7636};
7637
a9111321 7638static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7639 .num_items = 3,
7640 .items = {
7641 { "Mic", 0x0 },
7642 { "Front Mic", 0x1 },
7643 { "Line", 0x4 },
7644 },
7645};
7646
a9111321 7647static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7648 .num_items = 2,
7649 .items = {
7650 { "Mic", 0x0 },
7651 { "Line", 0x2 },
7652 },
7653};
7654
a9111321 7655static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7656 .num_items = 2,
7657 .items = {
7658 { "Mic", 0x0 },
7659 /* Front Mic (0x01) unused */
7660 { "Line", 0x2 },
7661 /* Line 2 (0x03) unused */
af901ca1 7662 /* CD (0x04) unused? */
4953550a
TI
7663 },
7664};
7665
a9111321 7666static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7667 .num_items = 2,
7668 .items = {
7669 { "Mic", 0x01 },
7670 { "Line", 0x2 }, /* Not sure! */
7671 },
7672};
7673
4953550a
TI
7674/*
7675 * 2ch mode
7676 */
a9111321 7677static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7678 { 2, NULL }
7679};
7680
272a527c
KY
7681/*
7682 * 2ch mode
7683 */
a9111321 7684static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { } /* end */
7690};
7691
4953550a
TI
7692/*
7693 * 4ch mode
7694 */
a9111321 7695static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7696 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7697 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7698 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7699 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7700 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7701 { } /* end */
7702};
7703
272a527c
KY
7704/*
7705 * 6ch mode
7706 */
a9111321 7707static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7708 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7709 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7710 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7711 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7712 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7713 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7714 { } /* end */
7715};
7716
a9111321 7717static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7718 { 2, alc882_3ST_ch2_init },
4953550a 7719 { 4, alc882_3ST_ch4_init },
272a527c
KY
7720 { 6, alc882_3ST_ch6_init },
7721};
7722
4953550a
TI
7723#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7724
a65cc60f 7725/*
7726 * 2ch mode
7727 */
a9111321 7728static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7729 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7732 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7733 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7734 { } /* end */
7735};
7736
7737/*
7738 * 4ch mode
7739 */
a9111321 7740static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7741 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7744 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7745 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7746 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7747 { } /* end */
7748};
7749
7750/*
7751 * 6ch mode
7752 */
a9111321 7753static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7754 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7761 { } /* end */
7762};
7763
a9111321 7764static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7765 { 2, alc883_3ST_ch2_clevo_init },
7766 { 4, alc883_3ST_ch4_clevo_init },
7767 { 6, alc883_3ST_ch6_clevo_init },
7768};
7769
7770
df694daa
KY
7771/*
7772 * 6ch mode
7773 */
a9111321 7774static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { } /* end */
7780};
7781
7782/*
7783 * 8ch mode
7784 */
a9111321 7785static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7786 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7787 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7788 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7790 { } /* end */
7791};
7792
a9111321 7793static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7794 { 6, alc882_sixstack_ch6_init },
7795 { 8, alc882_sixstack_ch8_init },
7796};
7797
76e6f5a9
RH
7798
7799/* Macbook Air 2,1 */
7800
a9111321 7801static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7802 { 2, NULL },
7803};
7804
87350ad0 7805/*
def319f9 7806 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7807 */
7808
7809/*
7810 * 2ch mode
7811 */
a9111321 7812static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7813 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7814 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7816 { } /* end */
7817};
7818
7819/*
a3f730af 7820 * 4ch mode
87350ad0 7821 */
a9111321 7822static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7825 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7826 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7827 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7828 { } /* end */
7829};
7830
a9111321 7831static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7832 { 2, alc885_mbp_ch2_init },
a3f730af 7833 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7834};
7835
92b9de83
KS
7836/*
7837 * 2ch
7838 * Speakers/Woofer/HP = Front
7839 * LineIn = Input
7840 */
a9111321 7841static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7842 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7844 { } /* end */
7845};
7846
7847/*
7848 * 6ch mode
7849 * Speakers/HP = Front
7850 * Woofer = LFE
7851 * LineIn = Surround
7852 */
a9111321 7853static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
7854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7857 { } /* end */
7858};
7859
a9111321 7860static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
7861 { 2, alc885_mb5_ch2_init },
7862 { 6, alc885_mb5_ch6_init },
7863};
87350ad0 7864
d01aecdf 7865#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7866
7867/*
7868 * 2ch mode
7869 */
a9111321 7870static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
7871 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7875 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7876 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7877 { } /* end */
7878};
7879
7880/*
7881 * 4ch mode
7882 */
a9111321 7883static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
7884 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7886 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7887 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7888 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7890 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7891 { } /* end */
7892};
7893
7894/*
7895 * 6ch mode
7896 */
a9111321 7897static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
7898 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7900 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7901 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7902 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7903 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7905 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7906 { } /* end */
7907};
7908
7909/*
7910 * 8ch mode
7911 */
a9111321 7912static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
7913 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7915 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7916 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7918 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7921 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922 { } /* end */
7923};
7924
a9111321 7925static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
7926 { 2, alc883_4ST_ch2_init },
7927 { 4, alc883_4ST_ch4_init },
7928 { 6, alc883_4ST_ch6_init },
7929 { 8, alc883_4ST_ch8_init },
7930};
7931
7932
7933/*
7934 * 2ch mode
7935 */
a9111321 7936static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
7937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7941 { } /* end */
7942};
7943
7944/*
7945 * 4ch mode
7946 */
a9111321 7947static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
7948 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7949 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7950 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7951 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7952 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7953 { } /* end */
7954};
7955
7956/*
7957 * 6ch mode
7958 */
a9111321 7959static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
7960 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7961 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7962 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7963 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7964 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7965 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7966 { } /* end */
7967};
7968
a9111321 7969static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
7970 { 2, alc883_3ST_ch2_intel_init },
7971 { 4, alc883_3ST_ch4_intel_init },
7972 { 6, alc883_3ST_ch6_intel_init },
7973};
7974
dd7714c9
WF
7975/*
7976 * 2ch mode
7977 */
a9111321 7978static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
7979 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7980 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7981 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7982 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7983 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7984 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7985 { } /* end */
7986};
7987
87a8c370
JK
7988/*
7989 * 6ch mode
7990 */
a9111321 7991static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7992 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7993 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7994 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7995 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7996 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7997 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7998 { } /* end */
7999};
8000
8001/*
8002 * 8ch mode
8003 */
a9111321 8004static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8005 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8006 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8007 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8008 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8009 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8010 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8011 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8012 { } /* end */
8013};
8014
a9111321 8015static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8016 { 2, alc889_ch2_intel_init },
87a8c370
JK
8017 { 6, alc889_ch6_intel_init },
8018 { 8, alc889_ch8_intel_init },
8019};
8020
4953550a
TI
8021/*
8022 * 6ch mode
8023 */
a9111321 8024static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8029 { } /* end */
8030};
8031
8032/*
8033 * 8ch mode
8034 */
a9111321 8035static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8038 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8039 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { } /* end */
8041};
8042
a9111321 8043static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8044 { 6, alc883_sixstack_ch6_init },
8045 { 8, alc883_sixstack_ch8_init },
8046};
8047
8048
1da177e4
LT
8049/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8050 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8051 */
a9111321 8052static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8055 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8056 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8057 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8058 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8059 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8060 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8061 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8062 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8072 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8074 { } /* end */
8075};
8076
76e6f5a9
RH
8077/* Macbook Air 2,1 same control for HP and internal Speaker */
8078
a9111321 8079static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8082 { }
8083};
8084
8085
a9111321 8086static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8087 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8088 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8090 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8092 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8093 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8095 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8096 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8097 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8098 { } /* end */
8099};
41d5545d 8100
a9111321 8101static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8102 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8103 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8105 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8106 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8107 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8109 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8111 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8113 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8114 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8116 { } /* end */
8117};
92b9de83 8118
a9111321 8119static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8121 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8123 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8124 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8125 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8127 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8129 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8130 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8131 { } /* end */
8132};
8133
a9111321 8134static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8135 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8136 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8137 { } /* end */
8138};
8139
8140
a9111321 8141static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8143 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8151 { } /* end */
8152};
8153
a9111321 8154static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8167 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8168 { } /* end */
8169};
8170
8171/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8172 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8173 */
a9111321 8174static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8176 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8178 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8179 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8183 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8184 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8188 { } /* end */
8189};
8190
a9111321 8191static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8195 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8196 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8200 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8202 { } /* end */
8203};
8204
a9111321 8205static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8206 {
8207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8208 .name = "Channel Mode",
8209 .info = alc_ch_mode_info,
8210 .get = alc_ch_mode_get,
8211 .put = alc_ch_mode_put,
8212 },
8213 { } /* end */
8214};
8215
a9111321 8216static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8217 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8220 /* Rear mixer */
05acb863
TI
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8223 /* CLFE mixer */
05acb863
TI
8224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8226 /* Side mixer */
05acb863
TI
8227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8228 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8229
e9edcee0 8230 /* Front Pin: output 0 (0x0c) */
05acb863 8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8234 /* Rear Pin: output 1 (0x0d) */
05acb863 8235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8237 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8238 /* CLFE Pin: output 2 (0x0e) */
05acb863 8239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8241 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8242 /* Side Pin: output 3 (0x0f) */
05acb863 8243 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8245 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8246 /* Mic (rear) pin: input vref at 80% */
16ded525 8247 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249 /* Front Mic pin: input vref at 80% */
16ded525 8250 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8252 /* Line In pin: input */
05acb863 8253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8255 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8256 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8259 /* CD pin widget for input */
05acb863 8260 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8261
8262 /* FIXME: use matrix-type input source selection */
8263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8264 /* Input mixer2 */
05acb863 8265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8266 /* Input mixer3 */
05acb863 8267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8268 /* ADC2: mute amp left and right */
8269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8270 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8271 /* ADC3: mute amp left and right */
8272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8273 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8274
8275 { }
8276};
8277
a9111321 8278static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8279 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8280 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8284 /* ADC1: mute amp left and right */
8285 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8286 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8287 { }
8288};
8289
a9111321 8290static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8291 /* change to EAPD mode */
8292 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8293 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8294 { }
4b146cb0
TI
8295};
8296
a9111321 8297static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8298 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8299 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8300 { }
8301};
8302
a9111321 8303static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8306 {}
8307};
87a8c370 8308
a9111321 8309static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8310 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8313 /* Rear mixer */
88102f3f
KY
8314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8316 /* CLFE mixer */
88102f3f
KY
8317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8319 /* Side mixer */
88102f3f
KY
8320 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8321 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8322
8323 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8327 /* Front Pin: output 0 (0x0c) */
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8330 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 /* Rear Pin: output 1 (0x0d) */
8332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8334 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8335 /* CLFE Pin: output 2 (0x0e) */
8336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8338 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8339 /* Side Pin: output 3 (0x0f) */
8340 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8341 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8342 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8343 /* Mic (rear) pin: input vref at 80% */
8344 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8345 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8346 /* Front Mic pin: input vref at 80% */
8347 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8348 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8349 /* Line In pin: input */
8350 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352
8353 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8354 /* Input mixer1 */
88102f3f 8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8356 /* Input mixer2 */
8357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8358 /* Input mixer3 */
88102f3f 8359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8360 /* ADC2: mute amp left and right */
8361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8362 /* ADC3: mute amp left and right */
8363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8364
8365 { }
8366};
8367
a9111321 8368static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8372 { }
8373};
8374
8375
8376/* Unmute Selector 24h and set the default input to front mic */
a9111321 8377static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8378 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 { }
8381};
8382
8383
4953550a
TI
8384#define alc883_init_verbs alc882_base_init_verbs
8385
9102cd1c 8386/* Mac Pro test */
a9111321 8387static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8392 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8393 /* FIXME: this looks suspicious...
d355c82a
JK
8394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8395 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8396 */
9102cd1c
TD
8397 { } /* end */
8398};
8399
a9111321 8400static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8401 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8405 /* Front Pin: output 0 (0x0c) */
8406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* Front Mic pin: input vref at 80% */
8410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8411 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8412 /* Speaker: output */
8413 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8415 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8416 /* Headphone output (output 0 - 0x0c) */
8417 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8418 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8419 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8420
8421 /* FIXME: use matrix-type input source selection */
8422 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8423 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8428 /* Input mixer2 */
8429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8433 /* Input mixer3 */
8434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8438 /* ADC1: mute amp left and right */
8439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8440 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8441 /* ADC2: mute amp left and right */
8442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8443 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8444 /* ADC3: mute amp left and right */
8445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8447
8448 { }
8449};
f12ab1e0 8450
41d5545d 8451/* Macbook 5,1 */
a9111321 8452static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8453 /* DACs */
8454 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8455 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8456 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8457 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8458 /* Front mixer */
41d5545d
KS
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8462 /* Surround mixer */
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8466 /* LFE mixer */
8467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8470 /* HP mixer */
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8474 /* Front Pin (0x0c) */
41d5545d
KS
8475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* LFE Pin (0x0e) */
8479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8480 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8482 /* HP Pin (0x0f) */
41d5545d
KS
8483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8486 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8487 /* Front Mic pin: input vref at 80% */
8488 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8489 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8490 /* Line In pin */
8491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8493
b8f171e7
AM
8494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8497 { }
8498};
8499
e458b1fa 8500/* Macmini 3,1 */
a9111321 8501static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8502 /* DACs */
8503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8506 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507 /* Front mixer */
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8511 /* Surround mixer */
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8515 /* LFE mixer */
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8519 /* HP mixer */
8520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8523 /* Front Pin (0x0c) */
8524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8525 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8526 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 /* LFE Pin (0x0e) */
8528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8530 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8531 /* HP Pin (0x0f) */
8532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8535 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8536 /* Line In pin */
8537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8539
8540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544 { }
8545};
8546
76e6f5a9 8547
a9111321 8548static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8549 /*Internal and HP Speaker Mixer*/
8550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8553 /*Internal Speaker Pin (0x0c)*/
8554 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 /* HP Pin: output 0 (0x0e) */
8558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8562 /* Line in (is hp when jack connected)*/
8563 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8564 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8565
8566 { }
8567 };
8568
8569
87350ad0 8570/* Macbook Pro rev3 */
a9111321 8571static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8572 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8576 /* Rear mixer */
8577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8580 /* HP mixer */
8581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8584 /* Front Pin: output 0 (0x0c) */
8585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8588 /* HP Pin: output 0 (0x0e) */
87350ad0 8589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8593 /* Mic (rear) pin: input vref at 80% */
8594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8596 /* Front Mic pin: input vref at 80% */
8597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8599 /* Line In pin: use output 1 when in LineOut mode */
8600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8602 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8603
8604 /* FIXME: use matrix-type input source selection */
8605 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8606 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8611 /* Input mixer2 */
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8616 /* Input mixer3 */
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8621 /* ADC1: mute amp left and right */
8622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8623 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8624 /* ADC2: mute amp left and right */
8625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8627 /* ADC3: mute amp left and right */
8628 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8629 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8630
8631 { }
8632};
8633
4b7e1803 8634/* iMac 9,1 */
a9111321 8635static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8636 /* Internal Speaker Pin (0x0c) */
8637 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8638 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8639 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8640 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8643 /* HP Pin: Rear */
4b7e1803
JM
8644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8647 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8648 /* Line in Rear */
8649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8651 /* Front Mic pin: input vref at 80% */
8652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8654 /* Rear mixer */
8655 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8658 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8667 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8672 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8677 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8680 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8683 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8685 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8686 { }
8687};
8688
c54728d8 8689/* iMac 24 mixer. */
a9111321 8690static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8691 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8692 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8693 { } /* end */
8694};
8695
8696/* iMac 24 init verbs. */
a9111321 8697static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8698 /* Internal speakers: output 0 (0x0c) */
8699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8702 /* Internal speakers: output 0 (0x0c) */
8703 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8705 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8706 /* Headphone: output 0 (0x0c) */
8707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8709 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8711 /* Front Mic: input vref at 80% */
8712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8714 { }
8715};
8716
8717/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8718static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8719{
a9fd4f3f 8720 struct alc_spec *spec = codec->spec;
c54728d8 8721
a9fd4f3f
TI
8722 spec->autocfg.hp_pins[0] = 0x14;
8723 spec->autocfg.speaker_pins[0] = 0x18;
8724 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8725 spec->automute = 1;
8726 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8727}
8728
9d54f08b
TI
8729#define alc885_mb5_setup alc885_imac24_setup
8730#define alc885_macmini3_setup alc885_imac24_setup
8731
76e6f5a9
RH
8732/* Macbook Air 2,1 */
8733static void alc885_mba21_setup(struct hda_codec *codec)
8734{
8735 struct alc_spec *spec = codec->spec;
8736
8737 spec->autocfg.hp_pins[0] = 0x14;
8738 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8739 spec->automute = 1;
8740 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8741}
8742
8743
8744
4f5d1706 8745static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8746{
a9fd4f3f 8747 struct alc_spec *spec = codec->spec;
87350ad0 8748
a9fd4f3f
TI
8749 spec->autocfg.hp_pins[0] = 0x15;
8750 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8751 spec->automute = 1;
8752 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8753}
8754
9d54f08b 8755static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8756{
9d54f08b 8757 struct alc_spec *spec = codec->spec;
4b7e1803 8758
9d54f08b 8759 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8760 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8761 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8762 spec->automute = 1;
8763 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8764}
87350ad0 8765
a9111321 8766static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8769
8770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8772
272a527c
KY
8773 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8776
8777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8778 { } /* end */
8779};
8780
8781/* toggle speaker-output according to the hp-jack state */
8782static void alc882_targa_automute(struct hda_codec *codec)
8783{
a9fd4f3f 8784 struct alc_spec *spec = codec->spec;
d922b51d 8785 alc_hp_automute(codec);
82beb8fd 8786 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8787 spec->jack_present ? 1 : 3);
8788}
8789
4f5d1706 8790static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8791{
8792 struct alc_spec *spec = codec->spec;
8793
8794 spec->autocfg.hp_pins[0] = 0x14;
8795 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8796 spec->automute = 1;
8797 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8798}
8799
8800static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8801{
a9fd4f3f 8802 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8803 alc882_targa_automute(codec);
272a527c
KY
8804}
8805
a9111321 8806static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8809
8810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8813
272a527c
KY
8814 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8816 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8817
8818 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8819 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8820 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8821 { } /* end */
8822};
8823
a9111321 8824static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8827
8828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8830 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8831
914759b7
TI
8832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8834 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8835
8836 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8837 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8838 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8839 { } /* end */
8840};
8841
9102cd1c
TD
8842static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8843{
8844 unsigned int gpiostate, gpiomask, gpiodir;
8845
8846 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8847 AC_VERB_GET_GPIO_DATA, 0);
8848
8849 if (!muted)
8850 gpiostate |= (1 << pin);
8851 else
8852 gpiostate &= ~(1 << pin);
8853
8854 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8855 AC_VERB_GET_GPIO_MASK, 0);
8856 gpiomask |= (1 << pin);
8857
8858 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8859 AC_VERB_GET_GPIO_DIRECTION, 0);
8860 gpiodir |= (1 << pin);
8861
8862
8863 snd_hda_codec_write(codec, codec->afg, 0,
8864 AC_VERB_SET_GPIO_MASK, gpiomask);
8865 snd_hda_codec_write(codec, codec->afg, 0,
8866 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8867
8868 msleep(1);
8869
8870 snd_hda_codec_write(codec, codec->afg, 0,
8871 AC_VERB_SET_GPIO_DATA, gpiostate);
8872}
8873
7debbe51
TI
8874/* set up GPIO at initialization */
8875static void alc885_macpro_init_hook(struct hda_codec *codec)
8876{
8877 alc882_gpio_mute(codec, 0, 0);
8878 alc882_gpio_mute(codec, 1, 0);
8879}
8880
8881/* set up GPIO and update auto-muting at initialization */
8882static void alc885_imac24_init_hook(struct hda_codec *codec)
8883{
8884 alc885_macpro_init_hook(codec);
d922b51d 8885 alc_hp_automute(codec);
7debbe51
TI
8886}
8887
eb4c41d3 8888/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 8889static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
8890 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8892 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8894 { } /* end */
8895};
8896
8897/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 8898static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
8899 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8901 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8902 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8903 { } /* end */
8904};
8905
8906/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 8907static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
8908 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8912 { } /* end */
8913};
8914
8915/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 8916static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
8917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8919 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8921 { } /* end */
8922};
8923
a9111321 8924static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
8925 { 2, alc889A_mb31_ch2_init },
8926 { 4, alc889A_mb31_ch4_init },
8927 { 5, alc889A_mb31_ch5_init },
8928 { 6, alc889A_mb31_ch6_init },
8929};
8930
a9111321 8931static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
8932 /* eanable EAPD on medion laptop */
8933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8935 { }
8936};
8937
4953550a 8938#define alc883_base_mixer alc882_base_mixer
834be88d 8939
a9111321 8940static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8954 { } /* end */
8955};
8956
a9111321 8957static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8959 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8960 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8963 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8965 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8966 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8967 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8968 { } /* end */
8969};
8970
a9111321 8971static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
8972 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8973 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8975 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8980 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8981 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8982 { } /* end */
8983};
8984
a9111321 8985static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8994 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8997 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8999 { } /* end */
9000};
df694daa 9001
a9111321 9002static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9004 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9006 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9009 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9010 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9013 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9020 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9022 { } /* end */
9023};
9024
a9111321 9025static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9027 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9028 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9030 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9031 HDA_OUTPUT),
9032 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9033 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9034 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9041 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9044 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9045 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9046 { } /* end */
9047};
9048
a9111321 9049static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9054 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9055 HDA_OUTPUT),
9056 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9057 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9058 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9059 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9060 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9068 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9070 { } /* end */
9071};
9072
a9111321 9073static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9075 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9076 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9077 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9078 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9081 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9084 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9086 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9087 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9090 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9091 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9092 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9093 { } /* end */
9094};
9095
a9111321 9096static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9102 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9112 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9114 { } /* end */
f12ab1e0 9115};
ccc656ce 9116
a9111321 9117static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9118 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9121 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9129 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9130 { } /* end */
f12ab1e0 9131};
ccc656ce 9132
a9111321 9133static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9134 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9136 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9138 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9139 { } /* end */
9140};
9141
a9111321 9142static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9146 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9151 { } /* end */
f12ab1e0 9152};
bc9f98a9 9153
a9111321 9154static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9155 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9162 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9163 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9164 { } /* end */
ea1fb29a 9165};
272a527c 9166
a9111321 9167static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9168 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9169 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9172 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9173 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9174 { } /* end */
9175};
9176
a9111321 9177static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9178 /* Unmute front mixer */
9179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9181
9182 /* Set speaker pin to front mixer */
9183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9184
9185 /* Init headphone pin */
9186 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9187 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9188 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9189 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9190
9191 { } /* end */
9192};
9193
9194/* toggle speaker-output according to the hp-jack state */
9195static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9196{
9197 struct alc_spec *spec = codec->spec;
9198
9199 spec->autocfg.hp_pins[0] = 0x1a;
9200 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9201 spec->automute = 1;
9202 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9203}
9204
a9111321 9205static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9206 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9207 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9214 { } /* end */
d1a991a6 9215};
2880a867 9216
a9111321 9217static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9219 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9225 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9227 { } /* end */
9228};
9229
a9111321 9230static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9231 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9232 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9234 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9235 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9236 0x0d, 1, 0x0, HDA_OUTPUT),
9237 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9238 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9239 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9240 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9241 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9242 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9243 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9245 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9247 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9249 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9250 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9251 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9252 { } /* end */
9253};
9254
a9111321 9255static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9256 /* Output mixers */
9257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9258 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9260 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9261 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9262 HDA_OUTPUT),
9263 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9264 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9265 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9266 /* Output switches */
9267 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9268 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9269 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9270 /* Boost mixers */
5f99f86a
DH
9271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9273 /* Input mixers */
9274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9277 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9278 { } /* end */
9279};
9280
a9111321 9281static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9288 { } /* end */
9289};
9290
a9111321 9291static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9292 .ops = &snd_hda_bind_vol,
9293 .values = {
9294 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9295 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9296 0
9297 },
9298};
9299
a9111321 9300static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9301 .ops = &snd_hda_bind_sw,
9302 .values = {
9303 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9304 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9305 0
9306 },
9307};
9308
a9111321 9309static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9313 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9314 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9317 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9318 { } /* end */
9319};
df694daa 9320
a9111321 9321static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9322 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9323 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9324 {
9325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9326 /* .name = "Capture Source", */
9327 .name = "Input Source",
9328 .count = 1,
9329 .info = alc_mux_enum_info,
9330 .get = alc_mux_enum_get,
9331 .put = alc_mux_enum_put,
9332 },
9333 { } /* end */
9334};
9c7f852e 9335
a9111321 9336static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9337 {
9338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9339 .name = "Channel Mode",
9340 .info = alc_ch_mode_info,
9341 .get = alc_ch_mode_get,
9342 .put = alc_ch_mode_put,
9343 },
9344 { } /* end */
9c7f852e
TI
9345};
9346
a8848bd6 9347/* toggle speaker-output according to the hp-jack state */
4f5d1706 9348static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9349{
a9fd4f3f 9350 struct alc_spec *spec = codec->spec;
a8848bd6 9351
a9fd4f3f
TI
9352 spec->autocfg.hp_pins[0] = 0x15;
9353 spec->autocfg.speaker_pins[0] = 0x14;
9354 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9355 spec->automute = 1;
9356 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9357}
9358
a9111321 9359static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9360 /* HP */
9361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9362 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9363 /* Subwoofer */
9364 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9365 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9366
9367 /* enable unsolicited event */
9368 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9369 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9370
9371 { } /* end */
9372};
9373
a9111321 9374static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9375 /* HP */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9378 /* Int speaker */
9379 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9380
9381 /* enable unsolicited event */
9382 /*
9383 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9385 */
9386
9387 { } /* end */
9388};
9389
a9111321 9390static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9391 /* HP */
9392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 /* Int speaker */
9395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397
9398 /* enable unsolicited event */
9399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9401
9402 { } /* end */
9403};
9404
a9111321 9405static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9406 /* HP */
9407 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9409 /* Subwoofer */
9410 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9412
9413 /* enable unsolicited event */
9414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9415
9416 { } /* end */
9417};
9418
a9111321 9419static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9422
9423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9425
64a8be74
DH
9426/* Connect Line-Out side jack (SPDIF) to Side */
9427 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9429 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9430/* Connect Mic jack to CLFE */
9431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9433 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9434/* Connect Line-in jack to Surround */
9435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9438/* Connect HP out jack to Front */
9439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9442
9443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9444
9445 { } /* end */
9446};
9447
a9111321 9448static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9450 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9451 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9452 { } /* end */
9453};
9454
a9111321 9455static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9456 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9458 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9460 { } /* end */
9461};
9462
a9111321 9463static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9466 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9467 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9468 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9469 { } /* end */
9470};
9471
a9111321 9472static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9475
9476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9477
9478 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9479 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9480 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9481 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9482 { } /* end */
9483};
9484
a9111321 9485static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9492 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9493 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9494 { } /* end */
9495};
9496
a9111321 9497static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9498 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9499 { }
9500};
9501
a9111321 9502static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9503 /* HP */
9504 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9506
9507 /* enable unsolicited event */
9508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9509
9510 { } /* end */
9511};
9512
4f5d1706 9513static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9514{
a9fd4f3f 9515 struct alc_spec *spec = codec->spec;
8718b700 9516
a9fd4f3f
TI
9517 spec->autocfg.hp_pins[0] = 0x1b;
9518 spec->autocfg.speaker_pins[0] = 0x14;
9519 spec->autocfg.speaker_pins[1] = 0x16;
9520 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9521 spec->automute = 1;
9522 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9523}
9524
a9111321 9525static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9527 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9528 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9530 { } /* end */
5795b9e6
CM
9531};
9532
3ea0d7cf
HRK
9533/*
9534 * 2ch mode
9535 */
a9111321 9536static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9541 { } /* end */
8341de60
CM
9542};
9543
3ea0d7cf
HRK
9544/*
9545 * 4ch mode
9546 */
a9111321 9547static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9550 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9551 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9552 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9553 { } /* end */
9554};
9555
9556/*
9557 * 6ch mode
9558 */
a9111321 9559static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9562 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9563 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9564 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9565 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9566 { } /* end */
8341de60
CM
9567};
9568
a9111321 9569static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9570 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9571 { 4, alc888_3st_hp_4ch_init },
4723c022 9572 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9573};
9574
e6a5e1b7 9575static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9576{
e6a5e1b7 9577 struct alc_spec *spec = codec->spec;
47fd830a 9578
e6a5e1b7
TI
9579 spec->autocfg.hp_pins[0] = 0x1b;
9580 spec->autocfg.line_out_pins[0] = 0x14;
9581 spec->autocfg.speaker_pins[0] = 0x15;
9582 spec->automute = 1;
9583 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9584}
9585
272a527c 9586/* toggle speaker-output according to the hp-jack state */
dc427170 9587static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9588{
a9fd4f3f 9589 struct alc_spec *spec = codec->spec;
272a527c 9590
a9fd4f3f
TI
9591 spec->autocfg.hp_pins[0] = 0x14;
9592 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9593 spec->automute = 1;
9594 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9595}
9596
ccc656ce 9597/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9598#define alc883_targa_init_hook alc882_targa_init_hook
9599#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9600
4f5d1706 9601static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9602{
a9fd4f3f
TI
9603 struct alc_spec *spec = codec->spec;
9604
9605 spec->autocfg.hp_pins[0] = 0x15;
9606 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9607 spec->automute = 1;
9608 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9609}
9610
9611static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9612{
d922b51d 9613 alc_hp_automute(codec);
eeb43387 9614 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9615}
9616
9617static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9618 unsigned int res)
9619{
0c4cc443 9620 switch (res >> 26) {
0c4cc443 9621 case ALC880_MIC_EVENT:
eeb43387 9622 alc88x_simple_mic_automute(codec);
0c4cc443 9623 break;
a9fd4f3f 9624 default:
d922b51d 9625 alc_sku_unsol_event(codec, res);
a9fd4f3f 9626 break;
0c4cc443 9627 }
368c7a95
J
9628}
9629
fb97dc67 9630/* toggle speaker-output according to the hp-jack state */
4f5d1706 9631static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9632{
a9fd4f3f 9633 struct alc_spec *spec = codec->spec;
fb97dc67 9634
a9fd4f3f
TI
9635 spec->autocfg.hp_pins[0] = 0x14;
9636 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9637 spec->automute = 1;
9638 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9639}
9640
4f5d1706 9641static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9642{
a9fd4f3f 9643 struct alc_spec *spec = codec->spec;
189609ae 9644
a9fd4f3f
TI
9645 spec->autocfg.hp_pins[0] = 0x1b;
9646 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9647 spec->automute = 1;
9648 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9649}
9650
e6a5e1b7 9651static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9652{
e6a5e1b7 9653 struct alc_spec *spec = codec->spec;
bc9f98a9 9654
e6a5e1b7
TI
9655 spec->autocfg.hp_pins[0] = 0x1b;
9656 spec->autocfg.line_out_pins[0] = 0x14;
9657 spec->autocfg.speaker_pins[0] = 0x15;
9658 spec->automute = 1;
9659 spec->detect_line = 1;
9660 spec->automute_lines = 1;
9661 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9662}
9663
676a9b53 9664/* toggle speaker-output according to the hp-jack state */
4f5d1706 9665static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9666{
a9fd4f3f 9667 struct alc_spec *spec = codec->spec;
676a9b53 9668
a9fd4f3f
TI
9669 spec->autocfg.hp_pins[0] = 0x14;
9670 spec->autocfg.speaker_pins[0] = 0x15;
9671 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9672 spec->automute = 1;
9673 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9674}
9675
a9111321 9676static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9677 /* HP Pin: output 0 (0x0c) */
9678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9680 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9681 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9684 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9685 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 /* eanable EAPD on medion laptop */
9687 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9688 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9689 /* enable unsolicited event */
9690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9691 { }
9692};
9693
4f5d1706 9694static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9695{
a9fd4f3f 9696 struct alc_spec *spec = codec->spec;
5795b9e6 9697
a9fd4f3f
TI
9698 spec->autocfg.hp_pins[0] = 0x1b;
9699 spec->autocfg.speaker_pins[0] = 0x14;
9700 spec->autocfg.speaker_pins[1] = 0x15;
9701 spec->autocfg.speaker_pins[2] = 0x16;
9702 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9703 spec->automute = 1;
9704 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9705}
9706
4f5d1706 9707static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9708{
a9fd4f3f 9709 struct alc_spec *spec = codec->spec;
e2757d5e 9710
a9fd4f3f
TI
9711 spec->autocfg.hp_pins[0] = 0x1b;
9712 spec->autocfg.speaker_pins[0] = 0x14;
9713 spec->autocfg.speaker_pins[1] = 0x15;
9714 spec->autocfg.speaker_pins[2] = 0x16;
9715 spec->autocfg.speaker_pins[3] = 0x17;
9716 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9717 spec->automute = 1;
9718 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9719}
9720
4f5d1706 9721static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9722{
9723 struct alc_spec *spec = codec->spec;
9724
9725 spec->autocfg.hp_pins[0] = 0x15;
9726 spec->autocfg.speaker_pins[0] = 0x14;
9727 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9730}
9731
a9111321 9732static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9734 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9735 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9736 /* enable unsolicited event */
9737 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9738 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9739 { } /* end */
9740};
9741
4f5d1706 9742static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9743{
a9fd4f3f 9744 struct alc_spec *spec = codec->spec;
e2757d5e 9745
a9fd4f3f
TI
9746 spec->autocfg.hp_pins[0] = 0x1b;
9747 spec->autocfg.speaker_pins[0] = 0x14;
9748 spec->autocfg.speaker_pins[1] = 0x15;
9749 spec->autocfg.speaker_pins[2] = 0x16;
21268961
TI
9750 spec->ext_mic_pin = 0x18;
9751 spec->int_mic_pin = 0x19;
4f5d1706 9752 spec->auto_mic = 1;
d922b51d
TI
9753 spec->automute = 1;
9754 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9755}
9756
a9111321 9757static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9761 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9763 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9764 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9765 /* enable unsolicited event */
9766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9767 { } /* end */
9768};
9769
e2757d5e
KY
9770static void alc883_eee1601_inithook(struct hda_codec *codec)
9771{
a9fd4f3f
TI
9772 struct alc_spec *spec = codec->spec;
9773
9774 spec->autocfg.hp_pins[0] = 0x14;
9775 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9776 alc_hp_automute(codec);
e2757d5e
KY
9777}
9778
a9111321 9779static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9780 /* Init rear pin (used as headphone output) */
9781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9782 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9783 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9784 /* Init line pin (used as output in 4ch and 6ch mode) */
9785 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9786 /* Init line 2 pin (used as headphone out by default) */
9787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9789 { } /* end */
9790};
9791
9792/* Mute speakers according to the headphone jack state */
9793static void alc889A_mb31_automute(struct hda_codec *codec)
9794{
9795 unsigned int present;
9796
9797 /* Mute only in 2ch or 4ch mode */
9798 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9799 == 0x00) {
864f92be 9800 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9801 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9802 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9803 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9804 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9805 }
9806}
9807
9808static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9809{
9810 if ((res >> 26) == ALC880_HP_EVENT)
9811 alc889A_mb31_automute(codec);
9812}
9813
4953550a 9814
cb53c626 9815#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9816#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9817#endif
9818
4c6d72d1 9819static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9820 ALC1200_DIGOUT_NID, 0,
9821};
9822
4c6d72d1 9823static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9824 ALC883_DIGOUT_NID, 0,
9825};
9c7f852e
TI
9826
9827/*
9828 * configuration and preset
9829 */
ea734963 9830static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9831 [ALC882_3ST_DIG] = "3stack-dig",
9832 [ALC882_6ST_DIG] = "6stack-dig",
9833 [ALC882_ARIMA] = "arima",
9834 [ALC882_W2JC] = "w2jc",
9835 [ALC882_TARGA] = "targa",
9836 [ALC882_ASUS_A7J] = "asus-a7j",
9837 [ALC882_ASUS_A7M] = "asus-a7m",
9838 [ALC885_MACPRO] = "macpro",
9839 [ALC885_MB5] = "mb5",
e458b1fa 9840 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9841 [ALC885_MBA21] = "mba21",
4953550a
TI
9842 [ALC885_MBP3] = "mbp3",
9843 [ALC885_IMAC24] = "imac24",
4b7e1803 9844 [ALC885_IMAC91] = "imac91",
4953550a 9845 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9846 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9847 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9848 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9849 [ALC883_TARGA_DIG] = "targa-dig",
9850 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9851 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9852 [ALC883_ACER] = "acer",
2880a867 9853 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9854 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9855 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9856 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9857 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9858 [ALC883_MEDION] = "medion",
7ad7b218 9859 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9860 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9861 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9862 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9863 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9864 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9865 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9866 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9867 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9868 [ALC883_MITAC] = "mitac",
a65cc60f 9869 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9870 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9871 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9872 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9873 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9874 [ALC889A_INTEL] = "intel-alc889a",
9875 [ALC889_INTEL] = "intel-x58",
3ab90935 9876 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9877 [ALC889A_MB31] = "mb31",
3e1647c5 9878 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9879 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9880};
9881
a9111321 9882static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
9883 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9884
ac3e3741 9885 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9886 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9887 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9888 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9889 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9890 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9891 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9892 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9893 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9894 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9895 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9896 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9897 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9898 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9899 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9900 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9901 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9902 ALC888_ACER_ASPIRE_6530G),
cc374c47 9903 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9904 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9905 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9906 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9907 /* default Acer -- disabled as it causes more problems.
9908 * model=auto should work fine now
9909 */
9910 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9911
5795b9e6 9912 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9913
25985edc 9914 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
9915 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9916 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9917 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9918 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9919 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9920
9921 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9922 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9923 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9924 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9925 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9926 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9927 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9928 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9929 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9930 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9931 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9932
9933 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9934 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9935 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9936 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9937 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9938 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9939 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9940 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 9941 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 9942
6f3bf657 9943 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9944 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9945 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9946 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9947 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9948 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9949 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9950 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9951 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9952 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9953 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9954 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9955 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9956 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9957 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9958 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9959 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9960 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9961 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9962 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9963 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9964 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9965 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9966 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9967 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9968 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9969 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9970 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9971 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9972 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9973 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9974
ac3e3741 9975 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9976 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9977 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9978 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9979 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9980 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9981 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9982 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9983 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9984 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9985 ALC883_FUJITSU_PI2515),
bfb53037 9986 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9987 ALC888_FUJITSU_XA3530),
272a527c 9988 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9989 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9990 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9991 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9992 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9993 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9994 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9995 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9996
17bba1b7
J
9997 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9998 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9999 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10000 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10001 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10002 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10003 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10004
4953550a 10005 {}
f3cd3f5d
WF
10006};
10007
4953550a 10008/* codec SSID table for Intel Mac */
a9111321 10009static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10010 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10011 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10012 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10013 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10014 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10015 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10016 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10017 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10018 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10019 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10020 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10021 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10022 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10023 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10024 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10025 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10026 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10027 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10028 * so apparently no perfect solution yet
4953550a
TI
10029 */
10030 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10031 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10032 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10033 {} /* terminator */
b25c9da1
WF
10034};
10035
a9111321 10036static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10037 [ALC882_3ST_DIG] = {
10038 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10039 .init_verbs = { alc882_base_init_verbs,
10040 alc882_adc1_init_verbs },
4953550a
TI
10041 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10042 .dac_nids = alc882_dac_nids,
10043 .dig_out_nid = ALC882_DIGOUT_NID,
10044 .dig_in_nid = ALC882_DIGIN_NID,
10045 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10046 .channel_mode = alc882_ch_modes,
10047 .need_dac_fix = 1,
10048 .input_mux = &alc882_capture_source,
10049 },
10050 [ALC882_6ST_DIG] = {
10051 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10052 .init_verbs = { alc882_base_init_verbs,
10053 alc882_adc1_init_verbs },
4953550a
TI
10054 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10055 .dac_nids = alc882_dac_nids,
10056 .dig_out_nid = ALC882_DIGOUT_NID,
10057 .dig_in_nid = ALC882_DIGIN_NID,
10058 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10059 .channel_mode = alc882_sixstack_modes,
10060 .input_mux = &alc882_capture_source,
10061 },
10062 [ALC882_ARIMA] = {
10063 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10064 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10065 alc882_eapd_verbs },
4953550a
TI
10066 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10067 .dac_nids = alc882_dac_nids,
10068 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10069 .channel_mode = alc882_sixstack_modes,
10070 .input_mux = &alc882_capture_source,
10071 },
10072 [ALC882_W2JC] = {
10073 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10074 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10075 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10076 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10077 .dac_nids = alc882_dac_nids,
10078 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10079 .channel_mode = alc880_threestack_modes,
10080 .need_dac_fix = 1,
10081 .input_mux = &alc882_capture_source,
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 },
76e6f5a9
RH
10084 [ALC885_MBA21] = {
10085 .mixers = { alc885_mba21_mixer },
10086 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10087 .num_dacs = 2,
10088 .dac_nids = alc882_dac_nids,
10089 .channel_mode = alc885_mba21_ch_modes,
10090 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10091 .input_mux = &alc882_capture_source,
d922b51d 10092 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10093 .setup = alc885_mba21_setup,
d922b51d 10094 .init_hook = alc_hp_automute,
76e6f5a9 10095 },
4953550a
TI
10096 [ALC885_MBP3] = {
10097 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10098 .init_verbs = { alc885_mbp3_init_verbs,
10099 alc880_gpio1_init_verbs },
be0ae923 10100 .num_dacs = 2,
4953550a 10101 .dac_nids = alc882_dac_nids,
be0ae923
TI
10102 .hp_nid = 0x04,
10103 .channel_mode = alc885_mbp_4ch_modes,
10104 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10105 .input_mux = &alc882_capture_source,
10106 .dig_out_nid = ALC882_DIGOUT_NID,
10107 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10108 .unsol_event = alc_sku_unsol_event,
4f5d1706 10109 .setup = alc885_mbp3_setup,
d922b51d 10110 .init_hook = alc_hp_automute,
4953550a
TI
10111 },
10112 [ALC885_MB5] = {
10113 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10114 .init_verbs = { alc885_mb5_init_verbs,
10115 alc880_gpio1_init_verbs },
10116 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10117 .dac_nids = alc882_dac_nids,
10118 .channel_mode = alc885_mb5_6ch_modes,
10119 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10120 .input_mux = &mb5_capture_source,
10121 .dig_out_nid = ALC882_DIGOUT_NID,
10122 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10123 .unsol_event = alc_sku_unsol_event,
9d54f08b 10124 .setup = alc885_mb5_setup,
d922b51d 10125 .init_hook = alc_hp_automute,
4953550a 10126 },
e458b1fa
LY
10127 [ALC885_MACMINI3] = {
10128 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10129 .init_verbs = { alc885_macmini3_init_verbs,
10130 alc880_gpio1_init_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .channel_mode = alc885_macmini3_6ch_modes,
10134 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10135 .input_mux = &macmini3_capture_source,
10136 .dig_out_nid = ALC882_DIGOUT_NID,
10137 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10138 .unsol_event = alc_sku_unsol_event,
9d54f08b 10139 .setup = alc885_macmini3_setup,
d922b51d 10140 .init_hook = alc_hp_automute,
e458b1fa 10141 },
4953550a
TI
10142 [ALC885_MACPRO] = {
10143 .mixers = { alc882_macpro_mixer },
10144 .init_verbs = { alc882_macpro_init_verbs },
10145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10146 .dac_nids = alc882_dac_nids,
10147 .dig_out_nid = ALC882_DIGOUT_NID,
10148 .dig_in_nid = ALC882_DIGIN_NID,
10149 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10150 .channel_mode = alc882_ch_modes,
10151 .input_mux = &alc882_capture_source,
10152 .init_hook = alc885_macpro_init_hook,
10153 },
10154 [ALC885_IMAC24] = {
10155 .mixers = { alc885_imac24_mixer },
10156 .init_verbs = { alc885_imac24_init_verbs },
10157 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10158 .dac_nids = alc882_dac_nids,
10159 .dig_out_nid = ALC882_DIGOUT_NID,
10160 .dig_in_nid = ALC882_DIGIN_NID,
10161 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10162 .channel_mode = alc882_ch_modes,
10163 .input_mux = &alc882_capture_source,
d922b51d 10164 .unsol_event = alc_sku_unsol_event,
4f5d1706 10165 .setup = alc885_imac24_setup,
4953550a
TI
10166 .init_hook = alc885_imac24_init_hook,
10167 },
4b7e1803 10168 [ALC885_IMAC91] = {
b7cccc52 10169 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10170 .init_verbs = { alc885_imac91_init_verbs,
10171 alc880_gpio1_init_verbs },
10172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10173 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10174 .channel_mode = alc885_mba21_ch_modes,
10175 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10176 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10177 .dig_out_nid = ALC882_DIGOUT_NID,
10178 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10179 .unsol_event = alc_sku_unsol_event,
9d54f08b 10180 .setup = alc885_imac91_setup,
d922b51d 10181 .init_hook = alc_hp_automute,
4b7e1803 10182 },
4953550a
TI
10183 [ALC882_TARGA] = {
10184 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10185 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10186 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10187 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10188 .dac_nids = alc882_dac_nids,
10189 .dig_out_nid = ALC882_DIGOUT_NID,
10190 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10191 .adc_nids = alc882_adc_nids,
10192 .capsrc_nids = alc882_capsrc_nids,
10193 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10194 .channel_mode = alc882_3ST_6ch_modes,
10195 .need_dac_fix = 1,
10196 .input_mux = &alc882_capture_source,
d922b51d 10197 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10198 .setup = alc882_targa_setup,
10199 .init_hook = alc882_targa_automute,
4953550a
TI
10200 },
10201 [ALC882_ASUS_A7J] = {
10202 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10203 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10204 alc882_asus_a7j_verbs},
4953550a
TI
10205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10206 .dac_nids = alc882_dac_nids,
10207 .dig_out_nid = ALC882_DIGOUT_NID,
10208 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10209 .adc_nids = alc882_adc_nids,
10210 .capsrc_nids = alc882_capsrc_nids,
10211 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10212 .channel_mode = alc882_3ST_6ch_modes,
10213 .need_dac_fix = 1,
10214 .input_mux = &alc882_capture_source,
10215 },
10216 [ALC882_ASUS_A7M] = {
10217 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10218 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10219 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10220 alc882_asus_a7m_verbs },
10221 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10222 .dac_nids = alc882_dac_nids,
10223 .dig_out_nid = ALC882_DIGOUT_NID,
10224 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10225 .channel_mode = alc880_threestack_modes,
10226 .need_dac_fix = 1,
10227 .input_mux = &alc882_capture_source,
10228 },
9c7f852e
TI
10229 [ALC883_3ST_2ch_DIG] = {
10230 .mixers = { alc883_3ST_2ch_mixer },
10231 .init_verbs = { alc883_init_verbs },
10232 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10233 .dac_nids = alc883_dac_nids,
10234 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10235 .dig_in_nid = ALC883_DIGIN_NID,
10236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10237 .channel_mode = alc883_3ST_2ch_modes,
10238 .input_mux = &alc883_capture_source,
10239 },
10240 [ALC883_3ST_6ch_DIG] = {
10241 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10242 .init_verbs = { alc883_init_verbs },
10243 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10244 .dac_nids = alc883_dac_nids,
10245 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10246 .dig_in_nid = ALC883_DIGIN_NID,
10247 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10248 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10249 .need_dac_fix = 1,
9c7f852e 10250 .input_mux = &alc883_capture_source,
f12ab1e0 10251 },
9c7f852e
TI
10252 [ALC883_3ST_6ch] = {
10253 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10254 .init_verbs = { alc883_init_verbs },
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10258 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10259 .need_dac_fix = 1,
9c7f852e 10260 .input_mux = &alc883_capture_source,
f12ab1e0 10261 },
17bba1b7
J
10262 [ALC883_3ST_6ch_INTEL] = {
10263 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10264 .init_verbs = { alc883_init_verbs },
10265 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10266 .dac_nids = alc883_dac_nids,
10267 .dig_out_nid = ALC883_DIGOUT_NID,
10268 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10269 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10270 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10271 .channel_mode = alc883_3ST_6ch_intel_modes,
10272 .need_dac_fix = 1,
10273 .input_mux = &alc883_3stack_6ch_intel,
10274 },
87a8c370
JK
10275 [ALC889A_INTEL] = {
10276 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10277 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10278 alc_hp15_unsol_verbs },
87a8c370
JK
10279 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10280 .dac_nids = alc883_dac_nids,
10281 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10282 .adc_nids = alc889_adc_nids,
10283 .dig_out_nid = ALC883_DIGOUT_NID,
10284 .dig_in_nid = ALC883_DIGIN_NID,
10285 .slave_dig_outs = alc883_slave_dig_outs,
10286 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10287 .channel_mode = alc889_8ch_intel_modes,
10288 .capsrc_nids = alc889_capsrc_nids,
10289 .input_mux = &alc889_capture_source,
4f5d1706 10290 .setup = alc889_automute_setup,
d922b51d
TI
10291 .init_hook = alc_hp_automute,
10292 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10293 .need_dac_fix = 1,
10294 },
10295 [ALC889_INTEL] = {
10296 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10297 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10298 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10299 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10300 .dac_nids = alc883_dac_nids,
10301 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10302 .adc_nids = alc889_adc_nids,
10303 .dig_out_nid = ALC883_DIGOUT_NID,
10304 .dig_in_nid = ALC883_DIGIN_NID,
10305 .slave_dig_outs = alc883_slave_dig_outs,
10306 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10307 .channel_mode = alc889_8ch_intel_modes,
10308 .capsrc_nids = alc889_capsrc_nids,
10309 .input_mux = &alc889_capture_source,
4f5d1706 10310 .setup = alc889_automute_setup,
6732bd0d 10311 .init_hook = alc889_intel_init_hook,
d922b51d 10312 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10313 .need_dac_fix = 1,
10314 },
9c7f852e
TI
10315 [ALC883_6ST_DIG] = {
10316 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10317 .init_verbs = { alc883_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10319 .dac_nids = alc883_dac_nids,
10320 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10321 .dig_in_nid = ALC883_DIGIN_NID,
10322 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10323 .channel_mode = alc883_sixstack_modes,
10324 .input_mux = &alc883_capture_source,
10325 },
ccc656ce 10326 [ALC883_TARGA_DIG] = {
c259249f 10327 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10328 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10329 alc883_targa_verbs},
ccc656ce
KY
10330 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10331 .dac_nids = alc883_dac_nids,
10332 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10333 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10334 .channel_mode = alc883_3ST_6ch_modes,
10335 .need_dac_fix = 1,
10336 .input_mux = &alc883_capture_source,
c259249f 10337 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10338 .setup = alc882_targa_setup,
10339 .init_hook = alc882_targa_automute,
ccc656ce
KY
10340 },
10341 [ALC883_TARGA_2ch_DIG] = {
c259249f 10342 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10343 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10344 alc883_targa_verbs},
ccc656ce
KY
10345 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10346 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10347 .adc_nids = alc883_adc_nids_alt,
10348 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10349 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10350 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10352 .channel_mode = alc883_3ST_2ch_modes,
10353 .input_mux = &alc883_capture_source,
c259249f 10354 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10355 .setup = alc882_targa_setup,
10356 .init_hook = alc882_targa_automute,
ccc656ce 10357 },
64a8be74 10358 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10359 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10360 alc883_chmode_mixer },
64a8be74 10361 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10362 alc883_targa_verbs },
64a8be74
DH
10363 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10364 .dac_nids = alc883_dac_nids,
10365 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10366 .adc_nids = alc883_adc_nids_rev,
10367 .capsrc_nids = alc883_capsrc_nids_rev,
10368 .dig_out_nid = ALC883_DIGOUT_NID,
10369 .dig_in_nid = ALC883_DIGIN_NID,
10370 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10371 .channel_mode = alc883_4ST_8ch_modes,
10372 .need_dac_fix = 1,
10373 .input_mux = &alc883_capture_source,
c259249f 10374 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10375 .setup = alc882_targa_setup,
10376 .init_hook = alc882_targa_automute,
64a8be74 10377 },
bab282b9 10378 [ALC883_ACER] = {
676a9b53 10379 .mixers = { alc883_base_mixer },
bab282b9
VA
10380 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10381 * and the headphone jack. Turn this on and rely on the
10382 * standard mute methods whenever the user wants to turn
10383 * these outputs off.
10384 */
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
bab282b9
VA
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10389 .channel_mode = alc883_3ST_2ch_modes,
10390 .input_mux = &alc883_capture_source,
10391 },
2880a867 10392 [ALC883_ACER_ASPIRE] = {
676a9b53 10393 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10394 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10395 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10396 .dac_nids = alc883_dac_nids,
10397 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10399 .channel_mode = alc883_3ST_2ch_modes,
10400 .input_mux = &alc883_capture_source,
d922b51d 10401 .unsol_event = alc_sku_unsol_event,
4f5d1706 10402 .setup = alc883_acer_aspire_setup,
d922b51d 10403 .init_hook = alc_hp_automute,
d1a991a6 10404 },
5b2d1eca 10405 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10406 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10407 alc883_chmode_mixer },
10408 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10409 alc888_acer_aspire_4930g_verbs },
10410 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10411 .dac_nids = alc883_dac_nids,
10412 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10413 .adc_nids = alc883_adc_nids_rev,
10414 .capsrc_nids = alc883_capsrc_nids_rev,
10415 .dig_out_nid = ALC883_DIGOUT_NID,
10416 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10417 .channel_mode = alc883_3ST_6ch_modes,
10418 .need_dac_fix = 1,
973b8cb0 10419 .const_channel_count = 6,
5b2d1eca 10420 .num_mux_defs =
ef8ef5fb
VP
10421 ARRAY_SIZE(alc888_2_capture_sources),
10422 .input_mux = alc888_2_capture_sources,
d922b51d 10423 .unsol_event = alc_sku_unsol_event,
4f5d1706 10424 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10425 .init_hook = alc_hp_automute,
d2fd4b09
TV
10426 },
10427 [ALC888_ACER_ASPIRE_6530G] = {
10428 .mixers = { alc888_acer_aspire_6530_mixer },
10429 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10430 alc888_acer_aspire_6530g_verbs },
10431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10432 .dac_nids = alc883_dac_nids,
10433 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10434 .adc_nids = alc883_adc_nids_rev,
10435 .capsrc_nids = alc883_capsrc_nids_rev,
10436 .dig_out_nid = ALC883_DIGOUT_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .num_mux_defs =
10440 ARRAY_SIZE(alc888_2_capture_sources),
10441 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10442 .unsol_event = alc_sku_unsol_event,
4f5d1706 10443 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10444 .init_hook = alc_hp_automute,
5b2d1eca 10445 },
3b315d70 10446 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10447 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10448 alc883_chmode_mixer },
10449 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10450 alc889_acer_aspire_8930g_verbs,
10451 alc889_eapd_verbs},
3b315d70
HM
10452 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10453 .dac_nids = alc883_dac_nids,
018df418
HM
10454 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10455 .adc_nids = alc889_adc_nids,
10456 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10457 .dig_out_nid = ALC883_DIGOUT_NID,
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
10460 .need_dac_fix = 1,
10461 .const_channel_count = 6,
10462 .num_mux_defs =
018df418
HM
10463 ARRAY_SIZE(alc889_capture_sources),
10464 .input_mux = alc889_capture_sources,
d922b51d 10465 .unsol_event = alc_sku_unsol_event,
4f5d1706 10466 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10467 .init_hook = alc_hp_automute,
f5de24b0 10468#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10469 .power_hook = alc_power_eapd,
f5de24b0 10470#endif
3b315d70 10471 },
fc86f954
DK
10472 [ALC888_ACER_ASPIRE_7730G] = {
10473 .mixers = { alc883_3ST_6ch_mixer,
10474 alc883_chmode_mixer },
10475 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10476 alc888_acer_aspire_7730G_verbs },
10477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10478 .dac_nids = alc883_dac_nids,
10479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10480 .adc_nids = alc883_adc_nids_rev,
10481 .capsrc_nids = alc883_capsrc_nids_rev,
10482 .dig_out_nid = ALC883_DIGOUT_NID,
10483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10484 .channel_mode = alc883_3ST_6ch_modes,
10485 .need_dac_fix = 1,
10486 .const_channel_count = 6,
10487 .input_mux = &alc883_capture_source,
d922b51d 10488 .unsol_event = alc_sku_unsol_event,
d9477207 10489 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10490 .init_hook = alc_hp_automute,
fc86f954 10491 },
c07584c8
TD
10492 [ALC883_MEDION] = {
10493 .mixers = { alc883_fivestack_mixer,
10494 alc883_chmode_mixer },
10495 .init_verbs = { alc883_init_verbs,
b373bdeb 10496 alc883_medion_eapd_verbs },
c07584c8
TD
10497 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10498 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10499 .adc_nids = alc883_adc_nids_alt,
10500 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10501 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10502 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10503 .channel_mode = alc883_sixstack_modes,
10504 .input_mux = &alc883_capture_source,
b373bdeb 10505 },
7ad7b218
MC
10506 [ALC883_MEDION_WIM2160] = {
10507 .mixers = { alc883_medion_wim2160_mixer },
10508 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10509 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10510 .dac_nids = alc883_dac_nids,
10511 .dig_out_nid = ALC883_DIGOUT_NID,
10512 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10513 .adc_nids = alc883_adc_nids,
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10515 .channel_mode = alc883_3ST_2ch_modes,
10516 .input_mux = &alc883_capture_source,
d922b51d 10517 .unsol_event = alc_sku_unsol_event,
7ad7b218 10518 .setup = alc883_medion_wim2160_setup,
d922b51d 10519 .init_hook = alc_hp_automute,
7ad7b218 10520 },
b373bdeb 10521 [ALC883_LAPTOP_EAPD] = {
676a9b53 10522 .mixers = { alc883_base_mixer },
b373bdeb
AN
10523 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10526 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10527 .channel_mode = alc883_3ST_2ch_modes,
10528 .input_mux = &alc883_capture_source,
10529 },
a65cc60f 10530 [ALC883_CLEVO_M540R] = {
10531 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10532 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10533 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10534 .dac_nids = alc883_dac_nids,
10535 .dig_out_nid = ALC883_DIGOUT_NID,
10536 .dig_in_nid = ALC883_DIGIN_NID,
10537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10538 .channel_mode = alc883_3ST_6ch_clevo_modes,
10539 .need_dac_fix = 1,
10540 .input_mux = &alc883_capture_source,
10541 /* This machine has the hardware HP auto-muting, thus
10542 * we need no software mute via unsol event
10543 */
10544 },
0c4cc443
HRK
10545 [ALC883_CLEVO_M720] = {
10546 .mixers = { alc883_clevo_m720_mixer },
10547 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10549 .dac_nids = alc883_dac_nids,
10550 .dig_out_nid = ALC883_DIGOUT_NID,
10551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10552 .channel_mode = alc883_3ST_2ch_modes,
10553 .input_mux = &alc883_capture_source,
0c4cc443 10554 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10555 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10556 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10557 },
bc9f98a9
KY
10558 [ALC883_LENOVO_101E_2ch] = {
10559 .mixers = { alc883_lenovo_101e_2ch_mixer},
10560 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10561 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10562 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10563 .adc_nids = alc883_adc_nids_alt,
10564 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10565 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10566 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567 .channel_mode = alc883_3ST_2ch_modes,
10568 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10569 .setup = alc883_lenovo_101e_setup,
10570 .unsol_event = alc_sku_unsol_event,
10571 .init_hook = alc_inithook,
bc9f98a9 10572 },
272a527c
KY
10573 [ALC883_LENOVO_NB0763] = {
10574 .mixers = { alc883_lenovo_nb0763_mixer },
10575 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10577 .dac_nids = alc883_dac_nids,
272a527c
KY
10578 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10579 .channel_mode = alc883_3ST_2ch_modes,
10580 .need_dac_fix = 1,
10581 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10582 .unsol_event = alc_sku_unsol_event,
dc427170 10583 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10584 .init_hook = alc_hp_automute,
272a527c
KY
10585 },
10586 [ALC888_LENOVO_MS7195_DIG] = {
10587 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10588 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10590 .dac_nids = alc883_dac_nids,
10591 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10592 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10593 .channel_mode = alc883_3ST_6ch_modes,
10594 .need_dac_fix = 1,
10595 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10596 .unsol_event = alc_sku_unsol_event,
10597 .setup = alc888_lenovo_ms7195_setup,
10598 .init_hook = alc_inithook,
189609ae
KY
10599 },
10600 [ALC883_HAIER_W66] = {
c259249f 10601 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10602 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10603 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10604 .dac_nids = alc883_dac_nids,
10605 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10606 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10607 .channel_mode = alc883_3ST_2ch_modes,
10608 .input_mux = &alc883_capture_source,
d922b51d 10609 .unsol_event = alc_sku_unsol_event,
4f5d1706 10610 .setup = alc883_haier_w66_setup,
d922b51d 10611 .init_hook = alc_hp_automute,
eea6419e 10612 },
4723c022 10613 [ALC888_3ST_HP] = {
eea6419e 10614 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10615 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
4723c022
CM
10618 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10619 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10620 .need_dac_fix = 1,
10621 .input_mux = &alc883_capture_source,
d922b51d 10622 .unsol_event = alc_sku_unsol_event,
4f5d1706 10623 .setup = alc888_3st_hp_setup,
d922b51d 10624 .init_hook = alc_hp_automute,
8341de60 10625 },
5795b9e6 10626 [ALC888_6ST_DELL] = {
f24dbdc6 10627 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10628 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10632 .dig_in_nid = ALC883_DIGIN_NID,
10633 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10634 .channel_mode = alc883_sixstack_modes,
10635 .input_mux = &alc883_capture_source,
d922b51d 10636 .unsol_event = alc_sku_unsol_event,
4f5d1706 10637 .setup = alc888_6st_dell_setup,
d922b51d 10638 .init_hook = alc_hp_automute,
5795b9e6 10639 },
a8848bd6
AS
10640 [ALC883_MITAC] = {
10641 .mixers = { alc883_mitac_mixer },
10642 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10644 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10646 .channel_mode = alc883_3ST_2ch_modes,
10647 .input_mux = &alc883_capture_source,
d922b51d 10648 .unsol_event = alc_sku_unsol_event,
4f5d1706 10649 .setup = alc883_mitac_setup,
d922b51d 10650 .init_hook = alc_hp_automute,
a8848bd6 10651 },
fb97dc67
J
10652 [ALC883_FUJITSU_PI2515] = {
10653 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10654 .init_verbs = { alc883_init_verbs,
10655 alc883_2ch_fujitsu_pi2515_verbs},
10656 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10657 .dac_nids = alc883_dac_nids,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10660 .channel_mode = alc883_3ST_2ch_modes,
10661 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10662 .unsol_event = alc_sku_unsol_event,
4f5d1706 10663 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10664 .init_hook = alc_hp_automute,
fb97dc67 10665 },
ef8ef5fb
VP
10666 [ALC888_FUJITSU_XA3530] = {
10667 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10668 .init_verbs = { alc883_init_verbs,
10669 alc888_fujitsu_xa3530_verbs },
10670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10671 .dac_nids = alc883_dac_nids,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10673 .adc_nids = alc883_adc_nids_rev,
10674 .capsrc_nids = alc883_capsrc_nids_rev,
10675 .dig_out_nid = ALC883_DIGOUT_NID,
10676 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10677 .channel_mode = alc888_4ST_8ch_intel_modes,
10678 .num_mux_defs =
10679 ARRAY_SIZE(alc888_2_capture_sources),
10680 .input_mux = alc888_2_capture_sources,
d922b51d 10681 .unsol_event = alc_sku_unsol_event,
4f5d1706 10682 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10683 .init_hook = alc_hp_automute,
ef8ef5fb 10684 },
e2757d5e
KY
10685 [ALC888_LENOVO_SKY] = {
10686 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10687 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10688 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10689 .dac_nids = alc883_dac_nids,
10690 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10691 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10692 .channel_mode = alc883_sixstack_modes,
10693 .need_dac_fix = 1,
10694 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10695 .unsol_event = alc_sku_unsol_event,
4f5d1706 10696 .setup = alc888_lenovo_sky_setup,
d922b51d 10697 .init_hook = alc_hp_automute,
e2757d5e
KY
10698 },
10699 [ALC888_ASUS_M90V] = {
10700 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10701 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10703 .dac_nids = alc883_dac_nids,
10704 .dig_out_nid = ALC883_DIGOUT_NID,
10705 .dig_in_nid = ALC883_DIGIN_NID,
10706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10707 .channel_mode = alc883_3ST_6ch_modes,
10708 .need_dac_fix = 1,
10709 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10710 .unsol_event = alc_sku_unsol_event,
10711 .setup = alc883_mode2_setup,
10712 .init_hook = alc_inithook,
e2757d5e
KY
10713 },
10714 [ALC888_ASUS_EEE1601] = {
10715 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10716 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10717 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10719 .dac_nids = alc883_dac_nids,
10720 .dig_out_nid = ALC883_DIGOUT_NID,
10721 .dig_in_nid = ALC883_DIGIN_NID,
10722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10723 .channel_mode = alc883_3ST_2ch_modes,
10724 .need_dac_fix = 1,
10725 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10726 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10727 .init_hook = alc883_eee1601_inithook,
10728 },
3ab90935
WF
10729 [ALC1200_ASUS_P5Q] = {
10730 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10731 .init_verbs = { alc883_init_verbs },
10732 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10733 .dac_nids = alc883_dac_nids,
10734 .dig_out_nid = ALC1200_DIGOUT_NID,
10735 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10736 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10737 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10738 .channel_mode = alc883_sixstack_modes,
10739 .input_mux = &alc883_capture_source,
10740 },
eb4c41d3
TS
10741 [ALC889A_MB31] = {
10742 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10743 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10744 alc880_gpio1_init_verbs },
10745 .adc_nids = alc883_adc_nids,
10746 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10747 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10748 .dac_nids = alc883_dac_nids,
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .channel_mode = alc889A_mb31_6ch_modes,
10751 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10752 .input_mux = &alc889A_mb31_capture_source,
10753 .dig_out_nid = ALC883_DIGOUT_NID,
10754 .unsol_event = alc889A_mb31_unsol_event,
10755 .init_hook = alc889A_mb31_automute,
10756 },
3e1647c5
GG
10757 [ALC883_SONY_VAIO_TT] = {
10758 .mixers = { alc883_vaiott_mixer },
10759 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10760 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10761 .dac_nids = alc883_dac_nids,
10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10763 .channel_mode = alc883_3ST_2ch_modes,
10764 .input_mux = &alc883_capture_source,
d922b51d 10765 .unsol_event = alc_sku_unsol_event,
4f5d1706 10766 .setup = alc883_vaiott_setup,
d922b51d 10767 .init_hook = alc_hp_automute,
3e1647c5 10768 },
9c7f852e
TI
10769};
10770
10771
4953550a
TI
10772/*
10773 * Pin config fixes
10774 */
10775enum {
954a29c8 10776 PINFIX_ABIT_AW9D_MAX,
32eea388 10777 PINFIX_LENOVO_Y530,
954a29c8 10778 PINFIX_PB_M5210,
c3d226ab 10779 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10780};
10781
f8f25ba3
TI
10782static const struct alc_fixup alc882_fixups[] = {
10783 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10784 .type = ALC_FIXUP_PINS,
10785 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10786 { 0x15, 0x01080104 }, /* side */
10787 { 0x16, 0x01011012 }, /* rear */
10788 { 0x17, 0x01016011 }, /* clfe */
10789 { }
10790 }
f8f25ba3 10791 },
32eea388
DH
10792 [PINFIX_LENOVO_Y530] = {
10793 .type = ALC_FIXUP_PINS,
10794 .v.pins = (const struct alc_pincfg[]) {
10795 { 0x15, 0x99130112 }, /* rear int speakers */
10796 { 0x16, 0x99130111 }, /* subwoofer */
10797 { }
10798 }
10799 },
954a29c8 10800 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10801 .type = ALC_FIXUP_VERBS,
10802 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10803 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10804 {}
10805 }
954a29c8 10806 },
c3d226ab 10807 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10808 .type = ALC_FIXUP_SKU,
10809 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10810 },
4953550a
TI
10811};
10812
a9111321 10813static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10814 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10815 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10816 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10817 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10818 {}
10819};
10820
9c7f852e
TI
10821/*
10822 * BIOS auto configuration
10823 */
21268961 10824static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
4953550a
TI
10825{
10826 struct alc_spec *spec = codec->spec;
21268961 10827 hda_nid_t nid;
f970de25 10828
21268961
TI
10829 nid = spec->adc_nids[adc_idx];
10830 /* mute ADC */
10831 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) {
10832 snd_hda_codec_write(codec, nid, 0,
10696aa0
TI
10833 AC_VERB_SET_AMP_GAIN_MUTE,
10834 AMP_IN_MUTE(0));
21268961
TI
10835 return;
10836 }
10837 if (!spec->capsrc_nids)
10838 return;
10839 nid = spec->capsrc_nids[adc_idx];
10840 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
10841 snd_hda_codec_write(codec, nid, 0,
4f574b7b
TI
10842 AC_VERB_SET_AMP_GAIN_MUTE,
10843 AMP_OUT_MUTE);
21268961 10844}
10696aa0 10845
21268961
TI
10846static void alc_auto_init_input_src(struct hda_codec *codec)
10847{
10848 struct alc_spec *spec = codec->spec;
10849 int c, nums;
10850
10851 for (c = 0; c < spec->num_adc_nids; c++)
10852 alc_auto_init_adc(codec, c);
10853 if (spec->dyn_adc_switch)
10854 nums = 1;
10855 else
10856 nums = spec->num_adc_nids;
10857 for (c = 0; c < nums; c++)
10858 alc_mux_select(codec, 0, spec->cur_mux[c], true);
9c7f852e
TI
10859}
10860
4953550a
TI
10861/* add mic boosts if needed */
10862static int alc_auto_add_mic_boost(struct hda_codec *codec)
10863{
10864 struct alc_spec *spec = codec->spec;
66ceeb6b 10865 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10866 int i, err;
53e8c323 10867 int type_idx = 0;
4953550a 10868 hda_nid_t nid;
5322bf27 10869 const char *prev_label = NULL;
4953550a 10870
66ceeb6b 10871 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10872 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10873 break;
10874 nid = cfg->inputs[i].pin;
10875 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10876 const char *label;
10877 char boost_label[32];
10878
10879 label = hda_get_autocfg_input_label(codec, cfg, i);
10880 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10881 type_idx++;
10882 else
10883 type_idx = 0;
5322bf27
DH
10884 prev_label = label;
10885
10886 snprintf(boost_label, sizeof(boost_label),
10887 "%s Boost Volume", label);
10888 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10889 boost_label, type_idx,
4953550a 10890 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10891 if (err < 0)
10892 return err;
10893 }
4953550a
TI
10894 }
10895 return 0;
10896}
f511b01c 10897
9c7f852e 10898/* almost identical with ALC880 parser... */
4953550a 10899static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10900{
10901 struct alc_spec *spec = codec->spec;
4c6d72d1 10902 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10903 int err;
9c7f852e 10904
05f5f477
TI
10905 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10906 alc882_ignore);
9c7f852e
TI
10907 if (err < 0)
10908 return err;
05f5f477
TI
10909 if (!spec->autocfg.line_outs)
10910 return 0; /* can't find valid BIOS pin config */
776e184e 10911
343a04be 10912 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
10913 if (err < 0)
10914 return err;
343a04be 10915 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
05f5f477
TI
10916 if (err < 0)
10917 return err;
343a04be 10918 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
489008cd
TI
10919 if (err < 0)
10920 return err;
343a04be 10921 err = alc_auto_create_hp_out(codec);
05f5f477
TI
10922 if (err < 0)
10923 return err;
343a04be 10924 err = alc_auto_create_speaker_out(codec);
05f5f477
TI
10925 if (err < 0)
10926 return err;
b7821709 10927 err = alc_auto_create_input_ctls(codec);
776e184e
TI
10928 if (err < 0)
10929 return err;
10930
05f5f477
TI
10931 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10932
757899ac 10933 alc_auto_parse_digital(codec);
05f5f477
TI
10934
10935 if (spec->kctls.list)
10936 add_mixer(spec, spec->kctls.list);
10937
05f5f477
TI
10938 err = alc_auto_add_mic_boost(codec);
10939 if (err < 0)
10940 return err;
61b9b9b1 10941
21268961
TI
10942 alc_remove_invalid_adc_nids(codec);
10943
10944 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10945 alc_auto_check_switches(codec);
10946
776e184e 10947 return 1; /* config found */
9c7f852e
TI
10948}
10949
10950/* additional initialization for auto-configuration model */
4953550a 10951static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10952{
f6c7e546 10953 struct alc_spec *spec = codec->spec;
343a04be
TI
10954 alc_auto_init_multi_out(codec);
10955 alc_auto_init_extra_out(codec);
0a7f5320 10956 alc_auto_init_analog_input(codec);
f970de25 10957 alc_auto_init_input_src(codec);
757899ac 10958 alc_auto_init_digital(codec);
f6c7e546 10959 if (spec->unsol_event)
7fb0d78f 10960 alc_inithook(codec);
9c7f852e
TI
10961}
10962
4953550a 10963static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10964{
10965 struct alc_spec *spec;
10966 int err, board_config;
10967
10968 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10969 if (spec == NULL)
10970 return -ENOMEM;
10971
10972 codec->spec = spec;
10973
1f0f4b80
TI
10974 spec->mixer_nid = 0x0b;
10975
4953550a
TI
10976 switch (codec->vendor_id) {
10977 case 0x10ec0882:
10978 case 0x10ec0885:
10979 break;
10980 default:
10981 /* ALC883 and variants */
10982 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10983 break;
10984 }
2c3bf9ab 10985
4953550a
TI
10986 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10987 alc882_models,
10988 alc882_cfg_tbl);
10989
10990 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10991 board_config = snd_hda_check_board_codec_sid_config(codec,
10992 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10993
10994 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10995 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10996 codec->chip_name);
10997 board_config = ALC882_AUTO;
9c7f852e
TI
10998 }
10999
b5bfbc67
TI
11000 if (board_config == ALC882_AUTO) {
11001 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11002 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11003 }
4953550a 11004
90622917
DH
11005 alc_auto_parse_customize_define(codec);
11006
4953550a 11007 if (board_config == ALC882_AUTO) {
9c7f852e 11008 /* automatic parse from the BIOS config */
4953550a 11009 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11010 if (err < 0) {
11011 alc_free(codec);
11012 return err;
f12ab1e0 11013 } else if (!err) {
9c7f852e
TI
11014 printk(KERN_INFO
11015 "hda_codec: Cannot set up configuration "
11016 "from BIOS. Using base mode...\n");
4953550a 11017 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11018 }
11019 }
11020
dc1eae25 11021 if (has_cdefine_beep(codec)) {
8af2591d
TI
11022 err = snd_hda_attach_beep_device(codec, 0x1);
11023 if (err < 0) {
11024 alc_free(codec);
11025 return err;
11026 }
680cd536
KK
11027 }
11028
4953550a 11029 if (board_config != ALC882_AUTO)
e9c364c0 11030 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11031
4953550a 11032 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab 11033 alc_auto_fill_adc_caps(codec);
21268961 11034 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 11035 alc_remove_invalid_adc_nids(codec);
2f893286
KY
11036 }
11037
b59bdf3b 11038 set_capture_mixer(codec);
da00c244 11039
dc1eae25 11040 if (has_cdefine_beep(codec))
da00c244 11041 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11042
b5bfbc67 11043 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11044
2134ea4f
TI
11045 spec->vmaster_nid = 0x0c;
11046
9c7f852e 11047 codec->patch_ops = alc_patch_ops;
4953550a
TI
11048 if (board_config == ALC882_AUTO)
11049 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11050
11051 alc_init_jacks(codec);
cb53c626
TI
11052#ifdef CONFIG_SND_HDA_POWER_SAVE
11053 if (!spec->loopback.amplist)
4953550a 11054 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11055#endif
9c7f852e
TI
11056
11057 return 0;
11058}
11059
4953550a 11060
9c7f852e
TI
11061/*
11062 * ALC262 support
11063 */
11064
11065#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11066#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11067
11068#define alc262_dac_nids alc260_dac_nids
11069#define alc262_adc_nids alc882_adc_nids
11070#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11071#define alc262_capsrc_nids alc882_capsrc_nids
11072#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11073
11074#define alc262_modes alc260_modes
11075#define alc262_capture_source alc882_capture_source
11076
4c6d72d1 11077static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11078 /* ADC0 */
11079 0x09
11080};
11081
4c6d72d1 11082static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11083
a9111321 11084static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11085 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11086 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11089 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11094 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11096 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11099 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11100 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11101 { } /* end */
11102};
11103
ce875f07 11104/* update HP, line and mono-out pins according to the master switch */
e9427969 11105#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11106
e9427969 11107static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11108{
11109 struct alc_spec *spec = codec->spec;
864f92be 11110
e9427969
TI
11111 spec->autocfg.hp_pins[0] = 0x1b;
11112 spec->autocfg.speaker_pins[0] = 0x16;
11113 spec->automute = 1;
11114 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11115}
11116
e9427969 11117static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11118{
11119 struct alc_spec *spec = codec->spec;
864f92be 11120
e9427969
TI
11121 spec->autocfg.hp_pins[0] = 0x15;
11122 spec->autocfg.speaker_pins[0] = 0x16;
11123 spec->automute = 1;
11124 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11125}
11126
b72519b5 11127#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11128#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11129
b72519b5
TI
11130#define ALC262_HP_MASTER_SWITCH \
11131 { \
11132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11133 .name = "Master Playback Switch", \
11134 .info = snd_ctl_boolean_mono_info, \
11135 .get = alc262_hp_master_sw_get, \
11136 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11137 }, \
11138 { \
11139 .iface = NID_MAPPING, \
11140 .name = "Master Playback Switch", \
11141 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11142 }
11143
5b0cb1d8 11144
a9111321 11145static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11146 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11147 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11148 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11150 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11151 HDA_OUTPUT),
11152 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11153 HDA_OUTPUT),
9c7f852e
TI
11154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11157 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11158 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11159 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11162 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11163 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11164 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11165 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11166 { } /* end */
11167};
11168
a9111321 11169static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11170 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11175 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11176 HDA_OUTPUT),
11177 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11178 HDA_OUTPUT),
cd7509a4
KY
11179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11180 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11181 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11186 { } /* end */
11187};
11188
a9111321 11189static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11190 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11191 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11192 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11193 { } /* end */
11194};
11195
66d2a9d6 11196/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11197static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11198{
11199 struct alc_spec *spec = codec->spec;
66d2a9d6 11200
a9fd4f3f 11201 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11202 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11203 spec->automute = 1;
11204 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11205}
11206
a9111321 11207static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11208 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11209 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11210 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11215 { } /* end */
11216};
11217
a9111321 11218static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11221
11222 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11223 { }
11224};
11225
a9111321 11226static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11227 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11233 { } /* end */
11234};
11235
a9111321 11236static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11237 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11238 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11241 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11242 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11245 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11247 {}
11248};
11249
a9111321 11250static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11251 .num_items = 1,
11252 .items = {
11253 { "Line", 0x1 },
11254 },
11255};
11256
42171c17 11257/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11258#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11259#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11260#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11261
11262#define ALC262_HIPPO_MASTER_SWITCH \
11263 { \
11264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11265 .name = "Master Playback Switch", \
11266 .info = snd_ctl_boolean_mono_info, \
11267 .get = alc262_hippo_master_sw_get, \
11268 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11269 }, \
11270 { \
11271 .iface = NID_MAPPING, \
11272 .name = "Master Playback Switch", \
11273 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11274 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11275 }
42171c17 11276
a9111321 11277static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11278 ALC262_HIPPO_MASTER_SWITCH,
11279 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11289 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11291 { } /* end */
11292};
11293
a9111321 11294static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11295 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11296 ALC262_HIPPO_MASTER_SWITCH,
11297 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11298 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11303 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11304 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11305 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11306 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11307 { } /* end */
11308};
11309
11310/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11311static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11312{
11313 struct alc_spec *spec = codec->spec;
11314
11315 spec->autocfg.hp_pins[0] = 0x15;
11316 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11317 spec->automute = 1;
11318 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11319}
11320
4f5d1706 11321static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11322{
11323 struct alc_spec *spec = codec->spec;
11324
11325 spec->autocfg.hp_pins[0] = 0x1b;
11326 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11327 spec->automute = 1;
11328 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11329}
11330
11331
a9111321 11332static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11333 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11334 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11337 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11338 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11339 { } /* end */
11340};
11341
a9111321 11342static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11343 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11344 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11348 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11349 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11350 { } /* end */
11351};
272a527c 11352
a9111321 11353static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11354 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11355 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11356 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11357 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11362 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11363 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11365 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11366 { } /* end */
11367};
11368
a9111321 11369static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11370 /* Headphone automute */
11371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11372 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11374
11375 /* P11 AUX_IN, white 4-pin connector */
11376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11377 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11378 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11379 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11380
11381 {}
11382};
11383
11384/* unsolicited event for HP jack sensing */
4f5d1706 11385static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11386{
a9fd4f3f 11387 struct alc_spec *spec = codec->spec;
ba340e82 11388
a9fd4f3f
TI
11389 spec->autocfg.hp_pins[0] = 0x1b;
11390 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11391 spec->automute = 1;
11392 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11393}
11394
ba340e82 11395
9c7f852e
TI
11396#define alc262_capture_mixer alc882_capture_mixer
11397#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11398
11399/*
11400 * generic initialization of ADC, input mixers and output mixers
11401 */
a9111321 11402static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11403 /*
11404 * Unmute ADC0-2 and set the default input to mic-in
11405 */
11406 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11408 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11410 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11412
cb53c626 11413 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11414 * mixer widget
f12ab1e0
TI
11415 * Note: PASD motherboards uses the Line In 2 as the input for
11416 * front panel mic (mic 2)
9c7f852e
TI
11417 */
11418 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11421 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11422 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11423 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11424
11425 /*
df694daa
KY
11426 * Set up output mixers (0x0c - 0x0e)
11427 */
11428 /* set vol=0 to output mixers */
11429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11432 /* set up input amps for analog loopback */
11433 /* Amp Indices: DAC = 0, mixer = 1 */
11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440
11441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11444 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11445 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11447
11448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11453
df694daa
KY
11454 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11456
df694daa
KY
11457 /* FIXME: use matrix-type input source selection */
11458 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11459 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11463 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11464 /* Input mixer2 */
11465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11469 /* Input mixer3 */
11470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11474
11475 { }
11476};
1da177e4 11477
a9111321 11478static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11479 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11480 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11481 { }
11482};
11483
a9111321 11484static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11486 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11488
11489 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11491 {}
11492};
11493
a9111321 11494static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11496 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11498
11499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11501 {}
272a527c
KY
11502};
11503
a9111321 11504static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11505 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11510 { } /* end */
11511};
11512
a9111321 11513static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11519 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11520 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11522 {}
11523};
11524
4f5d1706 11525static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11526{
a9fd4f3f
TI
11527 struct alc_spec *spec = codec->spec;
11528
11529 spec->autocfg.hp_pins[0] = 0x15;
11530 spec->autocfg.speaker_pins[0] = 0x14;
21268961
TI
11531 spec->ext_mic_pin = 0x18;
11532 spec->int_mic_pin = 0x12;
4f5d1706 11533 spec->auto_mic = 1;
d922b51d
TI
11534 spec->automute = 1;
11535 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11536}
11537
e8f9ae2a
PT
11538/*
11539 * nec model
11540 * 0x15 = headphone
11541 * 0x16 = internal speaker
11542 * 0x18 = external mic
11543 */
11544
a9111321 11545static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11546 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11547 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11548
11549 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11551 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11552
11553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11555 { } /* end */
11556};
11557
a9111321 11558static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11559 /* Unmute Speaker */
11560 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11561
11562 /* Headphone */
11563 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11565
11566 /* External mic to headphone */
11567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11568 /* External mic to speaker */
11569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11570 {}
11571};
11572
834be88d
TI
11573/*
11574 * fujitsu model
5d9fab2d
TV
11575 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11576 * 0x1b = port replicator headphone out
834be88d
TI
11577 */
11578
20f5e0b3 11579#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11580
a9111321 11581static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11582 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11584 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11586 {}
11587};
11588
a9111321 11589static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11590 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11592 {}
11593};
11594
a9111321 11595static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11596 /* Front Mic pin: input vref at 50% */
11597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11599 {}
11600};
11601
a9111321 11602static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11603 .num_items = 3,
834be88d
TI
11604 .items = {
11605 { "Mic", 0x0 },
28c4edb7 11606 { "Internal Mic", 0x1 },
834be88d
TI
11607 { "CD", 0x4 },
11608 },
11609};
11610
a9111321 11611static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11612 .num_items = 5,
11613 .items = {
11614 { "Mic", 0x0 },
accbe498 11615 { "Front Mic", 0x1 },
9c7f852e
TI
11616 { "Line", 0x2 },
11617 { "CD", 0x4 },
11618 { "AUX IN", 0x6 },
11619 },
11620};
11621
a9111321 11622static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11623 .num_items = 4,
11624 .items = {
11625 { "Mic", 0x0 },
11626 { "Front Mic", 0x2 },
11627 { "Line", 0x1 },
11628 { "CD", 0x4 },
11629 },
11630};
11631
0f0f391c 11632static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11633{
11634 struct alc_spec *spec = codec->spec;
834be88d 11635
0f0f391c
TI
11636 spec->autocfg.hp_pins[0] = 0x14;
11637 spec->autocfg.hp_pins[1] = 0x1b;
11638 spec->autocfg.speaker_pins[0] = 0x15;
11639 spec->automute = 1;
11640 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11641}
11642
834be88d 11643/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11644static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11645 .ops = &snd_hda_bind_vol,
11646 .values = {
11647 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11648 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11649 0
11650 },
11651};
834be88d 11652
a9111321 11653static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11655 {
11656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11657 .name = "Master Playback Switch",
0f0f391c
TI
11658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11659 .info = snd_ctl_boolean_mono_info,
11660 .get = alc262_hp_master_sw_get,
11661 .put = alc262_hp_master_sw_put,
834be88d 11662 },
5b0cb1d8
JK
11663 {
11664 .iface = NID_MAPPING,
11665 .name = "Master Playback Switch",
11666 .private_value = 0x1b,
11667 },
834be88d
TI
11668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11670 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11673 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11674 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11675 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11676 { } /* end */
11677};
11678
0f0f391c 11679static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11680{
0f0f391c 11681 struct alc_spec *spec = codec->spec;
0e31daf7 11682
0f0f391c
TI
11683 spec->autocfg.hp_pins[0] = 0x1b;
11684 spec->autocfg.speaker_pins[0] = 0x14;
11685 spec->autocfg.speaker_pins[1] = 0x16;
11686 spec->automute = 1;
11687 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11688}
11689
a9111321 11690static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11691 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11692 {
11693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11694 .name = "Master Playback Switch",
0f0f391c
TI
11695 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11696 .info = snd_ctl_boolean_mono_info,
11697 .get = alc262_hp_master_sw_get,
11698 .put = alc262_hp_master_sw_put,
0e31daf7
J
11699 },
11700 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11701 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11702 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11705 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11706 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11707 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11708 { } /* end */
11709};
11710
a9111321 11711static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 11712 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11713 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11716 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11717 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11718 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11719 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11720 { } /* end */
11721};
11722
304dcaac 11723/* additional init verbs for Benq laptops */
a9111321 11724static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
11725 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11726 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11727 {}
11728};
11729
a9111321 11730static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
11731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11733
11734 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11735 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11736 {}
11737};
11738
f651b50b 11739/* Samsung Q1 Ultra Vista model setup */
a9111321 11740static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11741 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11742 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11745 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11746 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11747 { } /* end */
11748};
11749
a9111321 11750static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11751 /* output mixer */
11752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11755 /* speaker */
11756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11759 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11760 /* HP */
f651b50b 11761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11765 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11766 /* internal mic */
11767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11769 /* ADC, choose mic */
11770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11780 {}
11781};
11782
f651b50b
TD
11783/* mute/unmute internal speaker according to the hp jack and mute state */
11784static void alc262_ultra_automute(struct hda_codec *codec)
11785{
11786 struct alc_spec *spec = codec->spec;
11787 unsigned int mute;
f651b50b 11788
bb9f76cd
TI
11789 mute = 0;
11790 /* auto-mute only when HP is used as HP */
11791 if (!spec->cur_mux[0]) {
864f92be 11792 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11793 if (spec->jack_present)
11794 mute = HDA_AMP_MUTE;
f651b50b 11795 }
bb9f76cd
TI
11796 /* mute/unmute internal speaker */
11797 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11798 HDA_AMP_MUTE, mute);
11799 /* mute/unmute HP */
11800 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11801 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc262_ultra_unsol_event(struct hda_codec *codec,
11806 unsigned int res)
11807{
11808 if ((res >> 26) != ALC880_HP_EVENT)
11809 return;
11810 alc262_ultra_automute(codec);
11811}
11812
a9111321 11813static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
11814 .num_items = 2,
11815 .items = {
11816 { "Mic", 0x1 },
11817 { "Headphone", 0x7 },
11818 },
11819};
11820
11821static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11822 struct snd_ctl_elem_value *ucontrol)
11823{
11824 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11825 struct alc_spec *spec = codec->spec;
11826 int ret;
11827
54cbc9ab 11828 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11829 if (!ret)
11830 return 0;
11831 /* reprogram the HP pin as mic or HP according to the input source */
11832 snd_hda_codec_write_cache(codec, 0x15, 0,
11833 AC_VERB_SET_PIN_WIDGET_CONTROL,
11834 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11835 alc262_ultra_automute(codec); /* mute/unmute HP */
11836 return ret;
11837}
11838
a9111321 11839static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
11840 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11841 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11842 {
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Capture Source",
54cbc9ab
TI
11845 .info = alc_mux_enum_info,
11846 .get = alc_mux_enum_get,
bb9f76cd
TI
11847 .put = alc262_ultra_mux_enum_put,
11848 },
5b0cb1d8
JK
11849 {
11850 .iface = NID_MAPPING,
11851 .name = "Capture Source",
11852 .private_value = 0x15,
11853 },
bb9f76cd
TI
11854 { } /* end */
11855};
11856
c3fc1f50
TI
11857/* We use two mixers depending on the output pin; 0x16 is a mono output
11858 * and thus it's bound with a different mixer.
11859 * This function returns which mixer amp should be used.
11860 */
11861static int alc262_check_volbit(hda_nid_t nid)
11862{
11863 if (!nid)
11864 return 0;
11865 else if (nid == 0x16)
11866 return 2;
11867 else
11868 return 1;
11869}
11870
11871static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11872 const char *pfx, int *vbits, int idx)
c3fc1f50 11873{
c3fc1f50
TI
11874 unsigned long val;
11875 int vbit;
11876
11877 vbit = alc262_check_volbit(nid);
11878 if (!vbit)
11879 return 0;
11880 if (*vbits & vbit) /* a volume control for this mixer already there */
11881 return 0;
11882 *vbits |= vbit;
c3fc1f50
TI
11883 if (vbit == 2)
11884 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11885 else
11886 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 11887 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
11888}
11889
11890static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11891 const char *pfx, int idx)
c3fc1f50 11892{
c3fc1f50
TI
11893 unsigned long val;
11894
11895 if (!nid)
11896 return 0;
c3fc1f50
TI
11897 if (nid == 0x16)
11898 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11899 else
11900 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 11901 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
11902}
11903
df694daa 11904/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11905static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11906 const struct auto_pin_cfg *cfg)
df694daa 11907{
c3fc1f50
TI
11908 const char *pfx;
11909 int vbits;
6843ca16 11910 int i, index, err;
df694daa
KY
11911
11912 spec->multiout.num_dacs = 1; /* only use one dac */
11913 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 11914 spec->private_dac_nids[0] = 2;
df694daa 11915
033688a5 11916 for (i = 0; i < 2; i++) {
6843ca16
TI
11917 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11918 if (!pfx)
11919 pfx = "PCM";
11920 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
11921 index);
033688a5
TI
11922 if (err < 0)
11923 return err;
11924 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11925 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
11926 "Speaker", i);
11927 if (err < 0)
11928 return err;
11929 }
11930 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11931 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
11932 "Headphone", i);
11933 if (err < 0)
11934 return err;
11935 }
11936 }
df694daa 11937
c3fc1f50
TI
11938 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11939 alc262_check_volbit(cfg->speaker_pins[0]) |
11940 alc262_check_volbit(cfg->hp_pins[0]);
c3fc1f50 11941 vbits = 0;
033688a5 11942 for (i = 0; i < 2; i++) {
6843ca16
TI
11943 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11944 if (!pfx)
11945 pfx = "PCM";
033688a5
TI
11946 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
11947 &vbits, i);
11948 if (err < 0)
11949 return err;
11950 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11951 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
11952 "Speaker", &vbits, i);
11953 if (err < 0)
11954 return err;
11955 }
11956 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11957 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
11958 "Headphone", &vbits, i);
11959 if (err < 0)
11960 return err;
11961 }
11962 }
f12ab1e0 11963 return 0;
df694daa
KY
11964}
11965
a9111321 11966static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
11967 /*
11968 * Unmute ADC0-2 and set the default input to mic-in
11969 */
11970 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976
cb53c626 11977 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11978 * mixer widget
f12ab1e0
TI
11979 * Note: PASD motherboards uses the Line In 2 as the input for
11980 * front panel mic (mic 2)
9c7f852e
TI
11981 */
11982 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 11990
9c7f852e
TI
11991 /*
11992 * Set up output mixers (0x0c - 0x0e)
11993 */
11994 /* set vol=0 to output mixers */
11995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11996 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11998
11999 /* set up input amps for analog loopback */
12000 /* Amp Indices: DAC = 0, mixer = 1 */
12001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12003 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12005 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12007
ce875f07 12008 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12010 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12011
12012 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12014
12015 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12017
12018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12019 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12021 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12022 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12023
0e4835c1 12024 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12025 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12026 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12028 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12029 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12030
12031
12032 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12033 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12034 /* Input mixer1: only unmute Mic */
9c7f852e 12035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12042 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12044 /* Input mixer2 */
12045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12046 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12047 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12054 /* Input mixer3 */
12055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12064
ce875f07
TI
12065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12066
9c7f852e
TI
12067 { }
12068};
12069
a9111321 12070static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12071 /*
12072 * Unmute ADC0-2 and set the default input to mic-in
12073 */
12074 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080
cb53c626 12081 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12082 * mixer widget
12083 * Note: PASD motherboards uses the Line In 2 as the input for front
12084 * panel mic (mic 2)
12085 */
12086 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12095 /*
12096 * Set up output mixers (0x0c - 0x0e)
12097 */
12098 /* set vol=0 to output mixers */
12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12102
12103 /* set up input amps for analog loopback */
12104 /* Amp Indices: DAC = 0, mixer = 1 */
12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12111
12112
12113 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12114 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12115 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12119 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12120
12121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12123
12124 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12126
12127 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12130 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12131 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12132 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12133
12134 /* FIXME: use matrix-type input source selection */
12135 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12136 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12142 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12144 /* Input mixer2 */
12145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12146 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12147 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12150 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12152 /* Input mixer3 */
12153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12158 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12160
ce875f07
TI
12161 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12162
cd7509a4
KY
12163 { }
12164};
12165
a9111321 12166static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12167
12168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12171
12172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12174 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12176
12177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12178 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12179 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12180 {}
12181};
12182
18675e42
TI
12183/*
12184 * Pin config fixes
12185 */
12186enum {
12187 PINFIX_FSC_H270,
d2a19da7 12188 PINFIX_HP_Z200,
18675e42
TI
12189};
12190
12191static const struct alc_fixup alc262_fixups[] = {
12192 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12193 .type = ALC_FIXUP_PINS,
12194 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12195 { 0x14, 0x99130110 }, /* speaker */
12196 { 0x15, 0x0221142f }, /* front HP */
12197 { 0x1b, 0x0121141f }, /* rear HP */
12198 { }
12199 }
12200 },
d2a19da7
DH
12201 [PINFIX_HP_Z200] = {
12202 .type = ALC_FIXUP_PINS,
12203 .v.pins = (const struct alc_pincfg[]) {
12204 { 0x16, 0x99130120 }, /* internal speaker */
12205 { }
12206 }
12207 },
18675e42
TI
12208};
12209
a9111321 12210static const struct snd_pci_quirk alc262_fixup_tbl[] = {
d2a19da7 12211 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
18675e42
TI
12212 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12213 {}
12214};
12215
9f99a638 12216
cb53c626
TI
12217#ifdef CONFIG_SND_HDA_POWER_SAVE
12218#define alc262_loopbacks alc880_loopbacks
12219#endif
12220
df694daa
KY
12221/*
12222 * BIOS auto configuration
12223 */
12224static int alc262_parse_auto_config(struct hda_codec *codec)
12225{
12226 struct alc_spec *spec = codec->spec;
12227 int err;
4c6d72d1 12228 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12229
f12ab1e0
TI
12230 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12231 alc262_ignore);
12232 if (err < 0)
df694daa 12233 return err;
e64f14f4 12234 if (!spec->autocfg.line_outs) {
0852d7a6 12235 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12236 spec->multiout.max_channels = 2;
12237 spec->no_analog = 1;
12238 goto dig_only;
12239 }
df694daa 12240 return 0; /* can't find valid BIOS pin config */
e64f14f4 12241 }
f12ab1e0
TI
12242 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12243 if (err < 0)
12244 return err;
b7821709 12245 err = alc_auto_create_input_ctls(codec);
f12ab1e0 12246 if (err < 0)
df694daa
KY
12247 return err;
12248
12249 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12250
e64f14f4 12251 dig_only:
757899ac 12252 alc_auto_parse_digital(codec);
df694daa 12253
603c4019 12254 if (spec->kctls.list)
d88897ea 12255 add_mixer(spec, spec->kctls.list);
df694daa 12256
776e184e
TI
12257 err = alc_auto_add_mic_boost(codec);
12258 if (err < 0)
12259 return err;
12260
21268961
TI
12261 alc_remove_invalid_adc_nids(codec);
12262
6227cdce 12263 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
21268961 12264 alc_auto_check_switches(codec);
4a79ba34 12265
df694daa
KY
12266 return 1;
12267}
12268
df694daa
KY
12269
12270/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12271static void alc262_auto_init(struct hda_codec *codec)
df694daa 12272{
f6c7e546 12273 struct alc_spec *spec = codec->spec;
343a04be
TI
12274 alc_auto_init_multi_out(codec);
12275 alc_auto_init_extra_out(codec);
0a7f5320 12276 alc_auto_init_analog_input(codec);
f970de25 12277 alc_auto_init_input_src(codec);
757899ac 12278 alc_auto_init_digital(codec);
f6c7e546 12279 if (spec->unsol_event)
7fb0d78f 12280 alc_inithook(codec);
df694daa
KY
12281}
12282
12283/*
12284 * configuration and preset
12285 */
ea734963 12286static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12287 [ALC262_BASIC] = "basic",
12288 [ALC262_HIPPO] = "hippo",
12289 [ALC262_HIPPO_1] = "hippo_1",
12290 [ALC262_FUJITSU] = "fujitsu",
12291 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12292 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12293 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12294 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12295 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12296 [ALC262_BENQ_T31] = "benq-t31",
12297 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12298 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12299 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12300 [ALC262_ULTRA] = "ultra",
0e31daf7 12301 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12302 [ALC262_NEC] = "nec",
ba340e82 12303 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12304 [ALC262_AUTO] = "auto",
12305};
12306
a9111321 12307static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12308 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12309 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12310 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12311 ALC262_HP_BPC),
12312 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12313 ALC262_HP_BPC),
5734a07c
TI
12314 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12315 ALC262_HP_BPC),
d2a19da7
DH
12316 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12317 ALC262_AUTO),
53eff7e1
TI
12318 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12319 ALC262_HP_BPC),
cd7509a4 12320 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12321 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12322 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12323 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12324 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12325 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12326 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12327 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12328 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12329 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12330 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12331 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12332 ALC262_HP_TC_T5735),
8c427226 12333 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12334 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12335 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12336 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12337 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12338 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12339 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12340 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12341#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12342 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12343 ALC262_SONY_ASSAMD),
c5b5165c 12344#endif
36ca6e13 12345 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12346 ALC262_TOSHIBA_RX1),
80ffe869 12347 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12348 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12349 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12350 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12351 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12352 ALC262_ULTRA),
3e420e78 12353 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12354 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12355 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12356 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12357 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12358 {}
12359};
12360
a9111321 12361static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12362 [ALC262_BASIC] = {
12363 .mixers = { alc262_base_mixer },
12364 .init_verbs = { alc262_init_verbs },
12365 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12366 .dac_nids = alc262_dac_nids,
12367 .hp_nid = 0x03,
12368 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12369 .channel_mode = alc262_modes,
a3bcba38 12370 .input_mux = &alc262_capture_source,
df694daa 12371 },
ccc656ce 12372 [ALC262_HIPPO] = {
42171c17 12373 .mixers = { alc262_hippo_mixer },
6732bd0d 12374 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12375 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12376 .dac_nids = alc262_dac_nids,
12377 .hp_nid = 0x03,
12378 .dig_out_nid = ALC262_DIGOUT_NID,
12379 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12380 .channel_mode = alc262_modes,
12381 .input_mux = &alc262_capture_source,
e9427969 12382 .unsol_event = alc_sku_unsol_event,
4f5d1706 12383 .setup = alc262_hippo_setup,
e9427969 12384 .init_hook = alc_inithook,
ccc656ce
KY
12385 },
12386 [ALC262_HIPPO_1] = {
12387 .mixers = { alc262_hippo1_mixer },
12388 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12389 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12390 .dac_nids = alc262_dac_nids,
12391 .hp_nid = 0x02,
12392 .dig_out_nid = ALC262_DIGOUT_NID,
12393 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12394 .channel_mode = alc262_modes,
12395 .input_mux = &alc262_capture_source,
e9427969 12396 .unsol_event = alc_sku_unsol_event,
4f5d1706 12397 .setup = alc262_hippo1_setup,
e9427969 12398 .init_hook = alc_inithook,
ccc656ce 12399 },
834be88d
TI
12400 [ALC262_FUJITSU] = {
12401 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12402 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12403 alc262_fujitsu_unsol_verbs },
834be88d
TI
12404 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12405 .dac_nids = alc262_dac_nids,
12406 .hp_nid = 0x03,
12407 .dig_out_nid = ALC262_DIGOUT_NID,
12408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12409 .channel_mode = alc262_modes,
12410 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12411 .unsol_event = alc_sku_unsol_event,
12412 .setup = alc262_fujitsu_setup,
12413 .init_hook = alc_inithook,
834be88d 12414 },
9c7f852e
TI
12415 [ALC262_HP_BPC] = {
12416 .mixers = { alc262_HP_BPC_mixer },
12417 .init_verbs = { alc262_HP_BPC_init_verbs },
12418 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12419 .dac_nids = alc262_dac_nids,
12420 .hp_nid = 0x03,
12421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12422 .channel_mode = alc262_modes,
12423 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12424 .unsol_event = alc_sku_unsol_event,
12425 .setup = alc262_hp_bpc_setup,
12426 .init_hook = alc_inithook,
f12ab1e0 12427 },
cd7509a4
KY
12428 [ALC262_HP_BPC_D7000_WF] = {
12429 .mixers = { alc262_HP_BPC_WildWest_mixer },
12430 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x03,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
accbe498 12436 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12437 .unsol_event = alc_sku_unsol_event,
12438 .setup = alc262_hp_wildwest_setup,
12439 .init_hook = alc_inithook,
f12ab1e0 12440 },
cd7509a4
KY
12441 [ALC262_HP_BPC_D7000_WL] = {
12442 .mixers = { alc262_HP_BPC_WildWest_mixer,
12443 alc262_HP_BPC_WildWest_option_mixer },
12444 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
accbe498 12450 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12451 .unsol_event = alc_sku_unsol_event,
12452 .setup = alc262_hp_wildwest_setup,
12453 .init_hook = alc_inithook,
f12ab1e0 12454 },
66d2a9d6
KY
12455 [ALC262_HP_TC_T5735] = {
12456 .mixers = { alc262_hp_t5735_mixer },
12457 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12459 .dac_nids = alc262_dac_nids,
12460 .hp_nid = 0x03,
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_capture_source,
dc99be47 12464 .unsol_event = alc_sku_unsol_event,
4f5d1706 12465 .setup = alc262_hp_t5735_setup,
dc99be47 12466 .init_hook = alc_inithook,
8c427226
KY
12467 },
12468 [ALC262_HP_RP5700] = {
12469 .mixers = { alc262_hp_rp5700_mixer },
12470 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12471 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12472 .dac_nids = alc262_dac_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12474 .channel_mode = alc262_modes,
12475 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12476 },
304dcaac
TI
12477 [ALC262_BENQ_ED8] = {
12478 .mixers = { alc262_base_mixer },
12479 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12480 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12481 .dac_nids = alc262_dac_nids,
12482 .hp_nid = 0x03,
12483 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12484 .channel_mode = alc262_modes,
12485 .input_mux = &alc262_capture_source,
f12ab1e0 12486 },
272a527c
KY
12487 [ALC262_SONY_ASSAMD] = {
12488 .mixers = { alc262_sony_mixer },
12489 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12490 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12491 .dac_nids = alc262_dac_nids,
12492 .hp_nid = 0x02,
12493 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12494 .channel_mode = alc262_modes,
12495 .input_mux = &alc262_capture_source,
e9427969 12496 .unsol_event = alc_sku_unsol_event,
4f5d1706 12497 .setup = alc262_hippo_setup,
e9427969 12498 .init_hook = alc_inithook,
83c34218
KY
12499 },
12500 [ALC262_BENQ_T31] = {
12501 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12502 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12503 alc_hp15_unsol_verbs },
83c34218
KY
12504 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12505 .dac_nids = alc262_dac_nids,
12506 .hp_nid = 0x03,
12507 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12508 .channel_mode = alc262_modes,
12509 .input_mux = &alc262_capture_source,
e9427969 12510 .unsol_event = alc_sku_unsol_event,
4f5d1706 12511 .setup = alc262_hippo_setup,
e9427969 12512 .init_hook = alc_inithook,
ea1fb29a 12513 },
f651b50b 12514 [ALC262_ULTRA] = {
f9e336f6
TI
12515 .mixers = { alc262_ultra_mixer },
12516 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12517 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12518 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12519 .dac_nids = alc262_dac_nids,
f651b50b
TD
12520 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12521 .channel_mode = alc262_modes,
12522 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12523 .adc_nids = alc262_adc_nids, /* ADC0 */
12524 .capsrc_nids = alc262_capsrc_nids,
12525 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12526 .unsol_event = alc262_ultra_unsol_event,
12527 .init_hook = alc262_ultra_automute,
12528 },
0e31daf7
J
12529 [ALC262_LENOVO_3000] = {
12530 .mixers = { alc262_lenovo_3000_mixer },
12531 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12532 alc262_lenovo_3000_unsol_verbs,
12533 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12534 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12535 .dac_nids = alc262_dac_nids,
12536 .hp_nid = 0x03,
12537 .dig_out_nid = ALC262_DIGOUT_NID,
12538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12539 .channel_mode = alc262_modes,
12540 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12541 .unsol_event = alc_sku_unsol_event,
12542 .setup = alc262_lenovo_3000_setup,
12543 .init_hook = alc_inithook,
0e31daf7 12544 },
e8f9ae2a
PT
12545 [ALC262_NEC] = {
12546 .mixers = { alc262_nec_mixer },
12547 .init_verbs = { alc262_nec_verbs },
12548 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12549 .dac_nids = alc262_dac_nids,
12550 .hp_nid = 0x03,
12551 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12552 .channel_mode = alc262_modes,
12553 .input_mux = &alc262_capture_source,
12554 },
4e555fe5
KY
12555 [ALC262_TOSHIBA_S06] = {
12556 .mixers = { alc262_toshiba_s06_mixer },
12557 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12558 alc262_eapd_verbs },
12559 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12560 .capsrc_nids = alc262_dmic_capsrc_nids,
12561 .dac_nids = alc262_dac_nids,
12562 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12563 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12564 .dig_out_nid = ALC262_DIGOUT_NID,
12565 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12566 .channel_mode = alc262_modes,
4f5d1706
TI
12567 .unsol_event = alc_sku_unsol_event,
12568 .setup = alc262_toshiba_s06_setup,
12569 .init_hook = alc_inithook,
4e555fe5 12570 },
9f99a638
HM
12571 [ALC262_TOSHIBA_RX1] = {
12572 .mixers = { alc262_toshiba_rx1_mixer },
12573 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12574 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12575 .dac_nids = alc262_dac_nids,
12576 .hp_nid = 0x03,
12577 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12578 .channel_mode = alc262_modes,
12579 .input_mux = &alc262_capture_source,
e9427969 12580 .unsol_event = alc_sku_unsol_event,
4f5d1706 12581 .setup = alc262_hippo_setup,
e9427969 12582 .init_hook = alc_inithook,
9f99a638 12583 },
ba340e82
TV
12584 [ALC262_TYAN] = {
12585 .mixers = { alc262_tyan_mixer },
12586 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12587 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12588 .dac_nids = alc262_dac_nids,
12589 .hp_nid = 0x02,
12590 .dig_out_nid = ALC262_DIGOUT_NID,
12591 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12592 .channel_mode = alc262_modes,
12593 .input_mux = &alc262_capture_source,
d922b51d 12594 .unsol_event = alc_sku_unsol_event,
4f5d1706 12595 .setup = alc262_tyan_setup,
d922b51d 12596 .init_hook = alc_hp_automute,
ba340e82 12597 },
df694daa
KY
12598};
12599
12600static int patch_alc262(struct hda_codec *codec)
12601{
12602 struct alc_spec *spec;
12603 int board_config;
12604 int err;
12605
dc041e0b 12606 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12607 if (spec == NULL)
12608 return -ENOMEM;
12609
12610 codec->spec = spec;
1f0f4b80
TI
12611
12612 spec->mixer_nid = 0x0b;
12613
df694daa 12614#if 0
f12ab1e0
TI
12615 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12616 * under-run
12617 */
df694daa
KY
12618 {
12619 int tmp;
12620 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12621 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12622 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12623 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12624 }
12625#endif
da00c244 12626 alc_auto_parse_customize_define(codec);
df694daa 12627
2c3bf9ab
TI
12628 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12629
f5fcc13c
TI
12630 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12631 alc262_models,
12632 alc262_cfg_tbl);
cd7509a4 12633
f5fcc13c 12634 if (board_config < 0) {
9a11f1aa
TI
12635 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12636 codec->chip_name);
df694daa
KY
12637 board_config = ALC262_AUTO;
12638 }
12639
b5bfbc67
TI
12640 if (board_config == ALC262_AUTO) {
12641 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12642 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12643 }
18675e42 12644
df694daa
KY
12645 if (board_config == ALC262_AUTO) {
12646 /* automatic parse from the BIOS config */
12647 err = alc262_parse_auto_config(codec);
12648 if (err < 0) {
12649 alc_free(codec);
12650 return err;
f12ab1e0 12651 } else if (!err) {
9c7f852e
TI
12652 printk(KERN_INFO
12653 "hda_codec: Cannot set up configuration "
12654 "from BIOS. Using base mode...\n");
df694daa
KY
12655 board_config = ALC262_BASIC;
12656 }
12657 }
12658
dc1eae25 12659 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12660 err = snd_hda_attach_beep_device(codec, 0x1);
12661 if (err < 0) {
12662 alc_free(codec);
12663 return err;
12664 }
680cd536
KK
12665 }
12666
df694daa 12667 if (board_config != ALC262_AUTO)
e9c364c0 12668 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12669
f12ab1e0 12670 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab 12671 alc_auto_fill_adc_caps(codec);
21268961 12672 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 12673 alc_remove_invalid_adc_nids(codec);
df694daa 12674 }
e64f14f4 12675 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12676 set_capture_mixer(codec);
dc1eae25 12677 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12678 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12679
b5bfbc67 12680 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12681
2134ea4f
TI
12682 spec->vmaster_nid = 0x0c;
12683
df694daa
KY
12684 codec->patch_ops = alc_patch_ops;
12685 if (board_config == ALC262_AUTO)
ae6b813a 12686 spec->init_hook = alc262_auto_init;
1c716153 12687 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
12688
12689 alc_init_jacks(codec);
cb53c626
TI
12690#ifdef CONFIG_SND_HDA_POWER_SAVE
12691 if (!spec->loopback.amplist)
12692 spec->loopback.amplist = alc262_loopbacks;
12693#endif
ea1fb29a 12694
df694daa
KY
12695 return 0;
12696}
12697
a361d84b
KY
12698/*
12699 * ALC268 channel source setting (2 channel)
12700 */
12701#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12702#define alc268_modes alc260_modes
ea1fb29a 12703
4c6d72d1 12704static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
12705 /* front, hp */
12706 0x02, 0x03
12707};
12708
4c6d72d1 12709static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
12710 /* ADC0-1 */
12711 0x08, 0x07
12712};
12713
4c6d72d1 12714static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
12715 /* ADC0 */
12716 0x08
12717};
12718
4c6d72d1 12719static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 12720
a9111321 12721static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
12722 /* output mixer control */
12723 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12724 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
12727 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12729 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12730 { }
12731};
12732
a9111321 12733static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
12734 /* output mixer control */
12735 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12736 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12737 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
12738 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12740 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
12741 { }
12742};
12743
aef9d318 12744/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 12745static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
12746 .ops = &snd_hda_bind_sw,
12747 .values = {
12748 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12749 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12750 0
12751 },
12752};
12753
a9111321 12754static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
12755 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12756 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12757 { }
12758};
12759
a9111321 12760static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
12761 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12762 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12763 { }
12764};
12765
d273809e 12766/* Toshiba specific */
a9111321 12767static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
12768 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12769 { } /* end */
12770};
12771
12772/* Acer specific */
889c4395 12773/* bind volumes of both NID 0x02 and 0x03 */
a9111321 12774static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
12775 .ops = &snd_hda_bind_vol,
12776 .values = {
12777 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12778 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12779 0
12780 },
12781};
12782
0f0f391c 12783static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
12784{
12785 struct alc_spec *spec = codec->spec;
889c4395 12786
0f0f391c
TI
12787 spec->autocfg.hp_pins[0] = 0x14;
12788 spec->autocfg.speaker_pins[0] = 0x15;
12789 spec->automute = 1;
12790 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
12791}
12792
0f0f391c
TI
12793#define alc268_acer_master_sw_get alc262_hp_master_sw_get
12794#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 12795
a9111321 12796static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
12797 /* output mixer control */
12798 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12799 {
12800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12801 .name = "Master Playback Switch",
0f0f391c
TI
12802 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12803 .info = snd_ctl_boolean_mono_info,
12804 .get = alc268_acer_master_sw_get,
8ef355da 12805 .put = alc268_acer_master_sw_put,
8ef355da
KY
12806 },
12807 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12808 { }
12809};
12810
a9111321 12811static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
12812 /* output mixer control */
12813 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12814 {
12815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12816 .name = "Master Playback Switch",
0f0f391c
TI
12817 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12818 .info = snd_ctl_boolean_mono_info,
12819 .get = alc268_acer_master_sw_get,
d273809e 12820 .put = alc268_acer_master_sw_put,
d273809e 12821 },
5f99f86a
DH
12822 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12823 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12824 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
12825 { }
12826};
12827
a9111321 12828static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
12829 /* output mixer control */
12830 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12831 {
12832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12833 .name = "Master Playback Switch",
0f0f391c
TI
12834 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12835 .info = snd_ctl_boolean_mono_info,
12836 .get = alc268_acer_master_sw_get,
c238b4f4 12837 .put = alc268_acer_master_sw_put,
c238b4f4 12838 },
5f99f86a
DH
12839 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12840 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
12841 { }
12842};
12843
a9111321 12844static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
12845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12849 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12850 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12851 { }
12852};
12853
a9111321 12854static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12855 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12856 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12860 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12862 { }
12863};
12864
12865/* unsolicited event for HP jack sensing */
4f5d1706 12866#define alc268_toshiba_setup alc262_hippo_setup
d273809e 12867
4f5d1706
TI
12868static void alc268_acer_lc_setup(struct hda_codec *codec)
12869{
12870 struct alc_spec *spec = codec->spec;
3b8510ce
TI
12871 spec->autocfg.hp_pins[0] = 0x15;
12872 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce 12873 spec->automute = 1;
54463a66 12874 spec->automute_mode = ALC_AUTOMUTE_AMP;
21268961
TI
12875 spec->ext_mic_pin = 0x18;
12876 spec->int_mic_pin = 0x12;
4f5d1706 12877 spec->auto_mic = 1;
8ef355da
KY
12878}
12879
a9111321 12880static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
12881 /* output mixer control */
12882 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12883 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12885 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
12886 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12887 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
12888 { }
12889};
12890
a9111321 12891static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
12892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12894 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12895 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12896 { }
12897};
12898
12899/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12900static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12901{
a9fd4f3f 12902 struct alc_spec *spec = codec->spec;
3866f0b0 12903
a9fd4f3f
TI
12904 spec->autocfg.hp_pins[0] = 0x15;
12905 spec->autocfg.speaker_pins[0] = 0x14;
21268961
TI
12906 spec->ext_mic_pin = 0x18;
12907 spec->int_mic_pin = 0x19;
4f5d1706 12908 spec->auto_mic = 1;
d922b51d
TI
12909 spec->automute = 1;
12910 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
12911}
12912
a9111321 12913static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
12914 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12919 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
12920 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
12922 { }
12923};
12924
a9111321 12925static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
12926 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12927 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12928 { }
12929};
12930
4f5d1706 12931static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12932{
a9fd4f3f 12933 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12934 spec->autocfg.hp_pins[0] = 0x15;
12935 spec->autocfg.speaker_pins[0] = 0x14;
21268961
TI
12936 spec->ext_mic_pin = 0x18;
12937 spec->int_mic_pin = 0x19;
4f5d1706 12938 spec->auto_mic = 1;
d922b51d
TI
12939 spec->automute = 1;
12940 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
12941}
12942
a361d84b
KY
12943/*
12944 * generic initialization of ADC, input mixers and output mixers
12945 */
a9111321 12946static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
12947 /* Unmute DAC0-1 and set vol = 0 */
12948 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12949 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12950
12951 /*
12952 * Set up output mixers (0x0c - 0x0e)
12953 */
12954 /* set vol=0 to output mixers */
12955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12956 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12957
12958 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12959 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960
12961 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12964 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12965 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12966 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12967 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12968 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12969
12970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12971 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12972 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 12974 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
12975
12976 /* set PCBEEP vol = 0, mute connections */
12977 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12978 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12979 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 12980
a9b3aa8a 12981 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 12982
a9b3aa8a
JZ
12983 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12985 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 12987
a361d84b
KY
12988 { }
12989};
12990
1f0f4b80
TI
12991/* only for model=test */
12992#ifdef CONFIG_SND_DEBUG
a361d84b
KY
12993/*
12994 * generic initialization of ADC, input mixers and output mixers
12995 */
a9111321 12996static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 12997 /* set output DAC */
4cfb91c6
TI
12998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13000
13001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13002 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13004 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13005 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13006
a361d84b 13007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13009 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010
13011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13012 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1f0f4b80
TI
13013 { }
13014};
13015#endif /* CONFIG_SND_DEBUG */
a361d84b 13016
1f0f4b80
TI
13017/* set PCBEEP vol = 0, mute connections */
13018static const struct hda_verb alc268_beep_init_verbs[] = {
aef9d318
TI
13019 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13021 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13022 { }
13023};
13024
a9111321 13025static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13026 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13027 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13028 { } /* end */
13029};
13030
a9111321 13031static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13032 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13033 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13034 _DEFINE_CAPSRC(1),
a361d84b
KY
13035 { } /* end */
13036};
13037
a9111321 13038static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13039 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13040 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13041 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13042 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13043 _DEFINE_CAPSRC(2),
a361d84b
KY
13044 { } /* end */
13045};
13046
a9111321 13047static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13048 .num_items = 4,
13049 .items = {
13050 { "Mic", 0x0 },
13051 { "Front Mic", 0x1 },
13052 { "Line", 0x2 },
13053 { "CD", 0x3 },
13054 },
13055};
13056
a9111321 13057static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13058 .num_items = 3,
13059 .items = {
13060 { "Mic", 0x0 },
13061 { "Internal Mic", 0x1 },
13062 { "Line", 0x2 },
13063 },
13064};
13065
a9111321 13066static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13067 .num_items = 3,
13068 .items = {
13069 { "Mic", 0x0 },
13070 { "Internal Mic", 0x6 },
13071 { "Line", 0x2 },
13072 },
13073};
13074
86c53bd2 13075#ifdef CONFIG_SND_DEBUG
a9111321 13076static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13077 /* Volume widgets */
13078 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13079 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13080 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13081 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13082 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13083 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13084 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13085 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13086 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13087 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13088 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13089 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13090 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13091 /* The below appears problematic on some hardwares */
13092 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13093 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13094 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13095 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13096 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13097
13098 /* Modes for retasking pin widgets */
13099 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13100 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13101 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13102 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13103
13104 /* Controls for GPIO pins, assuming they are configured as outputs */
13105 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13106 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13107 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13108 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13109
13110 /* Switches to allow the digital SPDIF output pin to be enabled.
13111 * The ALC268 does not have an SPDIF input.
13112 */
13113 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13114
13115 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13116 * this output to turn on an external amplifier.
13117 */
13118 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13119 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13120
13121 { } /* end */
13122};
13123#endif
13124
a361d84b
KY
13125/* create input playback/capture controls for the given pin */
13126static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13127 const char *ctlname, int idx)
13128{
3f3b7c1a 13129 hda_nid_t dac;
a361d84b
KY
13130 int err;
13131
3f3b7c1a
TI
13132 switch (nid) {
13133 case 0x14:
13134 case 0x16:
13135 dac = 0x02;
13136 break;
13137 case 0x15:
b08b1637
TI
13138 case 0x1a: /* ALC259/269 only */
13139 case 0x1b: /* ALC259/269 only */
531d8791 13140 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13141 dac = 0x03;
13142 break;
13143 default:
c7a9434d
TI
13144 snd_printd(KERN_WARNING "hda_codec: "
13145 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13146 return 0;
13147 }
13148 if (spec->multiout.dac_nids[0] != dac &&
13149 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13150 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13151 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13152 HDA_OUTPUT));
13153 if (err < 0)
13154 return err;
dda14410 13155 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13156 }
13157
3f3b7c1a 13158 if (nid != 0x16)
0afe5f89 13159 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13160 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13161 else /* mono */
0afe5f89 13162 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13163 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13164 if (err < 0)
13165 return err;
13166 return 0;
13167}
13168
13169/* add playback controls from the parsed DAC table */
13170static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13171 const struct auto_pin_cfg *cfg)
13172{
13173 hda_nid_t nid;
13174 int err;
13175
a361d84b 13176 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13177
13178 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13179 if (nid) {
13180 const char *name;
2e925dde
TI
13181 int index;
13182 name = alc_get_line_out_pfx(spec, 0, true, &index);
3f3b7c1a
TI
13183 err = alc268_new_analog_output(spec, nid, name, 0);
13184 if (err < 0)
13185 return err;
13186 }
a361d84b
KY
13187
13188 nid = cfg->speaker_pins[0];
13189 if (nid == 0x1d) {
0afe5f89 13190 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13191 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13192 if (err < 0)
13193 return err;
7bfb9c03 13194 } else if (nid) {
3f3b7c1a
TI
13195 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13196 if (err < 0)
13197 return err;
a361d84b
KY
13198 }
13199 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13200 if (nid) {
13201 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13202 if (err < 0)
13203 return err;
13204 }
a361d84b
KY
13205
13206 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13207 if (nid == 0x16) {
0afe5f89 13208 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13209 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13210 if (err < 0)
13211 return err;
13212 }
ea1fb29a 13213 return 0;
a361d84b
KY
13214}
13215
e9af4f36
TI
13216static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13217 hda_nid_t nid, int pin_type)
13218{
13219 int idx;
13220
13221 alc_set_pin_output(codec, nid, pin_type);
4f574b7b
TI
13222 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
13223 return;
e9af4f36
TI
13224 if (nid == 0x14 || nid == 0x16)
13225 idx = 0;
13226 else
13227 idx = 1;
13228 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13229}
13230
1f0f4b80
TI
13231static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13232{
13233 if (!nid)
13234 return;
13235 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7ec9c6cc 13236 AMP_OUT_ZERO);
1f0f4b80
TI
13237}
13238
e9af4f36
TI
13239static void alc268_auto_init_multi_out(struct hda_codec *codec)
13240{
13241 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13242 int i;
13243
13244 for (i = 0; i < spec->autocfg.line_outs; i++) {
13245 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13246 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13247 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13248 }
1f0f4b80
TI
13249 /* mute DACs */
13250 for (i = 0; i < spec->multiout.num_dacs; i++)
13251 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9af4f36
TI
13252}
13253
13254static void alc268_auto_init_hp_out(struct hda_codec *codec)
13255{
13256 struct alc_spec *spec = codec->spec;
13257 hda_nid_t pin;
e1ca7b4e 13258 int i;
e9af4f36 13259
e1ca7b4e
TI
13260 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13261 pin = spec->autocfg.hp_pins[i];
e9af4f36 13262 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13263 }
13264 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13265 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13266 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13267 }
13268 if (spec->autocfg.mono_out_pin)
13269 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13270 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1f0f4b80
TI
13271 /* mute DACs */
13272 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13273 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13274 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9af4f36
TI
13275}
13276
a361d84b
KY
13277static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13278{
13279 struct alc_spec *spec = codec->spec;
13280 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13281 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13282 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13283 unsigned int dac_vol1, dac_vol2;
13284
e9af4f36 13285 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13286 snd_hda_codec_write(codec, speaker_nid, 0,
13287 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13288 /* mute mixer inputs from 0x1d */
a361d84b
KY
13289 snd_hda_codec_write(codec, 0x0f, 0,
13290 AC_VERB_SET_AMP_GAIN_MUTE,
13291 AMP_IN_UNMUTE(1));
13292 snd_hda_codec_write(codec, 0x10, 0,
13293 AC_VERB_SET_AMP_GAIN_MUTE,
13294 AMP_IN_UNMUTE(1));
13295 } else {
e9af4f36 13296 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13297 snd_hda_codec_write(codec, 0x0f, 0,
13298 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13299 snd_hda_codec_write(codec, 0x10, 0,
13300 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13301 }
13302
13303 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13304 if (line_nid == 0x14)
a361d84b
KY
13305 dac_vol2 = AMP_OUT_ZERO;
13306 else if (line_nid == 0x15)
13307 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13308 if (hp_nid == 0x14)
a361d84b
KY
13309 dac_vol2 = AMP_OUT_ZERO;
13310 else if (hp_nid == 0x15)
13311 dac_vol1 = AMP_OUT_ZERO;
13312 if (line_nid != 0x16 || hp_nid != 0x16 ||
13313 spec->autocfg.line_out_pins[1] != 0x16 ||
13314 spec->autocfg.line_out_pins[2] != 0x16)
13315 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13316
13317 snd_hda_codec_write(codec, 0x02, 0,
13318 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13319 snd_hda_codec_write(codec, 0x03, 0,
13320 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13321}
13322
a361d84b
KY
13323/*
13324 * BIOS auto configuration
13325 */
13326static int alc268_parse_auto_config(struct hda_codec *codec)
13327{
13328 struct alc_spec *spec = codec->spec;
13329 int err;
4c6d72d1 13330 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13331
13332 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13333 alc268_ignore);
13334 if (err < 0)
13335 return err;
7e0e44d4
TI
13336 if (!spec->autocfg.line_outs) {
13337 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13338 spec->multiout.max_channels = 2;
13339 spec->no_analog = 1;
13340 goto dig_only;
13341 }
a361d84b 13342 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13343 }
a361d84b
KY
13344 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13345 if (err < 0)
13346 return err;
b7821709 13347 err = alc_auto_create_input_ctls(codec);
a361d84b
KY
13348 if (err < 0)
13349 return err;
13350
13351 spec->multiout.max_channels = 2;
13352
7e0e44d4 13353 dig_only:
a361d84b 13354 /* digital only support output */
757899ac 13355 alc_auto_parse_digital(codec);
603c4019 13356 if (spec->kctls.list)
d88897ea 13357 add_mixer(spec, spec->kctls.list);
a361d84b 13358
4f574b7b 13359 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
d88897ea 13360 add_mixer(spec, alc268_beep_mixer);
4f574b7b
TI
13361 add_verb(spec, alc268_beep_init_verbs);
13362 }
aef9d318 13363
776e184e
TI
13364 err = alc_auto_add_mic_boost(codec);
13365 if (err < 0)
13366 return err;
13367
21268961
TI
13368 alc_remove_invalid_adc_nids(codec);
13369
6227cdce 13370 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
21268961 13371 alc_auto_check_switches(codec);
1d955ebd 13372
a361d84b
KY
13373 return 1;
13374}
13375
a361d84b
KY
13376/* init callback for auto-configuration model -- overriding the default init */
13377static void alc268_auto_init(struct hda_codec *codec)
13378{
f6c7e546 13379 struct alc_spec *spec = codec->spec;
a361d84b
KY
13380 alc268_auto_init_multi_out(codec);
13381 alc268_auto_init_hp_out(codec);
13382 alc268_auto_init_mono_speaker_out(codec);
0a7f5320 13383 alc_auto_init_analog_input(codec);
f970de25 13384 alc_auto_init_input_src(codec);
757899ac 13385 alc_auto_init_digital(codec);
f6c7e546 13386 if (spec->unsol_event)
7fb0d78f 13387 alc_inithook(codec);
a361d84b
KY
13388}
13389
13390/*
13391 * configuration and preset
13392 */
ea734963 13393static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13394 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13395 [ALC268_3ST] = "3stack",
983f8ae4 13396 [ALC268_TOSHIBA] = "toshiba",
d273809e 13397 [ALC268_ACER] = "acer",
c238b4f4 13398 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13399 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13400 [ALC268_DELL] = "dell",
f12462c5 13401 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13402#ifdef CONFIG_SND_DEBUG
13403 [ALC268_TEST] = "test",
13404#endif
a361d84b
KY
13405 [ALC268_AUTO] = "auto",
13406};
13407
a9111321 13408static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13409 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13410 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13411 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13412 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13413 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13414 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13415 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13416 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
0a1896b2 13417 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
a1bf8088
DC
13418 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13419 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13420 /* almost compatible with toshiba but with optional digital outs;
13421 * auto-probing seems working fine
13422 */
8871e5b9 13423 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13424 ALC268_AUTO),
a361d84b 13425 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13426 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13427 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
eb5a6621 13428 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13429 {}
13430};
13431
3abf2f36 13432/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13433static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13434 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13435 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13436 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13437 ALC268_TOSHIBA),
13438 {}
13439};
13440
a9111321 13441static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13442 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13443 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13444 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13445 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13446 alc267_quanta_il1_verbs },
13447 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13448 .dac_nids = alc268_dac_nids,
13449 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13450 .adc_nids = alc268_adc_nids_alt,
13451 .hp_nid = 0x03,
13452 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13453 .channel_mode = alc268_modes,
4f5d1706
TI
13454 .unsol_event = alc_sku_unsol_event,
13455 .setup = alc267_quanta_il1_setup,
13456 .init_hook = alc_inithook,
eb5a6621 13457 },
a361d84b 13458 [ALC268_3ST] = {
aef9d318
TI
13459 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13460 alc268_beep_mixer },
a361d84b
KY
13461 .init_verbs = { alc268_base_init_verbs },
13462 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13463 .dac_nids = alc268_dac_nids,
13464 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13465 .adc_nids = alc268_adc_nids_alt,
e1406348 13466 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13467 .hp_nid = 0x03,
13468 .dig_out_nid = ALC268_DIGOUT_NID,
13469 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13470 .channel_mode = alc268_modes,
13471 .input_mux = &alc268_capture_source,
13472 },
d1a991a6 13473 [ALC268_TOSHIBA] = {
42171c17 13474 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13475 alc268_beep_mixer },
d273809e
TI
13476 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13477 alc268_toshiba_verbs },
d1a991a6
KY
13478 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13479 .dac_nids = alc268_dac_nids,
13480 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13481 .adc_nids = alc268_adc_nids_alt,
e1406348 13482 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13483 .hp_nid = 0x03,
13484 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13485 .channel_mode = alc268_modes,
13486 .input_mux = &alc268_capture_source,
e9427969 13487 .unsol_event = alc_sku_unsol_event,
4f5d1706 13488 .setup = alc268_toshiba_setup,
e9427969 13489 .init_hook = alc_inithook,
d273809e
TI
13490 },
13491 [ALC268_ACER] = {
432fd133 13492 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13493 alc268_beep_mixer },
d273809e
TI
13494 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13495 alc268_acer_verbs },
13496 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13497 .dac_nids = alc268_dac_nids,
13498 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13499 .adc_nids = alc268_adc_nids_alt,
e1406348 13500 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13501 .hp_nid = 0x02,
13502 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13503 .channel_mode = alc268_modes,
0ccb541c 13504 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13505 .unsol_event = alc_sku_unsol_event,
13506 .setup = alc268_acer_setup,
13507 .init_hook = alc_inithook,
d1a991a6 13508 },
c238b4f4
TI
13509 [ALC268_ACER_DMIC] = {
13510 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13511 alc268_beep_mixer },
13512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13513 alc268_acer_verbs },
13514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13515 .dac_nids = alc268_dac_nids,
13516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13517 .adc_nids = alc268_adc_nids_alt,
13518 .capsrc_nids = alc268_capsrc_nids,
13519 .hp_nid = 0x02,
13520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13521 .channel_mode = alc268_modes,
13522 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13523 .unsol_event = alc_sku_unsol_event,
13524 .setup = alc268_acer_setup,
13525 .init_hook = alc_inithook,
c238b4f4 13526 },
8ef355da
KY
13527 [ALC268_ACER_ASPIRE_ONE] = {
13528 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13529 alc268_beep_mixer,
fdbc6626 13530 alc268_capture_nosrc_mixer },
8ef355da
KY
13531 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13532 alc268_acer_aspire_one_verbs },
13533 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13534 .dac_nids = alc268_dac_nids,
13535 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13536 .adc_nids = alc268_adc_nids_alt,
13537 .capsrc_nids = alc268_capsrc_nids,
13538 .hp_nid = 0x03,
13539 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13540 .channel_mode = alc268_modes,
3b8510ce 13541 .unsol_event = alc_sku_unsol_event,
4f5d1706 13542 .setup = alc268_acer_lc_setup,
3b8510ce 13543 .init_hook = alc_inithook,
8ef355da 13544 },
3866f0b0 13545 [ALC268_DELL] = {
fdbc6626
TI
13546 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13547 alc268_capture_nosrc_mixer },
3866f0b0
TI
13548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13549 alc268_dell_verbs },
13550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13551 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13553 .adc_nids = alc268_adc_nids_alt,
13554 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13555 .hp_nid = 0x02,
13556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13557 .channel_mode = alc268_modes,
a9fd4f3f 13558 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13559 .setup = alc268_dell_setup,
13560 .init_hook = alc_inithook,
3866f0b0 13561 },
f12462c5 13562 [ALC268_ZEPTO] = {
aef9d318
TI
13563 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13564 alc268_beep_mixer },
f12462c5
MT
13565 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13566 alc268_toshiba_verbs },
13567 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13568 .dac_nids = alc268_dac_nids,
13569 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13570 .adc_nids = alc268_adc_nids_alt,
e1406348 13571 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13572 .hp_nid = 0x03,
13573 .dig_out_nid = ALC268_DIGOUT_NID,
13574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13575 .channel_mode = alc268_modes,
13576 .input_mux = &alc268_capture_source,
e9427969 13577 .unsol_event = alc_sku_unsol_event,
4f5d1706 13578 .setup = alc268_toshiba_setup,
e9427969 13579 .init_hook = alc_inithook,
f12462c5 13580 },
86c53bd2
JW
13581#ifdef CONFIG_SND_DEBUG
13582 [ALC268_TEST] = {
13583 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
1f0f4b80
TI
13585 alc268_volume_init_verbs,
13586 alc268_beep_init_verbs },
86c53bd2
JW
13587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13588 .dac_nids = alc268_dac_nids,
13589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13590 .adc_nids = alc268_adc_nids_alt,
e1406348 13591 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13592 .hp_nid = 0x03,
13593 .dig_out_nid = ALC268_DIGOUT_NID,
13594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13595 .channel_mode = alc268_modes,
13596 .input_mux = &alc268_capture_source,
13597 },
13598#endif
a361d84b
KY
13599};
13600
13601static int patch_alc268(struct hda_codec *codec)
13602{
13603 struct alc_spec *spec;
13604 int board_config;
22971e3a 13605 int i, has_beep, err;
a361d84b 13606
ef86f581 13607 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13608 if (spec == NULL)
13609 return -ENOMEM;
13610
13611 codec->spec = spec;
13612
1f0f4b80
TI
13613 /* ALC268 has no aa-loopback mixer */
13614
a361d84b
KY
13615 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13616 alc268_models,
13617 alc268_cfg_tbl);
13618
3abf2f36
TI
13619 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13620 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13621 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13622
a361d84b 13623 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13625 codec->chip_name);
a361d84b
KY
13626 board_config = ALC268_AUTO;
13627 }
13628
13629 if (board_config == ALC268_AUTO) {
13630 /* automatic parse from the BIOS config */
13631 err = alc268_parse_auto_config(codec);
13632 if (err < 0) {
13633 alc_free(codec);
13634 return err;
13635 } else if (!err) {
13636 printk(KERN_INFO
13637 "hda_codec: Cannot set up configuration "
13638 "from BIOS. Using base mode...\n");
13639 board_config = ALC268_3ST;
13640 }
13641 }
13642
13643 if (board_config != ALC268_AUTO)
e9c364c0 13644 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13645
22971e3a
TI
13646 has_beep = 0;
13647 for (i = 0; i < spec->num_mixers; i++) {
13648 if (spec->mixers[i] == alc268_beep_mixer) {
13649 has_beep = 1;
13650 break;
13651 }
13652 }
13653
13654 if (has_beep) {
13655 err = snd_hda_attach_beep_device(codec, 0x1);
13656 if (err < 0) {
13657 alc_free(codec);
13658 return err;
13659 }
13660 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13661 /* override the amp caps for beep generator */
13662 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13663 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13664 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13665 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13666 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13667 }
aef9d318 13668
7e0e44d4 13669 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
d6cc9fab 13670 alc_auto_fill_adc_caps(codec);
21268961 13671 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 13672 alc_remove_invalid_adc_nids(codec);
a361d84b 13673 }
2134ea4f 13674
d6cc9fab
TI
13675 if (!spec->cap_mixer && !spec->no_analog)
13676 set_capture_mixer(codec);
13677
2134ea4f
TI
13678 spec->vmaster_nid = 0x02;
13679
a361d84b
KY
13680 codec->patch_ops = alc_patch_ops;
13681 if (board_config == ALC268_AUTO)
13682 spec->init_hook = alc268_auto_init;
1c716153 13683 spec->shutup = alc_eapd_shutup;
ea1fb29a 13684
bf1b0225
KY
13685 alc_init_jacks(codec);
13686
a361d84b
KY
13687 return 0;
13688}
13689
f6a92248
KY
13690/*
13691 * ALC269 channel source setting (2 channel)
13692 */
13693#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13694
13695#define alc269_dac_nids alc260_dac_nids
13696
4c6d72d1 13697static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 13698 /* ADC1 */
f53281e6
KY
13699 0x08,
13700};
13701
4c6d72d1 13702static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
13703 0x23,
13704};
13705
4c6d72d1 13706static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
13707 /* ADC1 */
13708 0x09,
13709};
13710
4c6d72d1 13711static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
13712 0x22,
13713};
13714
f6a92248
KY
13715#define alc269_modes alc260_modes
13716#define alc269_capture_source alc880_lg_lw_capture_source
13717
a9111321 13718static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
13719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
13726 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13727 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
13729 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13730 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13731 { } /* end */
13732};
13733
a9111321 13734static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
13735 /* output mixer control */
13736 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13737 {
13738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13739 .name = "Master Playback Switch",
5e26dfd0 13740 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13741 .info = snd_hda_mixer_amp_switch_info,
13742 .get = snd_hda_mixer_amp_switch_get,
13743 .put = alc268_acer_master_sw_put,
13744 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13745 },
13746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13748 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
13749 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13750 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13751 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
13752 { }
13753};
13754
a9111321 13755static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
13756 /* output mixer control */
13757 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13758 {
13759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13760 .name = "Master Playback Switch",
5e26dfd0 13761 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13762 .info = snd_hda_mixer_amp_switch_info,
13763 .get = snd_hda_mixer_amp_switch_get,
13764 .put = alc268_acer_master_sw_put,
13765 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13766 },
13767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13769 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
13770 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13771 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13772 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
13773 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13774 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 13775 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
13776 { }
13777};
13778
a9111321 13779static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13780 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13781 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13783 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13784 { } /* end */
13785};
13786
a9111321 13787static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
13788 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13791 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13792 { } /* end */
13793};
13794
a9111321 13795static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
13796 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13797 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13798 { } /* end */
13799};
13800
f53281e6 13801/* capture mixer elements */
a9111321 13802static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
13803 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13804 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
13805 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13806 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
13807 { } /* end */
13808};
13809
a9111321 13810static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13811 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13812 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 13813 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
13814 { } /* end */
13815};
13816
a9111321 13817static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
13818 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13819 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
13820 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13821 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
13822 { } /* end */
13823};
13824
a9111321 13825static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
13826 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13827 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 13828 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
13829 { } /* end */
13830};
13831
26f5df26 13832/* FSC amilo */
84898e87 13833#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13834
a9111321 13835static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
13836 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13839 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13840 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13841 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13842 { }
13843};
f6a92248 13844
a9111321 13845static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
13846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13848 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13850 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13852 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13853 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13854 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13856 { }
13857};
13858
60db6b53
KY
13859/* toggle speaker-output according to the hp-jack state */
13860static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13861{
3b8510ce 13862 alc_hp_automute(codec);
f6a92248 13863
60db6b53
KY
13864 snd_hda_codec_write(codec, 0x20, 0,
13865 AC_VERB_SET_COEF_INDEX, 0x0c);
13866 snd_hda_codec_write(codec, 0x20, 0,
13867 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13868
60db6b53
KY
13869 snd_hda_codec_write(codec, 0x20, 0,
13870 AC_VERB_SET_COEF_INDEX, 0x0c);
13871 snd_hda_codec_write(codec, 0x20, 0,
13872 AC_VERB_SET_PROC_COEF, 0x480);
13873}
f6a92248 13874
3b8510ce
TI
13875#define alc269_lifebook_speaker_automute \
13876 alc269_quanta_fl1_speaker_automute
64154835 13877
64154835
TV
13878static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13879{
13880 unsigned int present_laptop;
13881 unsigned int present_dock;
13882
864f92be
WF
13883 present_laptop = snd_hda_jack_detect(codec, 0x18);
13884 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13885
13886 /* Laptop mic port overrides dock mic port, design decision */
13887 if (present_dock)
13888 snd_hda_codec_write(codec, 0x23, 0,
13889 AC_VERB_SET_CONNECT_SEL, 0x3);
13890 if (present_laptop)
13891 snd_hda_codec_write(codec, 0x23, 0,
13892 AC_VERB_SET_CONNECT_SEL, 0x0);
13893 if (!present_dock && !present_laptop)
13894 snd_hda_codec_write(codec, 0x23, 0,
13895 AC_VERB_SET_CONNECT_SEL, 0x1);
13896}
13897
60db6b53
KY
13898static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13899 unsigned int res)
13900{
4f5d1706
TI
13901 switch (res >> 26) {
13902 case ALC880_HP_EVENT:
60db6b53 13903 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13904 break;
13905 case ALC880_MIC_EVENT:
13906 alc_mic_automute(codec);
13907 break;
13908 }
60db6b53 13909}
f6a92248 13910
64154835
TV
13911static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13912 unsigned int res)
13913{
13914 if ((res >> 26) == ALC880_HP_EVENT)
13915 alc269_lifebook_speaker_automute(codec);
13916 if ((res >> 26) == ALC880_MIC_EVENT)
13917 alc269_lifebook_mic_autoswitch(codec);
13918}
13919
4f5d1706
TI
13920static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13921{
13922 struct alc_spec *spec = codec->spec;
20645d70
TI
13923 spec->autocfg.hp_pins[0] = 0x15;
13924 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
13925 spec->automute_mixer_nid[0] = 0x0c;
13926 spec->automute = 1;
13927 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
13928 spec->ext_mic_pin = 0x18;
13929 spec->int_mic_pin = 0x19;
4f5d1706
TI
13930 spec->auto_mic = 1;
13931}
13932
60db6b53
KY
13933static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13934{
13935 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13936 alc_mic_automute(codec);
60db6b53 13937}
f6a92248 13938
3b8510ce
TI
13939static void alc269_lifebook_setup(struct hda_codec *codec)
13940{
13941 struct alc_spec *spec = codec->spec;
13942 spec->autocfg.hp_pins[0] = 0x15;
13943 spec->autocfg.hp_pins[1] = 0x1a;
13944 spec->autocfg.speaker_pins[0] = 0x14;
13945 spec->automute_mixer_nid[0] = 0x0c;
13946 spec->automute = 1;
13947 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13948}
13949
64154835
TV
13950static void alc269_lifebook_init_hook(struct hda_codec *codec)
13951{
13952 alc269_lifebook_speaker_automute(codec);
13953 alc269_lifebook_mic_autoswitch(codec);
13954}
13955
a9111321 13956static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
13957 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13958 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13959 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13961 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13963 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13964 {}
13965};
13966
a9111321 13967static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
13968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13969 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13970 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13971 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13972 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13973 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13974 {}
13975};
13976
a9111321 13977static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
13978 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13979 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13980 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13984 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13985 {}
13986};
13987
a9111321 13988static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
13989 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13990 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13993 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13994 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13995 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13996 {}
13997};
13998
a9111321 13999static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14000 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14001 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14007 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14009 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14010 { }
14011};
14012
226b1ec8 14013static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14014{
4f5d1706 14015 struct alc_spec *spec = codec->spec;
20645d70
TI
14016 spec->autocfg.hp_pins[0] = 0x15;
14017 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14018 spec->automute_mixer_nid[0] = 0x0c;
14019 spec->automute = 1;
14020 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
14021 spec->ext_mic_pin = 0x18;
14022 spec->int_mic_pin = 0x19;
4f5d1706 14023 spec->auto_mic = 1;
f53281e6
KY
14024}
14025
226b1ec8 14026static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14027{
14028 struct alc_spec *spec = codec->spec;
20645d70
TI
14029 spec->autocfg.hp_pins[0] = 0x15;
14030 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14031 spec->automute_mixer_nid[0] = 0x0c;
14032 spec->automute = 1;
14033 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
14034 spec->ext_mic_pin = 0x18;
14035 spec->int_mic_pin = 0x12;
84898e87
KY
14036 spec->auto_mic = 1;
14037}
14038
226b1ec8 14039static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14040{
4f5d1706 14041 struct alc_spec *spec = codec->spec;
226b1ec8 14042 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14043 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14044 spec->automute_mixer_nid[0] = 0x0c;
14045 spec->automute = 1;
14046 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
14047 spec->ext_mic_pin = 0x18;
14048 spec->int_mic_pin = 0x19;
4f5d1706 14049 spec->auto_mic = 1;
f53281e6
KY
14050}
14051
226b1ec8
KY
14052static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14053{
14054 struct alc_spec *spec = codec->spec;
14055 spec->autocfg.hp_pins[0] = 0x21;
14056 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14057 spec->automute_mixer_nid[0] = 0x0c;
14058 spec->automute = 1;
14059 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
14060 spec->ext_mic_pin = 0x18;
14061 spec->int_mic_pin = 0x12;
226b1ec8
KY
14062 spec->auto_mic = 1;
14063}
14064
60db6b53
KY
14065/*
14066 * generic initialization of ADC, input mixers and output mixers
14067 */
a9111321 14068static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14069 /*
14070 * Unmute ADC0 and set the default input to mic-in
14071 */
84898e87 14072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14073
14074 /*
84898e87 14075 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14076 */
14077 /* set vol=0 to output mixers */
14078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14080
14081 /* set up input amps for analog loopback */
14082 /* Amp Indices: DAC = 0, mixer = 1 */
14083 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14085 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14086 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14089
14090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14092 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14097
14098 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14100
84898e87
KY
14101 /* FIXME: use Mux-type input source selection */
14102 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14103 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14104 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14105
84898e87
KY
14106 /* set EAPD */
14107 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14108 { }
14109};
14110
a9111321 14111static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14112 /*
14113 * Unmute ADC0 and set the default input to mic-in
14114 */
14115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14116
14117 /*
14118 * Set up output mixers (0x02 - 0x03)
14119 */
14120 /* set vol=0 to output mixers */
14121 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14122 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14123
14124 /* set up input amps for analog loopback */
14125 /* Amp Indices: DAC = 0, mixer = 1 */
14126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14132
14133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14134 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14135 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14136 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14137 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14138 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14140
14141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14143
14144 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14145 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14146 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14147 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14148
14149 /* set EAPD */
14150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14151 { }
14152};
14153
9d0b71b1
TI
14154#define alc269_auto_create_multi_out_ctls \
14155 alc268_auto_create_multi_out_ctls
f6a92248
KY
14156
14157#ifdef CONFIG_SND_HDA_POWER_SAVE
14158#define alc269_loopbacks alc880_loopbacks
14159#endif
14160
a9111321 14161static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14162 .substreams = 1,
14163 .channels_min = 2,
14164 .channels_max = 8,
14165 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14166 /* NID is set in alc_build_pcms */
14167 .ops = {
c2d986b0
TI
14168 .open = alc_playback_pcm_open,
14169 .prepare = alc_playback_pcm_prepare,
14170 .cleanup = alc_playback_pcm_cleanup
f03d3115
TI
14171 },
14172};
14173
a9111321 14174static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14175 .substreams = 1,
14176 .channels_min = 2,
14177 .channels_max = 2,
14178 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14179 /* NID is set in alc_build_pcms */
14180};
14181
ad35879a
TI
14182#ifdef CONFIG_SND_HDA_POWER_SAVE
14183static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14184{
14185 switch (codec->subsystem_id) {
14186 case 0x103c1586:
14187 return 1;
14188 }
14189 return 0;
14190}
14191
14192static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14193{
14194 /* update mute-LED according to the speaker mute state */
14195 if (nid == 0x01 || nid == 0x14) {
14196 int pinval;
14197 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14198 HDA_AMP_MUTE)
14199 pinval = 0x24;
14200 else
14201 pinval = 0x20;
14202 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14203 snd_hda_codec_update_cache(codec, 0x19, 0,
14204 AC_VERB_SET_PIN_WIDGET_CONTROL,
14205 pinval);
ad35879a
TI
14206 }
14207 return alc_check_power_status(codec, nid);
14208}
14209#endif /* CONFIG_SND_HDA_POWER_SAVE */
14210
d433a678
TI
14211/* different alc269-variants */
14212enum {
b6878571 14213 ALC269_TYPE_ALC269VA,
48c88e82 14214 ALC269_TYPE_ALC269VB,
b6878571 14215 ALC269_TYPE_ALC269VC,
d433a678
TI
14216};
14217
f6a92248
KY
14218/*
14219 * BIOS auto configuration
14220 */
14221static int alc269_parse_auto_config(struct hda_codec *codec)
14222{
14223 struct alc_spec *spec = codec->spec;
cfb9fb55 14224 int err;
4c6d72d1 14225 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14226
14227 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14228 alc269_ignore);
14229 if (err < 0)
14230 return err;
14231
14232 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14233 if (err < 0)
14234 return err;
b7821709 14235 err = alc_auto_create_input_ctls(codec);
f6a92248
KY
14236 if (err < 0)
14237 return err;
14238
14239 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14240
757899ac 14241 alc_auto_parse_digital(codec);
f6a92248 14242
603c4019 14243 if (spec->kctls.list)
d88897ea 14244 add_mixer(spec, spec->kctls.list);
f6a92248 14245
21268961
TI
14246 alc_remove_invalid_adc_nids(codec);
14247
b6878571 14248 if (spec->codec_variant != ALC269_TYPE_ALC269VA)
6227cdce 14249 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
1f0f4b80 14250 else
6227cdce 14251 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
21268961 14252 alc_auto_check_switches(codec);
6694635d 14253
f6a92248
KY
14254 err = alc_auto_add_mic_boost(codec);
14255 if (err < 0)
14256 return err;
14257
7e0e44d4 14258 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14259 set_capture_mixer(codec);
f53281e6 14260
f6a92248
KY
14261 return 1;
14262}
14263
e9af4f36
TI
14264#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14265#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14266
14267
14268/* init callback for auto-configuration model -- overriding the default init */
14269static void alc269_auto_init(struct hda_codec *codec)
14270{
f6c7e546 14271 struct alc_spec *spec = codec->spec;
f6a92248
KY
14272 alc269_auto_init_multi_out(codec);
14273 alc269_auto_init_hp_out(codec);
0a7f5320 14274 alc_auto_init_analog_input(codec);
f970de25 14275 alc_auto_init_input_src(codec);
757899ac 14276 alc_auto_init_digital(codec);
f6c7e546 14277 if (spec->unsol_event)
7fb0d78f 14278 alc_inithook(codec);
f6a92248
KY
14279}
14280
0ec33d1f
TI
14281static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14282{
14283 int val = alc_read_coef_idx(codec, 0x04);
14284 if (power_up)
14285 val |= 1 << 11;
14286 else
14287 val &= ~(1 << 11);
14288 alc_write_coef_idx(codec, 0x04, val);
14289}
14290
5402e4cb 14291static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14292{
0ec33d1f
TI
14293 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14294 alc269_toggle_power_output(codec, 0);
977ddd6b 14295 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14296 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14297 msleep(150);
14298 }
977ddd6b 14299}
0ec33d1f 14300
5402e4cb 14301#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14302static int alc269_resume(struct hda_codec *codec)
14303{
977ddd6b 14304 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14305 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14306 msleep(150);
14307 }
14308
14309 codec->patch_ops.init(codec);
14310
14311 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14312 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14313 msleep(200);
14314 }
14315
0ec33d1f
TI
14316 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14317 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14318
14319 snd_hda_codec_resume_amp(codec);
14320 snd_hda_codec_resume_cache(codec);
9e5341b9 14321 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14322 return 0;
14323}
0ec33d1f 14324#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14325
1a99d4a4 14326static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14327 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14328{
14329 int coef;
14330
58701120 14331 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14332 return;
1a99d4a4
KY
14333 coef = alc_read_coef_idx(codec, 0x1e);
14334 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14335}
14336
6981d184
TI
14337static void alc271_fixup_dmic(struct hda_codec *codec,
14338 const struct alc_fixup *fix, int action)
14339{
a9111321 14340 static const struct hda_verb verbs[] = {
6981d184
TI
14341 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14342 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14343 {}
14344 };
14345 unsigned int cfg;
14346
14347 if (strcmp(codec->chip_name, "ALC271X"))
14348 return;
14349 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14350 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14351 snd_hda_sequence_write(codec, verbs);
14352}
14353
ff818c24
TI
14354enum {
14355 ALC269_FIXUP_SONY_VAIO,
74dc8909 14356 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14357 ALC269_FIXUP_DELL_M101Z,
022c92be 14358 ALC269_FIXUP_SKU_IGNORE,
ac612407 14359 ALC269_FIXUP_ASUS_G73JW,
357f915e 14360 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14361 ALC275_FIXUP_SONY_HWEQ,
6981d184 14362 ALC271_FIXUP_DMIC,
ff818c24
TI
14363};
14364
ff818c24
TI
14365static const struct alc_fixup alc269_fixups[] = {
14366 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14367 .type = ALC_FIXUP_VERBS,
14368 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14369 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14370 {}
14371 }
ff818c24 14372 },
74dc8909 14373 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14374 .type = ALC_FIXUP_VERBS,
14375 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14376 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14377 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14378 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14379 { }
b5bfbc67
TI
14380 },
14381 .chained = true,
14382 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14383 },
145a902b 14384 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14385 .type = ALC_FIXUP_VERBS,
14386 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14387 /* Enables internal speaker */
14388 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14389 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14390 {}
14391 }
14392 },
022c92be 14393 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14394 .type = ALC_FIXUP_SKU,
14395 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14396 },
ac612407 14397 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14398 .type = ALC_FIXUP_PINS,
14399 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14400 { 0x17, 0x99130111 }, /* subwoofer */
14401 { }
14402 }
14403 },
357f915e 14404 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14405 .type = ALC_FIXUP_VERBS,
14406 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14407 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14408 {}
14409 }
14410 },
1a99d4a4 14411 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14412 .type = ALC_FIXUP_FUNC,
14413 .v.func = alc269_fixup_hweq,
14414 .chained = true,
14415 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14416 },
14417 [ALC271_FIXUP_DMIC] = {
14418 .type = ALC_FIXUP_FUNC,
14419 .v.func = alc271_fixup_dmic,
14420 },
ff818c24
TI
14421};
14422
a9111321 14423static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14424 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14425 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14426 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14427 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14428 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14429 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14430 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14431 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14432 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14433 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14434 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14435 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14436 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14437 {}
14438};
14439
14440
f6a92248
KY
14441/*
14442 * configuration and preset
14443 */
ea734963 14444static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14445 [ALC269_BASIC] = "basic",
2922c9af 14446 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14447 [ALC269_AMIC] = "laptop-amic",
14448 [ALC269_DMIC] = "laptop-dmic",
64154835 14449 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14450 [ALC269_LIFEBOOK] = "lifebook",
14451 [ALC269_AUTO] = "auto",
f6a92248
KY
14452};
14453
a9111321 14454static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14455 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14456 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14457 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14458 ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14468 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14469 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14471 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14472 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14473 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14474 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14475 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14476 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14477 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14478 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14479 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14480 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14481 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14482 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14483 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14484 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14485 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14486 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14487 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14488 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14489 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14490 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14491 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14492 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14493 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14494 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14495 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14496 ALC269_DMIC),
60db6b53 14497 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14498 ALC269_DMIC),
14499 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14500 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14501 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14502 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14503 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14504 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14505 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14506 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14507 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14508 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14509 {}
14510};
14511
a9111321 14512static const struct alc_config_preset alc269_presets[] = {
f6a92248 14513 [ALC269_BASIC] = {
f9e336f6 14514 .mixers = { alc269_base_mixer },
f6a92248
KY
14515 .init_verbs = { alc269_init_verbs },
14516 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14517 .dac_nids = alc269_dac_nids,
14518 .hp_nid = 0x03,
14519 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14520 .channel_mode = alc269_modes,
14521 .input_mux = &alc269_capture_source,
14522 },
60db6b53
KY
14523 [ALC269_QUANTA_FL1] = {
14524 .mixers = { alc269_quanta_fl1_mixer },
14525 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14526 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14527 .dac_nids = alc269_dac_nids,
14528 .hp_nid = 0x03,
14529 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14530 .channel_mode = alc269_modes,
14531 .input_mux = &alc269_capture_source,
14532 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14533 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14534 .init_hook = alc269_quanta_fl1_init_hook,
14535 },
84898e87
KY
14536 [ALC269_AMIC] = {
14537 .mixers = { alc269_laptop_mixer },
14538 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14539 .init_verbs = { alc269_init_verbs,
84898e87 14540 alc269_laptop_amic_init_verbs },
f53281e6
KY
14541 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14542 .dac_nids = alc269_dac_nids,
14543 .hp_nid = 0x03,
14544 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14545 .channel_mode = alc269_modes,
3b8510ce 14546 .unsol_event = alc_sku_unsol_event,
84898e87 14547 .setup = alc269_laptop_amic_setup,
3b8510ce 14548 .init_hook = alc_inithook,
f53281e6 14549 },
84898e87
KY
14550 [ALC269_DMIC] = {
14551 .mixers = { alc269_laptop_mixer },
14552 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14553 .init_verbs = { alc269_init_verbs,
84898e87
KY
14554 alc269_laptop_dmic_init_verbs },
14555 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14556 .dac_nids = alc269_dac_nids,
14557 .hp_nid = 0x03,
14558 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14559 .channel_mode = alc269_modes,
3b8510ce 14560 .unsol_event = alc_sku_unsol_event,
84898e87 14561 .setup = alc269_laptop_dmic_setup,
3b8510ce 14562 .init_hook = alc_inithook,
84898e87
KY
14563 },
14564 [ALC269VB_AMIC] = {
14565 .mixers = { alc269vb_laptop_mixer },
14566 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14567 .init_verbs = { alc269vb_init_verbs,
14568 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14569 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14570 .dac_nids = alc269_dac_nids,
14571 .hp_nid = 0x03,
14572 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14573 .channel_mode = alc269_modes,
3b8510ce 14574 .unsol_event = alc_sku_unsol_event,
226b1ec8 14575 .setup = alc269vb_laptop_amic_setup,
3b8510ce 14576 .init_hook = alc_inithook,
84898e87
KY
14577 },
14578 [ALC269VB_DMIC] = {
14579 .mixers = { alc269vb_laptop_mixer },
14580 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14581 .init_verbs = { alc269vb_init_verbs,
14582 alc269vb_laptop_dmic_init_verbs },
14583 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14584 .dac_nids = alc269_dac_nids,
14585 .hp_nid = 0x03,
14586 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14587 .channel_mode = alc269_modes,
3b8510ce 14588 .unsol_event = alc_sku_unsol_event,
84898e87 14589 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 14590 .init_hook = alc_inithook,
f53281e6 14591 },
26f5df26 14592 [ALC269_FUJITSU] = {
45bdd1c1 14593 .mixers = { alc269_fujitsu_mixer },
84898e87 14594 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14595 .init_verbs = { alc269_init_verbs,
84898e87 14596 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14597 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14598 .dac_nids = alc269_dac_nids,
14599 .hp_nid = 0x03,
14600 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14601 .channel_mode = alc269_modes,
3b8510ce 14602 .unsol_event = alc_sku_unsol_event,
84898e87 14603 .setup = alc269_laptop_dmic_setup,
3b8510ce 14604 .init_hook = alc_inithook,
26f5df26 14605 },
64154835
TV
14606 [ALC269_LIFEBOOK] = {
14607 .mixers = { alc269_lifebook_mixer },
14608 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14609 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14610 .dac_nids = alc269_dac_nids,
14611 .hp_nid = 0x03,
14612 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14613 .channel_mode = alc269_modes,
14614 .input_mux = &alc269_capture_source,
14615 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 14616 .setup = alc269_lifebook_setup,
64154835
TV
14617 .init_hook = alc269_lifebook_init_hook,
14618 },
fe3eb0a7
KY
14619 [ALC271_ACER] = {
14620 .mixers = { alc269_asus_mixer },
14621 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14622 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14623 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14624 .dac_nids = alc269_dac_nids,
14625 .adc_nids = alc262_dmic_adc_nids,
14626 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14627 .capsrc_nids = alc262_dmic_capsrc_nids,
14628 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14629 .channel_mode = alc269_modes,
14630 .input_mux = &alc269_capture_source,
14631 .dig_out_nid = ALC880_DIGOUT_NID,
14632 .unsol_event = alc_sku_unsol_event,
14633 .setup = alc269vb_laptop_dmic_setup,
14634 .init_hook = alc_inithook,
14635 },
f6a92248
KY
14636};
14637
977ddd6b
KY
14638static int alc269_fill_coef(struct hda_codec *codec)
14639{
14640 int val;
14641
14642 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14643 alc_write_coef_idx(codec, 0xf, 0x960b);
14644 alc_write_coef_idx(codec, 0xe, 0x8817);
14645 }
14646
14647 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14648 alc_write_coef_idx(codec, 0xf, 0x960b);
14649 alc_write_coef_idx(codec, 0xe, 0x8814);
14650 }
14651
14652 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14653 val = alc_read_coef_idx(codec, 0x04);
14654 /* Power up output pin */
14655 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14656 }
14657
14658 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14659 val = alc_read_coef_idx(codec, 0xd);
14660 if ((val & 0x0c00) >> 10 != 0x1) {
14661 /* Capless ramp up clock control */
b896b4eb 14662 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
14663 }
14664 val = alc_read_coef_idx(codec, 0x17);
14665 if ((val & 0x01c0) >> 6 != 0x4) {
14666 /* Class D power on reset */
b896b4eb 14667 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
14668 }
14669 }
b896b4eb
KY
14670
14671 val = alc_read_coef_idx(codec, 0xd); /* Class D */
14672 alc_write_coef_idx(codec, 0xd, val | (1<<14));
14673
14674 val = alc_read_coef_idx(codec, 0x4); /* HP */
14675 alc_write_coef_idx(codec, 0x4, val | (1<<11));
14676
977ddd6b
KY
14677 return 0;
14678}
14679
f6a92248
KY
14680static int patch_alc269(struct hda_codec *codec)
14681{
14682 struct alc_spec *spec;
48c88e82 14683 int board_config, coef;
f6a92248
KY
14684 int err;
14685
14686 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14687 if (spec == NULL)
14688 return -ENOMEM;
14689
14690 codec->spec = spec;
14691
1f0f4b80
TI
14692 spec->mixer_nid = 0x0b;
14693
da00c244
KY
14694 alc_auto_parse_customize_define(codec);
14695
c793bec5 14696 if (codec->vendor_id == 0x10ec0269) {
b6878571 14697 spec->codec_variant = ALC269_TYPE_ALC269VA;
c793bec5
KY
14698 coef = alc_read_coef_idx(codec, 0);
14699 if ((coef & 0x00f0) == 0x0010) {
14700 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14701 spec->cdefine.platform_type == 1) {
14702 alc_codec_rename(codec, "ALC271X");
c793bec5
KY
14703 } else if ((coef & 0xf000) == 0x2000) {
14704 alc_codec_rename(codec, "ALC259");
c793bec5
KY
14705 } else if ((coef & 0xf000) == 0x3000) {
14706 alc_codec_rename(codec, "ALC258");
b6878571
KY
14707 } else if ((coef & 0xfff0) == 0x3010) {
14708 alc_codec_rename(codec, "ALC277");
c793bec5
KY
14709 } else {
14710 alc_codec_rename(codec, "ALC269VB");
c793bec5 14711 }
b6878571
KY
14712 spec->codec_variant = ALC269_TYPE_ALC269VB;
14713 } else if ((coef & 0x00f0) == 0x0020) {
14714 if (coef == 0xa023)
14715 alc_codec_rename(codec, "ALC259");
14716 else if (coef == 0x6023)
14717 alc_codec_rename(codec, "ALC281X");
14718 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
14719 codec->bus->pci->subsystem_device == 0x21f3)
14720 alc_codec_rename(codec, "ALC3202");
14721 else
14722 alc_codec_rename(codec, "ALC269VC");
14723 spec->codec_variant = ALC269_TYPE_ALC269VC;
c793bec5
KY
14724 } else
14725 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14726 alc269_fill_coef(codec);
14727 }
977ddd6b 14728
f6a92248
KY
14729 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14730 alc269_models,
14731 alc269_cfg_tbl);
14732
14733 if (board_config < 0) {
9a11f1aa
TI
14734 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14735 codec->chip_name);
f6a92248
KY
14736 board_config = ALC269_AUTO;
14737 }
14738
b5bfbc67
TI
14739 if (board_config == ALC269_AUTO) {
14740 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14741 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14742 }
ff818c24 14743
f6a92248
KY
14744 if (board_config == ALC269_AUTO) {
14745 /* automatic parse from the BIOS config */
14746 err = alc269_parse_auto_config(codec);
14747 if (err < 0) {
14748 alc_free(codec);
14749 return err;
14750 } else if (!err) {
14751 printk(KERN_INFO
14752 "hda_codec: Cannot set up configuration "
14753 "from BIOS. Using base mode...\n");
14754 board_config = ALC269_BASIC;
14755 }
14756 }
14757
dc1eae25 14758 if (has_cdefine_beep(codec)) {
8af2591d
TI
14759 err = snd_hda_attach_beep_device(codec, 0x1);
14760 if (err < 0) {
14761 alc_free(codec);
14762 return err;
14763 }
680cd536
KK
14764 }
14765
f6a92248 14766 if (board_config != ALC269_AUTO)
e9c364c0 14767 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14768
84898e87 14769 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14770 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14771 * fix the sample rate of analog I/O to 44.1kHz
14772 */
14773 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14774 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
f03d3115 14775 }
f6a92248 14776
6694635d 14777 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
d6cc9fab 14778 alc_auto_fill_adc_caps(codec);
21268961 14779 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 14780 alc_remove_invalid_adc_nids(codec);
84898e87
KY
14781 }
14782
f9e336f6 14783 if (!spec->cap_mixer)
b59bdf3b 14784 set_capture_mixer(codec);
dc1eae25 14785 if (has_cdefine_beep(codec))
da00c244 14786 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14787
b5bfbc67 14788 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 14789
100d5eb3
TI
14790 spec->vmaster_nid = 0x02;
14791
f6a92248 14792 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
14793#ifdef SND_HDA_NEEDS_RESUME
14794 codec->patch_ops.resume = alc269_resume;
14795#endif
f6a92248
KY
14796 if (board_config == ALC269_AUTO)
14797 spec->init_hook = alc269_auto_init;
5402e4cb 14798 spec->shutup = alc269_shutup;
bf1b0225
KY
14799
14800 alc_init_jacks(codec);
f6a92248
KY
14801#ifdef CONFIG_SND_HDA_POWER_SAVE
14802 if (!spec->loopback.amplist)
14803 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14804 if (alc269_mic2_for_mute_led(codec))
14805 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14806#endif
14807
14808 return 0;
14809}
14810
df694daa
KY
14811/*
14812 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14813 */
14814
14815/*
14816 * set the path ways for 2 channel output
14817 * need to set the codec line out and mic 1 pin widgets to inputs
14818 */
a9111321 14819static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
14820 /* set pin widget 1Ah (line in) for input */
14821 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14822 /* set pin widget 18h (mic1/2) for input, for mic also enable
14823 * the vref
14824 */
df694daa
KY
14825 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14826
9c7f852e
TI
14827 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14828#if 0
14829 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14830 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14831#endif
df694daa
KY
14832 { } /* end */
14833};
14834/*
14835 * 6ch mode
14836 * need to set the codec line out and mic 1 pin widgets to outputs
14837 */
a9111321 14838static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
14839 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14840 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14841 /* set pin widget 18h (mic1) for output (CLFE)*/
14842 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14843
14844 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14845 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14846
9c7f852e
TI
14847 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14848#if 0
14849 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14850 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14851#endif
df694daa
KY
14852 { } /* end */
14853};
14854
a9111321 14855static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
14856 { 2, alc861_threestack_ch2_init },
14857 { 6, alc861_threestack_ch6_init },
14858};
22309c3e 14859/* Set mic1 as input and unmute the mixer */
a9111321 14860static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
14861 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14862 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14863 { } /* end */
14864};
14865/* Set mic1 as output and mute mixer */
a9111321 14866static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
14867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14868 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14869 { } /* end */
14870};
14871
a9111321 14872static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
14873 { 2, alc861_uniwill_m31_ch2_init },
14874 { 4, alc861_uniwill_m31_ch4_init },
14875};
df694daa 14876
7cdbff94 14877/* Set mic1 and line-in as input and unmute the mixer */
a9111321 14878static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
14879 /* set pin widget 1Ah (line in) for input */
14880 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14881 /* set pin widget 18h (mic1/2) for input, for mic also enable
14882 * the vref
14883 */
7cdbff94
MD
14884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14885
14886 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14887#if 0
14888 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14889 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14890#endif
14891 { } /* end */
14892};
14893/* Set mic1 nad line-in as output and mute mixer */
a9111321 14894static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
14895 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14896 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14897 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14898 /* set pin widget 18h (mic1) for output (CLFE)*/
14899 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14900 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14901 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14902 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14903
14904 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14905#if 0
14906 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14907 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14908#endif
14909 { } /* end */
14910};
14911
a9111321 14912static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
14913 { 2, alc861_asus_ch2_init },
14914 { 6, alc861_asus_ch6_init },
14915};
14916
df694daa
KY
14917/* patch-ALC861 */
14918
a9111321 14919static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
14920 /* output mixer control */
14921 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14922 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14923 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14925 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14926
14927 /*Input mixer control */
14928 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14930 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14933 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14935 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14938
df694daa
KY
14939 { } /* end */
14940};
14941
a9111321 14942static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
14943 /* output mixer control */
14944 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14945 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14946 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14947 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14948 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14949
14950 /* Input mixer control */
14951 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14952 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14953 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14954 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14955 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14956 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14957 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14958 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 14961
df694daa
KY
14962 {
14963 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14964 .name = "Channel Mode",
14965 .info = alc_ch_mode_info,
14966 .get = alc_ch_mode_get,
14967 .put = alc_ch_mode_put,
14968 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14969 },
14970 { } /* end */
a53d1aec
TD
14971};
14972
a9111321 14973static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
14974 /* output mixer control */
14975 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14977 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 14978
a53d1aec 14979 { } /* end */
f12ab1e0 14980};
a53d1aec 14981
a9111321 14982static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
14983 /* output mixer control */
14984 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14985 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14986 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14987 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14988 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14989
14990 /* Input mixer control */
14991 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14993 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14994 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14995 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14996 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14998 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15001
22309c3e
TI
15002 {
15003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15004 .name = "Channel Mode",
15005 .info = alc_ch_mode_info,
15006 .get = alc_ch_mode_get,
15007 .put = alc_ch_mode_put,
15008 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15009 },
15010 { } /* end */
f12ab1e0 15011};
7cdbff94 15012
a9111321 15013static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15014 /* output mixer control */
15015 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15016 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15017 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15018 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15019 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15020
15021 /* Input mixer control */
15022 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15023 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15024 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15025 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15026 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15027 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15029 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15032
7cdbff94
MD
15033 {
15034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15035 .name = "Channel Mode",
15036 .info = alc_ch_mode_info,
15037 .get = alc_ch_mode_get,
15038 .put = alc_ch_mode_put,
15039 .private_value = ARRAY_SIZE(alc861_asus_modes),
15040 },
15041 { }
56bb0cab
TI
15042};
15043
15044/* additional mixer */
a9111321 15045static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15046 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15047 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15048 { }
15049};
7cdbff94 15050
df694daa
KY
15051/*
15052 * generic initialization of ADC, input mixers and output mixers
15053 */
a9111321 15054static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15055 /*
15056 * Unmute ADC0 and set the default input to mic-in
15057 */
15058 /* port-A for surround (rear panel) */
15059 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15060 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15061 /* port-B for mic-in (rear panel) with vref */
15062 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15063 /* port-C for line-in (rear panel) */
15064 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15065 /* port-D for Front */
15066 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15067 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15068 /* port-E for HP out (front panel) */
15069 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15070 /* route front PCM to HP */
9dece1d7 15071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15072 /* port-F for mic-in (front panel) with vref */
15073 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15074 /* port-G for CLFE (rear panel) */
15075 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15076 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15077 /* port-H for side (rear panel) */
15078 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15079 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15080 /* CD-in */
15081 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15082 /* route front mic to ADC1*/
15083 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15084 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15085
df694daa
KY
15086 /* Unmute DAC0~3 & spdif out*/
15087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15088 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15089 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15090 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15092
df694daa
KY
15093 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15094 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15095 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15096 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15097 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15098
df694daa
KY
15099 /* Unmute Stereo Mixer 15 */
15100 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15103 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15104
15105 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15106 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15107 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15108 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15111 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15112 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15113 /* hp used DAC 3 (Front) */
15114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15115 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15116
15117 { }
15118};
15119
a9111321 15120static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15121 /*
15122 * Unmute ADC0 and set the default input to mic-in
15123 */
15124 /* port-A for surround (rear panel) */
15125 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15126 /* port-B for mic-in (rear panel) with vref */
15127 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15128 /* port-C for line-in (rear panel) */
15129 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15130 /* port-D for Front */
15131 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15132 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15133 /* port-E for HP out (front panel) */
15134 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15135 /* route front PCM to HP */
9dece1d7 15136 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15137 /* port-F for mic-in (front panel) with vref */
15138 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15139 /* port-G for CLFE (rear panel) */
15140 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15141 /* port-H for side (rear panel) */
15142 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15143 /* CD-in */
15144 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15145 /* route front mic to ADC1*/
15146 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 /* Unmute DAC0~3 & spdif out*/
15149 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15151 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15152 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15154
df694daa
KY
15155 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15156 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15157 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15158 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15160
df694daa
KY
15161 /* Unmute Stereo Mixer 15 */
15162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15166
15167 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15168 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15170 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15174 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15175 /* hp used DAC 3 (Front) */
15176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15178 { }
15179};
22309c3e 15180
a9111321 15181static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15182 /*
15183 * Unmute ADC0 and set the default input to mic-in
15184 */
15185 /* port-A for surround (rear panel) */
15186 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15187 /* port-B for mic-in (rear panel) with vref */
15188 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15189 /* port-C for line-in (rear panel) */
15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15191 /* port-D for Front */
15192 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15193 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15194 /* port-E for HP out (front panel) */
f12ab1e0
TI
15195 /* this has to be set to VREF80 */
15196 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15197 /* route front PCM to HP */
9dece1d7 15198 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15199 /* port-F for mic-in (front panel) with vref */
15200 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15201 /* port-G for CLFE (rear panel) */
15202 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15203 /* port-H for side (rear panel) */
15204 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15205 /* CD-in */
15206 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15207 /* route front mic to ADC1*/
15208 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 /* Unmute DAC0~3 & spdif out*/
15211 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15212 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15213 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15214 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15216
22309c3e
TI
15217 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15218 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15219 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15220 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15221 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15222
22309c3e
TI
15223 /* Unmute Stereo Mixer 15 */
15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15227 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15228
15229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15231 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15235 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15237 /* hp used DAC 3 (Front) */
15238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15240 { }
15241};
15242
a9111321 15243static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15244 /*
15245 * Unmute ADC0 and set the default input to mic-in
15246 */
f12ab1e0
TI
15247 /* port-A for surround (rear panel)
15248 * according to codec#0 this is the HP jack
15249 */
7cdbff94
MD
15250 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15251 /* route front PCM to HP */
15252 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15253 /* port-B for mic-in (rear panel) with vref */
15254 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15255 /* port-C for line-in (rear panel) */
15256 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15257 /* port-D for Front */
15258 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15259 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15260 /* port-E for HP out (front panel) */
f12ab1e0
TI
15261 /* this has to be set to VREF80 */
15262 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15263 /* route front PCM to HP */
9dece1d7 15264 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15265 /* port-F for mic-in (front panel) with vref */
15266 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15267 /* port-G for CLFE (rear panel) */
15268 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15269 /* port-H for side (rear panel) */
15270 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15271 /* CD-in */
15272 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15273 /* route front mic to ADC1*/
15274 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 /* Unmute DAC0~3 & spdif out*/
15277 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15278 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15279 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15280 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15282 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15283 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15284 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15285 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15286 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15287
7cdbff94
MD
15288 /* Unmute Stereo Mixer 15 */
15289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15293
15294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15295 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15296 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15301 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15302 /* hp used DAC 3 (Front) */
15303 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15304 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15305 { }
15306};
15307
56bb0cab 15308/* additional init verbs for ASUS laptops */
a9111321 15309static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15310 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15311 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15312 { }
15313};
7cdbff94 15314
a9111321 15315static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15316 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15317
a53d1aec
TD
15318 { }
15319};
15320
15321/* toggle speaker-output according to the hp-jack state */
15322static void alc861_toshiba_automute(struct hda_codec *codec)
15323{
864f92be 15324 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15325
47fd830a
TI
15326 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15327 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15328 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15329 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15330}
15331
15332static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15333 unsigned int res)
15334{
a53d1aec
TD
15335 if ((res >> 26) == ALC880_HP_EVENT)
15336 alc861_toshiba_automute(codec);
15337}
15338
df694daa
KY
15339#define ALC861_DIGOUT_NID 0x07
15340
a9111321 15341static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15342 { 8, NULL }
15343};
15344
4c6d72d1 15345static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15346 /* front, surround, clfe, side */
15347 0x03, 0x06, 0x05, 0x04
15348};
15349
4c6d72d1 15350static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15351 /* front, clfe, surround */
15352 0x03, 0x05, 0x06
15353};
15354
4c6d72d1 15355static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15356 /* ADC0-2 */
15357 0x08,
15358};
15359
a9111321 15360static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15361 .num_items = 5,
15362 .items = {
15363 { "Mic", 0x0 },
15364 { "Front Mic", 0x3 },
15365 { "Line", 0x1 },
15366 { "CD", 0x4 },
15367 { "Mixer", 0x5 },
15368 },
15369};
15370
1c20930a
TI
15371static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15372{
15373 struct alc_spec *spec = codec->spec;
15374 hda_nid_t mix, srcs[5];
3af9ee6b 15375 int i, num;
1c20930a
TI
15376
15377 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15378 return 0;
15379 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15380 if (num < 0)
15381 return 0;
15382 for (i = 0; i < num; i++) {
15383 unsigned int type;
a22d543a 15384 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15385 if (type != AC_WID_AUD_OUT)
15386 continue;
3af9ee6b
TI
15387 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15388 spec->multiout.num_dacs))
1c20930a
TI
15389 return srcs[i];
15390 }
15391 return 0;
15392}
15393
df694daa 15394/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 15395static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
df694daa 15396{
1c20930a 15397 struct alc_spec *spec = codec->spec;
cb053a82 15398 const struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa 15399 int i;
1c20930a 15400 hda_nid_t nid, dac;
df694daa
KY
15401
15402 spec->multiout.dac_nids = spec->private_dac_nids;
15403 for (i = 0; i < cfg->line_outs; i++) {
15404 nid = cfg->line_out_pins[i];
1c20930a
TI
15405 dac = alc861_look_for_dac(codec, nid);
15406 if (!dac)
15407 continue;
dda14410 15408 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15409 }
df694daa
KY
15410 return 0;
15411}
15412
bcb2f0f5
TI
15413static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15414 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15415{
bcb2f0f5 15416 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15417 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15418}
15419
bcb2f0f5
TI
15420#define alc861_create_out_sw(codec, pfx, nid, chs) \
15421 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15422
df694daa 15423/* add playback controls from the parsed DAC table */
1c20930a 15424static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15425 const struct auto_pin_cfg *cfg)
15426{
1c20930a 15427 struct alc_spec *spec = codec->spec;
df694daa 15428 hda_nid_t nid;
ce764ab2 15429 int i, err, noutputs;
1c20930a 15430
ce764ab2
TI
15431 noutputs = cfg->line_outs;
15432 if (spec->multi_ios > 0)
15433 noutputs += spec->multi_ios;
15434
15435 for (i = 0; i < noutputs; i++) {
6843ca16
TI
15436 const char *name;
15437 int index;
df694daa 15438 nid = spec->multiout.dac_nids[i];
f12ab1e0 15439 if (!nid)
df694daa 15440 continue;
6843ca16
TI
15441 name = alc_get_line_out_pfx(spec, i, true, &index);
15442 if (!name) {
df694daa 15443 /* Center/LFE */
1c20930a 15444 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15445 if (err < 0)
df694daa 15446 return err;
1c20930a 15447 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15448 if (err < 0)
df694daa
KY
15449 return err;
15450 } else {
5a882646 15451 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 15452 if (err < 0)
df694daa
KY
15453 return err;
15454 }
15455 }
15456 return 0;
15457}
15458
1c20930a 15459static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15460{
1c20930a 15461 struct alc_spec *spec = codec->spec;
df694daa
KY
15462 int err;
15463 hda_nid_t nid;
15464
f12ab1e0 15465 if (!pin)
df694daa
KY
15466 return 0;
15467
15468 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15469 nid = alc861_look_for_dac(codec, pin);
15470 if (nid) {
15471 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15472 if (err < 0)
15473 return err;
15474 spec->multiout.hp_nid = nid;
15475 }
df694daa
KY
15476 }
15477 return 0;
15478}
15479
f12ab1e0
TI
15480static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15481 hda_nid_t nid,
1c20930a 15482 int pin_type, hda_nid_t dac)
df694daa 15483{
1c20930a
TI
15484 hda_nid_t mix, srcs[5];
15485 int i, num;
15486
564c5bea
JL
15487 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15488 pin_type);
1c20930a 15489 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15490 AMP_OUT_UNMUTE);
1c20930a
TI
15491 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15492 return;
15493 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15494 if (num < 0)
15495 return;
15496 for (i = 0; i < num; i++) {
15497 unsigned int mute;
15498 if (srcs[i] == dac || srcs[i] == 0x15)
15499 mute = AMP_IN_UNMUTE(i);
15500 else
15501 mute = AMP_IN_MUTE(i);
15502 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15503 mute);
15504 }
df694daa
KY
15505}
15506
15507static void alc861_auto_init_multi_out(struct hda_codec *codec)
15508{
15509 struct alc_spec *spec = codec->spec;
15510 int i;
15511
1f0f4b80 15512 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
df694daa 15513 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15514 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15515 if (nid)
baba8ee9 15516 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15517 spec->multiout.dac_nids[i]);
df694daa
KY
15518 }
15519}
15520
15521static void alc861_auto_init_hp_out(struct hda_codec *codec)
15522{
15523 struct alc_spec *spec = codec->spec;
df694daa 15524
15870f05
TI
15525 if (spec->autocfg.hp_outs)
15526 alc861_auto_set_output_and_unmute(codec,
15527 spec->autocfg.hp_pins[0],
15528 PIN_HP,
1c20930a 15529 spec->multiout.hp_nid);
15870f05
TI
15530 if (spec->autocfg.speaker_outs)
15531 alc861_auto_set_output_and_unmute(codec,
15532 spec->autocfg.speaker_pins[0],
15533 PIN_OUT,
1c20930a 15534 spec->multiout.dac_nids[0]);
df694daa
KY
15535}
15536
df694daa 15537/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15538/* return 1 if successful, 0 if the proper config is not found,
15539 * or a negative error code
15540 */
df694daa
KY
15541static int alc861_parse_auto_config(struct hda_codec *codec)
15542{
15543 struct alc_spec *spec = codec->spec;
15544 int err;
4c6d72d1 15545 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 15546
f12ab1e0
TI
15547 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15548 alc861_ignore);
15549 if (err < 0)
df694daa 15550 return err;
f12ab1e0 15551 if (!spec->autocfg.line_outs)
df694daa
KY
15552 return 0; /* can't find valid BIOS pin config */
15553
cb053a82 15554 err = alc861_auto_fill_dac_nids(codec);
ce764ab2
TI
15555 if (err < 0)
15556 return err;
cb053a82 15557 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
f12ab1e0
TI
15558 if (err < 0)
15559 return err;
1c20930a 15560 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15561 if (err < 0)
15562 return err;
1c20930a 15563 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15564 if (err < 0)
15565 return err;
b7821709 15566 err = alc_auto_create_input_ctls(codec);
f12ab1e0 15567 if (err < 0)
df694daa
KY
15568 return err;
15569
15570 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15571
757899ac 15572 alc_auto_parse_digital(codec);
df694daa 15573
603c4019 15574 if (spec->kctls.list)
d88897ea 15575 add_mixer(spec, spec->kctls.list);
df694daa 15576
21268961 15577 alc_remove_invalid_adc_nids(codec);
df694daa 15578
6227cdce 15579 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
21268961 15580 alc_auto_check_switches(codec);
4a79ba34 15581
d6cc9fab
TI
15582 set_capture_mixer(codec);
15583
df694daa
KY
15584 return 1;
15585}
15586
ae6b813a
TI
15587/* additional initialization for auto-configuration model */
15588static void alc861_auto_init(struct hda_codec *codec)
df694daa 15589{
f6c7e546 15590 struct alc_spec *spec = codec->spec;
df694daa
KY
15591 alc861_auto_init_multi_out(codec);
15592 alc861_auto_init_hp_out(codec);
0a7f5320 15593 alc_auto_init_analog_input(codec);
757899ac 15594 alc_auto_init_digital(codec);
f6c7e546 15595 if (spec->unsol_event)
7fb0d78f 15596 alc_inithook(codec);
df694daa
KY
15597}
15598
cb53c626 15599#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 15600static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
15601 { 0x15, HDA_INPUT, 0 },
15602 { 0x15, HDA_INPUT, 1 },
15603 { 0x15, HDA_INPUT, 2 },
15604 { 0x15, HDA_INPUT, 3 },
15605 { } /* end */
15606};
15607#endif
15608
df694daa
KY
15609
15610/*
15611 * configuration and preset
15612 */
ea734963 15613static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
15614 [ALC861_3ST] = "3stack",
15615 [ALC660_3ST] = "3stack-660",
15616 [ALC861_3ST_DIG] = "3stack-dig",
15617 [ALC861_6ST_DIG] = "6stack-dig",
15618 [ALC861_UNIWILL_M31] = "uniwill-m31",
15619 [ALC861_TOSHIBA] = "toshiba",
15620 [ALC861_ASUS] = "asus",
15621 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15622 [ALC861_AUTO] = "auto",
15623};
15624
a9111321 15625static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15626 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15627 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15628 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15629 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15630 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15631 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15632 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15633 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15634 * Any other models that need this preset?
15635 */
15636 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15637 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15638 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15639 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15640 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15641 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15642 /* FIXME: the below seems conflict */
15643 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15644 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15645 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15646 {}
15647};
15648
a9111321 15649static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
15650 [ALC861_3ST] = {
15651 .mixers = { alc861_3ST_mixer },
15652 .init_verbs = { alc861_threestack_init_verbs },
15653 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15654 .dac_nids = alc861_dac_nids,
15655 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15656 .channel_mode = alc861_threestack_modes,
4e195a7b 15657 .need_dac_fix = 1,
df694daa
KY
15658 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15659 .adc_nids = alc861_adc_nids,
15660 .input_mux = &alc861_capture_source,
15661 },
15662 [ALC861_3ST_DIG] = {
15663 .mixers = { alc861_base_mixer },
15664 .init_verbs = { alc861_threestack_init_verbs },
15665 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15666 .dac_nids = alc861_dac_nids,
15667 .dig_out_nid = ALC861_DIGOUT_NID,
15668 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15669 .channel_mode = alc861_threestack_modes,
4e195a7b 15670 .need_dac_fix = 1,
df694daa
KY
15671 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15672 .adc_nids = alc861_adc_nids,
15673 .input_mux = &alc861_capture_source,
15674 },
15675 [ALC861_6ST_DIG] = {
15676 .mixers = { alc861_base_mixer },
15677 .init_verbs = { alc861_base_init_verbs },
15678 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15679 .dac_nids = alc861_dac_nids,
15680 .dig_out_nid = ALC861_DIGOUT_NID,
15681 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15682 .channel_mode = alc861_8ch_modes,
15683 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15684 .adc_nids = alc861_adc_nids,
15685 .input_mux = &alc861_capture_source,
15686 },
9c7f852e
TI
15687 [ALC660_3ST] = {
15688 .mixers = { alc861_3ST_mixer },
15689 .init_verbs = { alc861_threestack_init_verbs },
15690 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15691 .dac_nids = alc660_dac_nids,
15692 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15693 .channel_mode = alc861_threestack_modes,
4e195a7b 15694 .need_dac_fix = 1,
9c7f852e
TI
15695 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15696 .adc_nids = alc861_adc_nids,
15697 .input_mux = &alc861_capture_source,
15698 },
22309c3e
TI
15699 [ALC861_UNIWILL_M31] = {
15700 .mixers = { alc861_uniwill_m31_mixer },
15701 .init_verbs = { alc861_uniwill_m31_init_verbs },
15702 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15703 .dac_nids = alc861_dac_nids,
15704 .dig_out_nid = ALC861_DIGOUT_NID,
15705 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15706 .channel_mode = alc861_uniwill_m31_modes,
15707 .need_dac_fix = 1,
15708 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15709 .adc_nids = alc861_adc_nids,
15710 .input_mux = &alc861_capture_source,
15711 },
a53d1aec
TD
15712 [ALC861_TOSHIBA] = {
15713 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15714 .init_verbs = { alc861_base_init_verbs,
15715 alc861_toshiba_init_verbs },
a53d1aec
TD
15716 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15717 .dac_nids = alc861_dac_nids,
15718 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15719 .channel_mode = alc883_3ST_2ch_modes,
15720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15721 .adc_nids = alc861_adc_nids,
15722 .input_mux = &alc861_capture_source,
15723 .unsol_event = alc861_toshiba_unsol_event,
15724 .init_hook = alc861_toshiba_automute,
15725 },
7cdbff94
MD
15726 [ALC861_ASUS] = {
15727 .mixers = { alc861_asus_mixer },
15728 .init_verbs = { alc861_asus_init_verbs },
15729 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15730 .dac_nids = alc861_dac_nids,
15731 .dig_out_nid = ALC861_DIGOUT_NID,
15732 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15733 .channel_mode = alc861_asus_modes,
15734 .need_dac_fix = 1,
15735 .hp_nid = 0x06,
15736 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15737 .adc_nids = alc861_adc_nids,
15738 .input_mux = &alc861_capture_source,
15739 },
56bb0cab
TI
15740 [ALC861_ASUS_LAPTOP] = {
15741 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15742 .init_verbs = { alc861_asus_init_verbs,
15743 alc861_asus_laptop_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15745 .dac_nids = alc861_dac_nids,
15746 .dig_out_nid = ALC861_DIGOUT_NID,
15747 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15748 .channel_mode = alc883_3ST_2ch_modes,
15749 .need_dac_fix = 1,
15750 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15751 .adc_nids = alc861_adc_nids,
15752 .input_mux = &alc861_capture_source,
15753 },
15754};
df694daa 15755
cfc9b06f
TI
15756/* Pin config fixes */
15757enum {
15758 PINFIX_FSC_AMILO_PI1505,
15759};
15760
cfc9b06f
TI
15761static const struct alc_fixup alc861_fixups[] = {
15762 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
15763 .type = ALC_FIXUP_PINS,
15764 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
15765 { 0x0b, 0x0221101f }, /* HP */
15766 { 0x0f, 0x90170310 }, /* speaker */
15767 { }
15768 }
cfc9b06f
TI
15769 },
15770};
15771
a9111321 15772static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
15773 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15774 {}
15775};
df694daa
KY
15776
15777static int patch_alc861(struct hda_codec *codec)
15778{
15779 struct alc_spec *spec;
15780 int board_config;
15781 int err;
15782
dc041e0b 15783 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15784 if (spec == NULL)
15785 return -ENOMEM;
15786
f12ab1e0 15787 codec->spec = spec;
df694daa 15788
1f0f4b80
TI
15789 spec->mixer_nid = 0x15;
15790
f5fcc13c
TI
15791 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15792 alc861_models,
15793 alc861_cfg_tbl);
9c7f852e 15794
f5fcc13c 15795 if (board_config < 0) {
9a11f1aa
TI
15796 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15797 codec->chip_name);
df694daa
KY
15798 board_config = ALC861_AUTO;
15799 }
15800
b5bfbc67
TI
15801 if (board_config == ALC861_AUTO) {
15802 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15803 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15804 }
cfc9b06f 15805
df694daa
KY
15806 if (board_config == ALC861_AUTO) {
15807 /* automatic parse from the BIOS config */
15808 err = alc861_parse_auto_config(codec);
15809 if (err < 0) {
15810 alc_free(codec);
15811 return err;
f12ab1e0 15812 } else if (!err) {
9c7f852e
TI
15813 printk(KERN_INFO
15814 "hda_codec: Cannot set up configuration "
15815 "from BIOS. Using base mode...\n");
df694daa
KY
15816 board_config = ALC861_3ST_DIG;
15817 }
15818 }
15819
680cd536
KK
15820 err = snd_hda_attach_beep_device(codec, 0x23);
15821 if (err < 0) {
15822 alc_free(codec);
15823 return err;
15824 }
15825
df694daa 15826 if (board_config != ALC861_AUTO)
e9c364c0 15827 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15828
21268961
TI
15829 if (!spec->adc_nids) {
15830 alc_auto_fill_adc_caps(codec);
15831 alc_rebuild_imux_for_auto_mic(codec);
15832 alc_remove_invalid_adc_nids(codec);
15833 }
15834
c7a8eb10
TI
15835 if (!spec->cap_mixer)
15836 set_capture_mixer(codec);
45bdd1c1
TI
15837 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15838
2134ea4f
TI
15839 spec->vmaster_nid = 0x03;
15840
b5bfbc67 15841 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 15842
df694daa 15843 codec->patch_ops = alc_patch_ops;
c97259df 15844 if (board_config == ALC861_AUTO) {
ae6b813a 15845 spec->init_hook = alc861_auto_init;
c97259df
DC
15846#ifdef CONFIG_SND_HDA_POWER_SAVE
15847 spec->power_hook = alc_power_eapd;
15848#endif
15849 }
cb53c626
TI
15850#ifdef CONFIG_SND_HDA_POWER_SAVE
15851 if (!spec->loopback.amplist)
15852 spec->loopback.amplist = alc861_loopbacks;
15853#endif
ea1fb29a 15854
1da177e4
LT
15855 return 0;
15856}
15857
f32610ed
JS
15858/*
15859 * ALC861-VD support
15860 *
15861 * Based on ALC882
15862 *
15863 * In addition, an independent DAC
15864 */
15865#define ALC861VD_DIGOUT_NID 0x06
15866
4c6d72d1 15867static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
15868 /* front, surr, clfe, side surr */
15869 0x02, 0x03, 0x04, 0x05
15870};
15871
15872/* dac_nids for ALC660vd are in a different order - according to
15873 * Realtek's driver.
def319f9 15874 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15875 * of ALC660vd codecs, but for now there is only 3stack mixer
15876 * - and it is the same as in 861vd.
15877 * adc_nids in ALC660vd are (is) the same as in 861vd
15878 */
4c6d72d1 15879static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
15880 /* front, rear, clfe, rear_surr */
15881 0x02, 0x04, 0x03
15882};
15883
4c6d72d1 15884static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
15885 /* ADC0 */
15886 0x09,
15887};
15888
4c6d72d1 15889static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 15890
f32610ed
JS
15891/* input MUX */
15892/* FIXME: should be a matrix-type input source selection */
a9111321 15893static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
15894 .num_items = 4,
15895 .items = {
15896 { "Mic", 0x0 },
15897 { "Front Mic", 0x1 },
15898 { "Line", 0x2 },
15899 { "CD", 0x4 },
15900 },
15901};
15902
a9111321 15903static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 15904 .num_items = 2,
272a527c 15905 .items = {
8607f7c4 15906 { "Mic", 0x0 },
28c4edb7 15907 { "Internal Mic", 0x1 },
272a527c
KY
15908 },
15909};
15910
a9111321 15911static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
15912 .num_items = 2,
15913 .items = {
15914 { "Front Mic", 0x0 },
15915 { "ATAPI Mic", 0x1 },
15916 },
15917};
15918
f32610ed
JS
15919/*
15920 * 2ch mode
15921 */
a9111321 15922static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
15923 { 2, NULL }
15924};
15925
15926/*
15927 * 6ch mode
15928 */
a9111321 15929static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
15930 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15931 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15932 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15933 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15934 { } /* end */
15935};
15936
15937/*
15938 * 8ch mode
15939 */
a9111321 15940static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
15941 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15942 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15943 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15944 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15945 { } /* end */
15946};
15947
a9111321 15948static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
15949 { 6, alc861vd_6stack_ch6_init },
15950 { 8, alc861vd_6stack_ch8_init },
15951};
15952
a9111321 15953static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
15954 {
15955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15956 .name = "Channel Mode",
15957 .info = alc_ch_mode_info,
15958 .get = alc_ch_mode_get,
15959 .put = alc_ch_mode_put,
15960 },
15961 { } /* end */
15962};
15963
f32610ed
JS
15964/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15965 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15966 */
a9111321 15967static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
15968 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15970
15971 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15972 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15973
15974 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15975 HDA_OUTPUT),
15976 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15977 HDA_OUTPUT),
15978 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15979 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15980
15981 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15983
15984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15985
5f99f86a 15986 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
15987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15989
5f99f86a 15990 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
15991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15993
15994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15996
15997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15999
f32610ed
JS
16000 { } /* end */
16001};
16002
a9111321 16003static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16004 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16006
16007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16008
5f99f86a 16009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16012
5f99f86a 16013 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16016
16017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16019
16020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16021 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16022
f32610ed
JS
16023 { } /* end */
16024};
16025
a9111321 16026static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16027 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16028 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16029 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16030
16031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16032
5f99f86a 16033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16036
5f99f86a 16037 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16040
16041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16043
16044 { } /* end */
16045};
16046
b419f346 16047/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16048 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16049 */
a9111321 16050static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16051 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16052 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16053 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16054 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16055 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16058 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16059 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16060 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16061 { } /* end */
16062};
16063
d1a991a6
KY
16064/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16065 * Front Mic=0x18, ATAPI Mic = 0x19,
16066 */
a9111321 16067static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16068 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16072 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16074 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16075 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16076
d1a991a6
KY
16077 { } /* end */
16078};
16079
f32610ed
JS
16080/*
16081 * generic initialization of ADC, input mixers and output mixers
16082 */
a9111321 16083static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16084 /*
16085 * Unmute ADC0 and set the default input to mic-in
16086 */
16087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16089
16090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16091 * the analog-loopback mixer widget
16092 */
16093 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16099
16100 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16105
16106 /*
16107 * Set up output mixers (0x02 - 0x05)
16108 */
16109 /* set vol=0 to output mixers */
16110 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16114
16115 /* set up input amps for analog loopback */
16116 /* Amp Indices: DAC = 0, mixer = 1 */
16117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16125
16126 { }
16127};
16128
16129/*
16130 * 3-stack pin configuration:
16131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16132 */
a9111321 16133static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16134 /*
16135 * Set pin mode and muting
16136 */
16137 /* set front pin widgets 0x14 for output */
16138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16141
16142 /* Mic (rear) pin: input vref at 80% */
16143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16145 /* Front Mic pin: input vref at 80% */
16146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16147 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16148 /* Line In pin: input */
16149 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16150 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16151 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16153 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16155 /* CD pin widget for input */
16156 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16157
16158 { }
16159};
16160
16161/*
16162 * 6-stack pin configuration:
16163 */
a9111321 16164static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16165 /*
16166 * Set pin mode and muting
16167 */
16168 /* set front pin widgets 0x14 for output */
16169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16171 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16172
16173 /* Rear Pin: output 1 (0x0d) */
16174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16176 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16177 /* CLFE Pin: output 2 (0x0e) */
16178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16179 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16181 /* Side Pin: output 3 (0x0f) */
16182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16185
16186 /* Mic (rear) pin: input vref at 80% */
16187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16189 /* Front Mic pin: input vref at 80% */
16190 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16191 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16192 /* Line In pin: input */
16193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16195 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16198 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16199 /* CD pin widget for input */
16200 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16201
16202 { }
16203};
16204
a9111321 16205static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16207 { }
16208};
16209
a9111321 16210static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16211 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16212 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16213 { }
16214};
16215
a9111321 16216static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16220 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16221 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16222 {}
16223};
16224
4f5d1706 16225static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16226{
a9fd4f3f 16227 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16228 spec->autocfg.hp_pins[0] = 0x1b;
16229 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16230 spec->automute = 1;
16231 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16232}
16233
16234static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16235{
d922b51d 16236 alc_hp_automute(codec);
eeb43387 16237 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16238}
16239
16240static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16241 unsigned int res)
16242{
16243 switch (res >> 26) {
bdd148a3 16244 case ALC880_MIC_EVENT:
eeb43387 16245 alc88x_simple_mic_automute(codec);
bdd148a3 16246 break;
a9fd4f3f 16247 default:
d922b51d 16248 alc_sku_unsol_event(codec, res);
a9fd4f3f 16249 break;
bdd148a3
KY
16250 }
16251}
16252
a9111321 16253static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16254 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16255 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16257 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16258
16259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16265 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16267
272a527c
KY
16268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16273 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16276
16277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16280 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16282 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16285
16286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16290
16291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16292 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16294
16295 { } /* end */
16296};
16297
16298/* toggle speaker-output according to the hp-jack state */
4f5d1706 16299static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16300{
a9fd4f3f 16301 struct alc_spec *spec = codec->spec;
272a527c 16302
a9fd4f3f
TI
16303 spec->autocfg.hp_pins[0] = 0x15;
16304 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16305 spec->automute = 1;
16306 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16307}
16308
cb53c626
TI
16309#ifdef CONFIG_SND_HDA_POWER_SAVE
16310#define alc861vd_loopbacks alc880_loopbacks
16311#endif
16312
f32610ed
JS
16313/*
16314 * configuration and preset
16315 */
ea734963 16316static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16317 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16318 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16319 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16320 [ALC861VD_3ST] = "3stack",
16321 [ALC861VD_3ST_DIG] = "3stack-digout",
16322 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16323 [ALC861VD_LENOVO] = "lenovo",
272a527c 16324 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16325 [ALC861VD_HP] = "hp",
f32610ed
JS
16326 [ALC861VD_AUTO] = "auto",
16327};
16328
a9111321 16329static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16330 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16331 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16332 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16333 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16334 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16335 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16336 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16337 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16338 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16339 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16340 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16341 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16342 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16343 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16344 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16345 {}
16346};
16347
a9111321 16348static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16349 [ALC660VD_3ST] = {
16350 .mixers = { alc861vd_3st_mixer },
16351 .init_verbs = { alc861vd_volume_init_verbs,
16352 alc861vd_3stack_init_verbs },
16353 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16354 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16355 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16356 .channel_mode = alc861vd_3stack_2ch_modes,
16357 .input_mux = &alc861vd_capture_source,
16358 },
6963f84c
MC
16359 [ALC660VD_3ST_DIG] = {
16360 .mixers = { alc861vd_3st_mixer },
16361 .init_verbs = { alc861vd_volume_init_verbs,
16362 alc861vd_3stack_init_verbs },
16363 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16364 .dac_nids = alc660vd_dac_nids,
16365 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16366 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16367 .channel_mode = alc861vd_3stack_2ch_modes,
16368 .input_mux = &alc861vd_capture_source,
16369 },
f32610ed
JS
16370 [ALC861VD_3ST] = {
16371 .mixers = { alc861vd_3st_mixer },
16372 .init_verbs = { alc861vd_volume_init_verbs,
16373 alc861vd_3stack_init_verbs },
16374 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16375 .dac_nids = alc861vd_dac_nids,
16376 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16377 .channel_mode = alc861vd_3stack_2ch_modes,
16378 .input_mux = &alc861vd_capture_source,
16379 },
16380 [ALC861VD_3ST_DIG] = {
16381 .mixers = { alc861vd_3st_mixer },
16382 .init_verbs = { alc861vd_volume_init_verbs,
16383 alc861vd_3stack_init_verbs },
16384 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16385 .dac_nids = alc861vd_dac_nids,
16386 .dig_out_nid = ALC861VD_DIGOUT_NID,
16387 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16388 .channel_mode = alc861vd_3stack_2ch_modes,
16389 .input_mux = &alc861vd_capture_source,
16390 },
16391 [ALC861VD_6ST_DIG] = {
16392 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16393 .init_verbs = { alc861vd_volume_init_verbs,
16394 alc861vd_6stack_init_verbs },
16395 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16396 .dac_nids = alc861vd_dac_nids,
16397 .dig_out_nid = ALC861VD_DIGOUT_NID,
16398 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16399 .channel_mode = alc861vd_6stack_modes,
16400 .input_mux = &alc861vd_capture_source,
16401 },
bdd148a3
KY
16402 [ALC861VD_LENOVO] = {
16403 .mixers = { alc861vd_lenovo_mixer },
16404 .init_verbs = { alc861vd_volume_init_verbs,
16405 alc861vd_3stack_init_verbs,
16406 alc861vd_eapd_verbs,
16407 alc861vd_lenovo_unsol_verbs },
16408 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16409 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16410 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16411 .channel_mode = alc861vd_3stack_2ch_modes,
16412 .input_mux = &alc861vd_capture_source,
16413 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16414 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16415 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16416 },
272a527c
KY
16417 [ALC861VD_DALLAS] = {
16418 .mixers = { alc861vd_dallas_mixer },
16419 .init_verbs = { alc861vd_dallas_verbs },
16420 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16421 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16422 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16423 .channel_mode = alc861vd_3stack_2ch_modes,
16424 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 16425 .unsol_event = alc_sku_unsol_event,
4f5d1706 16426 .setup = alc861vd_dallas_setup,
d922b51d 16427 .init_hook = alc_hp_automute,
d1a991a6
KY
16428 },
16429 [ALC861VD_HP] = {
16430 .mixers = { alc861vd_hp_mixer },
16431 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16432 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16433 .dac_nids = alc861vd_dac_nids,
d1a991a6 16434 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16435 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16436 .channel_mode = alc861vd_3stack_2ch_modes,
16437 .input_mux = &alc861vd_hp_capture_source,
d922b51d 16438 .unsol_event = alc_sku_unsol_event,
4f5d1706 16439 .setup = alc861vd_dallas_setup,
d922b51d 16440 .init_hook = alc_hp_automute,
ea1fb29a 16441 },
13c94744
TI
16442 [ALC660VD_ASUS_V1S] = {
16443 .mixers = { alc861vd_lenovo_mixer },
16444 .init_verbs = { alc861vd_volume_init_verbs,
16445 alc861vd_3stack_init_verbs,
16446 alc861vd_eapd_verbs,
16447 alc861vd_lenovo_unsol_verbs },
16448 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16449 .dac_nids = alc660vd_dac_nids,
16450 .dig_out_nid = ALC861VD_DIGOUT_NID,
16451 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16452 .channel_mode = alc861vd_3stack_2ch_modes,
16453 .input_mux = &alc861vd_capture_source,
16454 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16455 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16456 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16457 },
f32610ed
JS
16458};
16459
16460/*
16461 * BIOS auto configuration
16462 */
f32610ed
JS
16463#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16464#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16465
16466/* add playback controls from the parsed DAC table */
569ed348 16467/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
16468 * different NIDs for mute/unmute switch and volume control */
16469static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16470 const struct auto_pin_cfg *cfg)
16471{
f32610ed 16472 hda_nid_t nid_v, nid_s;
ce764ab2 16473 int i, err, noutputs;
f32610ed 16474
ce764ab2
TI
16475 noutputs = cfg->line_outs;
16476 if (spec->multi_ios > 0)
16477 noutputs += spec->multi_ios;
16478
16479 for (i = 0; i < noutputs; i++) {
6843ca16
TI
16480 const char *name;
16481 int index;
f12ab1e0 16482 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16483 continue;
16484 nid_v = alc861vd_idx_to_mixer_vol(
16485 alc880_dac_to_idx(
16486 spec->multiout.dac_nids[i]));
16487 nid_s = alc861vd_idx_to_mixer_switch(
16488 alc880_dac_to_idx(
16489 spec->multiout.dac_nids[i]));
16490
6843ca16
TI
16491 name = alc_get_line_out_pfx(spec, i, true, &index);
16492 if (!name) {
f32610ed 16493 /* Center/LFE */
0afe5f89
TI
16494 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16495 "Center",
f12ab1e0
TI
16496 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16497 HDA_OUTPUT));
16498 if (err < 0)
f32610ed 16499 return err;
0afe5f89
TI
16500 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16501 "LFE",
f12ab1e0
TI
16502 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16503 HDA_OUTPUT));
16504 if (err < 0)
f32610ed 16505 return err;
0afe5f89
TI
16506 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16507 "Center",
f12ab1e0
TI
16508 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16509 HDA_INPUT));
16510 if (err < 0)
f32610ed 16511 return err;
0afe5f89
TI
16512 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16513 "LFE",
f12ab1e0
TI
16514 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16515 HDA_INPUT));
16516 if (err < 0)
f32610ed
JS
16517 return err;
16518 } else {
bcb2f0f5 16519 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 16520 name, index,
f12ab1e0
TI
16521 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16522 HDA_OUTPUT));
16523 if (err < 0)
f32610ed 16524 return err;
bcb2f0f5 16525 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 16526 name, index,
bdd148a3 16527 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16528 HDA_INPUT));
16529 if (err < 0)
f32610ed
JS
16530 return err;
16531 }
16532 }
16533 return 0;
16534}
16535
16536/* add playback controls for speaker and HP outputs */
16537/* Based on ALC880 version. But ALC861VD has separate,
16538 * different NIDs for mute/unmute switch and volume control */
16539static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16540 hda_nid_t pin, const char *pfx)
16541{
16542 hda_nid_t nid_v, nid_s;
16543 int err;
f32610ed 16544
f12ab1e0 16545 if (!pin)
f32610ed
JS
16546 return 0;
16547
16548 if (alc880_is_fixed_pin(pin)) {
16549 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16550 /* specify the DAC as the extra output */
f12ab1e0 16551 if (!spec->multiout.hp_nid)
f32610ed
JS
16552 spec->multiout.hp_nid = nid_v;
16553 else
16554 spec->multiout.extra_out_nid[0] = nid_v;
16555 /* control HP volume/switch on the output mixer amp */
16556 nid_v = alc861vd_idx_to_mixer_vol(
16557 alc880_fixed_pin_idx(pin));
16558 nid_s = alc861vd_idx_to_mixer_switch(
16559 alc880_fixed_pin_idx(pin));
16560
0afe5f89 16561 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16562 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16563 if (err < 0)
f32610ed 16564 return err;
0afe5f89 16565 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16566 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16567 if (err < 0)
f32610ed
JS
16568 return err;
16569 } else if (alc880_is_multi_pin(pin)) {
16570 /* set manual connection */
16571 /* we have only a switch on HP-out PIN */
0afe5f89 16572 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16573 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16574 if (err < 0)
f32610ed
JS
16575 return err;
16576 }
16577 return 0;
16578}
16579
16580/* parse the BIOS configuration and set up the alc_spec
16581 * return 1 if successful, 0 if the proper config is not found,
16582 * or a negative error code
16583 * Based on ALC880 version - had to change it to override
16584 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16585static int alc861vd_parse_auto_config(struct hda_codec *codec)
16586{
16587 struct alc_spec *spec = codec->spec;
16588 int err;
4c6d72d1 16589 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 16590
f12ab1e0
TI
16591 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16592 alc861vd_ignore);
16593 if (err < 0)
f32610ed 16594 return err;
f12ab1e0 16595 if (!spec->autocfg.line_outs)
f32610ed
JS
16596 return 0; /* can't find valid BIOS pin config */
16597
343a04be 16598 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
16599 if (err < 0)
16600 return err;
343a04be 16601 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
16602 if (err < 0)
16603 return err;
16604 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16605 if (err < 0)
16606 return err;
16607 err = alc861vd_auto_create_extra_out(spec,
16608 spec->autocfg.speaker_pins[0],
16609 "Speaker");
16610 if (err < 0)
16611 return err;
16612 err = alc861vd_auto_create_extra_out(spec,
16613 spec->autocfg.hp_pins[0],
16614 "Headphone");
16615 if (err < 0)
16616 return err;
b7821709 16617 err = alc_auto_create_input_ctls(codec);
f12ab1e0 16618 if (err < 0)
f32610ed
JS
16619 return err;
16620
16621 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16622
757899ac 16623 alc_auto_parse_digital(codec);
f32610ed 16624
603c4019 16625 if (spec->kctls.list)
d88897ea 16626 add_mixer(spec, spec->kctls.list);
f32610ed 16627
21268961 16628 alc_remove_invalid_adc_nids(codec);
f32610ed 16629
21268961
TI
16630 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
16631 alc_auto_check_switches(codec);
d6cc9fab 16632
776e184e
TI
16633 err = alc_auto_add_mic_boost(codec);
16634 if (err < 0)
16635 return err;
16636
f32610ed
JS
16637 return 1;
16638}
16639
16640/* additional initialization for auto-configuration model */
16641static void alc861vd_auto_init(struct hda_codec *codec)
16642{
f6c7e546 16643 struct alc_spec *spec = codec->spec;
343a04be
TI
16644 alc_auto_init_multi_out(codec);
16645 alc_auto_init_extra_out(codec);
0a7f5320 16646 alc_auto_init_analog_input(codec);
f970de25 16647 alc_auto_init_input_src(codec);
757899ac 16648 alc_auto_init_digital(codec);
f6c7e546 16649 if (spec->unsol_event)
7fb0d78f 16650 alc_inithook(codec);
f32610ed
JS
16651}
16652
f8f25ba3
TI
16653enum {
16654 ALC660VD_FIX_ASUS_GPIO1
16655};
16656
16657/* reset GPIO1 */
f8f25ba3
TI
16658static const struct alc_fixup alc861vd_fixups[] = {
16659 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
16660 .type = ALC_FIXUP_VERBS,
16661 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
16662 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16663 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16664 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16665 { }
16666 }
f8f25ba3
TI
16667 },
16668};
16669
a9111321 16670static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
16671 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16672 {}
16673};
16674
f32610ed
JS
16675static int patch_alc861vd(struct hda_codec *codec)
16676{
16677 struct alc_spec *spec;
16678 int err, board_config;
16679
16680 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16681 if (spec == NULL)
16682 return -ENOMEM;
16683
16684 codec->spec = spec;
16685
1f0f4b80
TI
16686 spec->mixer_nid = 0x0b;
16687
f32610ed
JS
16688 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16689 alc861vd_models,
16690 alc861vd_cfg_tbl);
16691
16692 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16693 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16694 codec->chip_name);
f32610ed
JS
16695 board_config = ALC861VD_AUTO;
16696 }
16697
b5bfbc67
TI
16698 if (board_config == ALC861VD_AUTO) {
16699 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16700 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16701 }
f8f25ba3 16702
f32610ed
JS
16703 if (board_config == ALC861VD_AUTO) {
16704 /* automatic parse from the BIOS config */
16705 err = alc861vd_parse_auto_config(codec);
16706 if (err < 0) {
16707 alc_free(codec);
16708 return err;
f12ab1e0 16709 } else if (!err) {
f32610ed
JS
16710 printk(KERN_INFO
16711 "hda_codec: Cannot set up configuration "
16712 "from BIOS. Using base mode...\n");
16713 board_config = ALC861VD_3ST;
16714 }
16715 }
16716
680cd536
KK
16717 err = snd_hda_attach_beep_device(codec, 0x23);
16718 if (err < 0) {
16719 alc_free(codec);
16720 return err;
16721 }
16722
f32610ed 16723 if (board_config != ALC861VD_AUTO)
e9c364c0 16724 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16725
2f893286 16726 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16727 /* always turn on EAPD */
d88897ea 16728 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16729 }
16730
dd704698 16731 if (!spec->adc_nids) {
d6cc9fab 16732 alc_auto_fill_adc_caps(codec);
21268961 16733 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 16734 alc_remove_invalid_adc_nids(codec);
dd704698 16735 }
f32610ed 16736
b59bdf3b 16737 set_capture_mixer(codec);
45bdd1c1 16738 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16739
2134ea4f
TI
16740 spec->vmaster_nid = 0x02;
16741
b5bfbc67 16742 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16743
f32610ed
JS
16744 codec->patch_ops = alc_patch_ops;
16745
16746 if (board_config == ALC861VD_AUTO)
16747 spec->init_hook = alc861vd_auto_init;
1c716153 16748 spec->shutup = alc_eapd_shutup;
cb53c626
TI
16749#ifdef CONFIG_SND_HDA_POWER_SAVE
16750 if (!spec->loopback.amplist)
16751 spec->loopback.amplist = alc861vd_loopbacks;
16752#endif
f32610ed
JS
16753
16754 return 0;
16755}
16756
bc9f98a9
KY
16757/*
16758 * ALC662 support
16759 *
16760 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16761 * configuration. Each pin widget can choose any input DACs and a mixer.
16762 * Each ADC is connected from a mixer of all inputs. This makes possible
16763 * 6-channel independent captures.
16764 *
16765 * In addition, an independent DAC for the multi-playback (not used in this
16766 * driver yet).
16767 */
16768#define ALC662_DIGOUT_NID 0x06
16769#define ALC662_DIGIN_NID 0x0a
16770
4c6d72d1 16771static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 16772 /* front, rear, clfe */
bc9f98a9
KY
16773 0x02, 0x03, 0x04
16774};
16775
4c6d72d1 16776static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
16777 0x02, 0x03
16778};
16779
4c6d72d1 16780static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16781 /* ADC1-2 */
b59bdf3b 16782 0x09, 0x08
bc9f98a9 16783};
e1406348 16784
4c6d72d1 16785static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
16786 /* ADC1-2 */
16787 0x08,
16788};
16789
4c6d72d1
TI
16790static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16791static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 16792
e1406348 16793
bc9f98a9
KY
16794/* input MUX */
16795/* FIXME: should be a matrix-type input source selection */
a9111321 16796static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
16797 .num_items = 4,
16798 .items = {
16799 { "Mic", 0x0 },
16800 { "Front Mic", 0x1 },
16801 { "Line", 0x2 },
16802 { "CD", 0x4 },
16803 },
16804};
16805
a9111321 16806static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
16807 .num_items = 2,
16808 .items = {
16809 { "Mic", 0x1 },
16810 { "Line", 0x2 },
16811 },
16812};
291702f0 16813
a9111321 16814static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
16815 .num_items = 3,
16816 .items = {
16817 { "Mic", 0x0 },
16818 { "Front Mic", 0x1 },
16819 { "Line", 0x2 },
16820 },
16821};
16822
4f5d1706 16823#if 0 /* set to 1 for testing other input sources below */
a9111321 16824static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
16825 .num_items = 16,
16826 .items = {
16827 { "Autoselect Mic", 0x0 },
16828 { "Internal Mic", 0x1 },
16829 { "In-0x02", 0x2 },
16830 { "In-0x03", 0x3 },
16831 { "In-0x04", 0x4 },
16832 { "In-0x05", 0x5 },
16833 { "In-0x06", 0x6 },
16834 { "In-0x07", 0x7 },
16835 { "In-0x08", 0x8 },
16836 { "In-0x09", 0x9 },
16837 { "In-0x0a", 0x0a },
16838 { "In-0x0b", 0x0b },
16839 { "In-0x0c", 0x0c },
16840 { "In-0x0d", 0x0d },
16841 { "In-0x0e", 0x0e },
16842 { "In-0x0f", 0x0f },
16843 },
16844};
16845#endif
16846
bc9f98a9
KY
16847/*
16848 * 2ch mode
16849 */
a9111321 16850static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
16851 { 2, NULL }
16852};
16853
16854/*
16855 * 2ch mode
16856 */
a9111321 16857static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
16858 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16859 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16862 { } /* end */
16863};
16864
16865/*
16866 * 6ch mode
16867 */
a9111321 16868static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
16869 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16870 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16871 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16874 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16875 { } /* end */
16876};
16877
a9111321 16878static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
16879 { 2, alc662_3ST_ch2_init },
16880 { 6, alc662_3ST_ch6_init },
16881};
16882
16883/*
16884 * 2ch mode
16885 */
a9111321 16886static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
16887 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16888 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16889 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16890 { } /* end */
16891};
16892
16893/*
16894 * 6ch mode
16895 */
a9111321 16896static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
16897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16899 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16900 { } /* end */
16901};
16902
a9111321 16903static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
16904 { 2, alc662_sixstack_ch6_init },
16905 { 6, alc662_sixstack_ch8_init },
16906};
16907
16908/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16909 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16910 */
16911
a9111321 16912static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
16913 /* output mixer control */
16914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 16915 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16916 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 16917 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16918 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16919 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16920 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16921 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16923
16924 /*Input mixer control */
16925 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16926 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16927 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16928 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16929 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16930 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
16933 { } /* end */
16934};
16935
a9111321 16936static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 16937 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16938 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
16939 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16942 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16943 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16946 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16947 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16948 { } /* end */
16949};
16950
a9111321 16951static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 16952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 16953 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 16954 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 16955 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
16956 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16957 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
16958 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16959 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
16960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16961 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16962 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16963 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16964 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16967 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16968 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16969 { } /* end */
16970};
16971
a9111321 16972static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
16973 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16974 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
16975 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16976 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
16977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
16982 { } /* end */
16983};
16984
a9111321 16985static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
16986 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16987 ALC262_HIPPO_MASTER_SWITCH,
291702f0 16988
5f99f86a 16989 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
16990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 16992
5f99f86a 16993 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
16994 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16995 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
16996 { } /* end */
16997};
16998
a9111321 16999static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17000 ALC262_HIPPO_MASTER_SWITCH,
17001 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17003 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17004 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17005 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17006 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17007 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17010 { } /* end */
17011};
17012
a9111321 17013static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17014 .ops = &snd_hda_bind_vol,
17015 .values = {
17016 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17017 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17018 0
17019 },
17020};
17021
a9111321 17022static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17023 .ops = &snd_hda_bind_sw,
17024 .values = {
17025 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17026 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17027 0
17028 },
17029};
17030
a9111321 17031static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17032 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17033 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17036 { } /* end */
17037};
17038
a9111321 17039static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17040 .ops = &snd_hda_bind_sw,
17041 .values = {
17042 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17043 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17044 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17045 0
17046 },
17047};
17048
a9111321 17049static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17050 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17051 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17054 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17055 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17056
17057 { } /* end */
17058};
17059
a9111321 17060static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17061 .ops = &snd_hda_bind_sw,
17062 .values = {
17063 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17064 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17065 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17066 0
17067 },
17068};
17069
a9111321 17070static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17071 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17072 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17075 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17076 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17077 { } /* end */
17078};
17079
a9111321 17080static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17081 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17086 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17087 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17088 { } /* end */
17089};
17090
a9111321 17091static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17092 .ops = &snd_hda_bind_vol,
17093 .values = {
17094 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17095 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17096 0
17097 },
17098};
17099
a9111321 17100static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17101 .ops = &snd_hda_bind_sw,
17102 .values = {
17103 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17104 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17105 0
17106 },
17107};
17108
a9111321 17109static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17110 HDA_BIND_VOL("Master Playback Volume",
17111 &alc663_asus_two_bind_master_vol),
17112 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17117 { } /* end */
17118};
17119
a9111321 17120static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17121 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17122 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17123 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17127 { } /* end */
17128};
17129
a9111321 17130static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17132 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17133 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17134 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17136
17137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17138 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17139 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17140 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17141 { } /* end */
17142};
17143
a9111321 17144static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17146 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17148
17149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17153 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17154 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17155 { } /* end */
17156};
17157
a9111321 17158static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17159 .ops = &snd_hda_bind_sw,
17160 .values = {
17161 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17162 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17163 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17164 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17165 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17166 0
17167 },
17168};
17169
a9111321 17170static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17171 .ops = &snd_hda_bind_sw,
17172 .values = {
17173 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17174 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17175 0
17176 },
17177};
17178
a9111321 17179static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17180 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17181 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17182 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17183 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17184 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17185 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17186 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17189 { } /* end */
17190};
17191
a9111321 17192static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17193 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17194 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17195 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17196 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17197 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17200 { } /* end */
17201};
17202
17203
a9111321 17204static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17205 {
17206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17207 .name = "Channel Mode",
17208 .info = alc_ch_mode_info,
17209 .get = alc_ch_mode_get,
17210 .put = alc_ch_mode_put,
17211 },
17212 { } /* end */
17213};
17214
a9111321 17215static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17216 /* ADC: mute amp left and right */
17217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17218 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17219
b60dd394
KY
17220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17226
17227 /* Front Pin: output 0 (0x0c) */
17228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17230
17231 /* Rear Pin: output 1 (0x0d) */
17232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17234
17235 /* CLFE Pin: output 2 (0x0e) */
17236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17237 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17238
17239 /* Mic (rear) pin: input vref at 80% */
17240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17241 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17242 /* Front Mic pin: input vref at 80% */
17243 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17244 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17245 /* Line In pin: input */
17246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17247 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17248 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17249 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17250 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17251 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17252 /* CD pin widget for input */
17253 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17254
17255 /* FIXME: use matrix-type input source selection */
17256 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17257 /* Input mixer */
17258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17259 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17260
a7f2371f
TI
17261 { }
17262};
17263
a9111321 17264static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17265 /* always trun on EAPD */
17266 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17267 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17268 { }
17269};
17270
a9111321 17271static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17272 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17274 {}
17275};
17276
a9111321 17277static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17278 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17279 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17280 {}
bc9f98a9
KY
17281};
17282
8c427226 17283/* Set Unsolicited Event*/
a9111321 17284static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17286 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17287 {}
17288};
17289
a9111321 17290static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17293 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17294 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17295 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17298 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17299 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17300 {}
17301};
17302
a9111321 17303static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17304 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17305 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17306 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17309 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17310 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17311 {}
17312};
17313
a9111321 17314static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17316 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17317 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17318 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17323 {}
17324};
6dda9f4a 17325
a9111321 17326static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17334 {}
17335};
6dda9f4a 17336
a9111321 17337static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17338 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17339 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17340 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17341 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17347 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17348 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17350 {}
17351};
17352
a9111321 17353static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
17354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17356 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17359 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17363 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17366 {}
17367};
17368
a9111321 17369static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
17370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17371 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17372 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17373
17374 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17376 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17377
17378 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17379 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17380 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17381 {}
17382};
17383
a9111321 17384static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
17385 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17386 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17387 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17388
17389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17390 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17391 {}
17392};
17393
a9111321 17394static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
17395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17398 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17399 {}
17400};
17401
a9111321 17402static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
17403 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17404 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17407 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17408 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17409 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17412 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17413 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17414 {}
17415};
17416
a9111321 17417static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
17418 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17419 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17421 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17422 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17423 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17424 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17425 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17429 {}
17430};
17431
a9111321 17432static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
17433 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17434 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17435 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17436 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17437 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17439 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17440 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17441 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17442 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17445 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17446 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17447 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17448 {}
17449};
17450
a9111321 17451static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
17452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17456 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17457 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17459 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17460 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17461 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17462 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17468 {}
17469};
17470
a9111321 17471static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
17472 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17473 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17474 { } /* end */
17475};
17476
a9111321 17477static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
17478 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17479 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17480 { } /* end */
17481};
17482
e6a5e1b7 17483static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 17484{
e6a5e1b7 17485 struct alc_spec *spec = codec->spec;
bc9f98a9 17486
e6a5e1b7
TI
17487 spec->autocfg.hp_pins[0] = 0x1b;
17488 spec->autocfg.line_out_pins[0] = 0x14;
17489 spec->autocfg.speaker_pins[0] = 0x15;
17490 spec->automute = 1;
17491 spec->detect_line = 1;
17492 spec->automute_lines = 1;
17493 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
17494}
17495
4f5d1706
TI
17496static void alc662_eeepc_setup(struct hda_codec *codec)
17497{
17498 struct alc_spec *spec = codec->spec;
17499
17500 alc262_hippo1_setup(codec);
21268961
TI
17501 spec->ext_mic_pin = 0x18;
17502 spec->int_mic_pin = 0x19;
4f5d1706
TI
17503 spec->auto_mic = 1;
17504}
17505
4f5d1706 17506static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17507{
42171c17
TI
17508 struct alc_spec *spec = codec->spec;
17509
17510 spec->autocfg.hp_pins[0] = 0x14;
17511 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
17512 spec->automute = 1;
17513 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
17514}
17515
4f5d1706
TI
17516static void alc663_m51va_setup(struct hda_codec *codec)
17517{
17518 struct alc_spec *spec = codec->spec;
3b8510ce
TI
17519 spec->autocfg.hp_pins[0] = 0x21;
17520 spec->autocfg.speaker_pins[0] = 0x14;
17521 spec->automute_mixer_nid[0] = 0x0c;
17522 spec->automute = 1;
17523 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
17524 spec->ext_mic_pin = 0x18;
17525 spec->int_mic_pin = 0x12;
4f5d1706
TI
17526 spec->auto_mic = 1;
17527}
17528
f1d4e28b 17529/* ***************** Mode1 ******************************/
ebb83eeb
KY
17530static void alc663_mode1_setup(struct hda_codec *codec)
17531{
17532 struct alc_spec *spec = codec->spec;
3b8510ce
TI
17533 spec->autocfg.hp_pins[0] = 0x21;
17534 spec->autocfg.speaker_pins[0] = 0x14;
17535 spec->automute_mixer_nid[0] = 0x0c;
17536 spec->automute = 1;
17537 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
17538 spec->ext_mic_pin = 0x18;
17539 spec->int_mic_pin = 0x19;
ebb83eeb
KY
17540 spec->auto_mic = 1;
17541}
17542
f1d4e28b 17543/* ***************** Mode2 ******************************/
3b8510ce 17544static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 17545{
3b8510ce
TI
17546 struct alc_spec *spec = codec->spec;
17547 spec->autocfg.hp_pins[0] = 0x1b;
17548 spec->autocfg.speaker_pins[0] = 0x14;
17549 spec->automute = 1;
17550 spec->automute_mode = ALC_AUTOMUTE_PIN;
21268961
TI
17551 spec->ext_mic_pin = 0x18;
17552 spec->int_mic_pin = 0x19;
3b8510ce 17553 spec->auto_mic = 1;
f1d4e28b
KY
17554}
17555
f1d4e28b 17556/* ***************** Mode3 ******************************/
3b8510ce 17557static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 17558{
3b8510ce
TI
17559 struct alc_spec *spec = codec->spec;
17560 spec->autocfg.hp_pins[0] = 0x21;
17561 spec->autocfg.hp_pins[0] = 0x15;
17562 spec->autocfg.speaker_pins[0] = 0x14;
17563 spec->automute = 1;
17564 spec->automute_mode = ALC_AUTOMUTE_PIN;
21268961
TI
17565 spec->ext_mic_pin = 0x18;
17566 spec->int_mic_pin = 0x19;
3b8510ce 17567 spec->auto_mic = 1;
f1d4e28b
KY
17568}
17569
f1d4e28b 17570/* ***************** Mode4 ******************************/
3b8510ce 17571static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 17572{
3b8510ce
TI
17573 struct alc_spec *spec = codec->spec;
17574 spec->autocfg.hp_pins[0] = 0x21;
17575 spec->autocfg.speaker_pins[0] = 0x14;
17576 spec->autocfg.speaker_pins[1] = 0x16;
17577 spec->automute_mixer_nid[0] = 0x0c;
17578 spec->automute_mixer_nid[1] = 0x0e;
17579 spec->automute = 1;
17580 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
17581 spec->ext_mic_pin = 0x18;
17582 spec->int_mic_pin = 0x19;
3b8510ce 17583 spec->auto_mic = 1;
f1d4e28b
KY
17584}
17585
f1d4e28b 17586/* ***************** Mode5 ******************************/
3b8510ce 17587static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 17588{
3b8510ce
TI
17589 struct alc_spec *spec = codec->spec;
17590 spec->autocfg.hp_pins[0] = 0x15;
17591 spec->autocfg.speaker_pins[0] = 0x14;
17592 spec->autocfg.speaker_pins[1] = 0x16;
17593 spec->automute_mixer_nid[0] = 0x0c;
17594 spec->automute_mixer_nid[1] = 0x0e;
17595 spec->automute = 1;
17596 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
17597 spec->ext_mic_pin = 0x18;
17598 spec->int_mic_pin = 0x19;
3b8510ce 17599 spec->auto_mic = 1;
f1d4e28b
KY
17600}
17601
f1d4e28b 17602/* ***************** Mode6 ******************************/
3b8510ce 17603static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 17604{
3b8510ce
TI
17605 struct alc_spec *spec = codec->spec;
17606 spec->autocfg.hp_pins[0] = 0x1b;
17607 spec->autocfg.hp_pins[0] = 0x15;
17608 spec->autocfg.speaker_pins[0] = 0x14;
17609 spec->automute_mixer_nid[0] = 0x0c;
17610 spec->automute = 1;
17611 spec->automute_mode = ALC_AUTOMUTE_MIXER;
21268961
TI
17612 spec->ext_mic_pin = 0x18;
17613 spec->int_mic_pin = 0x19;
3b8510ce 17614 spec->auto_mic = 1;
f1d4e28b
KY
17615}
17616
ebb83eeb 17617/* ***************** Mode7 ******************************/
3b8510ce 17618static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 17619{
3b8510ce
TI
17620 struct alc_spec *spec = codec->spec;
17621 spec->autocfg.hp_pins[0] = 0x1b;
17622 spec->autocfg.hp_pins[0] = 0x21;
17623 spec->autocfg.speaker_pins[0] = 0x14;
17624 spec->autocfg.speaker_pins[0] = 0x17;
17625 spec->automute = 1;
17626 spec->automute_mode = ALC_AUTOMUTE_PIN;
21268961
TI
17627 spec->ext_mic_pin = 0x18;
17628 spec->int_mic_pin = 0x19;
3b8510ce 17629 spec->auto_mic = 1;
ebb83eeb
KY
17630}
17631
17632/* ***************** Mode8 ******************************/
3b8510ce 17633static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 17634{
3b8510ce
TI
17635 struct alc_spec *spec = codec->spec;
17636 spec->autocfg.hp_pins[0] = 0x21;
17637 spec->autocfg.hp_pins[1] = 0x15;
17638 spec->autocfg.speaker_pins[0] = 0x14;
17639 spec->autocfg.speaker_pins[0] = 0x17;
17640 spec->automute = 1;
17641 spec->automute_mode = ALC_AUTOMUTE_PIN;
21268961
TI
17642 spec->ext_mic_pin = 0x18;
17643 spec->int_mic_pin = 0x12;
3b8510ce 17644 spec->auto_mic = 1;
ebb83eeb
KY
17645}
17646
e6a5e1b7 17647static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 17648{
e6a5e1b7
TI
17649 struct alc_spec *spec = codec->spec;
17650 spec->autocfg.hp_pins[0] = 0x21;
17651 spec->autocfg.line_out_pins[0] = 0x15;
17652 spec->autocfg.speaker_pins[0] = 0x14;
17653 spec->automute = 1;
17654 spec->automute_mode = ALC_AUTOMUTE_AMP;
17655 spec->detect_line = 1;
17656 spec->automute_lines = 1;
21268961
TI
17657 spec->ext_mic_pin = 0x18;
17658 spec->int_mic_pin = 0x12;
e6a5e1b7 17659 spec->auto_mic = 1;
6dda9f4a
KY
17660}
17661
4f5d1706
TI
17662#define alc663_g50v_setup alc663_m51va_setup
17663
a9111321 17664static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 17665 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 17666 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 17667
5f99f86a 17668 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17669 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 17671
5f99f86a 17672 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17673 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17674 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
17675 { } /* end */
17676};
17677
a9111321 17678static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
17679 /* Master Playback automatically created from Speaker and Headphone */
17680 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17681 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17682 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17684
8607f7c4
DH
17685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 17687 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 17688
28c4edb7
DH
17689 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17690 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 17691 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
17692 { } /* end */
17693};
17694
cb53c626
TI
17695#ifdef CONFIG_SND_HDA_POWER_SAVE
17696#define alc662_loopbacks alc880_loopbacks
17697#endif
17698
bc9f98a9 17699
bc9f98a9
KY
17700/*
17701 * configuration and preset
17702 */
ea734963 17703static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
17704 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17705 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17706 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 17707 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 17708 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 17709 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 17710 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 17711 [ALC662_ECS] = "ecs",
6dda9f4a
KY
17712 [ALC663_ASUS_M51VA] = "m51va",
17713 [ALC663_ASUS_G71V] = "g71v",
17714 [ALC663_ASUS_H13] = "h13",
17715 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
17716 [ALC663_ASUS_MODE1] = "asus-mode1",
17717 [ALC662_ASUS_MODE2] = "asus-mode2",
17718 [ALC663_ASUS_MODE3] = "asus-mode3",
17719 [ALC663_ASUS_MODE4] = "asus-mode4",
17720 [ALC663_ASUS_MODE5] = "asus-mode5",
17721 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
17722 [ALC663_ASUS_MODE7] = "asus-mode7",
17723 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
17724 [ALC272_DELL] = "dell",
17725 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 17726 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
17727 [ALC662_AUTO] = "auto",
17728};
17729
a9111321 17730static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 17731 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
17732 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17733 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 17734 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 17735 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 17736 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 17737 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 17738 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 17739 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 17740 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
17741 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17742 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 17743 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17744 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17745 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17746 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17747 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17748 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 17749 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17750 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17751 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
17752 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17753 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17754 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17755 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 17756 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
17757 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17758 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17759 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 17760 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17761 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17762 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17763 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 17764 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 17765 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17766 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17767 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17768 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 17769 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 17770 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 17771 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 17772 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
17773 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17774 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
17775 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17776 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17777 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 17778 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
17779 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17780 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 17781 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
17782 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17783 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17784 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17785 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17786 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 17787 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 17788 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 17789 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
17790 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17791 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17792 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17793 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
17794 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17795 ALC662_3ST_6ch_DIG),
4dee8baa 17796 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 17797 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
17798 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17799 ALC662_3ST_6ch_DIG),
6227cdce 17800 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 17801 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 17802 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 17803 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 17804 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 17805 ALC662_3ST_6ch_DIG),
dea0a509
TI
17806 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17807 ALC663_ASUS_H13),
965b76d2 17808 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
17809 {}
17810};
17811
a9111321 17812static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 17813 [ALC662_3ST_2ch_DIG] = {
f9e336f6 17814 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 17815 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17817 .dac_nids = alc662_dac_nids,
17818 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17819 .dig_in_nid = ALC662_DIGIN_NID,
17820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17821 .channel_mode = alc662_3ST_2ch_modes,
17822 .input_mux = &alc662_capture_source,
17823 },
17824 [ALC662_3ST_6ch_DIG] = {
f9e336f6 17825 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 17826 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17827 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17828 .dac_nids = alc662_dac_nids,
17829 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17830 .dig_in_nid = ALC662_DIGIN_NID,
17831 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17832 .channel_mode = alc662_3ST_6ch_modes,
17833 .need_dac_fix = 1,
17834 .input_mux = &alc662_capture_source,
f12ab1e0 17835 },
bc9f98a9 17836 [ALC662_3ST_6ch] = {
f9e336f6 17837 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 17838 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17839 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17840 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17842 .channel_mode = alc662_3ST_6ch_modes,
17843 .need_dac_fix = 1,
17844 .input_mux = &alc662_capture_source,
f12ab1e0 17845 },
bc9f98a9 17846 [ALC662_5ST_DIG] = {
f9e336f6 17847 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 17848 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17849 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17850 .dac_nids = alc662_dac_nids,
17851 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17852 .dig_in_nid = ALC662_DIGIN_NID,
17853 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17854 .channel_mode = alc662_5stack_modes,
17855 .input_mux = &alc662_capture_source,
17856 },
17857 [ALC662_LENOVO_101E] = {
f9e336f6 17858 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
17859 .init_verbs = { alc662_init_verbs,
17860 alc662_eapd_init_verbs,
17861 alc662_sue_init_verbs },
bc9f98a9
KY
17862 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17863 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17865 .channel_mode = alc662_3ST_2ch_modes,
17866 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
17867 .unsol_event = alc_sku_unsol_event,
17868 .setup = alc662_lenovo_101e_setup,
17869 .init_hook = alc_inithook,
bc9f98a9 17870 },
291702f0 17871 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 17872 .mixers = { alc662_eeepc_p701_mixer },
291702f0 17873 .init_verbs = { alc662_init_verbs,
a7f2371f 17874 alc662_eapd_init_verbs,
291702f0
KY
17875 alc662_eeepc_sue_init_verbs },
17876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17877 .dac_nids = alc662_dac_nids,
291702f0
KY
17878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17879 .channel_mode = alc662_3ST_2ch_modes,
e9427969 17880 .unsol_event = alc_sku_unsol_event,
4f5d1706 17881 .setup = alc662_eeepc_setup,
e9427969 17882 .init_hook = alc_inithook,
291702f0 17883 },
8c427226 17884 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 17885 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
17886 alc662_chmode_mixer },
17887 .init_verbs = { alc662_init_verbs,
a7f2371f 17888 alc662_eapd_init_verbs,
8c427226
KY
17889 alc662_eeepc_ep20_sue_init_verbs },
17890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17891 .dac_nids = alc662_dac_nids,
8c427226
KY
17892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17893 .channel_mode = alc662_3ST_6ch_modes,
17894 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 17895 .unsol_event = alc_sku_unsol_event,
4f5d1706 17896 .setup = alc662_eeepc_ep20_setup,
e9427969 17897 .init_hook = alc_inithook,
8c427226 17898 },
f1d4e28b 17899 [ALC662_ECS] = {
f9e336f6 17900 .mixers = { alc662_ecs_mixer },
f1d4e28b 17901 .init_verbs = { alc662_init_verbs,
a7f2371f 17902 alc662_eapd_init_verbs,
f1d4e28b
KY
17903 alc662_ecs_init_verbs },
17904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17905 .dac_nids = alc662_dac_nids,
17906 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17907 .channel_mode = alc662_3ST_2ch_modes,
e9427969 17908 .unsol_event = alc_sku_unsol_event,
4f5d1706 17909 .setup = alc662_eeepc_setup,
e9427969 17910 .init_hook = alc_inithook,
f1d4e28b 17911 },
6dda9f4a 17912 [ALC663_ASUS_M51VA] = {
f9e336f6 17913 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
17914 .init_verbs = { alc662_init_verbs,
17915 alc662_eapd_init_verbs,
17916 alc663_m51va_init_verbs },
6dda9f4a
KY
17917 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17918 .dac_nids = alc662_dac_nids,
17919 .dig_out_nid = ALC662_DIGOUT_NID,
17920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17921 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 17922 .unsol_event = alc_sku_unsol_event,
4f5d1706 17923 .setup = alc663_m51va_setup,
3b8510ce 17924 .init_hook = alc_inithook,
6dda9f4a
KY
17925 },
17926 [ALC663_ASUS_G71V] = {
f9e336f6 17927 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
17928 .init_verbs = { alc662_init_verbs,
17929 alc662_eapd_init_verbs,
17930 alc663_g71v_init_verbs },
6dda9f4a
KY
17931 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17932 .dac_nids = alc662_dac_nids,
17933 .dig_out_nid = ALC662_DIGOUT_NID,
17934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17935 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 17936 .unsol_event = alc_sku_unsol_event,
4f5d1706 17937 .setup = alc663_g71v_setup,
e6a5e1b7 17938 .init_hook = alc_inithook,
6dda9f4a
KY
17939 },
17940 [ALC663_ASUS_H13] = {
f9e336f6 17941 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
17942 .init_verbs = { alc662_init_verbs,
17943 alc662_eapd_init_verbs,
17944 alc663_m51va_init_verbs },
6dda9f4a
KY
17945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17946 .dac_nids = alc662_dac_nids,
17947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17948 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
17949 .setup = alc663_m51va_setup,
17950 .unsol_event = alc_sku_unsol_event,
17951 .init_hook = alc_inithook,
6dda9f4a
KY
17952 },
17953 [ALC663_ASUS_G50V] = {
f9e336f6 17954 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
17955 .init_verbs = { alc662_init_verbs,
17956 alc662_eapd_init_verbs,
17957 alc663_g50v_init_verbs },
6dda9f4a
KY
17958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17959 .dac_nids = alc662_dac_nids,
17960 .dig_out_nid = ALC662_DIGOUT_NID,
17961 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17962 .channel_mode = alc662_3ST_6ch_modes,
17963 .input_mux = &alc663_capture_source,
3b8510ce 17964 .unsol_event = alc_sku_unsol_event,
4f5d1706 17965 .setup = alc663_g50v_setup,
3b8510ce 17966 .init_hook = alc_inithook,
6dda9f4a 17967 },
f1d4e28b 17968 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
17969 .mixers = { alc663_m51va_mixer },
17970 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 17971 .init_verbs = { alc662_init_verbs,
a7f2371f 17972 alc662_eapd_init_verbs,
f1d4e28b
KY
17973 alc663_21jd_amic_init_verbs },
17974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17975 .hp_nid = 0x03,
17976 .dac_nids = alc662_dac_nids,
17977 .dig_out_nid = ALC662_DIGOUT_NID,
17978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17979 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 17980 .unsol_event = alc_sku_unsol_event,
4f5d1706 17981 .setup = alc663_mode1_setup,
3b8510ce 17982 .init_hook = alc_inithook,
f1d4e28b
KY
17983 },
17984 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
17985 .mixers = { alc662_1bjd_mixer },
17986 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 17987 .init_verbs = { alc662_init_verbs,
a7f2371f 17988 alc662_eapd_init_verbs,
f1d4e28b
KY
17989 alc662_1bjd_amic_init_verbs },
17990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17991 .dac_nids = alc662_dac_nids,
17992 .dig_out_nid = ALC662_DIGOUT_NID,
17993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17994 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 17995 .unsol_event = alc_sku_unsol_event,
4f5d1706 17996 .setup = alc662_mode2_setup,
3b8510ce 17997 .init_hook = alc_inithook,
f1d4e28b
KY
17998 },
17999 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18000 .mixers = { alc663_two_hp_m1_mixer },
18001 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18002 .init_verbs = { alc662_init_verbs,
a7f2371f 18003 alc662_eapd_init_verbs,
f1d4e28b
KY
18004 alc663_two_hp_amic_m1_init_verbs },
18005 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18006 .hp_nid = 0x03,
18007 .dac_nids = alc662_dac_nids,
18008 .dig_out_nid = ALC662_DIGOUT_NID,
18009 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18010 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18011 .unsol_event = alc_sku_unsol_event,
4f5d1706 18012 .setup = alc663_mode3_setup,
3b8510ce 18013 .init_hook = alc_inithook,
f1d4e28b
KY
18014 },
18015 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18016 .mixers = { alc663_asus_21jd_clfe_mixer },
18017 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18018 .init_verbs = { alc662_init_verbs,
a7f2371f 18019 alc662_eapd_init_verbs,
f1d4e28b
KY
18020 alc663_21jd_amic_init_verbs},
18021 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18022 .hp_nid = 0x03,
18023 .dac_nids = alc662_dac_nids,
18024 .dig_out_nid = ALC662_DIGOUT_NID,
18025 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18026 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18027 .unsol_event = alc_sku_unsol_event,
4f5d1706 18028 .setup = alc663_mode4_setup,
3b8510ce 18029 .init_hook = alc_inithook,
f1d4e28b
KY
18030 },
18031 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18032 .mixers = { alc663_asus_15jd_clfe_mixer },
18033 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18034 .init_verbs = { alc662_init_verbs,
a7f2371f 18035 alc662_eapd_init_verbs,
f1d4e28b
KY
18036 alc663_15jd_amic_init_verbs },
18037 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18038 .hp_nid = 0x03,
18039 .dac_nids = alc662_dac_nids,
18040 .dig_out_nid = ALC662_DIGOUT_NID,
18041 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18042 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18043 .unsol_event = alc_sku_unsol_event,
4f5d1706 18044 .setup = alc663_mode5_setup,
3b8510ce 18045 .init_hook = alc_inithook,
f1d4e28b
KY
18046 },
18047 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18048 .mixers = { alc663_two_hp_m2_mixer },
18049 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18050 .init_verbs = { alc662_init_verbs,
a7f2371f 18051 alc662_eapd_init_verbs,
f1d4e28b
KY
18052 alc663_two_hp_amic_m2_init_verbs },
18053 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18054 .hp_nid = 0x03,
18055 .dac_nids = alc662_dac_nids,
18056 .dig_out_nid = ALC662_DIGOUT_NID,
18057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18058 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18059 .unsol_event = alc_sku_unsol_event,
4f5d1706 18060 .setup = alc663_mode6_setup,
3b8510ce 18061 .init_hook = alc_inithook,
f1d4e28b 18062 },
ebb83eeb
KY
18063 [ALC663_ASUS_MODE7] = {
18064 .mixers = { alc663_mode7_mixer },
18065 .cap_mixer = alc662_auto_capture_mixer,
18066 .init_verbs = { alc662_init_verbs,
a7f2371f 18067 alc662_eapd_init_verbs,
ebb83eeb
KY
18068 alc663_mode7_init_verbs },
18069 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18070 .hp_nid = 0x03,
18071 .dac_nids = alc662_dac_nids,
18072 .dig_out_nid = ALC662_DIGOUT_NID,
18073 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18074 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18075 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18076 .setup = alc663_mode7_setup,
3b8510ce 18077 .init_hook = alc_inithook,
ebb83eeb
KY
18078 },
18079 [ALC663_ASUS_MODE8] = {
18080 .mixers = { alc663_mode8_mixer },
18081 .cap_mixer = alc662_auto_capture_mixer,
18082 .init_verbs = { alc662_init_verbs,
a7f2371f 18083 alc662_eapd_init_verbs,
ebb83eeb
KY
18084 alc663_mode8_init_verbs },
18085 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18086 .hp_nid = 0x03,
18087 .dac_nids = alc662_dac_nids,
18088 .dig_out_nid = ALC662_DIGOUT_NID,
18089 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18090 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18091 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18092 .setup = alc663_mode8_setup,
3b8510ce 18093 .init_hook = alc_inithook,
ebb83eeb 18094 },
622e84cd
KY
18095 [ALC272_DELL] = {
18096 .mixers = { alc663_m51va_mixer },
18097 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18098 .init_verbs = { alc662_init_verbs,
18099 alc662_eapd_init_verbs,
18100 alc272_dell_init_verbs },
622e84cd 18101 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18102 .dac_nids = alc272_dac_nids,
622e84cd
KY
18103 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18104 .adc_nids = alc272_adc_nids,
18105 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18106 .capsrc_nids = alc272_capsrc_nids,
18107 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18108 .unsol_event = alc_sku_unsol_event,
4f5d1706 18109 .setup = alc663_m51va_setup,
3b8510ce 18110 .init_hook = alc_inithook,
622e84cd
KY
18111 },
18112 [ALC272_DELL_ZM1] = {
18113 .mixers = { alc663_m51va_mixer },
18114 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18115 .init_verbs = { alc662_init_verbs,
18116 alc662_eapd_init_verbs,
18117 alc272_dell_zm1_init_verbs },
622e84cd 18118 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18119 .dac_nids = alc272_dac_nids,
622e84cd
KY
18120 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18121 .adc_nids = alc662_adc_nids,
b59bdf3b 18122 .num_adc_nids = 1,
622e84cd
KY
18123 .capsrc_nids = alc662_capsrc_nids,
18124 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18125 .unsol_event = alc_sku_unsol_event,
4f5d1706 18126 .setup = alc663_m51va_setup,
3b8510ce 18127 .init_hook = alc_inithook,
622e84cd 18128 },
9541ba1d
CP
18129 [ALC272_SAMSUNG_NC10] = {
18130 .mixers = { alc272_nc10_mixer },
18131 .init_verbs = { alc662_init_verbs,
a7f2371f 18132 alc662_eapd_init_verbs,
9541ba1d
CP
18133 alc663_21jd_amic_init_verbs },
18134 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18135 .dac_nids = alc272_dac_nids,
18136 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18137 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18138 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18139 .unsol_event = alc_sku_unsol_event,
4f5d1706 18140 .setup = alc663_mode4_setup,
3b8510ce 18141 .init_hook = alc_inithook,
9541ba1d 18142 },
bc9f98a9
KY
18143};
18144
18145
18146/*
18147 * BIOS auto configuration
18148 */
18149
7085ec12 18150/* convert from MIX nid to DAC */
604401a9 18151static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18152{
604401a9 18153 hda_nid_t list[5];
1304ac89
TI
18154 int i, num;
18155
18156 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18157 for (i = 0; i < num; i++) {
18158 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18159 return list[i];
18160 }
18161 return 0;
7085ec12
TI
18162}
18163
604401a9
TI
18164/* go down to the selector widget before the mixer */
18165static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18166{
18167 hda_nid_t srcs[5];
18168 int num = snd_hda_get_connections(codec, pin, srcs,
18169 ARRAY_SIZE(srcs));
18170 if (num != 1 ||
18171 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18172 return pin;
18173 return srcs[0];
18174}
18175
7085ec12 18176/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18177static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18178 hda_nid_t dac)
18179{
cc1c452e 18180 hda_nid_t mix[5];
7085ec12
TI
18181 int i, num;
18182
604401a9 18183 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18184 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18185 for (i = 0; i < num; i++) {
604401a9 18186 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18187 return mix[i];
18188 }
18189 return 0;
18190}
18191
ce764ab2
TI
18192/* select the connection from pin to DAC if needed */
18193static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18194 hda_nid_t dac)
18195{
18196 hda_nid_t mix[5];
18197 int i, num;
18198
18199 pin = alc_go_down_to_selector(codec, pin);
18200 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18201 if (num < 2)
18202 return 0;
18203 for (i = 0; i < num; i++) {
18204 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18205 snd_hda_codec_update_cache(codec, pin, 0,
18206 AC_VERB_SET_CONNECT_SEL, i);
18207 return 0;
18208 }
18209 }
18210 return 0;
18211}
18212
7085ec12 18213/* look for an empty DAC slot */
604401a9 18214static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18215{
18216 struct alc_spec *spec = codec->spec;
18217 hda_nid_t srcs[5];
3af9ee6b 18218 int i, num;
7085ec12 18219
604401a9 18220 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18221 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18222 for (i = 0; i < num; i++) {
604401a9 18223 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18224 if (!nid)
18225 continue;
3af9ee6b
TI
18226 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18227 spec->multiout.num_dacs))
18228 continue;
18229 if (spec->multiout.hp_nid == nid)
18230 continue;
18231 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18232 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18233 continue;
18234 return nid;
7085ec12
TI
18235 }
18236 return 0;
18237}
18238
3af9ee6b
TI
18239static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18240{
18241 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18242 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18243 return alc_auto_look_for_dac(codec, pin);
18244 return 0;
18245}
18246
7085ec12 18247/* fill in the dac_nids table from the parsed pin configuration */
343a04be 18248static int alc_auto_fill_dac_nids(struct hda_codec *codec)
7085ec12
TI
18249{
18250 struct alc_spec *spec = codec->spec;
cb053a82 18251 const struct auto_pin_cfg *cfg = &spec->autocfg;
350434ee 18252 bool redone = false;
7085ec12 18253 int i;
7085ec12 18254
3af9ee6b 18255 again:
3fccdfd8 18256 spec->multiout.num_dacs = 0;
3af9ee6b
TI
18257 spec->multiout.hp_nid = 0;
18258 spec->multiout.extra_out_nid[0] = 0;
18259 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18260 spec->multiout.dac_nids = spec->private_dac_nids;
18261
18262 /* fill hard-wired DACs first */
18263 if (!redone) {
18264 for (i = 0; i < cfg->line_outs; i++)
18265 spec->private_dac_nids[i] =
18266 get_dac_if_single(codec, cfg->line_out_pins[i]);
18267 if (cfg->hp_outs)
18268 spec->multiout.hp_nid =
18269 get_dac_if_single(codec, cfg->hp_pins[0]);
18270 if (cfg->speaker_outs)
18271 spec->multiout.extra_out_nid[0] =
18272 get_dac_if_single(codec, cfg->speaker_pins[0]);
18273 }
18274
7085ec12 18275 for (i = 0; i < cfg->line_outs; i++) {
3af9ee6b
TI
18276 hda_nid_t pin = cfg->line_out_pins[i];
18277 if (spec->private_dac_nids[i])
7085ec12 18278 continue;
3af9ee6b
TI
18279 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18280 if (!spec->private_dac_nids[i] && !redone) {
18281 /* if we can't find primary DACs, re-probe without
18282 * checking the hard-wired DACs
18283 */
18284 redone = true;
18285 goto again;
18286 }
18287 }
18288
18289 for (i = 0; i < cfg->line_outs; i++) {
18290 if (spec->private_dac_nids[i])
18291 spec->multiout.num_dacs++;
18292 else
18293 memmove(spec->private_dac_nids + i,
18294 spec->private_dac_nids + i + 1,
18295 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
7085ec12 18296 }
3af9ee6b 18297
bb8bf4d4
TI
18298 if (cfg->hp_outs && !spec->multiout.hp_nid)
18299 spec->multiout.hp_nid =
18300 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18301 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18302 spec->multiout.extra_out_nid[0] =
18303 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18304
7085ec12
TI
18305 return 0;
18306}
18307
343a04be 18308static int alc_auto_add_vol_ctl(struct hda_codec *codec,
97aaab7b
TI
18309 const char *pfx, int cidx,
18310 hda_nid_t nid, unsigned int chs)
7085ec12 18311{
97aaab7b
TI
18312 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18313 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
7085ec12
TI
18314}
18315
343a04be
TI
18316#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18317 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
97aaab7b
TI
18318
18319/* create a mute-switch for the given mixer widget;
18320 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18321 */
343a04be 18322static int alc_auto_add_sw_ctl(struct hda_codec *codec,
97aaab7b
TI
18323 const char *pfx, int cidx,
18324 hda_nid_t nid, unsigned int chs)
7085ec12 18325{
97aaab7b
TI
18326 int type;
18327 unsigned long val;
18328 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18329 type = ALC_CTL_WIDGET_MUTE;
18330 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18331 } else {
18332 type = ALC_CTL_BIND_MUTE;
18333 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18334 }
18335 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
7085ec12
TI
18336}
18337
343a04be
TI
18338#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18339 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
7085ec12 18340
bc9f98a9 18341/* add playback controls from the parsed DAC table */
343a04be 18342static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18343 const struct auto_pin_cfg *cfg)
18344{
7085ec12 18345 struct alc_spec *spec = codec->spec;
ce764ab2
TI
18346 hda_nid_t nid, mix, pin;
18347 int i, err, noutputs;
bc9f98a9 18348
ce764ab2
TI
18349 noutputs = cfg->line_outs;
18350 if (spec->multi_ios > 0)
18351 noutputs += spec->multi_ios;
18352
18353 for (i = 0; i < noutputs; i++) {
6843ca16
TI
18354 const char *name;
18355 int index;
7085ec12
TI
18356 nid = spec->multiout.dac_nids[i];
18357 if (!nid)
18358 continue;
ce764ab2
TI
18359 if (i >= cfg->line_outs)
18360 pin = spec->multi_io[i - 1].pin;
18361 else
18362 pin = cfg->line_out_pins[i];
18363 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18364 if (!mix)
bc9f98a9 18365 continue;
6843ca16
TI
18366 name = alc_get_line_out_pfx(spec, i, true, &index);
18367 if (!name) {
bc9f98a9 18368 /* Center/LFE */
343a04be 18369 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
bc9f98a9
KY
18370 if (err < 0)
18371 return err;
343a04be 18372 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
bc9f98a9
KY
18373 if (err < 0)
18374 return err;
343a04be 18375 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
bc9f98a9
KY
18376 if (err < 0)
18377 return err;
343a04be 18378 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
bc9f98a9
KY
18379 if (err < 0)
18380 return err;
18381 } else {
343a04be 18382 err = alc_auto_add_stereo_vol(codec, name, index, nid);
bc9f98a9
KY
18383 if (err < 0)
18384 return err;
343a04be 18385 err = alc_auto_add_stereo_sw(codec, name, index, mix);
bc9f98a9
KY
18386 if (err < 0)
18387 return err;
18388 }
18389 }
18390 return 0;
18391}
18392
18393/* add playback controls for speaker and HP outputs */
343a04be 18394static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3af9ee6b 18395 hda_nid_t dac, const char *pfx)
bc9f98a9 18396{
7085ec12 18397 struct alc_spec *spec = codec->spec;
3af9ee6b 18398 hda_nid_t mix;
bc9f98a9 18399 int err;
bc9f98a9
KY
18400
18401 if (!pin)
18402 return 0;
3af9ee6b 18403 if (!dac) {
7085ec12
TI
18404 /* the corresponding DAC is already occupied */
18405 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18406 return 0; /* no way */
18407 /* create a switch only */
0afe5f89 18408 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18409 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18410 }
18411
3af9ee6b 18412 mix = alc_auto_dac_to_mix(codec, pin, dac);
7085ec12
TI
18413 if (!mix)
18414 return 0;
343a04be 18415 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
7085ec12
TI
18416 if (err < 0)
18417 return err;
343a04be 18418 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
7085ec12
TI
18419 if (err < 0)
18420 return err;
3af9ee6b 18421 return 0;
bc9f98a9
KY
18422}
18423
343a04be
TI
18424static int alc_auto_create_hp_out(struct hda_codec *codec)
18425{
18426 struct alc_spec *spec = codec->spec;
18427 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18428 spec->multiout.hp_nid,
18429 "Headphone");
18430}
18431
18432static int alc_auto_create_speaker_out(struct hda_codec *codec)
18433{
18434 struct alc_spec *spec = codec->spec;
18435 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18436 spec->multiout.extra_out_nid[0],
18437 "Speaker");
18438}
18439
343a04be 18440static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
bc9f98a9 18441 hda_nid_t nid, int pin_type,
7085ec12 18442 hda_nid_t dac)
bc9f98a9 18443{
7085ec12 18444 int i, num;
343a04be 18445 hda_nid_t mix = 0;
ce503f38 18446 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18447
f6c7e546 18448 alc_set_pin_output(codec, nid, pin_type);
cd511556 18449 nid = alc_go_down_to_selector(codec, nid);
7085ec12 18450 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 18451 for (i = 0; i < num; i++) {
604401a9 18452 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 18453 continue;
cd511556
TI
18454 mix = srcs[i];
18455 break;
bc9f98a9 18456 }
cd511556
TI
18457 if (!mix)
18458 return;
18459
18460 /* need the manual connection? */
18461 if (num > 1)
18462 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18463 /* unmute mixer widget inputs */
18464 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18465 AMP_IN_UNMUTE(0));
18466 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18467 AMP_IN_UNMUTE(1));
18468 /* initialize volume */
18469 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18470 nid = dac;
18471 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18472 nid = mix;
18473 else
18474 return;
18475 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18476 AMP_OUT_ZERO);
bc9f98a9
KY
18477}
18478
343a04be 18479static void alc_auto_init_multi_out(struct hda_codec *codec)
bc9f98a9
KY
18480{
18481 struct alc_spec *spec = codec->spec;
7085ec12 18482 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18483 int i;
18484
18485 for (i = 0; i <= HDA_SIDE; i++) {
18486 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18487 if (nid)
343a04be 18488 alc_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18489 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18490 }
18491}
18492
343a04be 18493static void alc_auto_init_extra_out(struct hda_codec *codec)
bc9f98a9
KY
18494{
18495 struct alc_spec *spec = codec->spec;
18496 hda_nid_t pin;
18497
18498 pin = spec->autocfg.hp_pins[0];
7085ec12 18499 if (pin)
343a04be 18500 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
7085ec12 18501 spec->multiout.hp_nid);
f6c7e546
TI
18502 pin = spec->autocfg.speaker_pins[0];
18503 if (pin)
343a04be 18504 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
7085ec12 18505 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18506}
18507
ce764ab2
TI
18508/*
18509 * multi-io helper
18510 */
18511static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18512 unsigned int location)
18513{
18514 struct alc_spec *spec = codec->spec;
18515 struct auto_pin_cfg *cfg = &spec->autocfg;
18516 int type, i, num_pins = 0;
18517
18518 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18519 for (i = 0; i < cfg->num_inputs; i++) {
18520 hda_nid_t nid = cfg->inputs[i].pin;
18521 hda_nid_t dac;
18522 unsigned int defcfg, caps;
18523 if (cfg->inputs[i].type != type)
18524 continue;
18525 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18526 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18527 continue;
18528 if (location && get_defcfg_location(defcfg) != location)
18529 continue;
18530 caps = snd_hda_query_pin_caps(codec, nid);
18531 if (!(caps & AC_PINCAP_OUT))
18532 continue;
18533 dac = alc_auto_look_for_dac(codec, nid);
18534 if (!dac)
18535 continue;
18536 spec->multi_io[num_pins].pin = nid;
18537 spec->multi_io[num_pins].dac = dac;
18538 num_pins++;
dda14410 18539 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
18540 }
18541 }
18542 spec->multiout.num_dacs = 1;
18543 if (num_pins < 2)
18544 return 0;
18545 return num_pins;
18546}
18547
18548static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18549 struct snd_ctl_elem_info *uinfo)
18550{
18551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18552 struct alc_spec *spec = codec->spec;
18553
18554 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18555 uinfo->count = 1;
18556 uinfo->value.enumerated.items = spec->multi_ios + 1;
18557 if (uinfo->value.enumerated.item > spec->multi_ios)
18558 uinfo->value.enumerated.item = spec->multi_ios;
18559 sprintf(uinfo->value.enumerated.name, "%dch",
18560 (uinfo->value.enumerated.item + 1) * 2);
18561 return 0;
18562}
18563
18564static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18565 struct snd_ctl_elem_value *ucontrol)
18566{
18567 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18568 struct alc_spec *spec = codec->spec;
18569 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18570 return 0;
18571}
18572
18573static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18574{
18575 struct alc_spec *spec = codec->spec;
18576 hda_nid_t nid = spec->multi_io[idx].pin;
18577
18578 if (!spec->multi_io[idx].ctl_in)
18579 spec->multi_io[idx].ctl_in =
18580 snd_hda_codec_read(codec, nid, 0,
18581 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18582 if (output) {
18583 snd_hda_codec_update_cache(codec, nid, 0,
18584 AC_VERB_SET_PIN_WIDGET_CONTROL,
18585 PIN_OUT);
18586 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18587 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18588 HDA_AMP_MUTE, 0);
18589 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18590 } else {
18591 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18593 HDA_AMP_MUTE, HDA_AMP_MUTE);
18594 snd_hda_codec_update_cache(codec, nid, 0,
18595 AC_VERB_SET_PIN_WIDGET_CONTROL,
18596 spec->multi_io[idx].ctl_in);
18597 }
18598 return 0;
18599}
18600
18601static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18602 struct snd_ctl_elem_value *ucontrol)
18603{
18604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18605 struct alc_spec *spec = codec->spec;
18606 int i, ch;
18607
18608 ch = ucontrol->value.enumerated.item[0];
18609 if (ch < 0 || ch > spec->multi_ios)
18610 return -EINVAL;
18611 if (ch == (spec->ext_channel_count - 1) / 2)
18612 return 0;
18613 spec->ext_channel_count = (ch + 1) * 2;
18614 for (i = 0; i < spec->multi_ios; i++)
18615 alc_set_multi_io(codec, i, i < ch);
18616 spec->multiout.max_channels = spec->ext_channel_count;
18617 return 1;
18618}
18619
a9111321 18620static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
18621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18622 .name = "Channel Mode",
18623 .info = alc_auto_ch_mode_info,
18624 .get = alc_auto_ch_mode_get,
18625 .put = alc_auto_ch_mode_put,
18626};
18627
cb053a82
TI
18628static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18629 int (*fill_dac)(struct hda_codec *))
ce764ab2
TI
18630{
18631 struct alc_spec *spec = codec->spec;
18632 struct auto_pin_cfg *cfg = &spec->autocfg;
18633 unsigned int location, defcfg;
18634 int num_pins;
18635
3fccdfd8
TI
18636 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18637 /* use HP as primary out */
18638 cfg->speaker_outs = cfg->line_outs;
18639 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18640 sizeof(cfg->speaker_pins));
18641 cfg->line_outs = cfg->hp_outs;
18642 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18643 cfg->hp_outs = 0;
18644 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18645 cfg->line_out_type = AUTO_PIN_HP_OUT;
cb053a82
TI
18646 if (fill_dac)
18647 fill_dac(codec);
3fccdfd8 18648 }
ce764ab2 18649 if (cfg->line_outs != 1 ||
3fccdfd8 18650 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
ce764ab2
TI
18651 return 0;
18652
18653 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18654 location = get_defcfg_location(defcfg);
18655
18656 num_pins = alc_auto_fill_multi_ios(codec, location);
18657 if (num_pins > 0) {
18658 struct snd_kcontrol_new *knew;
18659
18660 knew = alc_kcontrol_new(spec);
18661 if (!knew)
18662 return -ENOMEM;
18663 *knew = alc_auto_channel_mode_enum;
18664 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18665 if (!knew->name)
18666 return -ENOMEM;
18667
18668 spec->multi_ios = num_pins;
18669 spec->ext_channel_count = 2;
18670 spec->multiout.num_dacs = num_pins + 1;
18671 }
18672 return 0;
18673}
18674
bc9f98a9
KY
18675static int alc662_parse_auto_config(struct hda_codec *codec)
18676{
18677 struct alc_spec *spec = codec->spec;
18678 int err;
4c6d72d1 18679 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
18680
18681 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18682 alc662_ignore);
18683 if (err < 0)
18684 return err;
18685 if (!spec->autocfg.line_outs)
18686 return 0; /* can't find valid BIOS pin config */
18687
343a04be 18688 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
18689 if (err < 0)
18690 return err;
343a04be 18691 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
18692 if (err < 0)
18693 return err;
343a04be 18694 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18695 if (err < 0)
18696 return err;
343a04be 18697 err = alc_auto_create_extra_out(codec,
f12ab1e0 18698 spec->autocfg.speaker_pins[0],
3af9ee6b 18699 spec->multiout.extra_out_nid[0],
f12ab1e0
TI
18700 "Speaker");
18701 if (err < 0)
18702 return err;
343a04be 18703 err = alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3af9ee6b 18704 spec->multiout.hp_nid,
f12ab1e0
TI
18705 "Headphone");
18706 if (err < 0)
18707 return err;
b7821709 18708 err = alc_auto_create_input_ctls(codec);
f12ab1e0 18709 if (err < 0)
bc9f98a9
KY
18710 return err;
18711
18712 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18713
757899ac 18714 alc_auto_parse_digital(codec);
bc9f98a9 18715
603c4019 18716 if (spec->kctls.list)
d88897ea 18717 add_mixer(spec, spec->kctls.list);
bc9f98a9 18718
21268961 18719 alc_remove_invalid_adc_nids(codec);
ee979a14 18720
6227cdce
KY
18721 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18722 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18723 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18724 else
18725 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
21268961
TI
18726 alc_auto_check_switches(codec);
18727
18728 err = alc_auto_add_mic_boost(codec);
18729 if (err < 0)
18730 return err;
4a79ba34 18731
8c87286f 18732 return 1;
bc9f98a9
KY
18733}
18734
18735/* additional initialization for auto-configuration model */
18736static void alc662_auto_init(struct hda_codec *codec)
18737{
f6c7e546 18738 struct alc_spec *spec = codec->spec;
343a04be
TI
18739 alc_auto_init_multi_out(codec);
18740 alc_auto_init_extra_out(codec);
0a7f5320 18741 alc_auto_init_analog_input(codec);
f970de25 18742 alc_auto_init_input_src(codec);
757899ac 18743 alc_auto_init_digital(codec);
f6c7e546 18744 if (spec->unsol_event)
7fb0d78f 18745 alc_inithook(codec);
bc9f98a9
KY
18746}
18747
6be7948f 18748static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 18749 const struct alc_fixup *fix, int action)
6fc398cb 18750{
b5bfbc67 18751 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 18752 return;
6be7948f
TB
18753 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
18754 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
18755 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
18756 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
18757 (0 << AC_AMPCAP_MUTE_SHIFT)))
18758 printk(KERN_WARNING
18759 "hda_codec: failed to override amp caps for NID 0x2\n");
18760}
18761
6cb3b707 18762enum {
2df03514 18763 ALC662_FIXUP_ASPIRE,
6cb3b707 18764 ALC662_FIXUP_IDEAPAD,
6be7948f 18765 ALC272_FIXUP_MARIO,
d2ebd479 18766 ALC662_FIXUP_CZC_P10T,
94024cd1 18767 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
18768};
18769
18770static const struct alc_fixup alc662_fixups[] = {
2df03514 18771 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
18772 .type = ALC_FIXUP_PINS,
18773 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
18774 { 0x15, 0x99130112 }, /* subwoofer */
18775 { }
18776 }
18777 },
6cb3b707 18778 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
18779 .type = ALC_FIXUP_PINS,
18780 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
18781 { 0x17, 0x99130112 }, /* subwoofer */
18782 { }
18783 }
18784 },
6be7948f 18785 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
18786 .type = ALC_FIXUP_FUNC,
18787 .v.func = alc272_fixup_mario,
d2ebd479
AA
18788 },
18789 [ALC662_FIXUP_CZC_P10T] = {
18790 .type = ALC_FIXUP_VERBS,
18791 .v.verbs = (const struct hda_verb[]) {
18792 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
18793 {}
18794 }
18795 },
94024cd1
DH
18796 [ALC662_FIXUP_SKU_IGNORE] = {
18797 .type = ALC_FIXUP_SKU,
18798 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 18799 },
6cb3b707
DH
18800};
18801
a9111321 18802static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 18803 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 18804 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 18805 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 18806 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 18807 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 18808 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 18809 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
18810 {}
18811};
18812
6be7948f
TB
18813static const struct alc_model_fixup alc662_fixup_models[] = {
18814 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
18815 {}
18816};
6cb3b707
DH
18817
18818
bc9f98a9
KY
18819static int patch_alc662(struct hda_codec *codec)
18820{
18821 struct alc_spec *spec;
18822 int err, board_config;
693194f3 18823 int coef;
bc9f98a9
KY
18824
18825 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18826 if (!spec)
18827 return -ENOMEM;
18828
18829 codec->spec = spec;
18830
1f0f4b80
TI
18831 spec->mixer_nid = 0x0b;
18832
da00c244
KY
18833 alc_auto_parse_customize_define(codec);
18834
2c3bf9ab
TI
18835 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18836
693194f3
KY
18837 coef = alc_read_coef_idx(codec, 0);
18838 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 18839 alc_codec_rename(codec, "ALC661");
693194f3
KY
18840 else if (coef & (1 << 14) &&
18841 codec->bus->pci->subsystem_vendor == 0x1025 &&
18842 spec->cdefine.platform_type == 1)
c027ddcd 18843 alc_codec_rename(codec, "ALC272X");
693194f3
KY
18844 else if (coef == 0x4011)
18845 alc_codec_rename(codec, "ALC656");
274693f3 18846
bc9f98a9
KY
18847 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
18848 alc662_models,
18849 alc662_cfg_tbl);
18850 if (board_config < 0) {
9a11f1aa
TI
18851 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18852 codec->chip_name);
bc9f98a9
KY
18853 board_config = ALC662_AUTO;
18854 }
18855
18856 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
18857 alc_pick_fixup(codec, alc662_fixup_models,
18858 alc662_fixup_tbl, alc662_fixups);
18859 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
18860 /* automatic parse from the BIOS config */
18861 err = alc662_parse_auto_config(codec);
18862 if (err < 0) {
18863 alc_free(codec);
18864 return err;
8c87286f 18865 } else if (!err) {
bc9f98a9
KY
18866 printk(KERN_INFO
18867 "hda_codec: Cannot set up configuration "
18868 "from BIOS. Using base mode...\n");
18869 board_config = ALC662_3ST_2ch_DIG;
18870 }
18871 }
18872
dc1eae25 18873 if (has_cdefine_beep(codec)) {
8af2591d
TI
18874 err = snd_hda_attach_beep_device(codec, 0x1);
18875 if (err < 0) {
18876 alc_free(codec);
18877 return err;
18878 }
680cd536
KK
18879 }
18880
bc9f98a9 18881 if (board_config != ALC662_AUTO)
e9c364c0 18882 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 18883
dd704698 18884 if (!spec->adc_nids) {
d6cc9fab 18885 alc_auto_fill_adc_caps(codec);
21268961 18886 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 18887 alc_remove_invalid_adc_nids(codec);
dd704698 18888 }
bc9f98a9 18889
f9e336f6 18890 if (!spec->cap_mixer)
b59bdf3b 18891 set_capture_mixer(codec);
cec27c89 18892
dc1eae25 18893 if (has_cdefine_beep(codec)) {
da00c244
KY
18894 switch (codec->vendor_id) {
18895 case 0x10ec0662:
18896 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18897 break;
18898 case 0x10ec0272:
18899 case 0x10ec0663:
18900 case 0x10ec0665:
18901 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18902 break;
18903 case 0x10ec0273:
18904 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18905 break;
18906 }
cec27c89 18907 }
2134ea4f
TI
18908 spec->vmaster_nid = 0x02;
18909
b5bfbc67
TI
18910 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18911
bc9f98a9 18912 codec->patch_ops = alc_patch_ops;
b5bfbc67 18913 if (board_config == ALC662_AUTO)
bc9f98a9 18914 spec->init_hook = alc662_auto_init;
1c716153 18915 spec->shutup = alc_eapd_shutup;
6cb3b707 18916
bf1b0225
KY
18917 alc_init_jacks(codec);
18918
cb53c626
TI
18919#ifdef CONFIG_SND_HDA_POWER_SAVE
18920 if (!spec->loopback.amplist)
18921 spec->loopback.amplist = alc662_loopbacks;
18922#endif
bc9f98a9
KY
18923
18924 return 0;
18925}
18926
274693f3
KY
18927static int patch_alc888(struct hda_codec *codec)
18928{
18929 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
18930 kfree(codec->chip_name);
01e0f137
KY
18931 if (codec->vendor_id == 0x10ec0887)
18932 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
18933 else
18934 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
18935 if (!codec->chip_name) {
18936 alc_free(codec);
274693f3 18937 return -ENOMEM;
ac2c92e0
TI
18938 }
18939 return patch_alc662(codec);
274693f3 18940 }
ac2c92e0 18941 return patch_alc882(codec);
274693f3
KY
18942}
18943
b478b998
KY
18944static int patch_alc899(struct hda_codec *codec)
18945{
18946 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
18947 kfree(codec->chip_name);
18948 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
18949 }
18950 return patch_alc882(codec);
18951}
18952
d1eb57f4
KY
18953/*
18954 * ALC680 support
18955 */
c69aefab 18956#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
18957#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18958#define alc680_modes alc260_modes
18959
4c6d72d1 18960static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
18961 /* Lout1, Lout2, hp */
18962 0x02, 0x03, 0x04
18963};
18964
4c6d72d1 18965static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
18966 /* ADC0-2 */
18967 /* DMIC, MIC, Line-in*/
18968 0x07, 0x08, 0x09
18969};
18970
c69aefab
KY
18971/*
18972 * Analog capture ADC cgange
18973 */
21268961 18974static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
66ceeb6b 18975{
21268961
TI
18976 static hda_nid_t pins[] = {0x18, 0x19};
18977 static hda_nid_t adcs[] = {0x08, 0x09};
66ceeb6b
TI
18978 int i;
18979
21268961
TI
18980 for (i = 0; i < ARRAY_SIZE(pins); i++) {
18981 if (!is_jack_detectable(codec, pins[i]))
66ceeb6b 18982 continue;
21268961
TI
18983 if (snd_hda_jack_detect(codec, pins[i]))
18984 return adcs[i];
66ceeb6b 18985 }
21268961
TI
18986 return 0x07;
18987}
66ceeb6b 18988
21268961
TI
18989static void alc680_rec_autoswitch(struct hda_codec *codec)
18990{
18991 struct alc_spec *spec = codec->spec;
18992 hda_nid_t nid = alc680_get_cur_adc(codec);
18993 if (spec->cur_adc && nid != spec->cur_adc) {
66ceeb6b 18994 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
21268961
TI
18995 spec->cur_adc = nid;
18996 snd_hda_codec_setup_stream(codec, nid,
18997 spec->cur_adc_stream_tag, 0,
18998 spec->cur_adc_format);
18999 }
66ceeb6b
TI
19000}
19001
c69aefab
KY
19002static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19003 struct hda_codec *codec,
19004 unsigned int stream_tag,
19005 unsigned int format,
19006 struct snd_pcm_substream *substream)
19007{
19008 struct alc_spec *spec = codec->spec;
21268961 19009 hda_nid_t nid = alc680_get_cur_adc(codec);
c69aefab 19010
21268961 19011 spec->cur_adc = nid;
c69aefab
KY
19012 spec->cur_adc_stream_tag = stream_tag;
19013 spec->cur_adc_format = format;
21268961 19014 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
c69aefab
KY
19015 return 0;
19016}
19017
19018static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19019 struct hda_codec *codec,
19020 struct snd_pcm_substream *substream)
19021{
21268961
TI
19022 struct alc_spec *spec = codec->spec;
19023 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
19024 spec->cur_adc = 0;
c69aefab
KY
19025 return 0;
19026}
19027
a9111321 19028static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19029 .substreams = 1, /* can be overridden */
19030 .channels_min = 2,
19031 .channels_max = 2,
19032 /* NID is set in alc_build_pcms */
19033 .ops = {
19034 .prepare = alc680_capture_pcm_prepare,
19035 .cleanup = alc680_capture_pcm_cleanup
19036 },
19037};
19038
a9111321 19039static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19040 /* output mixer control */
19041 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19042 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19045 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19047 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19048 { }
19049};
19050
a9111321 19051static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19052 .ops = &snd_hda_bind_vol,
19053 .values = {
19054 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19055 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19056 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19057 0
19058 },
19059};
19060
a9111321 19061static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19062 .ops = &snd_hda_bind_sw,
19063 .values = {
19064 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19065 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19066 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19067 0
19068 },
19069};
19070
a9111321 19071static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19072 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19073 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19074 { } /* end */
19075};
19076
19077/*
19078 * generic initialization of ADC, input mixers and output mixers
19079 */
a9111321 19080static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19081 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19082 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19083 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19084
c69aefab
KY
19085 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19089 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19091
19092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19097
19098 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19099 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19100 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19101
d1eb57f4
KY
19102 { }
19103};
19104
c69aefab
KY
19105/* toggle speaker-output according to the hp-jack state */
19106static void alc680_base_setup(struct hda_codec *codec)
19107{
19108 struct alc_spec *spec = codec->spec;
19109
19110 spec->autocfg.hp_pins[0] = 0x16;
19111 spec->autocfg.speaker_pins[0] = 0x14;
19112 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19113 spec->autocfg.num_inputs = 2;
19114 spec->autocfg.inputs[0].pin = 0x18;
19115 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19116 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19117 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19118 spec->automute = 1;
19119 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19120}
19121
19122static void alc680_unsol_event(struct hda_codec *codec,
19123 unsigned int res)
19124{
19125 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19126 alc_hp_automute(codec);
c69aefab
KY
19127 if ((res >> 26) == ALC880_MIC_EVENT)
19128 alc680_rec_autoswitch(codec);
19129}
19130
19131static void alc680_inithook(struct hda_codec *codec)
19132{
d922b51d 19133 alc_hp_automute(codec);
c69aefab
KY
19134 alc680_rec_autoswitch(codec);
19135}
19136
d1eb57f4
KY
19137/* create input playback/capture controls for the given pin */
19138static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19139 const char *ctlname, int idx)
19140{
19141 hda_nid_t dac;
19142 int err;
19143
19144 switch (nid) {
19145 case 0x14:
19146 dac = 0x02;
19147 break;
19148 case 0x15:
19149 dac = 0x03;
19150 break;
19151 case 0x16:
19152 dac = 0x04;
19153 break;
19154 default:
19155 return 0;
19156 }
19157 if (spec->multiout.dac_nids[0] != dac &&
19158 spec->multiout.dac_nids[1] != dac) {
19159 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19160 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19161 HDA_OUTPUT));
19162 if (err < 0)
19163 return err;
19164
19165 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19166 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19167
19168 if (err < 0)
19169 return err;
dda14410 19170 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19171 }
19172
19173 return 0;
19174}
19175
19176/* add playback controls from the parsed DAC table */
19177static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19178 const struct auto_pin_cfg *cfg)
19179{
19180 hda_nid_t nid;
19181 int err;
19182
19183 spec->multiout.dac_nids = spec->private_dac_nids;
19184
19185 nid = cfg->line_out_pins[0];
19186 if (nid) {
19187 const char *name;
2e925dde
TI
19188 int index;
19189 name = alc_get_line_out_pfx(spec, 0, true, &index);
d1eb57f4
KY
19190 err = alc680_new_analog_output(spec, nid, name, 0);
19191 if (err < 0)
19192 return err;
19193 }
19194
19195 nid = cfg->speaker_pins[0];
19196 if (nid) {
19197 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19198 if (err < 0)
19199 return err;
19200 }
19201 nid = cfg->hp_pins[0];
19202 if (nid) {
19203 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19204 if (err < 0)
19205 return err;
19206 }
19207
19208 return 0;
19209}
19210
19211static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19212 hda_nid_t nid, int pin_type)
19213{
19214 alc_set_pin_output(codec, nid, pin_type);
19215}
19216
19217static void alc680_auto_init_multi_out(struct hda_codec *codec)
19218{
19219 struct alc_spec *spec = codec->spec;
19220 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19221 if (nid) {
19222 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19223 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19224 }
19225}
19226
19227static void alc680_auto_init_hp_out(struct hda_codec *codec)
19228{
19229 struct alc_spec *spec = codec->spec;
19230 hda_nid_t pin;
19231
19232 pin = spec->autocfg.hp_pins[0];
19233 if (pin)
19234 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19235 pin = spec->autocfg.speaker_pins[0];
19236 if (pin)
19237 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19238}
19239
d1eb57f4
KY
19240/*
19241 * BIOS auto configuration
19242 */
19243static int alc680_parse_auto_config(struct hda_codec *codec)
19244{
19245 struct alc_spec *spec = codec->spec;
19246 int err;
4c6d72d1 19247 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19248
19249 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19250 alc680_ignore);
19251 if (err < 0)
19252 return err;
c69aefab 19253
d1eb57f4
KY
19254 if (!spec->autocfg.line_outs) {
19255 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19256 spec->multiout.max_channels = 2;
19257 spec->no_analog = 1;
19258 goto dig_only;
19259 }
19260 return 0; /* can't find valid BIOS pin config */
19261 }
19262 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19263 if (err < 0)
19264 return err;
19265
21268961
TI
19266 err = alc_auto_create_input_ctls(codec);
19267 if (err < 0)
19268 return err;
19269
d1eb57f4
KY
19270 spec->multiout.max_channels = 2;
19271
19272 dig_only:
19273 /* digital only support output */
757899ac 19274 alc_auto_parse_digital(codec);
d1eb57f4
KY
19275 if (spec->kctls.list)
19276 add_mixer(spec, spec->kctls.list);
19277
21268961
TI
19278 alc_remove_invalid_adc_nids(codec);
19279
19280 alc_auto_check_switches(codec);
19281
d1eb57f4
KY
19282 err = alc_auto_add_mic_boost(codec);
19283 if (err < 0)
19284 return err;
19285
19286 return 1;
19287}
19288
d1eb57f4
KY
19289/* init callback for auto-configuration model -- overriding the default init */
19290static void alc680_auto_init(struct hda_codec *codec)
19291{
19292 struct alc_spec *spec = codec->spec;
19293 alc680_auto_init_multi_out(codec);
19294 alc680_auto_init_hp_out(codec);
0a7f5320 19295 alc_auto_init_analog_input(codec);
21268961 19296 alc_auto_init_input_src(codec);
757899ac 19297 alc_auto_init_digital(codec);
d1eb57f4
KY
19298 if (spec->unsol_event)
19299 alc_inithook(codec);
19300}
19301
19302/*
19303 * configuration and preset
19304 */
ea734963 19305static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19306 [ALC680_BASE] = "base",
19307 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19308};
19309
a9111321 19310static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19311 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19312 {}
19313};
19314
a9111321 19315static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19316 [ALC680_BASE] = {
19317 .mixers = { alc680_base_mixer },
c69aefab 19318 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19319 .init_verbs = { alc680_init_verbs },
19320 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19321 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19322 .dig_out_nid = ALC680_DIGOUT_NID,
19323 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19324 .channel_mode = alc680_modes,
c69aefab
KY
19325 .unsol_event = alc680_unsol_event,
19326 .setup = alc680_base_setup,
19327 .init_hook = alc680_inithook,
19328
d1eb57f4
KY
19329 },
19330};
19331
19332static int patch_alc680(struct hda_codec *codec)
19333{
19334 struct alc_spec *spec;
19335 int board_config;
19336 int err;
19337
19338 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19339 if (spec == NULL)
19340 return -ENOMEM;
19341
19342 codec->spec = spec;
19343
1f0f4b80
TI
19344 /* ALC680 has no aa-loopback mixer */
19345
d1eb57f4
KY
19346 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19347 alc680_models,
19348 alc680_cfg_tbl);
19349
19350 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19351 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19352 codec->chip_name);
19353 board_config = ALC680_AUTO;
19354 }
19355
19356 if (board_config == ALC680_AUTO) {
19357 /* automatic parse from the BIOS config */
19358 err = alc680_parse_auto_config(codec);
19359 if (err < 0) {
19360 alc_free(codec);
19361 return err;
19362 } else if (!err) {
19363 printk(KERN_INFO
19364 "hda_codec: Cannot set up configuration "
19365 "from BIOS. Using base mode...\n");
19366 board_config = ALC680_BASE;
19367 }
19368 }
19369
21268961 19370 if (board_config != ALC680_AUTO) {
d1eb57f4 19371 setup_preset(codec, &alc680_presets[board_config]);
21268961
TI
19372 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
19373 }
d1eb57f4 19374
d1eb57f4 19375 if (!spec->adc_nids) {
d6cc9fab 19376 alc_auto_fill_adc_caps(codec);
21268961 19377 alc_rebuild_imux_for_auto_mic(codec);
d6cc9fab 19378 alc_remove_invalid_adc_nids(codec);
d1eb57f4
KY
19379 }
19380
19381 if (!spec->cap_mixer)
19382 set_capture_mixer(codec);
19383
19384 spec->vmaster_nid = 0x02;
19385
19386 codec->patch_ops = alc_patch_ops;
19387 if (board_config == ALC680_AUTO)
19388 spec->init_hook = alc680_auto_init;
19389
19390 return 0;
19391}
19392
1da177e4
LT
19393/*
19394 * patch entries
19395 */
a9111321 19396static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 19397 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 19398 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19399 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19400 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19401 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19402 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19403 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19404 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19405 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 19406 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 19407 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19408 .patch = patch_alc861 },
f32610ed
JS
19409 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19410 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19411 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19412 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19413 .patch = patch_alc882 },
bc9f98a9
KY
19414 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19415 .patch = patch_alc662 },
6dda9f4a 19416 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19417 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19418 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19419 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19420 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19421 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19422 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19423 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19424 .patch = patch_alc882 },
cb308f97 19425 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19426 .patch = patch_alc882 },
df694daa 19427 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 19428 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 19429 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19430 .patch = patch_alc882 },
274693f3 19431 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19432 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19433 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 19434 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
19435 {} /* terminator */
19436};
1289e9e8
TI
19437
19438MODULE_ALIAS("snd-hda-codec-id:10ec*");
19439
19440MODULE_LICENSE("GPL");
19441MODULE_DESCRIPTION("Realtek HD-audio codec");
19442
19443static struct hda_codec_preset_list realtek_list = {
19444 .preset = snd_hda_preset_realtek,
19445 .owner = THIS_MODULE,
19446};
19447
19448static int __init patch_realtek_init(void)
19449{
19450 return snd_hda_add_codec_preset(&realtek_list);
19451}
19452
19453static void __exit patch_realtek_exit(void)
19454{
19455 snd_hda_delete_codec_preset(&realtek_list);
19456}
19457
19458module_init(patch_realtek_init)
19459module_exit(patch_realtek_exit)