]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Use get_wcaps_type()
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 351
840b64c0
TI
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
1da177e4 358 /* capture source */
a1e8d2da 359 unsigned int num_mux_defs;
1da177e4
LT
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
6c819492
TI
362 struct alc_mic_route ext_mic;
363 struct alc_mic_route int_mic;
1da177e4
LT
364
365 /* channel model */
d2a6d7dc 366 const struct hda_channel_mode *channel_mode;
1da177e4 367 int num_channel_mode;
4e195a7b 368 int need_dac_fix;
3b315d70
HM
369 int const_channel_count;
370 int ext_channel_count;
1da177e4
LT
371
372 /* PCM information */
4c5186ed 373 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 374
e9edcee0
TI
375 /* dynamic controls, init_verbs and input_mux */
376 struct auto_pin_cfg autocfg;
da00c244 377 struct alc_customize_define cdefine;
603c4019 378 struct snd_array kctls;
61b9b9b1 379 struct hda_input_mux private_imux[3];
41923e44 380 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
381 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 383
ae6b813a
TI
384 /* hooks */
385 void (*init_hook)(struct hda_codec *codec);
386 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 387#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 388 void (*power_hook)(struct hda_codec *codec);
f5de24b0 389#endif
1c716153 390 void (*shutup)(struct hda_codec *codec);
ae6b813a 391
834be88d 392 /* for pin sensing */
834be88d 393 unsigned int jack_present: 1;
e6a5e1b7 394 unsigned int line_jack_present:1;
e9427969 395 unsigned int master_mute:1;
6c819492 396 unsigned int auto_mic:1;
d922b51d 397 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
398 unsigned int detect_line:1; /* Line-out detection enabled */
399 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 400 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 401
e64f14f4
TI
402 /* other flags */
403 unsigned int no_analog :1; /* digital I/O only */
840b64c0 404 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 405 unsigned int single_input_src:1;
d922b51d
TI
406
407 /* auto-mute control */
408 int automute_mode;
3b8510ce 409 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 410
4a79ba34 411 int init_amp;
d433a678 412 int codec_variant; /* flag for other variants */
e64f14f4 413
2134ea4f
TI
414 /* for virtual master */
415 hda_nid_t vmaster_nid;
cb53c626
TI
416#ifdef CONFIG_SND_HDA_POWER_SAVE
417 struct hda_loopback_check loopback;
418#endif
2c3bf9ab
TI
419
420 /* for PLL fix */
421 hda_nid_t pll_nid;
422 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
423
424 /* fix-up list */
425 int fixup_id;
426 const struct alc_fixup *fixup_list;
427 const char *fixup_name;
ce764ab2
TI
428
429 /* multi-io */
430 int multi_ios;
431 struct alc_multi_io multi_io[4];
df694daa
KY
432};
433
434/*
435 * configuration template - to be copied to the spec instance
436 */
437struct alc_config_preset {
a9111321 438 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
439 * with spec
440 */
a9111321 441 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
442 const struct hda_verb *init_verbs[5];
443 unsigned int num_dacs;
4c6d72d1 444 const hda_nid_t *dac_nids;
df694daa
KY
445 hda_nid_t dig_out_nid; /* optional */
446 hda_nid_t hp_nid; /* optional */
4c6d72d1 447 const hda_nid_t *slave_dig_outs;
df694daa 448 unsigned int num_adc_nids;
4c6d72d1
TI
449 const hda_nid_t *adc_nids;
450 const hda_nid_t *capsrc_nids;
df694daa
KY
451 hda_nid_t dig_in_nid;
452 unsigned int num_channel_mode;
453 const struct hda_channel_mode *channel_mode;
4e195a7b 454 int need_dac_fix;
3b315d70 455 int const_channel_count;
a1e8d2da 456 unsigned int num_mux_defs;
df694daa 457 const struct hda_input_mux *input_mux;
ae6b813a 458 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 459 void (*setup)(struct hda_codec *);
ae6b813a 460 void (*init_hook)(struct hda_codec *);
cb53c626 461#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 462 const struct hda_amp_list *loopbacks;
c97259df 463 void (*power_hook)(struct hda_codec *codec);
cb53c626 464#endif
1da177e4
LT
465};
466
1da177e4
LT
467
468/*
469 * input MUX handling
470 */
9c7f852e
TI
471static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
473{
474 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
475 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
476 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
477 if (mux_idx >= spec->num_mux_defs)
478 mux_idx = 0;
5311114d
TI
479 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
480 mux_idx = 0;
a1e8d2da 481 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
482}
483
9c7f852e
TI
484static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
486{
487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
488 struct alc_spec *spec = codec->spec;
489 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
490
491 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
492 return 0;
493}
494
9c7f852e
TI
495static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
497{
498 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
499 struct alc_spec *spec = codec->spec;
cd896c33 500 const struct hda_input_mux *imux;
1da177e4 501 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 502 unsigned int mux_idx;
e1406348
TI
503 hda_nid_t nid = spec->capsrc_nids ?
504 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 505 unsigned int type;
1da177e4 506
cd896c33
TI
507 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
508 imux = &spec->input_mux[mux_idx];
5311114d
TI
509 if (!imux->num_items && mux_idx > 0)
510 imux = &spec->input_mux[0];
cd896c33 511
a22d543a 512 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 513 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
514 /* Matrix-mixer style (e.g. ALC882) */
515 unsigned int *cur_val = &spec->cur_mux[adc_idx];
516 unsigned int i, idx;
517
518 idx = ucontrol->value.enumerated.item[0];
519 if (idx >= imux->num_items)
520 idx = imux->num_items - 1;
521 if (*cur_val == idx)
522 return 0;
523 for (i = 0; i < imux->num_items; i++) {
524 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
525 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
526 imux->items[i].index,
527 HDA_AMP_MUTE, v);
528 }
529 *cur_val = idx;
530 return 1;
531 } else {
532 /* MUX style (e.g. ALC880) */
cd896c33 533 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
534 &spec->cur_mux[adc_idx]);
535 }
536}
e9edcee0 537
1da177e4
LT
538/*
539 * channel mode setting
540 */
9c7f852e
TI
541static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
542 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
543{
544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
545 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
546 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
547 spec->num_channel_mode);
1da177e4
LT
548}
549
9c7f852e
TI
550static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
552{
553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554 struct alc_spec *spec = codec->spec;
d2a6d7dc 555 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 556 spec->num_channel_mode,
3b315d70 557 spec->ext_channel_count);
1da177e4
LT
558}
559
9c7f852e
TI
560static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
562{
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 struct alc_spec *spec = codec->spec;
4e195a7b
TI
565 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
566 spec->num_channel_mode,
3b315d70
HM
567 &spec->ext_channel_count);
568 if (err >= 0 && !spec->const_channel_count) {
569 spec->multiout.max_channels = spec->ext_channel_count;
570 if (spec->need_dac_fix)
571 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
572 }
4e195a7b 573 return err;
1da177e4
LT
574}
575
a9430dd8 576/*
4c5186ed 577 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 578 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
579 * being part of a format specifier. Maximum allowed length of a value is
580 * 63 characters plus NULL terminator.
7cf51e48
JW
581 *
582 * Note: some retasking pin complexes seem to ignore requests for input
583 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
584 * are requested. Therefore order this list so that this behaviour will not
585 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
586 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
587 * March 2006.
4c5186ed 588 */
a9111321 589static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
590 "Mic 50pc bias", "Mic 80pc bias",
591 "Line in", "Line out", "Headphone out",
4c5186ed 592};
a9111321 593static const unsigned char alc_pin_mode_values[] = {
7cf51e48 594 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
595};
596/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
597 * in the pin being assumed to be exclusively an input or an output pin. In
598 * addition, "input" pins may or may not process the mic bias option
599 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
600 * accept requests for bias as of chip versions up to March 2006) and/or
601 * wiring in the computer.
a9430dd8 602 */
a1e8d2da
JW
603#define ALC_PIN_DIR_IN 0x00
604#define ALC_PIN_DIR_OUT 0x01
605#define ALC_PIN_DIR_INOUT 0x02
606#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
607#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 608
ea1fb29a 609/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
610 * For each direction the minimum and maximum values are given.
611 */
a9111321 612static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
613 { 0, 2 }, /* ALC_PIN_DIR_IN */
614 { 3, 4 }, /* ALC_PIN_DIR_OUT */
615 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
616 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
617 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
618};
619#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
620#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
621#define alc_pin_mode_n_items(_dir) \
622 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
623
9c7f852e
TI
624static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *uinfo)
a9430dd8 626{
4c5186ed
JW
627 unsigned int item_num = uinfo->value.enumerated.item;
628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
629
630 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 631 uinfo->count = 1;
4c5186ed
JW
632 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
633
634 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
635 item_num = alc_pin_mode_min(dir);
636 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
637 return 0;
638}
639
9c7f852e
TI
640static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_value *ucontrol)
a9430dd8 642{
4c5186ed 643 unsigned int i;
a9430dd8
JW
644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 646 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 647 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
648 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
649 AC_VERB_GET_PIN_WIDGET_CONTROL,
650 0x00);
a9430dd8 651
4c5186ed
JW
652 /* Find enumerated value for current pinctl setting */
653 i = alc_pin_mode_min(dir);
4b35d2ca 654 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 655 i++;
9c7f852e 656 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
657 return 0;
658}
659
9c7f852e
TI
660static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_value *ucontrol)
a9430dd8 662{
4c5186ed 663 signed int change;
a9430dd8
JW
664 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
665 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
666 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
667 long val = *ucontrol->value.integer.value;
9c7f852e
TI
668 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
669 AC_VERB_GET_PIN_WIDGET_CONTROL,
670 0x00);
a9430dd8 671
f12ab1e0 672 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
673 val = alc_pin_mode_min(dir);
674
675 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
676 if (change) {
677 /* Set pin mode to that requested */
82beb8fd
TI
678 snd_hda_codec_write_cache(codec, nid, 0,
679 AC_VERB_SET_PIN_WIDGET_CONTROL,
680 alc_pin_mode_values[val]);
cdcd9268 681
ea1fb29a 682 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
683 * for the requested pin mode. Enum values of 2 or less are
684 * input modes.
685 *
686 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
687 * reduces noise slightly (particularly on input) so we'll
688 * do it. However, having both input and output buffers
689 * enabled simultaneously doesn't seem to be problematic if
690 * this turns out to be necessary in the future.
cdcd9268
JW
691 */
692 if (val <= 2) {
47fd830a
TI
693 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
694 HDA_AMP_MUTE, HDA_AMP_MUTE);
695 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
696 HDA_AMP_MUTE, 0);
cdcd9268 697 } else {
47fd830a
TI
698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
699 HDA_AMP_MUTE, HDA_AMP_MUTE);
700 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
701 HDA_AMP_MUTE, 0);
cdcd9268
JW
702 }
703 }
a9430dd8
JW
704 return change;
705}
706
4c5186ed 707#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 708 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 709 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
710 .info = alc_pin_mode_info, \
711 .get = alc_pin_mode_get, \
712 .put = alc_pin_mode_put, \
713 .private_value = nid | (dir<<16) }
df694daa 714
5c8f858d
JW
715/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
716 * together using a mask with more than one bit set. This control is
717 * currently used only by the ALC260 test model. At this stage they are not
718 * needed for any "production" models.
719 */
720#ifdef CONFIG_SND_DEBUG
a5ce8890 721#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 722
9c7f852e
TI
723static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
724 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
725{
726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
727 hda_nid_t nid = kcontrol->private_value & 0xffff;
728 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
729 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
730 unsigned int val = snd_hda_codec_read(codec, nid, 0,
731 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
732
733 *valp = (val & mask) != 0;
734 return 0;
735}
9c7f852e
TI
736static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
737 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
738{
739 signed int change;
740 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
741 hda_nid_t nid = kcontrol->private_value & 0xffff;
742 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
743 long val = *ucontrol->value.integer.value;
9c7f852e
TI
744 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
745 AC_VERB_GET_GPIO_DATA,
746 0x00);
5c8f858d
JW
747
748 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
749 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
750 if (val == 0)
5c8f858d
JW
751 gpio_data &= ~mask;
752 else
753 gpio_data |= mask;
82beb8fd
TI
754 snd_hda_codec_write_cache(codec, nid, 0,
755 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
756
757 return change;
758}
759#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
760 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 761 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
762 .info = alc_gpio_data_info, \
763 .get = alc_gpio_data_get, \
764 .put = alc_gpio_data_put, \
765 .private_value = nid | (mask<<16) }
766#endif /* CONFIG_SND_DEBUG */
767
92621f13
JW
768/* A switch control to allow the enabling of the digital IO pins on the
769 * ALC260. This is incredibly simplistic; the intention of this control is
770 * to provide something in the test model allowing digital outputs to be
771 * identified if present. If models are found which can utilise these
772 * outputs a more complete mixer control can be devised for those models if
773 * necessary.
774 */
775#ifdef CONFIG_SND_DEBUG
a5ce8890 776#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 777
9c7f852e
TI
778static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
779 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
780{
781 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
782 hda_nid_t nid = kcontrol->private_value & 0xffff;
783 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
784 long *valp = ucontrol->value.integer.value;
9c7f852e 785 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 786 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
787
788 *valp = (val & mask) != 0;
789 return 0;
790}
9c7f852e
TI
791static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
792 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
793{
794 signed int change;
795 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
796 hda_nid_t nid = kcontrol->private_value & 0xffff;
797 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
798 long val = *ucontrol->value.integer.value;
9c7f852e 799 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 800 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 801 0x00);
92621f13
JW
802
803 /* Set/unset the masked control bit(s) as needed */
9c7f852e 804 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
805 if (val==0)
806 ctrl_data &= ~mask;
807 else
808 ctrl_data |= mask;
82beb8fd
TI
809 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
810 ctrl_data);
92621f13
JW
811
812 return change;
813}
814#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
815 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 816 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
817 .info = alc_spdif_ctrl_info, \
818 .get = alc_spdif_ctrl_get, \
819 .put = alc_spdif_ctrl_put, \
820 .private_value = nid | (mask<<16) }
821#endif /* CONFIG_SND_DEBUG */
822
f8225f6d
JW
823/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
824 * Again, this is only used in the ALC26x test models to help identify when
825 * the EAPD line must be asserted for features to work.
826 */
827#ifdef CONFIG_SND_DEBUG
828#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
829
830static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
831 struct snd_ctl_elem_value *ucontrol)
832{
833 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
834 hda_nid_t nid = kcontrol->private_value & 0xffff;
835 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
836 long *valp = ucontrol->value.integer.value;
837 unsigned int val = snd_hda_codec_read(codec, nid, 0,
838 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
839
840 *valp = (val & mask) != 0;
841 return 0;
842}
843
844static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
845 struct snd_ctl_elem_value *ucontrol)
846{
847 int change;
848 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
849 hda_nid_t nid = kcontrol->private_value & 0xffff;
850 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
851 long val = *ucontrol->value.integer.value;
852 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
853 AC_VERB_GET_EAPD_BTLENABLE,
854 0x00);
855
856 /* Set/unset the masked control bit(s) as needed */
857 change = (!val ? 0 : mask) != (ctrl_data & mask);
858 if (!val)
859 ctrl_data &= ~mask;
860 else
861 ctrl_data |= mask;
862 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
863 ctrl_data);
864
865 return change;
866}
867
868#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
869 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 870 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
871 .info = alc_eapd_ctrl_info, \
872 .get = alc_eapd_ctrl_get, \
873 .put = alc_eapd_ctrl_put, \
874 .private_value = nid | (mask<<16) }
875#endif /* CONFIG_SND_DEBUG */
876
23f0c048
TI
877/*
878 * set up the input pin config (depending on the given auto-pin type)
879 */
880static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
881 int auto_pin_type)
882{
883 unsigned int val = PIN_IN;
884
86e2959a 885 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 886 unsigned int pincap;
954a29c8
TI
887 unsigned int oldval;
888 oldval = snd_hda_codec_read(codec, nid, 0,
889 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 890 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 891 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
892 /* if the default pin setup is vref50, we give it priority */
893 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 894 val = PIN_VREF80;
461c6c3a
TI
895 else if (pincap & AC_PINCAP_VREF_50)
896 val = PIN_VREF50;
897 else if (pincap & AC_PINCAP_VREF_100)
898 val = PIN_VREF100;
899 else if (pincap & AC_PINCAP_VREF_GRD)
900 val = PIN_VREFGRD;
23f0c048
TI
901 }
902 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
903}
904
f6837bbd
TI
905static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
906{
907 struct alc_spec *spec = codec->spec;
908 struct auto_pin_cfg *cfg = &spec->autocfg;
909
910 if (!cfg->line_outs) {
911 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
912 cfg->line_out_pins[cfg->line_outs])
913 cfg->line_outs++;
914 }
915 if (!cfg->speaker_outs) {
916 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
917 cfg->speaker_pins[cfg->speaker_outs])
918 cfg->speaker_outs++;
919 }
920 if (!cfg->hp_outs) {
921 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
922 cfg->hp_pins[cfg->hp_outs])
923 cfg->hp_outs++;
924 }
925}
926
d88897ea
TI
927/*
928 */
a9111321 929static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
930{
931 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
932 return;
933 spec->mixers[spec->num_mixers++] = mix;
934}
935
936static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
937{
938 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
939 return;
940 spec->init_verbs[spec->num_init_verbs++] = verb;
941}
942
df694daa
KY
943/*
944 * set up from the preset table
945 */
e9c364c0 946static void setup_preset(struct hda_codec *codec,
9c7f852e 947 const struct alc_config_preset *preset)
df694daa 948{
e9c364c0 949 struct alc_spec *spec = codec->spec;
df694daa
KY
950 int i;
951
952 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 953 add_mixer(spec, preset->mixers[i]);
f9e336f6 954 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
955 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
956 i++)
d88897ea 957 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 958
df694daa
KY
959 spec->channel_mode = preset->channel_mode;
960 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 961 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 962 spec->const_channel_count = preset->const_channel_count;
df694daa 963
3b315d70
HM
964 if (preset->const_channel_count)
965 spec->multiout.max_channels = preset->const_channel_count;
966 else
967 spec->multiout.max_channels = spec->channel_mode[0].channels;
968 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
969
970 spec->multiout.num_dacs = preset->num_dacs;
971 spec->multiout.dac_nids = preset->dac_nids;
972 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 973 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 974 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 975
a1e8d2da 976 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 977 if (!spec->num_mux_defs)
a1e8d2da 978 spec->num_mux_defs = 1;
df694daa
KY
979 spec->input_mux = preset->input_mux;
980
981 spec->num_adc_nids = preset->num_adc_nids;
982 spec->adc_nids = preset->adc_nids;
e1406348 983 spec->capsrc_nids = preset->capsrc_nids;
df694daa 984 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
985
986 spec->unsol_event = preset->unsol_event;
987 spec->init_hook = preset->init_hook;
cb53c626 988#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 989 spec->power_hook = preset->power_hook;
cb53c626
TI
990 spec->loopback.amplist = preset->loopbacks;
991#endif
e9c364c0
TI
992
993 if (preset->setup)
994 preset->setup(codec);
f6837bbd
TI
995
996 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
997}
998
bc9f98a9 999/* Enable GPIO mask and set output */
a9111321 1000static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1001 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1002 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1003 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1004 { }
1005};
1006
a9111321 1007static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1008 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1009 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1011 { }
1012};
1013
a9111321 1014static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1015 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1016 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1017 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1018 { }
1019};
1020
2c3bf9ab
TI
1021/*
1022 * Fix hardware PLL issue
1023 * On some codecs, the analog PLL gating control must be off while
1024 * the default value is 1.
1025 */
1026static void alc_fix_pll(struct hda_codec *codec)
1027{
1028 struct alc_spec *spec = codec->spec;
1029 unsigned int val;
1030
1031 if (!spec->pll_nid)
1032 return;
1033 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1034 spec->pll_coef_idx);
1035 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1036 AC_VERB_GET_PROC_COEF, 0);
1037 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1038 spec->pll_coef_idx);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1040 val & ~(1 << spec->pll_coef_bit));
1041}
1042
1043static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1044 unsigned int coef_idx, unsigned int coef_bit)
1045{
1046 struct alc_spec *spec = codec->spec;
1047 spec->pll_nid = nid;
1048 spec->pll_coef_idx = coef_idx;
1049 spec->pll_coef_bit = coef_bit;
1050 alc_fix_pll(codec);
1051}
1052
9ad0e496
KY
1053static int alc_init_jacks(struct hda_codec *codec)
1054{
cd372fb3 1055#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1056 struct alc_spec *spec = codec->spec;
1057 int err;
1058 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1059 unsigned int mic_nid = spec->ext_mic.pin;
1060
265a0247 1061 if (hp_nid) {
cd372fb3
TI
1062 err = snd_hda_input_jack_add(codec, hp_nid,
1063 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1064 if (err < 0)
1065 return err;
cd372fb3 1066 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1067 }
9ad0e496 1068
265a0247 1069 if (mic_nid) {
cd372fb3
TI
1070 err = snd_hda_input_jack_add(codec, mic_nid,
1071 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1072 if (err < 0)
1073 return err;
cd372fb3 1074 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1075 }
cd372fb3 1076#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1077 return 0;
1078}
9ad0e496 1079
e6a5e1b7 1080static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1081{
e6a5e1b7 1082 int i, present = 0;
c9b58006 1083
e6a5e1b7
TI
1084 for (i = 0; i < num_pins; i++) {
1085 hda_nid_t nid = pins[i];
bb35febd
TI
1086 if (!nid)
1087 break;
cd372fb3 1088 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1089 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1090 }
e6a5e1b7
TI
1091 return present;
1092}
bb35febd 1093
e6a5e1b7 1094static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1095 bool mute, bool hp_out)
e6a5e1b7
TI
1096{
1097 struct alc_spec *spec = codec->spec;
1098 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1099 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1100 int i;
1101
1102 for (i = 0; i < num_pins; i++) {
1103 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1104 if (!nid)
1105 break;
3b8510ce
TI
1106 switch (spec->automute_mode) {
1107 case ALC_AUTOMUTE_PIN:
bb35febd 1108 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1109 AC_VERB_SET_PIN_WIDGET_CONTROL,
1110 pin_bits);
3b8510ce
TI
1111 break;
1112 case ALC_AUTOMUTE_AMP:
bb35febd 1113 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1114 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1115 break;
1116 case ALC_AUTOMUTE_MIXER:
1117 nid = spec->automute_mixer_nid[i];
1118 if (!nid)
1119 break;
1120 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1121 HDA_AMP_MUTE, mute_bits);
3b8510ce 1122 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1123 HDA_AMP_MUTE, mute_bits);
3b8510ce 1124 break;
bb35febd 1125 }
a9fd4f3f 1126 }
c9b58006
KY
1127}
1128
e6a5e1b7
TI
1129/* Toggle internal speakers muting */
1130static void update_speakers(struct hda_codec *codec)
1131{
1132 struct alc_spec *spec = codec->spec;
1a1455de 1133 int on;
e6a5e1b7 1134
1a1455de
TI
1135 if (!spec->automute)
1136 on = 0;
1137 else
1138 on = spec->jack_present | spec->line_jack_present;
1139 on |= spec->master_mute;
e6a5e1b7 1140 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1141 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1142
1143 /* toggle line-out mutes if needed, too */
1a1455de
TI
1144 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1145 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1146 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1147 return;
1a1455de
TI
1148 if (!spec->automute_lines || !spec->automute)
1149 on = 0;
1150 else
1151 on = spec->jack_present;
1152 on |= spec->master_mute;
e6a5e1b7 1153 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1154 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1155}
1156
1157static void alc_hp_automute(struct hda_codec *codec)
1158{
1159 struct alc_spec *spec = codec->spec;
1160
1161 if (!spec->automute)
1162 return;
1163 spec->jack_present =
1164 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1165 spec->autocfg.hp_pins);
1166 update_speakers(codec);
1167}
1168
1169static void alc_line_automute(struct hda_codec *codec)
1170{
1171 struct alc_spec *spec = codec->spec;
1172
1173 if (!spec->automute || !spec->detect_line)
1174 return;
1175 spec->line_jack_present =
1176 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1177 spec->autocfg.line_out_pins);
1178 update_speakers(codec);
1179}
1180
6c819492
TI
1181static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1182 hda_nid_t nid)
1183{
1184 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1185 int i, nums;
1186
1187 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1188 for (i = 0; i < nums; i++)
1189 if (conn[i] == nid)
1190 return i;
1191 return -1;
1192}
1193
840b64c0
TI
1194/* switch the current ADC according to the jack state */
1195static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1196{
1197 struct alc_spec *spec = codec->spec;
1198 unsigned int present;
1199 hda_nid_t new_adc;
1200
1201 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1202 if (present)
1203 spec->cur_adc_idx = 1;
1204 else
1205 spec->cur_adc_idx = 0;
1206 new_adc = spec->adc_nids[spec->cur_adc_idx];
1207 if (spec->cur_adc && spec->cur_adc != new_adc) {
1208 /* stream is running, let's swap the current ADC */
f0cea797 1209 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1210 spec->cur_adc = new_adc;
1211 snd_hda_codec_setup_stream(codec, new_adc,
1212 spec->cur_adc_stream_tag, 0,
1213 spec->cur_adc_format);
1214 }
1215}
1216
7fb0d78f
KY
1217static void alc_mic_automute(struct hda_codec *codec)
1218{
1219 struct alc_spec *spec = codec->spec;
6c819492
TI
1220 struct alc_mic_route *dead, *alive;
1221 unsigned int present, type;
1222 hda_nid_t cap_nid;
1223
b59bdf3b
TI
1224 if (!spec->auto_mic)
1225 return;
6c819492
TI
1226 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1227 return;
1228 if (snd_BUG_ON(!spec->adc_nids))
1229 return;
1230
840b64c0
TI
1231 if (spec->dual_adc_switch) {
1232 alc_dual_mic_adc_auto_switch(codec);
1233 return;
1234 }
1235
6c819492
TI
1236 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1237
864f92be 1238 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1239 if (present) {
1240 alive = &spec->ext_mic;
1241 dead = &spec->int_mic;
1242 } else {
1243 alive = &spec->int_mic;
1244 dead = &spec->ext_mic;
1245 }
1246
6c819492
TI
1247 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1248 if (type == AC_WID_AUD_MIX) {
1249 /* Matrix-mixer style (e.g. ALC882) */
1250 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1251 alive->mux_idx,
1252 HDA_AMP_MUTE, 0);
1253 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1254 dead->mux_idx,
1255 HDA_AMP_MUTE, HDA_AMP_MUTE);
1256 } else {
1257 /* MUX style (e.g. ALC880) */
1258 snd_hda_codec_write_cache(codec, cap_nid, 0,
1259 AC_VERB_SET_CONNECT_SEL,
1260 alive->mux_idx);
1261 }
cd372fb3 1262 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1263
1264 /* FIXME: analog mixer */
7fb0d78f
KY
1265}
1266
c9b58006
KY
1267/* unsolicited event for HP jack sensing */
1268static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1269{
1270 if (codec->vendor_id == 0x10ec0880)
1271 res >>= 28;
1272 else
1273 res >>= 26;
a9fd4f3f
TI
1274 switch (res) {
1275 case ALC880_HP_EVENT:
d922b51d 1276 alc_hp_automute(codec);
a9fd4f3f 1277 break;
e6a5e1b7
TI
1278 case ALC880_FRONT_EVENT:
1279 alc_line_automute(codec);
1280 break;
a9fd4f3f 1281 case ALC880_MIC_EVENT:
7fb0d78f 1282 alc_mic_automute(codec);
a9fd4f3f
TI
1283 break;
1284 }
7fb0d78f
KY
1285}
1286
1287static void alc_inithook(struct hda_codec *codec)
1288{
d922b51d 1289 alc_hp_automute(codec);
e6a5e1b7 1290 alc_line_automute(codec);
7fb0d78f 1291 alc_mic_automute(codec);
c9b58006
KY
1292}
1293
f9423e7a
KY
1294/* additional initialization for ALC888 variants */
1295static void alc888_coef_init(struct hda_codec *codec)
1296{
1297 unsigned int tmp;
1298
1299 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1300 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1301 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1302 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1303 /* alc888S-VC */
1304 snd_hda_codec_read(codec, 0x20, 0,
1305 AC_VERB_SET_PROC_COEF, 0x830);
1306 else
1307 /* alc888-VB */
1308 snd_hda_codec_read(codec, 0x20, 0,
1309 AC_VERB_SET_PROC_COEF, 0x3030);
1310}
1311
87a8c370
JK
1312static void alc889_coef_init(struct hda_codec *codec)
1313{
1314 unsigned int tmp;
1315
1316 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1317 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1318 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1319 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1320}
1321
3fb4a508
TI
1322/* turn on/off EAPD control (only if available) */
1323static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1324{
1325 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1326 return;
1327 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1328 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1329 on ? 2 : 0);
1330}
1331
691f1fcc
TI
1332/* turn on/off EAPD controls of the codec */
1333static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1334{
1335 /* We currently only handle front, HP */
1336 switch (codec->vendor_id) {
1337 case 0x10ec0260:
1338 set_eapd(codec, 0x0f, on);
1339 set_eapd(codec, 0x10, on);
1340 break;
1341 case 0x10ec0262:
1342 case 0x10ec0267:
1343 case 0x10ec0268:
1344 case 0x10ec0269:
1345 case 0x10ec0270:
1346 case 0x10ec0272:
1347 case 0x10ec0660:
1348 case 0x10ec0662:
1349 case 0x10ec0663:
1350 case 0x10ec0665:
1351 case 0x10ec0862:
1352 case 0x10ec0889:
1353 case 0x10ec0892:
1354 set_eapd(codec, 0x14, on);
1355 set_eapd(codec, 0x15, on);
1356 break;
1357 }
1358}
1359
1c716153
TI
1360/* generic shutup callback;
1361 * just turning off EPAD and a little pause for avoiding pop-noise
1362 */
1363static void alc_eapd_shutup(struct hda_codec *codec)
1364{
1365 alc_auto_setup_eapd(codec, false);
1366 msleep(200);
1367}
1368
4a79ba34 1369static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1370{
4a79ba34 1371 unsigned int tmp;
bc9f98a9 1372
4a79ba34
TI
1373 switch (type) {
1374 case ALC_INIT_GPIO1:
bc9f98a9
KY
1375 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1376 break;
4a79ba34 1377 case ALC_INIT_GPIO2:
bc9f98a9
KY
1378 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1379 break;
4a79ba34 1380 case ALC_INIT_GPIO3:
bdd148a3
KY
1381 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1382 break;
4a79ba34 1383 case ALC_INIT_DEFAULT:
691f1fcc 1384 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1385 switch (codec->vendor_id) {
1386 case 0x10ec0260:
1387 snd_hda_codec_write(codec, 0x1a, 0,
1388 AC_VERB_SET_COEF_INDEX, 7);
1389 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1390 AC_VERB_GET_PROC_COEF, 0);
1391 snd_hda_codec_write(codec, 0x1a, 0,
1392 AC_VERB_SET_COEF_INDEX, 7);
1393 snd_hda_codec_write(codec, 0x1a, 0,
1394 AC_VERB_SET_PROC_COEF,
1395 tmp | 0x2010);
1396 break;
1397 case 0x10ec0262:
1398 case 0x10ec0880:
1399 case 0x10ec0882:
1400 case 0x10ec0883:
1401 case 0x10ec0885:
4a5a4c56 1402 case 0x10ec0887:
20b67ddd 1403 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1404 alc889_coef_init(codec);
c9b58006 1405 break;
f9423e7a 1406 case 0x10ec0888:
4a79ba34 1407 alc888_coef_init(codec);
f9423e7a 1408 break;
0aea778e 1409#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1410 case 0x10ec0267:
1411 case 0x10ec0268:
1412 snd_hda_codec_write(codec, 0x20, 0,
1413 AC_VERB_SET_COEF_INDEX, 7);
1414 tmp = snd_hda_codec_read(codec, 0x20, 0,
1415 AC_VERB_GET_PROC_COEF, 0);
1416 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1417 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1418 snd_hda_codec_write(codec, 0x20, 0,
1419 AC_VERB_SET_PROC_COEF,
1420 tmp | 0x3000);
1421 break;
0aea778e 1422#endif /* XXX */
bc9f98a9 1423 }
4a79ba34
TI
1424 break;
1425 }
1426}
1427
1a1455de
TI
1428static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1429 struct snd_ctl_elem_info *uinfo)
1430{
ae8a60a5
TI
1431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1432 struct alc_spec *spec = codec->spec;
1433 static const char * const texts2[] = {
1434 "Disabled", "Enabled"
1435 };
1436 static const char * const texts3[] = {
1a1455de
TI
1437 "Disabled", "Speaker Only", "Line-Out+Speaker"
1438 };
ae8a60a5 1439 const char * const *texts;
1a1455de
TI
1440
1441 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1442 uinfo->count = 1;
ae8a60a5
TI
1443 if (spec->automute_hp_lo) {
1444 uinfo->value.enumerated.items = 3;
1445 texts = texts3;
1446 } else {
1447 uinfo->value.enumerated.items = 2;
1448 texts = texts2;
1449 }
1450 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1451 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1452 strcpy(uinfo->value.enumerated.name,
1453 texts[uinfo->value.enumerated.item]);
1454 return 0;
1455}
1456
1457static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1458 struct snd_ctl_elem_value *ucontrol)
1459{
1460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1461 struct alc_spec *spec = codec->spec;
1462 unsigned int val;
1463 if (!spec->automute)
1464 val = 0;
1465 else if (!spec->automute_lines)
1466 val = 1;
1467 else
1468 val = 2;
1469 ucontrol->value.enumerated.item[0] = val;
1470 return 0;
1471}
1472
1473static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1474 struct snd_ctl_elem_value *ucontrol)
1475{
1476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1477 struct alc_spec *spec = codec->spec;
1478
1479 switch (ucontrol->value.enumerated.item[0]) {
1480 case 0:
1481 if (!spec->automute)
1482 return 0;
1483 spec->automute = 0;
1484 break;
1485 case 1:
1486 if (spec->automute && !spec->automute_lines)
1487 return 0;
1488 spec->automute = 1;
1489 spec->automute_lines = 0;
1490 break;
1491 case 2:
ae8a60a5
TI
1492 if (!spec->automute_hp_lo)
1493 return -EINVAL;
1a1455de
TI
1494 if (spec->automute && spec->automute_lines)
1495 return 0;
1496 spec->automute = 1;
1497 spec->automute_lines = 1;
1498 break;
1499 default:
1500 return -EINVAL;
1501 }
1502 update_speakers(codec);
1503 return 1;
1504}
1505
a9111321 1506static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508 .name = "Auto-Mute Mode",
1509 .info = alc_automute_mode_info,
1510 .get = alc_automute_mode_get,
1511 .put = alc_automute_mode_put,
1512};
1513
1514static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1515
1516static int alc_add_automute_mode_enum(struct hda_codec *codec)
1517{
1518 struct alc_spec *spec = codec->spec;
1519 struct snd_kcontrol_new *knew;
1520
1521 knew = alc_kcontrol_new(spec);
1522 if (!knew)
1523 return -ENOMEM;
1524 *knew = alc_automute_mode_enum;
1525 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1526 if (!knew->name)
1527 return -ENOMEM;
1528 return 0;
1529}
1530
4a79ba34
TI
1531static void alc_init_auto_hp(struct hda_codec *codec)
1532{
1533 struct alc_spec *spec = codec->spec;
bb35febd 1534 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1535 int present = 0;
bb35febd 1536 int i;
4a79ba34 1537
1daf5f46
TI
1538 if (cfg->hp_pins[0])
1539 present++;
1540 if (cfg->line_out_pins[0])
1541 present++;
1542 if (cfg->speaker_pins[0])
1543 present++;
1544 if (present < 2) /* need two different output types */
1545 return;
ae8a60a5
TI
1546 if (present == 3)
1547 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1548
bb35febd 1549 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1550 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1551 sizeof(cfg->speaker_pins));
1552 cfg->speaker_outs = cfg->line_outs;
1553 }
1554
1555 if (!cfg->hp_pins[0]) {
1556 memcpy(cfg->hp_pins, cfg->line_out_pins,
1557 sizeof(cfg->hp_pins));
1558 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1559 }
1560
bb35febd 1561 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1562 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1563 if (!is_jack_detectable(codec, nid))
1a1455de 1564 continue;
bb35febd 1565 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1566 nid);
1567 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1568 AC_VERB_SET_UNSOLICITED_ENABLE,
1569 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1570 spec->automute = 1;
1571 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1572 }
1a1455de
TI
1573 if (spec->automute && cfg->line_out_pins[0] &&
1574 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1575 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1576 for (i = 0; i < cfg->line_outs; i++) {
1577 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1578 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1579 continue;
1580 snd_printdd("realtek: Enable Line-Out auto-muting "
1581 "on NID 0x%x\n", nid);
1582 snd_hda_codec_write_cache(codec, nid, 0,
1583 AC_VERB_SET_UNSOLICITED_ENABLE,
1584 AC_USRSP_EN | ALC880_FRONT_EVENT);
1585 spec->detect_line = 1;
1586 }
ae8a60a5
TI
1587 spec->automute_lines = 1;
1588 }
1589
1590 if (spec->automute) {
1a1455de
TI
1591 /* create a control for automute mode */
1592 alc_add_automute_mode_enum(codec);
ae8a60a5 1593 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1594 }
4a79ba34
TI
1595}
1596
6c819492
TI
1597static void alc_init_auto_mic(struct hda_codec *codec)
1598{
1599 struct alc_spec *spec = codec->spec;
1600 struct auto_pin_cfg *cfg = &spec->autocfg;
1601 hda_nid_t fixed, ext;
1602 int i;
1603
1604 /* there must be only two mic inputs exclusively */
66ceeb6b 1605 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1606 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1607 return;
1608
1609 fixed = ext = 0;
66ceeb6b
TI
1610 for (i = 0; i < cfg->num_inputs; i++) {
1611 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1612 unsigned int defcfg;
6c819492 1613 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1614 switch (snd_hda_get_input_pin_attr(defcfg)) {
1615 case INPUT_PIN_ATTR_INT:
6c819492
TI
1616 if (fixed)
1617 return; /* already occupied */
1618 fixed = nid;
1619 break;
99ae28be
TI
1620 case INPUT_PIN_ATTR_UNUSED:
1621 return; /* invalid entry */
1622 default:
6c819492
TI
1623 if (ext)
1624 return; /* already occupied */
1625 ext = nid;
1626 break;
6c819492
TI
1627 }
1628 }
eaa9b3a7
TI
1629 if (!ext || !fixed)
1630 return;
6c819492
TI
1631 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1632 return; /* no unsol support */
1633 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1634 ext, fixed);
1635 spec->ext_mic.pin = ext;
1636 spec->int_mic.pin = fixed;
1637 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1638 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1639 spec->auto_mic = 1;
1640 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1641 AC_VERB_SET_UNSOLICITED_ENABLE,
1642 AC_USRSP_EN | ALC880_MIC_EVENT);
1643 spec->unsol_event = alc_sku_unsol_event;
1644}
1645
90622917
DH
1646/* Could be any non-zero and even value. When used as fixup, tells
1647 * the driver to ignore any present sku defines.
1648 */
1649#define ALC_FIXUP_SKU_IGNORE (2)
1650
da00c244
KY
1651static int alc_auto_parse_customize_define(struct hda_codec *codec)
1652{
1653 unsigned int ass, tmp, i;
7fb56223 1654 unsigned nid = 0;
da00c244
KY
1655 struct alc_spec *spec = codec->spec;
1656
b6cbe517
TI
1657 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1658
90622917
DH
1659 if (spec->cdefine.fixup) {
1660 ass = spec->cdefine.sku_cfg;
1661 if (ass == ALC_FIXUP_SKU_IGNORE)
1662 return -1;
1663 goto do_sku;
1664 }
1665
da00c244 1666 ass = codec->subsystem_id & 0xffff;
b6cbe517 1667 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1668 goto do_sku;
1669
1670 nid = 0x1d;
1671 if (codec->vendor_id == 0x10ec0260)
1672 nid = 0x17;
1673 ass = snd_hda_codec_get_pincfg(codec, nid);
1674
1675 if (!(ass & 1)) {
1676 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1677 codec->chip_name, ass);
1678 return -1;
1679 }
1680
1681 /* check sum */
1682 tmp = 0;
1683 for (i = 1; i < 16; i++) {
1684 if ((ass >> i) & 1)
1685 tmp++;
1686 }
1687 if (((ass >> 16) & 0xf) != tmp)
1688 return -1;
1689
1690 spec->cdefine.port_connectivity = ass >> 30;
1691 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1692 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1693 spec->cdefine.customization = ass >> 8;
1694do_sku:
1695 spec->cdefine.sku_cfg = ass;
1696 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1697 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1698 spec->cdefine.swap = (ass & 0x2) >> 1;
1699 spec->cdefine.override = ass & 0x1;
1700
1701 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1702 nid, spec->cdefine.sku_cfg);
1703 snd_printd("SKU: port_connectivity=0x%x\n",
1704 spec->cdefine.port_connectivity);
1705 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1706 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1707 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1708 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1709 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1710 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1711 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1712
1713 return 0;
1714}
1715
4a79ba34
TI
1716/* check subsystem ID and set up device-specific initialization;
1717 * return 1 if initialized, 0 if invalid SSID
1718 */
1719/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1720 * 31 ~ 16 : Manufacture ID
1721 * 15 ~ 8 : SKU ID
1722 * 7 ~ 0 : Assembly ID
1723 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1724 */
1725static int alc_subsystem_id(struct hda_codec *codec,
1726 hda_nid_t porta, hda_nid_t porte,
6227cdce 1727 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1728{
1729 unsigned int ass, tmp, i;
1730 unsigned nid;
1731 struct alc_spec *spec = codec->spec;
1732
90622917
DH
1733 if (spec->cdefine.fixup) {
1734 ass = spec->cdefine.sku_cfg;
1735 if (ass == ALC_FIXUP_SKU_IGNORE)
1736 return 0;
1737 goto do_sku;
1738 }
1739
4a79ba34
TI
1740 ass = codec->subsystem_id & 0xffff;
1741 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1742 goto do_sku;
1743
1744 /* invalid SSID, check the special NID pin defcfg instead */
1745 /*
def319f9 1746 * 31~30 : port connectivity
4a79ba34
TI
1747 * 29~21 : reserve
1748 * 20 : PCBEEP input
1749 * 19~16 : Check sum (15:1)
1750 * 15~1 : Custom
1751 * 0 : override
1752 */
1753 nid = 0x1d;
1754 if (codec->vendor_id == 0x10ec0260)
1755 nid = 0x17;
1756 ass = snd_hda_codec_get_pincfg(codec, nid);
1757 snd_printd("realtek: No valid SSID, "
1758 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1759 ass, nid);
6227cdce 1760 if (!(ass & 1))
4a79ba34
TI
1761 return 0;
1762 if ((ass >> 30) != 1) /* no physical connection */
1763 return 0;
1764
1765 /* check sum */
1766 tmp = 0;
1767 for (i = 1; i < 16; i++) {
1768 if ((ass >> i) & 1)
1769 tmp++;
1770 }
1771 if (((ass >> 16) & 0xf) != tmp)
1772 return 0;
1773do_sku:
1774 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1775 ass & 0xffff, codec->vendor_id);
1776 /*
1777 * 0 : override
1778 * 1 : Swap Jack
1779 * 2 : 0 --> Desktop, 1 --> Laptop
1780 * 3~5 : External Amplifier control
1781 * 7~6 : Reserved
1782 */
1783 tmp = (ass & 0x38) >> 3; /* external Amp control */
1784 switch (tmp) {
1785 case 1:
1786 spec->init_amp = ALC_INIT_GPIO1;
1787 break;
1788 case 3:
1789 spec->init_amp = ALC_INIT_GPIO2;
1790 break;
1791 case 7:
1792 spec->init_amp = ALC_INIT_GPIO3;
1793 break;
1794 case 5:
5a8cfb4e 1795 default:
4a79ba34 1796 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1797 break;
1798 }
ea1fb29a 1799
8c427226 1800 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1801 * when the external headphone out jack is plugged"
1802 */
8c427226 1803 if (!(ass & 0x8000))
4a79ba34 1804 return 1;
c9b58006
KY
1805 /*
1806 * 10~8 : Jack location
1807 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1808 * 14~13: Resvered
1809 * 15 : 1 --> enable the function "Mute internal speaker
1810 * when the external headphone out jack is plugged"
1811 */
c9b58006 1812 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1813 hda_nid_t nid;
c9b58006
KY
1814 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1815 if (tmp == 0)
01d4825d 1816 nid = porta;
c9b58006 1817 else if (tmp == 1)
01d4825d 1818 nid = porte;
c9b58006 1819 else if (tmp == 2)
01d4825d 1820 nid = portd;
6227cdce
KY
1821 else if (tmp == 3)
1822 nid = porti;
c9b58006 1823 else
4a79ba34 1824 return 1;
01d4825d
TI
1825 for (i = 0; i < spec->autocfg.line_outs; i++)
1826 if (spec->autocfg.line_out_pins[i] == nid)
1827 return 1;
1828 spec->autocfg.hp_pins[0] = nid;
c9b58006 1829 }
4a79ba34
TI
1830 return 1;
1831}
ea1fb29a 1832
4a79ba34 1833static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1834 hda_nid_t porta, hda_nid_t porte,
1835 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1836{
6227cdce 1837 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1838 struct alc_spec *spec = codec->spec;
1839 snd_printd("realtek: "
1840 "Enable default setup for auto mode as fallback\n");
1841 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1842 }
1a1455de
TI
1843
1844 alc_init_auto_hp(codec);
1845 alc_init_auto_mic(codec);
bc9f98a9
KY
1846}
1847
f95474ec 1848/*
f8f25ba3 1849 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1850 */
1851
1852struct alc_pincfg {
1853 hda_nid_t nid;
1854 u32 val;
1855};
1856
e1eb5f10
TB
1857struct alc_model_fixup {
1858 const int id;
1859 const char *name;
1860};
1861
f8f25ba3 1862struct alc_fixup {
b5bfbc67 1863 int type;
361fe6e9
TI
1864 bool chained;
1865 int chain_id;
b5bfbc67
TI
1866 union {
1867 unsigned int sku;
1868 const struct alc_pincfg *pins;
1869 const struct hda_verb *verbs;
1870 void (*func)(struct hda_codec *codec,
1871 const struct alc_fixup *fix,
1872 int action);
1873 } v;
f8f25ba3
TI
1874};
1875
b5bfbc67
TI
1876enum {
1877 ALC_FIXUP_INVALID,
1878 ALC_FIXUP_SKU,
1879 ALC_FIXUP_PINS,
1880 ALC_FIXUP_VERBS,
1881 ALC_FIXUP_FUNC,
1882};
1883
1884enum {
1885 ALC_FIXUP_ACT_PRE_PROBE,
1886 ALC_FIXUP_ACT_PROBE,
58701120 1887 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1888};
1889
1890static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1891{
b5bfbc67
TI
1892 struct alc_spec *spec = codec->spec;
1893 int id = spec->fixup_id;
aa1d0c52 1894#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1895 const char *modelname = spec->fixup_name;
aa1d0c52 1896#endif
b5bfbc67 1897 int depth = 0;
f95474ec 1898
b5bfbc67
TI
1899 if (!spec->fixup_list)
1900 return;
1901
1902 while (id >= 0) {
1903 const struct alc_fixup *fix = spec->fixup_list + id;
1904 const struct alc_pincfg *cfg;
1905
1906 switch (fix->type) {
1907 case ALC_FIXUP_SKU:
1908 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1909 break;;
1910 snd_printdd(KERN_INFO "hda_codec: %s: "
1911 "Apply sku override for %s\n",
1912 codec->chip_name, modelname);
1913 spec->cdefine.sku_cfg = fix->v.sku;
1914 spec->cdefine.fixup = 1;
1915 break;
1916 case ALC_FIXUP_PINS:
1917 cfg = fix->v.pins;
1918 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1919 break;
1920 snd_printdd(KERN_INFO "hda_codec: %s: "
1921 "Apply pincfg for %s\n",
1922 codec->chip_name, modelname);
1923 for (; cfg->nid; cfg++)
1924 snd_hda_codec_set_pincfg(codec, cfg->nid,
1925 cfg->val);
1926 break;
1927 case ALC_FIXUP_VERBS:
1928 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1929 break;
1930 snd_printdd(KERN_INFO "hda_codec: %s: "
1931 "Apply fix-verbs for %s\n",
1932 codec->chip_name, modelname);
1933 add_verb(codec->spec, fix->v.verbs);
1934 break;
1935 case ALC_FIXUP_FUNC:
1936 if (!fix->v.func)
1937 break;
1938 snd_printdd(KERN_INFO "hda_codec: %s: "
1939 "Apply fix-func for %s\n",
1940 codec->chip_name, modelname);
1941 fix->v.func(codec, fix, action);
1942 break;
1943 default:
1944 snd_printk(KERN_ERR "hda_codec: %s: "
1945 "Invalid fixup type %d\n",
1946 codec->chip_name, fix->type);
1947 break;
1948 }
24af2b1c 1949 if (!fix->chained)
b5bfbc67
TI
1950 break;
1951 if (++depth > 10)
1952 break;
24af2b1c 1953 id = fix->chain_id;
9d57883f 1954 }
f95474ec
TI
1955}
1956
e1eb5f10 1957static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1958 const struct alc_model_fixup *models,
1959 const struct snd_pci_quirk *quirk,
1960 const struct alc_fixup *fixlist)
e1eb5f10 1961{
b5bfbc67
TI
1962 struct alc_spec *spec = codec->spec;
1963 int id = -1;
1964 const char *name = NULL;
e1eb5f10 1965
e1eb5f10
TB
1966 if (codec->modelname && models) {
1967 while (models->name) {
1968 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1969 id = models->id;
1970 name = models->name;
e1eb5f10
TB
1971 break;
1972 }
1973 models++;
1974 }
b5bfbc67
TI
1975 }
1976 if (id < 0) {
1977 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1978 if (quirk) {
1979 id = quirk->value;
1980#ifdef CONFIG_SND_DEBUG_VERBOSE
1981 name = quirk->name;
1982#endif
1983 }
1984 }
1985
1986 spec->fixup_id = id;
1987 if (id >= 0) {
1988 spec->fixup_list = fixlist;
1989 spec->fixup_name = name;
e1eb5f10 1990 }
f95474ec
TI
1991}
1992
274693f3
KY
1993static int alc_read_coef_idx(struct hda_codec *codec,
1994 unsigned int coef_idx)
1995{
1996 unsigned int val;
1997 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
1998 coef_idx);
1999 val = snd_hda_codec_read(codec, 0x20, 0,
2000 AC_VERB_GET_PROC_COEF, 0);
2001 return val;
2002}
2003
977ddd6b
KY
2004static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2005 unsigned int coef_val)
2006{
2007 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2008 coef_idx);
2009 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2010 coef_val);
2011}
2012
757899ac
TI
2013/* set right pin controls for digital I/O */
2014static void alc_auto_init_digital(struct hda_codec *codec)
2015{
2016 struct alc_spec *spec = codec->spec;
2017 int i;
2018 hda_nid_t pin;
2019
2020 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2021 pin = spec->autocfg.dig_out_pins[i];
2022 if (pin) {
2023 snd_hda_codec_write(codec, pin, 0,
2024 AC_VERB_SET_PIN_WIDGET_CONTROL,
2025 PIN_OUT);
2026 }
2027 }
2028 pin = spec->autocfg.dig_in_pin;
2029 if (pin)
2030 snd_hda_codec_write(codec, pin, 0,
2031 AC_VERB_SET_PIN_WIDGET_CONTROL,
2032 PIN_IN);
2033}
2034
2035/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2036static void alc_auto_parse_digital(struct hda_codec *codec)
2037{
2038 struct alc_spec *spec = codec->spec;
2039 int i, err;
2040 hda_nid_t dig_nid;
2041
2042 /* support multiple SPDIFs; the secondary is set up as a slave */
2043 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2044 err = snd_hda_get_connections(codec,
2045 spec->autocfg.dig_out_pins[i],
2046 &dig_nid, 1);
2047 if (err < 0)
2048 continue;
2049 if (!i) {
2050 spec->multiout.dig_out_nid = dig_nid;
2051 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2052 } else {
2053 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2054 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2055 break;
2056 spec->slave_dig_outs[i - 1] = dig_nid;
2057 }
2058 }
2059
2060 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2061 dig_nid = codec->start_nid;
2062 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2063 unsigned int wcaps = get_wcaps(codec, dig_nid);
2064 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2065 continue;
2066 if (!(wcaps & AC_WCAP_DIGITAL))
2067 continue;
2068 if (!(wcaps & AC_WCAP_CONN_LIST))
2069 continue;
2070 err = get_connection_index(codec, dig_nid,
2071 spec->autocfg.dig_in_pin);
2072 if (err >= 0) {
2073 spec->dig_in_nid = dig_nid;
2074 break;
2075 }
2076 }
757899ac
TI
2077 }
2078}
2079
ef8ef5fb
VP
2080/*
2081 * ALC888
2082 */
2083
2084/*
2085 * 2ch mode
2086 */
a9111321 2087static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2088/* Mic-in jack as mic in */
2089 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2090 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2091/* Line-in jack as Line in */
2092 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2093 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2094/* Line-Out as Front */
2095 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2096 { } /* end */
2097};
2098
2099/*
2100 * 4ch mode
2101 */
a9111321 2102static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2103/* Mic-in jack as mic in */
2104 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2105 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2106/* Line-in jack as Surround */
2107 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2108 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2109/* Line-Out as Front */
2110 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2111 { } /* end */
2112};
2113
2114/*
2115 * 6ch mode
2116 */
a9111321 2117static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2118/* Mic-in jack as CLFE */
2119 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2120 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2121/* Line-in jack as Surround */
2122 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2123 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2124/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2125 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2126 { } /* end */
2127};
2128
2129/*
2130 * 8ch mode
2131 */
a9111321 2132static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2133/* Mic-in jack as CLFE */
2134 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2135 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2136/* Line-in jack as Surround */
2137 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2138 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2139/* Line-Out as Side */
2140 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2141 { } /* end */
2142};
2143
a9111321 2144static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2145 { 2, alc888_4ST_ch2_intel_init },
2146 { 4, alc888_4ST_ch4_intel_init },
2147 { 6, alc888_4ST_ch6_intel_init },
2148 { 8, alc888_4ST_ch8_intel_init },
2149};
2150
2151/*
2152 * ALC888 Fujitsu Siemens Amillo xa3530
2153 */
2154
a9111321 2155static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2156/* Front Mic: set to PIN_IN (empty by default) */
2157 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2158/* Connect Internal HP to Front */
2159 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2160 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2161 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2162/* Connect Bass HP to Front */
2163 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2165 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2166/* Connect Line-Out side jack (SPDIF) to Side */
2167 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2168 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2169 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2170/* Connect Mic jack to CLFE */
2171 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2173 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2174/* Connect Line-in jack to Surround */
2175 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2177 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2178/* Connect HP out jack to Front */
2179 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2180 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2181 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2182/* Enable unsolicited event for HP jack and Line-out jack */
2183 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2184 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2185 {}
2186};
2187
4f5d1706 2188static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2189{
2190 struct alc_spec *spec = codec->spec;
2191
2192 spec->autocfg.hp_pins[0] = 0x15;
2193 spec->autocfg.speaker_pins[0] = 0x14;
2194 spec->autocfg.speaker_pins[1] = 0x16;
2195 spec->autocfg.speaker_pins[2] = 0x17;
2196 spec->autocfg.speaker_pins[3] = 0x19;
2197 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2198 spec->automute = 1;
2199 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2200}
2201
2202static void alc889_intel_init_hook(struct hda_codec *codec)
2203{
2204 alc889_coef_init(codec);
d922b51d 2205 alc_hp_automute(codec);
6732bd0d
WF
2206}
2207
4f5d1706 2208static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2209{
2210 struct alc_spec *spec = codec->spec;
2211
2212 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2213 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2214 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2215 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2216 spec->automute = 1;
2217 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2218}
ef8ef5fb 2219
5b2d1eca
VP
2220/*
2221 * ALC888 Acer Aspire 4930G model
2222 */
2223
a9111321 2224static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2225/* Front Mic: set to PIN_IN (empty by default) */
2226 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2227/* Unselect Front Mic by default in input mixer 3 */
2228 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2229/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2230 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2231/* Connect Internal HP to front */
2232 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2233 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2234 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2235/* Connect HP out to front */
2236 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2237 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2239 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2240 { }
2241};
2242
d2fd4b09
TV
2243/*
2244 * ALC888 Acer Aspire 6530G model
2245 */
2246
a9111321 2247static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2248/* Route to built-in subwoofer as well as speakers */
2249 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2250 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2251 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2252 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2253/* Bias voltage on for external mic port */
2254 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2255/* Front Mic: set to PIN_IN (empty by default) */
2256 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2257/* Unselect Front Mic by default in input mixer 3 */
2258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2259/* Enable unsolicited event for HP jack */
2260 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2261/* Enable speaker output */
2262 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2263 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2264 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2265/* Enable headphone output */
2266 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2267 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2268 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2269 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2270 { }
2271};
2272
d9477207
DK
2273/*
2274 *ALC888 Acer Aspire 7730G model
2275 */
2276
a9111321 2277static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2278/* Bias voltage on for external mic port */
2279 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2280/* Front Mic: set to PIN_IN (empty by default) */
2281 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2282/* Unselect Front Mic by default in input mixer 3 */
2283 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2284/* Enable unsolicited event for HP jack */
2285 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2286/* Enable speaker output */
2287 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2288 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2289 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2290/* Enable headphone output */
2291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2293 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2294 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2295/*Enable internal subwoofer */
2296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2299 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2300 { }
2301};
2302
3b315d70 2303/*
018df418 2304 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2305 */
2306
a9111321 2307static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2308/* Front Mic: set to PIN_IN (empty by default) */
2309 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2310/* Unselect Front Mic by default in input mixer 3 */
2311 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2312/* Enable unsolicited event for HP jack */
2313 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2314/* Connect Internal Front to Front */
2315 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2316 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2317 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2318/* Connect Internal Rear to Rear */
2319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2320 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2321 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2322/* Connect Internal CLFE to CLFE */
2323 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2324 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2325 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2326/* Connect HP out to Front */
018df418 2327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2330/* Enable all DACs */
2331/* DAC DISABLE/MUTE 1? */
2332/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2333 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2334 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2335/* DAC DISABLE/MUTE 2? */
2336/* some bit here disables the other DACs. Init=0x4900 */
2337 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2338 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2339/* DMIC fix
2340 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2341 * which makes the stereo useless. However, either the mic or the ALC889
2342 * makes the signal become a difference/sum signal instead of standard
2343 * stereo, which is annoying. So instead we flip this bit which makes the
2344 * codec replicate the sum signal to both channels, turning it into a
2345 * normal mono mic.
2346 */
2347/* DMIC_CONTROL? Init value = 0x0001 */
2348 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2349 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2350 { }
2351};
2352
a9111321 2353static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2354 /* Front mic only available on one ADC */
2355 {
2356 .num_items = 4,
2357 .items = {
2358 { "Mic", 0x0 },
2359 { "Line", 0x2 },
2360 { "CD", 0x4 },
2361 { "Front Mic", 0xb },
2362 },
2363 },
2364 {
2365 .num_items = 3,
2366 .items = {
2367 { "Mic", 0x0 },
2368 { "Line", 0x2 },
2369 { "CD", 0x4 },
2370 },
2371 }
2372};
2373
a9111321 2374static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2375 /* Interal mic only available on one ADC */
2376 {
684a8842 2377 .num_items = 5,
d2fd4b09 2378 .items = {
8607f7c4 2379 { "Mic", 0x0 },
684a8842 2380 { "Line In", 0x2 },
d2fd4b09 2381 { "CD", 0x4 },
684a8842 2382 { "Input Mix", 0xa },
28c4edb7 2383 { "Internal Mic", 0xb },
d2fd4b09
TV
2384 },
2385 },
2386 {
684a8842 2387 .num_items = 4,
d2fd4b09 2388 .items = {
8607f7c4 2389 { "Mic", 0x0 },
684a8842 2390 { "Line In", 0x2 },
d2fd4b09 2391 { "CD", 0x4 },
684a8842 2392 { "Input Mix", 0xa },
d2fd4b09
TV
2393 },
2394 }
2395};
2396
a9111321 2397static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2398 /* Digital mic only available on first "ADC" */
2399 {
2400 .num_items = 5,
2401 .items = {
2402 { "Mic", 0x0 },
2403 { "Line", 0x2 },
2404 { "CD", 0x4 },
2405 { "Front Mic", 0xb },
2406 { "Input Mix", 0xa },
2407 },
2408 },
2409 {
2410 .num_items = 4,
2411 .items = {
2412 { "Mic", 0x0 },
2413 { "Line", 0x2 },
2414 { "CD", 0x4 },
2415 { "Input Mix", 0xa },
2416 },
2417 },
2418 {
2419 .num_items = 4,
2420 .items = {
2421 { "Mic", 0x0 },
2422 { "Line", 0x2 },
2423 { "CD", 0x4 },
2424 { "Input Mix", 0xa },
2425 },
2426 }
2427};
2428
a9111321 2429static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2432 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2433 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2434 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2435 HDA_OUTPUT),
2436 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2437 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2438 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2439 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2440 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2441 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2442 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2443 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2444 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2446 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2448 { } /* end */
2449};
2450
a9111321 2451static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2452 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2453 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2454 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2455 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2456 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2457 HDA_OUTPUT),
786c51f9
ŁW
2458 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2459 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2460 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2461 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2462 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2468 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2470 { } /* end */
2471};
2472
a9111321 2473static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2474 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2475 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2476 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2477 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2479 HDA_OUTPUT),
2480 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2482 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2486 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2487 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2488 { } /* end */
2489};
2490
2491
4f5d1706 2492static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2493{
a9fd4f3f 2494 struct alc_spec *spec = codec->spec;
5b2d1eca 2495
a9fd4f3f
TI
2496 spec->autocfg.hp_pins[0] = 0x15;
2497 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2498 spec->autocfg.speaker_pins[1] = 0x16;
2499 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2500 spec->automute = 1;
2501 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2502}
2503
4f5d1706 2504static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2505{
2506 struct alc_spec *spec = codec->spec;
2507
2508 spec->autocfg.hp_pins[0] = 0x15;
2509 spec->autocfg.speaker_pins[0] = 0x14;
2510 spec->autocfg.speaker_pins[1] = 0x16;
2511 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2512 spec->automute = 1;
2513 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2514}
2515
d9477207
DK
2516static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2517{
2518 struct alc_spec *spec = codec->spec;
2519
2520 spec->autocfg.hp_pins[0] = 0x15;
2521 spec->autocfg.speaker_pins[0] = 0x14;
2522 spec->autocfg.speaker_pins[1] = 0x16;
2523 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2524 spec->automute = 1;
2525 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2526}
2527
4f5d1706 2528static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2529{
2530 struct alc_spec *spec = codec->spec;
2531
2532 spec->autocfg.hp_pins[0] = 0x15;
2533 spec->autocfg.speaker_pins[0] = 0x14;
2534 spec->autocfg.speaker_pins[1] = 0x16;
2535 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2536 spec->automute = 1;
2537 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2538}
2539
1da177e4 2540/*
e9edcee0
TI
2541 * ALC880 3-stack model
2542 *
2543 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2544 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2545 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2546 */
2547
4c6d72d1 2548static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2549 /* front, rear, clfe, rear_surr */
2550 0x02, 0x05, 0x04, 0x03
2551};
2552
4c6d72d1 2553static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2554 /* ADC0-2 */
2555 0x07, 0x08, 0x09,
2556};
2557
2558/* The datasheet says the node 0x07 is connected from inputs,
2559 * but it shows zero connection in the real implementation on some devices.
df694daa 2560 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2561 */
4c6d72d1 2562static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2563 /* ADC1-2 */
2564 0x08, 0x09,
2565};
2566
2567#define ALC880_DIGOUT_NID 0x06
2568#define ALC880_DIGIN_NID 0x0a
2569
a9111321 2570static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2571 .num_items = 4,
2572 .items = {
2573 { "Mic", 0x0 },
2574 { "Front Mic", 0x3 },
2575 { "Line", 0x2 },
2576 { "CD", 0x4 },
2577 },
2578};
2579
2580/* channel source setting (2/6 channel selection for 3-stack) */
2581/* 2ch mode */
a9111321 2582static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2583 /* set line-in to input, mute it */
2584 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2585 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2586 /* set mic-in to input vref 80%, mute it */
2587 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2588 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2589 { } /* end */
2590};
2591
2592/* 6ch mode */
a9111321 2593static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2594 /* set line-in to output, unmute it */
2595 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2596 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2597 /* set mic-in to output, unmute it */
2598 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2599 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2600 { } /* end */
2601};
2602
a9111321 2603static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2604 { 2, alc880_threestack_ch2_init },
2605 { 6, alc880_threestack_ch6_init },
2606};
2607
a9111321 2608static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2609 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2610 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2612 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2614 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2615 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2616 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2617 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2618 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2619 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2620 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2621 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2622 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2623 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2624 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2625 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2626 {
2627 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2628 .name = "Channel Mode",
df694daa
KY
2629 .info = alc_ch_mode_info,
2630 .get = alc_ch_mode_get,
2631 .put = alc_ch_mode_put,
e9edcee0
TI
2632 },
2633 { } /* end */
2634};
2635
2636/* capture mixer elements */
f9e336f6
TI
2637static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2638 struct snd_ctl_elem_info *uinfo)
2639{
2640 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2641 struct alc_spec *spec = codec->spec;
2642 int err;
1da177e4 2643
5a9e02e9 2644 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2645 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2646 HDA_INPUT);
2647 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2648 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2649 return err;
2650}
2651
2652static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2653 unsigned int size, unsigned int __user *tlv)
2654{
2655 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2656 struct alc_spec *spec = codec->spec;
2657 int err;
1da177e4 2658
5a9e02e9 2659 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2660 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2661 HDA_INPUT);
2662 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2663 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2664 return err;
2665}
2666
2667typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2668 struct snd_ctl_elem_value *ucontrol);
2669
2670static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2671 struct snd_ctl_elem_value *ucontrol,
2672 getput_call_t func)
2673{
2674 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2675 struct alc_spec *spec = codec->spec;
2676 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2677 int err;
2678
5a9e02e9 2679 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2680 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2681 3, 0, HDA_INPUT);
2682 err = func(kcontrol, ucontrol);
5a9e02e9 2683 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2684 return err;
2685}
2686
2687static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2688 struct snd_ctl_elem_value *ucontrol)
2689{
2690 return alc_cap_getput_caller(kcontrol, ucontrol,
2691 snd_hda_mixer_amp_volume_get);
2692}
2693
2694static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2695 struct snd_ctl_elem_value *ucontrol)
2696{
2697 return alc_cap_getput_caller(kcontrol, ucontrol,
2698 snd_hda_mixer_amp_volume_put);
2699}
2700
2701/* capture mixer elements */
2702#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2703
2704static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2705 struct snd_ctl_elem_value *ucontrol)
2706{
2707 return alc_cap_getput_caller(kcontrol, ucontrol,
2708 snd_hda_mixer_amp_switch_get);
2709}
2710
2711static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2712 struct snd_ctl_elem_value *ucontrol)
2713{
2714 return alc_cap_getput_caller(kcontrol, ucontrol,
2715 snd_hda_mixer_amp_switch_put);
2716}
2717
a23b688f 2718#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2719 { \
2720 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2721 .name = "Capture Switch", \
2722 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2723 .count = num, \
2724 .info = alc_cap_sw_info, \
2725 .get = alc_cap_sw_get, \
2726 .put = alc_cap_sw_put, \
2727 }, \
2728 { \
2729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2730 .name = "Capture Volume", \
2731 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2732 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2733 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2734 .count = num, \
2735 .info = alc_cap_vol_info, \
2736 .get = alc_cap_vol_get, \
2737 .put = alc_cap_vol_put, \
2738 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2739 }
2740
2741#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2742 { \
2743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2744 /* .name = "Capture Source", */ \
2745 .name = "Input Source", \
2746 .count = num, \
2747 .info = alc_mux_enum_info, \
2748 .get = alc_mux_enum_get, \
2749 .put = alc_mux_enum_put, \
a23b688f
TI
2750 }
2751
2752#define DEFINE_CAPMIX(num) \
a9111321 2753static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2754 _DEFINE_CAPMIX(num), \
2755 _DEFINE_CAPSRC(num), \
2756 { } /* end */ \
2757}
2758
2759#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2760static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2761 _DEFINE_CAPMIX(num), \
2762 { } /* end */ \
f9e336f6
TI
2763}
2764
2765/* up to three ADCs */
2766DEFINE_CAPMIX(1);
2767DEFINE_CAPMIX(2);
2768DEFINE_CAPMIX(3);
a23b688f
TI
2769DEFINE_CAPMIX_NOSRC(1);
2770DEFINE_CAPMIX_NOSRC(2);
2771DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2772
2773/*
2774 * ALC880 5-stack model
2775 *
9c7f852e
TI
2776 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2777 * Side = 0x02 (0xd)
e9edcee0
TI
2778 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2779 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2780 */
2781
2782/* additional mixers to alc880_three_stack_mixer */
a9111321 2783static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2784 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2785 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2786 { } /* end */
2787};
2788
e9edcee0
TI
2789/* channel source setting (6/8 channel selection for 5-stack) */
2790/* 6ch mode */
a9111321 2791static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2792 /* set line-in to input, mute it */
2793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2795 { } /* end */
2796};
2797
e9edcee0 2798/* 8ch mode */
a9111321 2799static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2800 /* set line-in to output, unmute it */
2801 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2802 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2803 { } /* end */
2804};
2805
a9111321 2806static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2807 { 6, alc880_fivestack_ch6_init },
2808 { 8, alc880_fivestack_ch8_init },
2809};
2810
2811
2812/*
2813 * ALC880 6-stack model
2814 *
9c7f852e
TI
2815 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2816 * Side = 0x05 (0x0f)
e9edcee0
TI
2817 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2818 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2819 */
2820
4c6d72d1 2821static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2822 /* front, rear, clfe, rear_surr */
2823 0x02, 0x03, 0x04, 0x05
f12ab1e0 2824};
e9edcee0 2825
a9111321 2826static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2827 .num_items = 4,
2828 .items = {
2829 { "Mic", 0x0 },
2830 { "Front Mic", 0x1 },
2831 { "Line", 0x2 },
2832 { "CD", 0x4 },
2833 },
2834};
2835
2836/* fixed 8-channels */
a9111321 2837static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2838 { 8, NULL },
2839};
2840
a9111321 2841static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2842 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2843 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2844 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2845 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2846 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2847 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2848 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2849 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2850 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2851 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2852 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2853 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2854 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2855 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2858 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2859 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2860 {
2861 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2862 .name = "Channel Mode",
df694daa
KY
2863 .info = alc_ch_mode_info,
2864 .get = alc_ch_mode_get,
2865 .put = alc_ch_mode_put,
16ded525
TI
2866 },
2867 { } /* end */
2868};
2869
e9edcee0
TI
2870
2871/*
2872 * ALC880 W810 model
2873 *
2874 * W810 has rear IO for:
2875 * Front (DAC 02)
2876 * Surround (DAC 03)
2877 * Center/LFE (DAC 04)
2878 * Digital out (06)
2879 *
2880 * The system also has a pair of internal speakers, and a headphone jack.
2881 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2882 *
e9edcee0
TI
2883 * There is a variable resistor to control the speaker or headphone
2884 * volume. This is a hardware-only device without a software API.
2885 *
2886 * Plugging headphones in will disable the internal speakers. This is
2887 * implemented in hardware, not via the driver using jack sense. In
2888 * a similar fashion, plugging into the rear socket marked "front" will
2889 * disable both the speakers and headphones.
2890 *
2891 * For input, there's a microphone jack, and an "audio in" jack.
2892 * These may not do anything useful with this driver yet, because I
2893 * haven't setup any initialization verbs for these yet...
2894 */
2895
4c6d72d1 2896static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2897 /* front, rear/surround, clfe */
2898 0x02, 0x03, 0x04
16ded525
TI
2899};
2900
e9edcee0 2901/* fixed 6 channels */
a9111321 2902static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2903 { 6, NULL }
2904};
2905
2906/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2907static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2908 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2909 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2910 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2911 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2912 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2913 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2914 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2915 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2916 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2917 { } /* end */
2918};
2919
2920
2921/*
2922 * Z710V model
2923 *
2924 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2925 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2926 * Line = 0x1a
e9edcee0
TI
2927 */
2928
4c6d72d1 2929static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2930 0x02
2931};
2932#define ALC880_Z71V_HP_DAC 0x03
2933
2934/* fixed 2 channels */
a9111321 2935static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2936 { 2, NULL }
2937};
2938
a9111321 2939static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2940 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2941 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2942 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2943 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2944 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2945 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2947 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2948 { } /* end */
2949};
2950
e9edcee0 2951
e9edcee0
TI
2952/*
2953 * ALC880 F1734 model
2954 *
2955 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2956 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2957 */
2958
4c6d72d1 2959static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
2960 0x03
2961};
2962#define ALC880_F1734_HP_DAC 0x02
2963
a9111321 2964static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2965 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2966 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2967 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2968 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2973 { } /* end */
2974};
2975
a9111321 2976static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
2977 .num_items = 2,
2978 .items = {
2979 { "Mic", 0x1 },
2980 { "CD", 0x4 },
2981 },
2982};
2983
e9edcee0 2984
e9edcee0
TI
2985/*
2986 * ALC880 ASUS model
2987 *
2988 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2989 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2990 * Mic = 0x18, Line = 0x1a
2991 */
2992
2993#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2994#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2995
a9111321 2996static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2997 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2998 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2999 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3000 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3001 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3002 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3003 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3004 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3005 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3006 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3007 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3008 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3009 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3011 {
3012 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3013 .name = "Channel Mode",
df694daa
KY
3014 .info = alc_ch_mode_info,
3015 .get = alc_ch_mode_get,
3016 .put = alc_ch_mode_put,
16ded525
TI
3017 },
3018 { } /* end */
3019};
e9edcee0 3020
e9edcee0
TI
3021/*
3022 * ALC880 ASUS W1V model
3023 *
3024 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3025 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3026 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3027 */
3028
3029/* additional mixers to alc880_asus_mixer */
a9111321 3030static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3031 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3032 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3033 { } /* end */
3034};
3035
df694daa 3036/* TCL S700 */
a9111321 3037static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3038 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3039 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3040 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3042 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3044 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3046 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3047 { } /* end */
3048};
3049
ccc656ce 3050/* Uniwill */
a9111321 3051static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3052 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3053 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3054 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3055 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3056 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3057 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3058 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3059 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3060 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3061 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3065 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3066 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3067 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3068 {
3069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3070 .name = "Channel Mode",
3071 .info = alc_ch_mode_info,
3072 .get = alc_ch_mode_get,
3073 .put = alc_ch_mode_put,
3074 },
3075 { } /* end */
3076};
3077
a9111321 3078static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3079 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3080 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3081 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3082 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3083 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3084 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3085 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3086 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3087 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3088 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3089 { } /* end */
3090};
3091
a9111321 3092static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3093 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3094 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3095 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3096 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3097 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3098 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3099 { } /* end */
3100};
3101
2134ea4f
TI
3102/*
3103 * virtual master controls
3104 */
3105
3106/*
3107 * slave controls for virtual master
3108 */
ea734963 3109static const char * const alc_slave_vols[] = {
2134ea4f
TI
3110 "Front Playback Volume",
3111 "Surround Playback Volume",
3112 "Center Playback Volume",
3113 "LFE Playback Volume",
3114 "Side Playback Volume",
3115 "Headphone Playback Volume",
3116 "Speaker Playback Volume",
3117 "Mono Playback Volume",
2134ea4f 3118 "Line-Out Playback Volume",
26f5df26 3119 "PCM Playback Volume",
2134ea4f
TI
3120 NULL,
3121};
3122
ea734963 3123static const char * const alc_slave_sws[] = {
2134ea4f
TI
3124 "Front Playback Switch",
3125 "Surround Playback Switch",
3126 "Center Playback Switch",
3127 "LFE Playback Switch",
3128 "Side Playback Switch",
3129 "Headphone Playback Switch",
3130 "Speaker Playback Switch",
3131 "Mono Playback Switch",
edb54a55 3132 "IEC958 Playback Switch",
23033b2b
TI
3133 "Line-Out Playback Switch",
3134 "PCM Playback Switch",
2134ea4f
TI
3135 NULL,
3136};
3137
1da177e4 3138/*
e9edcee0 3139 * build control elements
1da177e4 3140 */
603c4019 3141
5b0cb1d8
JK
3142#define NID_MAPPING (-1)
3143
3144#define SUBDEV_SPEAKER_ (0 << 6)
3145#define SUBDEV_HP_ (1 << 6)
3146#define SUBDEV_LINE_ (2 << 6)
3147#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3148#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3149#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3150
603c4019
TI
3151static void alc_free_kctls(struct hda_codec *codec);
3152
67d634c0 3153#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3154/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3155static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3156 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3157 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3158 { } /* end */
3159};
67d634c0 3160#endif
45bdd1c1 3161
1da177e4
LT
3162static int alc_build_controls(struct hda_codec *codec)
3163{
3164 struct alc_spec *spec = codec->spec;
2f44f847 3165 struct snd_kcontrol *kctl = NULL;
a9111321 3166 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3167 int i, j, err;
3168 unsigned int u;
3169 hda_nid_t nid;
1da177e4
LT
3170
3171 for (i = 0; i < spec->num_mixers; i++) {
3172 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3173 if (err < 0)
3174 return err;
3175 }
f9e336f6
TI
3176 if (spec->cap_mixer) {
3177 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3178 if (err < 0)
3179 return err;
3180 }
1da177e4 3181 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3182 err = snd_hda_create_spdif_out_ctls(codec,
3183 spec->multiout.dig_out_nid);
1da177e4
LT
3184 if (err < 0)
3185 return err;
e64f14f4
TI
3186 if (!spec->no_analog) {
3187 err = snd_hda_create_spdif_share_sw(codec,
3188 &spec->multiout);
3189 if (err < 0)
3190 return err;
3191 spec->multiout.share_spdif = 1;
3192 }
1da177e4
LT
3193 }
3194 if (spec->dig_in_nid) {
3195 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3196 if (err < 0)
3197 return err;
3198 }
2134ea4f 3199
67d634c0 3200#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3201 /* create beep controls if needed */
3202 if (spec->beep_amp) {
a9111321 3203 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3204 for (knew = alc_beep_mixer; knew->name; knew++) {
3205 struct snd_kcontrol *kctl;
3206 kctl = snd_ctl_new1(knew, codec);
3207 if (!kctl)
3208 return -ENOMEM;
3209 kctl->private_value = spec->beep_amp;
5e26dfd0 3210 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3211 if (err < 0)
3212 return err;
3213 }
3214 }
67d634c0 3215#endif
45bdd1c1 3216
2134ea4f 3217 /* if we have no master control, let's create it */
e64f14f4
TI
3218 if (!spec->no_analog &&
3219 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3220 unsigned int vmaster_tlv[4];
2134ea4f 3221 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3222 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3223 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3224 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3225 if (err < 0)
3226 return err;
3227 }
e64f14f4
TI
3228 if (!spec->no_analog &&
3229 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3230 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3231 NULL, alc_slave_sws);
3232 if (err < 0)
3233 return err;
3234 }
3235
5b0cb1d8 3236 /* assign Capture Source enums to NID */
fbe618f2
TI
3237 if (spec->capsrc_nids || spec->adc_nids) {
3238 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3239 if (!kctl)
3240 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3241 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3242 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3243 if (!nids)
3244 nids = spec->adc_nids;
3245 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3246 if (err < 0)
3247 return err;
3248 }
5b0cb1d8
JK
3249 }
3250 if (spec->cap_mixer) {
3251 const char *kname = kctl ? kctl->id.name : NULL;
3252 for (knew = spec->cap_mixer; knew->name; knew++) {
3253 if (kname && strcmp(knew->name, kname) == 0)
3254 continue;
3255 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3256 for (i = 0; kctl && i < kctl->count; i++) {
3257 err = snd_hda_add_nid(codec, kctl, i,
3258 spec->adc_nids[i]);
3259 if (err < 0)
3260 return err;
3261 }
3262 }
3263 }
3264
3265 /* other nid->control mapping */
3266 for (i = 0; i < spec->num_mixers; i++) {
3267 for (knew = spec->mixers[i]; knew->name; knew++) {
3268 if (knew->iface != NID_MAPPING)
3269 continue;
3270 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3271 if (kctl == NULL)
3272 continue;
3273 u = knew->subdevice;
3274 for (j = 0; j < 4; j++, u >>= 8) {
3275 nid = u & 0x3f;
3276 if (nid == 0)
3277 continue;
3278 switch (u & 0xc0) {
3279 case SUBDEV_SPEAKER_:
3280 nid = spec->autocfg.speaker_pins[nid];
3281 break;
3282 case SUBDEV_LINE_:
3283 nid = spec->autocfg.line_out_pins[nid];
3284 break;
3285 case SUBDEV_HP_:
3286 nid = spec->autocfg.hp_pins[nid];
3287 break;
3288 default:
3289 continue;
3290 }
3291 err = snd_hda_add_nid(codec, kctl, 0, nid);
3292 if (err < 0)
3293 return err;
3294 }
3295 u = knew->private_value;
3296 for (j = 0; j < 4; j++, u >>= 8) {
3297 nid = u & 0xff;
3298 if (nid == 0)
3299 continue;
3300 err = snd_hda_add_nid(codec, kctl, 0, nid);
3301 if (err < 0)
3302 return err;
3303 }
3304 }
3305 }
bae84e70
TI
3306
3307 alc_free_kctls(codec); /* no longer needed */
3308
1da177e4
LT
3309 return 0;
3310}
3311
e9edcee0 3312
1da177e4
LT
3313/*
3314 * initialize the codec volumes, etc
3315 */
3316
e9edcee0
TI
3317/*
3318 * generic initialization of ADC, input mixers and output mixers
3319 */
a9111321 3320static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3321 /*
3322 * Unmute ADC0-2 and set the default input to mic-in
3323 */
71fe7b82 3324 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3325 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3326 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3327 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3328 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3329 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3330
e9edcee0
TI
3331 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3332 * mixer widget
9c7f852e
TI
3333 * Note: PASD motherboards uses the Line In 2 as the input for front
3334 * panel mic (mic 2)
1da177e4 3335 */
e9edcee0 3336 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3342 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3344
e9edcee0
TI
3345 /*
3346 * Set up output mixers (0x0c - 0x0f)
1da177e4 3347 */
e9edcee0
TI
3348 /* set vol=0 to output mixers */
3349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3350 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3351 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3352 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3353 /* set up input amps for analog loopback */
3354 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3357 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3358 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3360 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3361 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3362 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3363
3364 { }
3365};
3366
e9edcee0
TI
3367/*
3368 * 3-stack pin configuration:
3369 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3370 */
a9111321 3371static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3372 /*
3373 * preset connection lists of input pins
3374 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3375 */
3376 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3377 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3378 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3379
3380 /*
3381 * Set pin mode and muting
3382 */
3383 /* set front pin widgets 0x14 for output */
05acb863 3384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3385 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3386 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3387 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3388 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3389 /* Mic2 (as headphone out) for HP output */
3390 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3391 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3392 /* Line In pin widget for input */
05acb863 3393 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3394 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3395 /* Line2 (as front mic) pin widget for input and vref at 80% */
3396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3397 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3398 /* CD pin widget for input */
05acb863 3399 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3400
e9edcee0
TI
3401 { }
3402};
1da177e4 3403
e9edcee0
TI
3404/*
3405 * 5-stack pin configuration:
3406 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3407 * line-in/side = 0x1a, f-mic = 0x1b
3408 */
a9111321 3409static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3410 /*
3411 * preset connection lists of input pins
3412 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3413 */
e9edcee0
TI
3414 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3415 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3416
e9edcee0
TI
3417 /*
3418 * Set pin mode and muting
1da177e4 3419 */
e9edcee0
TI
3420 /* set pin widgets 0x14-0x17 for output */
3421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3424 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3425 /* unmute pins for output (no gain on this amp) */
3426 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3428 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3429 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3430
3431 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3433 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3434 /* Mic2 (as headphone out) for HP output */
3435 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3436 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3437 /* Line In pin widget for input */
3438 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3439 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3440 /* Line2 (as front mic) pin widget for input and vref at 80% */
3441 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3442 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3443 /* CD pin widget for input */
3444 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3445
3446 { }
3447};
3448
e9edcee0
TI
3449/*
3450 * W810 pin configuration:
3451 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3452 */
a9111321 3453static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3454 /* hphone/speaker input selector: front DAC */
3455 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3456
05acb863 3457 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3459 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3460 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3461 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3462 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3463
e9edcee0 3464 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3465 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3466
1da177e4
LT
3467 { }
3468};
3469
e9edcee0
TI
3470/*
3471 * Z71V pin configuration:
3472 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3473 */
a9111321 3474static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3475 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3476 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3477 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3478 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3479
16ded525 3480 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3481 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3482 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3483 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3484
3485 { }
3486};
3487
e9edcee0
TI
3488/*
3489 * 6-stack pin configuration:
9c7f852e
TI
3490 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3491 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3492 */
a9111321 3493static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3494 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3495
16ded525 3496 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3497 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3499 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3500 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3501 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3502 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3503 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3504
16ded525 3505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3506 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3507 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3508 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3509 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3510 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3514
e9edcee0
TI
3515 { }
3516};
3517
ccc656ce
KY
3518/*
3519 * Uniwill pin configuration:
3520 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3521 * line = 0x1a
3522 */
a9111321 3523static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3524 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3525
3526 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3527 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3528 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3529 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3532 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3533 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3534 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3535 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3536 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3537 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3538 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3539 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3540
3541 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3543 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3544 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3546 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3547 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3548 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3549 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3550
3551 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3552 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3553
3554 { }
3555};
3556
3557/*
3558* Uniwill P53
ea1fb29a 3559* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3560 */
a9111321 3561static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3562 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3563
3564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3565 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3567 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3572 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3576
3577 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3579 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3580 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3583
3584 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3585 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3586
3587 { }
3588};
3589
a9111321 3590static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3591 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3592 { }
3593};
3594
458a4fab 3595/* auto-toggle front mic */
eeb43387 3596static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3597{
3598 unsigned int present;
3599 unsigned char bits;
ccc656ce 3600
864f92be 3601 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3602 bits = present ? HDA_AMP_MUTE : 0;
3603 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3604}
3605
4f5d1706 3606static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3607{
a9fd4f3f
TI
3608 struct alc_spec *spec = codec->spec;
3609
3610 spec->autocfg.hp_pins[0] = 0x14;
3611 spec->autocfg.speaker_pins[0] = 0x15;
3612 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3613 spec->automute = 1;
3614 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3615}
3616
3617static void alc880_uniwill_init_hook(struct hda_codec *codec)
3618{
d922b51d 3619 alc_hp_automute(codec);
eeb43387 3620 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3621}
3622
3623static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3624 unsigned int res)
3625{
3626 /* Looks like the unsol event is incompatible with the standard
3627 * definition. 4bit tag is placed at 28 bit!
3628 */
458a4fab 3629 switch (res >> 28) {
458a4fab 3630 case ALC880_MIC_EVENT:
eeb43387 3631 alc88x_simple_mic_automute(codec);
458a4fab 3632 break;
a9fd4f3f 3633 default:
d922b51d 3634 alc_sku_unsol_event(codec, res);
a9fd4f3f 3635 break;
458a4fab 3636 }
ccc656ce
KY
3637}
3638
4f5d1706 3639static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3640{
a9fd4f3f 3641 struct alc_spec *spec = codec->spec;
ccc656ce 3642
a9fd4f3f
TI
3643 spec->autocfg.hp_pins[0] = 0x14;
3644 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3645 spec->automute = 1;
3646 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3647}
3648
3649static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3650{
3651 unsigned int present;
ea1fb29a 3652
ccc656ce 3653 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3654 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3655 present &= HDA_AMP_VOLMASK;
3656 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3657 HDA_AMP_VOLMASK, present);
3658 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3659 HDA_AMP_VOLMASK, present);
ccc656ce 3660}
47fd830a 3661
ccc656ce
KY
3662static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3663 unsigned int res)
3664{
3665 /* Looks like the unsol event is incompatible with the standard
3666 * definition. 4bit tag is placed at 28 bit!
3667 */
f12ab1e0 3668 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3669 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3670 else
d922b51d 3671 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3672}
3673
e9edcee0
TI
3674/*
3675 * F1734 pin configuration:
3676 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3677 */
a9111321 3678static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3679 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3680 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3681 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3682 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3683 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3684
e9edcee0 3685 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3686 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3687 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3688 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3689
e9edcee0
TI
3690 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3691 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3692 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3693 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3694 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3695 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3696 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3697 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3698 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3699
937b4160
TI
3700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3701 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3702
dfc0ff62
TI
3703 { }
3704};
3705
e9edcee0
TI
3706/*
3707 * ASUS pin configuration:
3708 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3709 */
a9111321 3710static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3711 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3712 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3713 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3714 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3715
3716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3718 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3719 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3720 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3722 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3724
3725 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3726 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3727 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3731 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3733 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3734
e9edcee0
TI
3735 { }
3736};
16ded525 3737
e9edcee0 3738/* Enable GPIO mask and set output */
bc9f98a9
KY
3739#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3740#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3741#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3742
3743/* Clevo m520g init */
a9111321 3744static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3745 /* headphone output */
3746 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3747 /* line-out */
3748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3750 /* Line-in */
3751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3753 /* CD */
3754 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3755 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3756 /* Mic1 (rear panel) */
3757 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3758 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3759 /* Mic2 (front panel) */
3760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3762 /* headphone */
3763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3765 /* change to EAPD mode */
3766 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3767 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3768
3769 { }
16ded525
TI
3770};
3771
a9111321 3772static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3773 /* change to EAPD mode */
3774 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3775 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3776
df694daa
KY
3777 /* Headphone output */
3778 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3779 /* Front output*/
3780 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3782
3783 /* Line In pin widget for input */
3784 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3785 /* CD pin widget for input */
3786 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3787 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3789
3790 /* change to EAPD mode */
3791 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3792 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3793
3794 { }
3795};
16ded525 3796
e9edcee0 3797/*
ae6b813a
TI
3798 * LG m1 express dual
3799 *
3800 * Pin assignment:
3801 * Rear Line-In/Out (blue): 0x14
3802 * Build-in Mic-In: 0x15
3803 * Speaker-out: 0x17
3804 * HP-Out (green): 0x1b
3805 * Mic-In/Out (red): 0x19
3806 * SPDIF-Out: 0x1e
3807 */
3808
3809/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3810static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3811 0x05, 0x02, 0x03
3812};
3813
3814/* seems analog CD is not working */
a9111321 3815static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3816 .num_items = 3,
3817 .items = {
3818 { "Mic", 0x1 },
3819 { "Line", 0x5 },
3820 { "Internal Mic", 0x6 },
3821 },
3822};
3823
3824/* 2,4,6 channel modes */
a9111321 3825static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3826 /* set line-in and mic-in to input */
3827 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3828 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3829 { }
3830};
3831
a9111321 3832static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3833 /* set line-in to out and mic-in to input */
3834 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3835 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3836 { }
3837};
3838
a9111321 3839static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3840 /* set line-in and mic-in to output */
3841 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3842 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3843 { }
3844};
3845
a9111321 3846static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3847 { 2, alc880_lg_ch2_init },
3848 { 4, alc880_lg_ch4_init },
3849 { 6, alc880_lg_ch6_init },
3850};
3851
a9111321 3852static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3853 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3854 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3855 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3856 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3857 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3858 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3859 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3860 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3861 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3863 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3864 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3865 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3866 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3867 {
3868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3869 .name = "Channel Mode",
3870 .info = alc_ch_mode_info,
3871 .get = alc_ch_mode_get,
3872 .put = alc_ch_mode_put,
3873 },
3874 { } /* end */
3875};
3876
a9111321 3877static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3878 /* set capture source to mic-in */
3879 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3880 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3881 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3882 /* mute all amp mixer inputs */
3883 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3884 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3886 /* line-in to input */
3887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3889 /* built-in mic */
3890 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3891 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3892 /* speaker-out */
3893 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3894 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3895 /* mic-in to input */
3896 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3897 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3898 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3899 /* HP-out */
3900 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3901 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3902 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3903 /* jack sense */
a9fd4f3f 3904 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3905 { }
3906};
3907
3908/* toggle speaker-output according to the hp-jack state */
4f5d1706 3909static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3910{
a9fd4f3f 3911 struct alc_spec *spec = codec->spec;
ae6b813a 3912
a9fd4f3f
TI
3913 spec->autocfg.hp_pins[0] = 0x1b;
3914 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3915 spec->automute = 1;
3916 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3917}
3918
d681518a
TI
3919/*
3920 * LG LW20
3921 *
3922 * Pin assignment:
3923 * Speaker-out: 0x14
3924 * Mic-In: 0x18
e4f41da9
CM
3925 * Built-in Mic-In: 0x19
3926 * Line-In: 0x1b
3927 * HP-Out: 0x1a
d681518a
TI
3928 * SPDIF-Out: 0x1e
3929 */
3930
a9111321 3931static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3932 .num_items = 3,
d681518a
TI
3933 .items = {
3934 { "Mic", 0x0 },
3935 { "Internal Mic", 0x1 },
e4f41da9 3936 { "Line In", 0x2 },
d681518a
TI
3937 },
3938};
3939
0a8c5da3
CM
3940#define alc880_lg_lw_modes alc880_threestack_modes
3941
a9111321 3942static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3943 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3944 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3945 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3946 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3947 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3948 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3949 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3950 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3951 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3952 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3953 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3954 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3955 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3956 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3957 {
3958 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3959 .name = "Channel Mode",
3960 .info = alc_ch_mode_info,
3961 .get = alc_ch_mode_get,
3962 .put = alc_ch_mode_put,
3963 },
d681518a
TI
3964 { } /* end */
3965};
3966
a9111321 3967static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3968 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3969 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3970 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3971
d681518a
TI
3972 /* set capture source to mic-in */
3973 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3974 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3976 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3977 /* speaker-out */
3978 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3979 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3980 /* HP-out */
d681518a
TI
3981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3982 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3983 /* mic-in to input */
3984 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3985 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3986 /* built-in mic */
3987 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3988 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3989 /* jack sense */
a9fd4f3f 3990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3991 { }
3992};
3993
3994/* toggle speaker-output according to the hp-jack state */
4f5d1706 3995static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3996{
a9fd4f3f 3997 struct alc_spec *spec = codec->spec;
d681518a 3998
a9fd4f3f
TI
3999 spec->autocfg.hp_pins[0] = 0x1b;
4000 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4001 spec->automute = 1;
4002 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4003}
4004
a9111321 4005static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4006 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4007 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4010 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4011 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4012 { } /* end */
4013};
4014
a9111321 4015static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4016 .num_items = 2,
4017 .items = {
4018 { "Mic", 0x0 },
4019 { "Internal Mic", 0x1 },
4020 },
4021};
4022
a9111321 4023static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4024 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4025
4026 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4027 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4028
4029 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4030 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4031 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4032 /* Mic2 (as headphone out) for HP output */
4033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4034 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4035 /* Internal Speaker */
4036 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4037 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4038
4039 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4040 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4041
4042 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4043 { }
4044};
4045
4046/* toggle speaker-output according to the hp-jack state */
4047static void alc880_medion_rim_automute(struct hda_codec *codec)
4048{
a9fd4f3f 4049 struct alc_spec *spec = codec->spec;
d922b51d 4050 alc_hp_automute(codec);
a9fd4f3f
TI
4051 /* toggle EAPD */
4052 if (spec->jack_present)
df99cd33
TI
4053 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4054 else
4055 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4056}
4057
4058static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4059 unsigned int res)
4060{
4061 /* Looks like the unsol event is incompatible with the standard
4062 * definition. 4bit tag is placed at 28 bit!
4063 */
4064 if ((res >> 28) == ALC880_HP_EVENT)
4065 alc880_medion_rim_automute(codec);
4066}
4067
4f5d1706 4068static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4069{
4070 struct alc_spec *spec = codec->spec;
4071
4072 spec->autocfg.hp_pins[0] = 0x14;
4073 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4074 spec->automute = 1;
4075 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4076}
4077
cb53c626 4078#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4079static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4080 { 0x0b, HDA_INPUT, 0 },
4081 { 0x0b, HDA_INPUT, 1 },
4082 { 0x0b, HDA_INPUT, 2 },
4083 { 0x0b, HDA_INPUT, 3 },
4084 { 0x0b, HDA_INPUT, 4 },
4085 { } /* end */
4086};
4087
a9111321 4088static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4089 { 0x0b, HDA_INPUT, 1 },
4090 { 0x0b, HDA_INPUT, 6 },
4091 { 0x0b, HDA_INPUT, 7 },
4092 { } /* end */
4093};
4094#endif
4095
ae6b813a
TI
4096/*
4097 * Common callbacks
e9edcee0
TI
4098 */
4099
584c0c4c
TI
4100static void alc_init_special_input_src(struct hda_codec *codec);
4101
1da177e4
LT
4102static int alc_init(struct hda_codec *codec)
4103{
4104 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4105 unsigned int i;
4106
2c3bf9ab 4107 alc_fix_pll(codec);
4a79ba34 4108 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4109
e9edcee0
TI
4110 for (i = 0; i < spec->num_init_verbs; i++)
4111 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4112 alc_init_special_input_src(codec);
ae6b813a
TI
4113
4114 if (spec->init_hook)
4115 spec->init_hook(codec);
4116
58701120
TI
4117 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4118
9e5341b9 4119 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4120 return 0;
4121}
4122
ae6b813a
TI
4123static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4124{
4125 struct alc_spec *spec = codec->spec;
4126
4127 if (spec->unsol_event)
4128 spec->unsol_event(codec, res);
4129}
4130
cb53c626
TI
4131#ifdef CONFIG_SND_HDA_POWER_SAVE
4132static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4133{
4134 struct alc_spec *spec = codec->spec;
4135 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4136}
4137#endif
4138
1da177e4
LT
4139/*
4140 * Analog playback callbacks
4141 */
4142static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4143 struct hda_codec *codec,
c8b6bf9b 4144 struct snd_pcm_substream *substream)
1da177e4
LT
4145{
4146 struct alc_spec *spec = codec->spec;
9a08160b
TI
4147 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4148 hinfo);
1da177e4
LT
4149}
4150
4151static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4152 struct hda_codec *codec,
4153 unsigned int stream_tag,
4154 unsigned int format,
c8b6bf9b 4155 struct snd_pcm_substream *substream)
1da177e4
LT
4156{
4157 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4158 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4159 stream_tag, format, substream);
1da177e4
LT
4160}
4161
4162static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4163 struct hda_codec *codec,
c8b6bf9b 4164 struct snd_pcm_substream *substream)
1da177e4
LT
4165{
4166 struct alc_spec *spec = codec->spec;
4167 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4168}
4169
4170/*
4171 * Digital out
4172 */
4173static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4174 struct hda_codec *codec,
c8b6bf9b 4175 struct snd_pcm_substream *substream)
1da177e4
LT
4176{
4177 struct alc_spec *spec = codec->spec;
4178 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4179}
4180
6b97eb45
TI
4181static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4182 struct hda_codec *codec,
4183 unsigned int stream_tag,
4184 unsigned int format,
4185 struct snd_pcm_substream *substream)
4186{
4187 struct alc_spec *spec = codec->spec;
4188 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4189 stream_tag, format, substream);
4190}
4191
9b5f12e5
TI
4192static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4193 struct hda_codec *codec,
4194 struct snd_pcm_substream *substream)
4195{
4196 struct alc_spec *spec = codec->spec;
4197 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4198}
4199
1da177e4
LT
4200static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4201 struct hda_codec *codec,
c8b6bf9b 4202 struct snd_pcm_substream *substream)
1da177e4
LT
4203{
4204 struct alc_spec *spec = codec->spec;
4205 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4206}
4207
4208/*
4209 * Analog capture
4210 */
6330079f 4211static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4212 struct hda_codec *codec,
4213 unsigned int stream_tag,
4214 unsigned int format,
c8b6bf9b 4215 struct snd_pcm_substream *substream)
1da177e4
LT
4216{
4217 struct alc_spec *spec = codec->spec;
4218
6330079f 4219 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4220 stream_tag, 0, format);
4221 return 0;
4222}
4223
6330079f 4224static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4225 struct hda_codec *codec,
c8b6bf9b 4226 struct snd_pcm_substream *substream)
1da177e4
LT
4227{
4228 struct alc_spec *spec = codec->spec;
4229
888afa15
TI
4230 snd_hda_codec_cleanup_stream(codec,
4231 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4232 return 0;
4233}
4234
840b64c0
TI
4235/* analog capture with dynamic dual-adc changes */
4236static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4237 struct hda_codec *codec,
4238 unsigned int stream_tag,
4239 unsigned int format,
4240 struct snd_pcm_substream *substream)
4241{
4242 struct alc_spec *spec = codec->spec;
4243 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4244 spec->cur_adc_stream_tag = stream_tag;
4245 spec->cur_adc_format = format;
4246 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4247 return 0;
4248}
4249
4250static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4251 struct hda_codec *codec,
4252 struct snd_pcm_substream *substream)
4253{
4254 struct alc_spec *spec = codec->spec;
4255 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4256 spec->cur_adc = 0;
4257 return 0;
4258}
4259
a9111321 4260static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4261 .substreams = 1,
4262 .channels_min = 2,
4263 .channels_max = 2,
4264 .nid = 0, /* fill later */
4265 .ops = {
4266 .prepare = dualmic_capture_pcm_prepare,
4267 .cleanup = dualmic_capture_pcm_cleanup
4268 },
4269};
1da177e4
LT
4270
4271/*
4272 */
a9111321 4273static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4274 .substreams = 1,
4275 .channels_min = 2,
4276 .channels_max = 8,
e9edcee0 4277 /* NID is set in alc_build_pcms */
1da177e4
LT
4278 .ops = {
4279 .open = alc880_playback_pcm_open,
4280 .prepare = alc880_playback_pcm_prepare,
4281 .cleanup = alc880_playback_pcm_cleanup
4282 },
4283};
4284
a9111321 4285static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4286 .substreams = 1,
4287 .channels_min = 2,
4288 .channels_max = 2,
4289 /* NID is set in alc_build_pcms */
4290};
4291
a9111321 4292static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4293 .substreams = 1,
4294 .channels_min = 2,
4295 .channels_max = 2,
4296 /* NID is set in alc_build_pcms */
4297};
4298
a9111321 4299static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4300 .substreams = 2, /* can be overridden */
1da177e4
LT
4301 .channels_min = 2,
4302 .channels_max = 2,
e9edcee0 4303 /* NID is set in alc_build_pcms */
1da177e4 4304 .ops = {
6330079f
TI
4305 .prepare = alc880_alt_capture_pcm_prepare,
4306 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4307 },
4308};
4309
a9111321 4310static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4311 .substreams = 1,
4312 .channels_min = 2,
4313 .channels_max = 2,
4314 /* NID is set in alc_build_pcms */
4315 .ops = {
4316 .open = alc880_dig_playback_pcm_open,
6b97eb45 4317 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4318 .prepare = alc880_dig_playback_pcm_prepare,
4319 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4320 },
4321};
4322
a9111321 4323static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4324 .substreams = 1,
4325 .channels_min = 2,
4326 .channels_max = 2,
4327 /* NID is set in alc_build_pcms */
4328};
4329
4c5186ed 4330/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4331static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4332 .substreams = 0,
4333 .channels_min = 0,
4334 .channels_max = 0,
4335};
4336
1da177e4
LT
4337static int alc_build_pcms(struct hda_codec *codec)
4338{
4339 struct alc_spec *spec = codec->spec;
4340 struct hda_pcm *info = spec->pcm_rec;
4341 int i;
4342
4343 codec->num_pcms = 1;
4344 codec->pcm_info = info;
4345
e64f14f4
TI
4346 if (spec->no_analog)
4347 goto skip_analog;
4348
812a2cca
TI
4349 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4350 "%s Analog", codec->chip_name);
1da177e4 4351 info->name = spec->stream_name_analog;
274693f3 4352
4a471b7d 4353 if (spec->stream_analog_playback) {
da3cec35
TI
4354 if (snd_BUG_ON(!spec->multiout.dac_nids))
4355 return -EINVAL;
4a471b7d
TI
4356 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4357 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4358 }
4359 if (spec->stream_analog_capture) {
da3cec35
TI
4360 if (snd_BUG_ON(!spec->adc_nids))
4361 return -EINVAL;
4a471b7d
TI
4362 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4363 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4364 }
4365
4366 if (spec->channel_mode) {
4367 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4368 for (i = 0; i < spec->num_channel_mode; i++) {
4369 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4370 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4371 }
1da177e4
LT
4372 }
4373 }
4374
e64f14f4 4375 skip_analog:
e08a007d 4376 /* SPDIF for stream index #1 */
1da177e4 4377 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4378 snprintf(spec->stream_name_digital,
4379 sizeof(spec->stream_name_digital),
4380 "%s Digital", codec->chip_name);
e08a007d 4381 codec->num_pcms = 2;
b25c9da1 4382 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4383 info = spec->pcm_rec + 1;
1da177e4 4384 info->name = spec->stream_name_digital;
8c441982
TI
4385 if (spec->dig_out_type)
4386 info->pcm_type = spec->dig_out_type;
4387 else
4388 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4389 if (spec->multiout.dig_out_nid &&
4390 spec->stream_digital_playback) {
1da177e4
LT
4391 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4392 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4393 }
4a471b7d
TI
4394 if (spec->dig_in_nid &&
4395 spec->stream_digital_capture) {
1da177e4
LT
4396 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4397 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4398 }
963f803f
TI
4399 /* FIXME: do we need this for all Realtek codec models? */
4400 codec->spdif_status_reset = 1;
1da177e4
LT
4401 }
4402
e64f14f4
TI
4403 if (spec->no_analog)
4404 return 0;
4405
e08a007d
TI
4406 /* If the use of more than one ADC is requested for the current
4407 * model, configure a second analog capture-only PCM.
4408 */
4409 /* Additional Analaog capture for index #2 */
6330079f
TI
4410 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4411 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4412 codec->num_pcms = 3;
c06134d7 4413 info = spec->pcm_rec + 2;
e08a007d 4414 info->name = spec->stream_name_analog;
6330079f
TI
4415 if (spec->alt_dac_nid) {
4416 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4417 *spec->stream_analog_alt_playback;
4418 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4419 spec->alt_dac_nid;
4420 } else {
4421 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4422 alc_pcm_null_stream;
4423 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4424 }
ce85c9ac 4425 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4426 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4427 *spec->stream_analog_alt_capture;
4428 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4429 spec->adc_nids[1];
4430 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4431 spec->num_adc_nids - 1;
4432 } else {
4433 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4434 alc_pcm_null_stream;
4435 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4436 }
4437 }
4438
1da177e4
LT
4439 return 0;
4440}
4441
a4e09aa3
TI
4442static inline void alc_shutup(struct hda_codec *codec)
4443{
1c716153
TI
4444 struct alc_spec *spec = codec->spec;
4445
4446 if (spec && spec->shutup)
4447 spec->shutup(codec);
a4e09aa3
TI
4448 snd_hda_shutup_pins(codec);
4449}
4450
603c4019
TI
4451static void alc_free_kctls(struct hda_codec *codec)
4452{
4453 struct alc_spec *spec = codec->spec;
4454
4455 if (spec->kctls.list) {
4456 struct snd_kcontrol_new *kctl = spec->kctls.list;
4457 int i;
4458 for (i = 0; i < spec->kctls.used; i++)
4459 kfree(kctl[i].name);
4460 }
4461 snd_array_free(&spec->kctls);
4462}
4463
1da177e4
LT
4464static void alc_free(struct hda_codec *codec)
4465{
e9edcee0 4466 struct alc_spec *spec = codec->spec;
e9edcee0 4467
f12ab1e0 4468 if (!spec)
e9edcee0
TI
4469 return;
4470
a4e09aa3 4471 alc_shutup(codec);
cd372fb3 4472 snd_hda_input_jack_free(codec);
603c4019 4473 alc_free_kctls(codec);
e9edcee0 4474 kfree(spec);
680cd536 4475 snd_hda_detach_beep_device(codec);
1da177e4
LT
4476}
4477
f5de24b0 4478#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4479static void alc_power_eapd(struct hda_codec *codec)
4480{
691f1fcc 4481 alc_auto_setup_eapd(codec, false);
c97259df
DC
4482}
4483
f5de24b0
HM
4484static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4485{
4486 struct alc_spec *spec = codec->spec;
a4e09aa3 4487 alc_shutup(codec);
f5de24b0 4488 if (spec && spec->power_hook)
c97259df 4489 spec->power_hook(codec);
f5de24b0
HM
4490 return 0;
4491}
4492#endif
4493
e044c39a 4494#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4495static int alc_resume(struct hda_codec *codec)
4496{
1c716153 4497 msleep(150); /* to avoid pop noise */
e044c39a
TI
4498 codec->patch_ops.init(codec);
4499 snd_hda_codec_resume_amp(codec);
4500 snd_hda_codec_resume_cache(codec);
9e5341b9 4501 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4502 return 0;
4503}
e044c39a
TI
4504#endif
4505
1da177e4
LT
4506/*
4507 */
a9111321 4508static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4509 .build_controls = alc_build_controls,
4510 .build_pcms = alc_build_pcms,
4511 .init = alc_init,
4512 .free = alc_free,
ae6b813a 4513 .unsol_event = alc_unsol_event,
e044c39a
TI
4514#ifdef SND_HDA_NEEDS_RESUME
4515 .resume = alc_resume,
4516#endif
cb53c626 4517#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4518 .suspend = alc_suspend,
cb53c626
TI
4519 .check_power_status = alc_check_power_status,
4520#endif
c97259df 4521 .reboot_notify = alc_shutup,
1da177e4
LT
4522};
4523
c027ddcd
KY
4524/* replace the codec chip_name with the given string */
4525static int alc_codec_rename(struct hda_codec *codec, const char *name)
4526{
4527 kfree(codec->chip_name);
4528 codec->chip_name = kstrdup(name, GFP_KERNEL);
4529 if (!codec->chip_name) {
4530 alc_free(codec);
4531 return -ENOMEM;
4532 }
4533 return 0;
4534}
4535
2fa522be
TI
4536/*
4537 * Test configuration for debugging
4538 *
4539 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4540 * enum controls.
4541 */
4542#ifdef CONFIG_SND_DEBUG
4c6d72d1 4543static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4544 0x02, 0x03, 0x04, 0x05
4545};
4546
a9111321 4547static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4548 .num_items = 7,
2fa522be
TI
4549 .items = {
4550 { "In-1", 0x0 },
4551 { "In-2", 0x1 },
4552 { "In-3", 0x2 },
4553 { "In-4", 0x3 },
4554 { "CD", 0x4 },
ae6b813a
TI
4555 { "Front", 0x5 },
4556 { "Surround", 0x6 },
2fa522be
TI
4557 },
4558};
4559
a9111321 4560static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4561 { 2, NULL },
fd2c326d 4562 { 4, NULL },
2fa522be 4563 { 6, NULL },
fd2c326d 4564 { 8, NULL },
2fa522be
TI
4565};
4566
9c7f852e
TI
4567static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4568 struct snd_ctl_elem_info *uinfo)
2fa522be 4569{
4c6d72d1 4570 static const char * const texts[] = {
2fa522be
TI
4571 "N/A", "Line Out", "HP Out",
4572 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4573 };
4574 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4575 uinfo->count = 1;
4576 uinfo->value.enumerated.items = 8;
4577 if (uinfo->value.enumerated.item >= 8)
4578 uinfo->value.enumerated.item = 7;
4579 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4580 return 0;
4581}
4582
9c7f852e
TI
4583static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4584 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4585{
4586 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4587 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4588 unsigned int pin_ctl, item = 0;
4589
4590 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4591 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4592 if (pin_ctl & AC_PINCTL_OUT_EN) {
4593 if (pin_ctl & AC_PINCTL_HP_EN)
4594 item = 2;
4595 else
4596 item = 1;
4597 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4598 switch (pin_ctl & AC_PINCTL_VREFEN) {
4599 case AC_PINCTL_VREF_HIZ: item = 3; break;
4600 case AC_PINCTL_VREF_50: item = 4; break;
4601 case AC_PINCTL_VREF_GRD: item = 5; break;
4602 case AC_PINCTL_VREF_80: item = 6; break;
4603 case AC_PINCTL_VREF_100: item = 7; break;
4604 }
4605 }
4606 ucontrol->value.enumerated.item[0] = item;
4607 return 0;
4608}
4609
9c7f852e
TI
4610static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4611 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4612{
4613 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4614 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4615 static const unsigned int ctls[] = {
2fa522be
TI
4616 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4617 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4618 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4619 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4620 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4621 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4622 };
4623 unsigned int old_ctl, new_ctl;
4624
4625 old_ctl = snd_hda_codec_read(codec, nid, 0,
4626 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4627 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4628 if (old_ctl != new_ctl) {
82beb8fd
TI
4629 int val;
4630 snd_hda_codec_write_cache(codec, nid, 0,
4631 AC_VERB_SET_PIN_WIDGET_CONTROL,
4632 new_ctl);
47fd830a
TI
4633 val = ucontrol->value.enumerated.item[0] >= 3 ?
4634 HDA_AMP_MUTE : 0;
4635 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4636 HDA_AMP_MUTE, val);
2fa522be
TI
4637 return 1;
4638 }
4639 return 0;
4640}
4641
9c7f852e
TI
4642static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4643 struct snd_ctl_elem_info *uinfo)
2fa522be 4644{
4c6d72d1 4645 static const char * const texts[] = {
2fa522be
TI
4646 "Front", "Surround", "CLFE", "Side"
4647 };
4648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4649 uinfo->count = 1;
4650 uinfo->value.enumerated.items = 4;
4651 if (uinfo->value.enumerated.item >= 4)
4652 uinfo->value.enumerated.item = 3;
4653 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4654 return 0;
4655}
4656
9c7f852e
TI
4657static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4659{
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4662 unsigned int sel;
4663
4664 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4665 ucontrol->value.enumerated.item[0] = sel & 3;
4666 return 0;
4667}
4668
9c7f852e
TI
4669static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4670 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4671{
4672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4673 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4674 unsigned int sel;
4675
4676 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4677 if (ucontrol->value.enumerated.item[0] != sel) {
4678 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4679 snd_hda_codec_write_cache(codec, nid, 0,
4680 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4681 return 1;
4682 }
4683 return 0;
4684}
4685
4686#define PIN_CTL_TEST(xname,nid) { \
4687 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4688 .name = xname, \
5b0cb1d8 4689 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4690 .info = alc_test_pin_ctl_info, \
4691 .get = alc_test_pin_ctl_get, \
4692 .put = alc_test_pin_ctl_put, \
4693 .private_value = nid \
4694 }
4695
4696#define PIN_SRC_TEST(xname,nid) { \
4697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4698 .name = xname, \
5b0cb1d8 4699 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4700 .info = alc_test_pin_src_info, \
4701 .get = alc_test_pin_src_get, \
4702 .put = alc_test_pin_src_put, \
4703 .private_value = nid \
4704 }
4705
a9111321 4706static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4707 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4708 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4709 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4710 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4711 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4712 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4713 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4714 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4715 PIN_CTL_TEST("Front Pin Mode", 0x14),
4716 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4717 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4718 PIN_CTL_TEST("Side Pin Mode", 0x17),
4719 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4720 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4721 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4722 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4723 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4724 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4725 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4726 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4727 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4728 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4729 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4730 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4731 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4732 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4733 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4734 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4735 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4736 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4737 {
4738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4739 .name = "Channel Mode",
df694daa
KY
4740 .info = alc_ch_mode_info,
4741 .get = alc_ch_mode_get,
4742 .put = alc_ch_mode_put,
2fa522be
TI
4743 },
4744 { } /* end */
4745};
4746
a9111321 4747static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4748 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4749 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4750 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4751 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4752 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4753 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4754 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4755 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4756 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4757 /* Vol output for 0x0c-0x0f */
05acb863
TI
4758 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4760 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4761 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4762 /* Set output pins 0x14-0x17 */
05acb863
TI
4763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4765 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4767 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4769 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4770 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4771 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4772 /* Set input pins 0x18-0x1c */
16ded525
TI
4773 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4774 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4775 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4776 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4778 /* Mute input pins 0x18-0x1b */
05acb863
TI
4779 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4780 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4782 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4783 /* ADC set up */
05acb863 4784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4785 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4787 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4789 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4790 /* Analog input/passthru */
4791 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4792 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4796 { }
4797};
4798#endif
4799
1da177e4
LT
4800/*
4801 */
4802
ea734963 4803static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4804 [ALC880_3ST] = "3stack",
4805 [ALC880_TCL_S700] = "tcl",
4806 [ALC880_3ST_DIG] = "3stack-digout",
4807 [ALC880_CLEVO] = "clevo",
4808 [ALC880_5ST] = "5stack",
4809 [ALC880_5ST_DIG] = "5stack-digout",
4810 [ALC880_W810] = "w810",
4811 [ALC880_Z71V] = "z71v",
4812 [ALC880_6ST] = "6stack",
4813 [ALC880_6ST_DIG] = "6stack-digout",
4814 [ALC880_ASUS] = "asus",
4815 [ALC880_ASUS_W1V] = "asus-w1v",
4816 [ALC880_ASUS_DIG] = "asus-dig",
4817 [ALC880_ASUS_DIG2] = "asus-dig2",
4818 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4819 [ALC880_UNIWILL_P53] = "uniwill-p53",
4820 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4821 [ALC880_F1734] = "F1734",
4822 [ALC880_LG] = "lg",
4823 [ALC880_LG_LW] = "lg-lw",
df99cd33 4824 [ALC880_MEDION_RIM] = "medion",
2fa522be 4825#ifdef CONFIG_SND_DEBUG
f5fcc13c 4826 [ALC880_TEST] = "test",
2fa522be 4827#endif
f5fcc13c
TI
4828 [ALC880_AUTO] = "auto",
4829};
4830
a9111321 4831static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4832 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4833 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4834 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4835 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4836 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4837 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4838 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4839 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4840 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4841 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4842 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4843 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4844 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4845 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4846 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4847 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4848 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4849 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4850 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4851 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4852 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4853 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4854 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4855 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4856 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4857 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4858 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4859 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4860 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4861 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4862 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4863 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4864 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4865 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4866 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4867 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4868 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4869 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4870 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4871 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4872 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4873 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4874 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4875 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4876 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4877 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4878 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4879 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4880 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4881 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4882 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4883 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4884 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4885 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4886 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4887 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4888 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4889 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4890 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4891 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4892 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4893 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4894 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4895 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4896 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4897 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4898 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4899 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4900 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4901 /* default Intel */
4902 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4903 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4904 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4905 {}
4906};
4907
16ded525 4908/*
df694daa 4909 * ALC880 codec presets
16ded525 4910 */
a9111321 4911static const struct alc_config_preset alc880_presets[] = {
16ded525 4912 [ALC880_3ST] = {
e9edcee0 4913 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4914 .init_verbs = { alc880_volume_init_verbs,
4915 alc880_pin_3stack_init_verbs },
16ded525 4916 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4917 .dac_nids = alc880_dac_nids,
16ded525
TI
4918 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4919 .channel_mode = alc880_threestack_modes,
4e195a7b 4920 .need_dac_fix = 1,
16ded525
TI
4921 .input_mux = &alc880_capture_source,
4922 },
4923 [ALC880_3ST_DIG] = {
e9edcee0 4924 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4925 .init_verbs = { alc880_volume_init_verbs,
4926 alc880_pin_3stack_init_verbs },
16ded525 4927 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4928 .dac_nids = alc880_dac_nids,
4929 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4930 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4931 .channel_mode = alc880_threestack_modes,
4e195a7b 4932 .need_dac_fix = 1,
16ded525
TI
4933 .input_mux = &alc880_capture_source,
4934 },
df694daa
KY
4935 [ALC880_TCL_S700] = {
4936 .mixers = { alc880_tcl_s700_mixer },
4937 .init_verbs = { alc880_volume_init_verbs,
4938 alc880_pin_tcl_S700_init_verbs,
4939 alc880_gpio2_init_verbs },
4940 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4941 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4942 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4943 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4944 .hp_nid = 0x03,
4945 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4946 .channel_mode = alc880_2_jack_modes,
4947 .input_mux = &alc880_capture_source,
4948 },
16ded525 4949 [ALC880_5ST] = {
f12ab1e0
TI
4950 .mixers = { alc880_three_stack_mixer,
4951 alc880_five_stack_mixer},
4952 .init_verbs = { alc880_volume_init_verbs,
4953 alc880_pin_5stack_init_verbs },
16ded525
TI
4954 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4955 .dac_nids = alc880_dac_nids,
16ded525
TI
4956 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4957 .channel_mode = alc880_fivestack_modes,
4958 .input_mux = &alc880_capture_source,
4959 },
4960 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4961 .mixers = { alc880_three_stack_mixer,
4962 alc880_five_stack_mixer },
4963 .init_verbs = { alc880_volume_init_verbs,
4964 alc880_pin_5stack_init_verbs },
16ded525
TI
4965 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4966 .dac_nids = alc880_dac_nids,
4967 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4968 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4969 .channel_mode = alc880_fivestack_modes,
4970 .input_mux = &alc880_capture_source,
4971 },
b6482d48
TI
4972 [ALC880_6ST] = {
4973 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4974 .init_verbs = { alc880_volume_init_verbs,
4975 alc880_pin_6stack_init_verbs },
b6482d48
TI
4976 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4977 .dac_nids = alc880_6st_dac_nids,
4978 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4979 .channel_mode = alc880_sixstack_modes,
4980 .input_mux = &alc880_6stack_capture_source,
4981 },
16ded525 4982 [ALC880_6ST_DIG] = {
e9edcee0 4983 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4984 .init_verbs = { alc880_volume_init_verbs,
4985 alc880_pin_6stack_init_verbs },
16ded525
TI
4986 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4987 .dac_nids = alc880_6st_dac_nids,
4988 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4989 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4990 .channel_mode = alc880_sixstack_modes,
4991 .input_mux = &alc880_6stack_capture_source,
4992 },
4993 [ALC880_W810] = {
e9edcee0 4994 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4995 .init_verbs = { alc880_volume_init_verbs,
4996 alc880_pin_w810_init_verbs,
b0af0de5 4997 alc880_gpio2_init_verbs },
16ded525
TI
4998 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
4999 .dac_nids = alc880_w810_dac_nids,
5000 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5001 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5002 .channel_mode = alc880_w810_modes,
5003 .input_mux = &alc880_capture_source,
5004 },
5005 [ALC880_Z71V] = {
e9edcee0 5006 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5007 .init_verbs = { alc880_volume_init_verbs,
5008 alc880_pin_z71v_init_verbs },
16ded525
TI
5009 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5010 .dac_nids = alc880_z71v_dac_nids,
5011 .dig_out_nid = ALC880_DIGOUT_NID,
5012 .hp_nid = 0x03,
e9edcee0
TI
5013 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5014 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5015 .input_mux = &alc880_capture_source,
5016 },
5017 [ALC880_F1734] = {
e9edcee0 5018 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5019 .init_verbs = { alc880_volume_init_verbs,
5020 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5021 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5022 .dac_nids = alc880_f1734_dac_nids,
5023 .hp_nid = 0x02,
5024 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5025 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5026 .input_mux = &alc880_f1734_capture_source,
5027 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5028 .setup = alc880_uniwill_p53_setup,
d922b51d 5029 .init_hook = alc_hp_automute,
16ded525
TI
5030 },
5031 [ALC880_ASUS] = {
e9edcee0 5032 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5033 .init_verbs = { alc880_volume_init_verbs,
5034 alc880_pin_asus_init_verbs,
e9edcee0
TI
5035 alc880_gpio1_init_verbs },
5036 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5037 .dac_nids = alc880_asus_dac_nids,
5038 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5039 .channel_mode = alc880_asus_modes,
4e195a7b 5040 .need_dac_fix = 1,
16ded525
TI
5041 .input_mux = &alc880_capture_source,
5042 },
5043 [ALC880_ASUS_DIG] = {
e9edcee0 5044 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5045 .init_verbs = { alc880_volume_init_verbs,
5046 alc880_pin_asus_init_verbs,
e9edcee0
TI
5047 alc880_gpio1_init_verbs },
5048 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5049 .dac_nids = alc880_asus_dac_nids,
16ded525 5050 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5051 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5052 .channel_mode = alc880_asus_modes,
4e195a7b 5053 .need_dac_fix = 1,
16ded525
TI
5054 .input_mux = &alc880_capture_source,
5055 },
df694daa
KY
5056 [ALC880_ASUS_DIG2] = {
5057 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5058 .init_verbs = { alc880_volume_init_verbs,
5059 alc880_pin_asus_init_verbs,
df694daa
KY
5060 alc880_gpio2_init_verbs }, /* use GPIO2 */
5061 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5062 .dac_nids = alc880_asus_dac_nids,
5063 .dig_out_nid = ALC880_DIGOUT_NID,
5064 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5065 .channel_mode = alc880_asus_modes,
4e195a7b 5066 .need_dac_fix = 1,
df694daa
KY
5067 .input_mux = &alc880_capture_source,
5068 },
16ded525 5069 [ALC880_ASUS_W1V] = {
e9edcee0 5070 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5071 .init_verbs = { alc880_volume_init_verbs,
5072 alc880_pin_asus_init_verbs,
e9edcee0
TI
5073 alc880_gpio1_init_verbs },
5074 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5075 .dac_nids = alc880_asus_dac_nids,
16ded525 5076 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5077 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5078 .channel_mode = alc880_asus_modes,
4e195a7b 5079 .need_dac_fix = 1,
16ded525
TI
5080 .input_mux = &alc880_capture_source,
5081 },
5082 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5083 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5084 .init_verbs = { alc880_volume_init_verbs,
5085 alc880_pin_asus_init_verbs },
e9edcee0
TI
5086 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5087 .dac_nids = alc880_asus_dac_nids,
16ded525 5088 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5089 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5090 .channel_mode = alc880_asus_modes,
4e195a7b 5091 .need_dac_fix = 1,
16ded525
TI
5092 .input_mux = &alc880_capture_source,
5093 },
ccc656ce
KY
5094 [ALC880_UNIWILL] = {
5095 .mixers = { alc880_uniwill_mixer },
5096 .init_verbs = { alc880_volume_init_verbs,
5097 alc880_uniwill_init_verbs },
5098 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5099 .dac_nids = alc880_asus_dac_nids,
5100 .dig_out_nid = ALC880_DIGOUT_NID,
5101 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5102 .channel_mode = alc880_threestack_modes,
5103 .need_dac_fix = 1,
5104 .input_mux = &alc880_capture_source,
5105 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5106 .setup = alc880_uniwill_setup,
a9fd4f3f 5107 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5108 },
5109 [ALC880_UNIWILL_P53] = {
5110 .mixers = { alc880_uniwill_p53_mixer },
5111 .init_verbs = { alc880_volume_init_verbs,
5112 alc880_uniwill_p53_init_verbs },
5113 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5114 .dac_nids = alc880_asus_dac_nids,
5115 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5116 .channel_mode = alc880_threestack_modes,
5117 .input_mux = &alc880_capture_source,
5118 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5119 .setup = alc880_uniwill_p53_setup,
d922b51d 5120 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5121 },
5122 [ALC880_FUJITSU] = {
45bdd1c1 5123 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5124 .init_verbs = { alc880_volume_init_verbs,
5125 alc880_uniwill_p53_init_verbs,
5126 alc880_beep_init_verbs },
5127 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5128 .dac_nids = alc880_dac_nids,
d53d7d9e 5129 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5130 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5131 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5132 .input_mux = &alc880_capture_source,
5133 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5134 .setup = alc880_uniwill_p53_setup,
d922b51d 5135 .init_hook = alc_hp_automute,
ccc656ce 5136 },
df694daa
KY
5137 [ALC880_CLEVO] = {
5138 .mixers = { alc880_three_stack_mixer },
5139 .init_verbs = { alc880_volume_init_verbs,
5140 alc880_pin_clevo_init_verbs },
5141 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5142 .dac_nids = alc880_dac_nids,
5143 .hp_nid = 0x03,
5144 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5145 .channel_mode = alc880_threestack_modes,
4e195a7b 5146 .need_dac_fix = 1,
df694daa
KY
5147 .input_mux = &alc880_capture_source,
5148 },
ae6b813a
TI
5149 [ALC880_LG] = {
5150 .mixers = { alc880_lg_mixer },
5151 .init_verbs = { alc880_volume_init_verbs,
5152 alc880_lg_init_verbs },
5153 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5154 .dac_nids = alc880_lg_dac_nids,
5155 .dig_out_nid = ALC880_DIGOUT_NID,
5156 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5157 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5158 .need_dac_fix = 1,
ae6b813a 5159 .input_mux = &alc880_lg_capture_source,
d922b51d 5160 .unsol_event = alc_sku_unsol_event,
4f5d1706 5161 .setup = alc880_lg_setup,
d922b51d 5162 .init_hook = alc_hp_automute,
cb53c626
TI
5163#ifdef CONFIG_SND_HDA_POWER_SAVE
5164 .loopbacks = alc880_lg_loopbacks,
5165#endif
ae6b813a 5166 },
d681518a
TI
5167 [ALC880_LG_LW] = {
5168 .mixers = { alc880_lg_lw_mixer },
5169 .init_verbs = { alc880_volume_init_verbs,
5170 alc880_lg_lw_init_verbs },
0a8c5da3 5171 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5172 .dac_nids = alc880_dac_nids,
5173 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5174 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5175 .channel_mode = alc880_lg_lw_modes,
d681518a 5176 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5177 .unsol_event = alc_sku_unsol_event,
4f5d1706 5178 .setup = alc880_lg_lw_setup,
d922b51d 5179 .init_hook = alc_hp_automute,
d681518a 5180 },
df99cd33
TI
5181 [ALC880_MEDION_RIM] = {
5182 .mixers = { alc880_medion_rim_mixer },
5183 .init_verbs = { alc880_volume_init_verbs,
5184 alc880_medion_rim_init_verbs,
5185 alc_gpio2_init_verbs },
5186 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5187 .dac_nids = alc880_dac_nids,
5188 .dig_out_nid = ALC880_DIGOUT_NID,
5189 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5190 .channel_mode = alc880_2_jack_modes,
5191 .input_mux = &alc880_medion_rim_capture_source,
5192 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5193 .setup = alc880_medion_rim_setup,
5194 .init_hook = alc880_medion_rim_automute,
df99cd33 5195 },
16ded525
TI
5196#ifdef CONFIG_SND_DEBUG
5197 [ALC880_TEST] = {
e9edcee0
TI
5198 .mixers = { alc880_test_mixer },
5199 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5200 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5201 .dac_nids = alc880_test_dac_nids,
5202 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5203 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5204 .channel_mode = alc880_test_modes,
5205 .input_mux = &alc880_test_capture_source,
5206 },
5207#endif
5208};
5209
e9edcee0
TI
5210/*
5211 * Automatic parse of I/O pins from the BIOS configuration
5212 */
5213
e9edcee0
TI
5214enum {
5215 ALC_CTL_WIDGET_VOL,
5216 ALC_CTL_WIDGET_MUTE,
5217 ALC_CTL_BIND_MUTE,
5218};
a9111321 5219static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5220 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5221 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5222 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5223};
5224
ce764ab2
TI
5225static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5226{
5227 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5228 return snd_array_new(&spec->kctls);
5229}
5230
e9edcee0 5231/* add dynamic controls */
f12ab1e0 5232static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5233 int cidx, unsigned long val)
e9edcee0 5234{
c8b6bf9b 5235 struct snd_kcontrol_new *knew;
e9edcee0 5236
ce764ab2 5237 knew = alc_kcontrol_new(spec);
603c4019
TI
5238 if (!knew)
5239 return -ENOMEM;
e9edcee0 5240 *knew = alc880_control_templates[type];
543537bd 5241 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5242 if (!knew->name)
e9edcee0 5243 return -ENOMEM;
66ceeb6b 5244 knew->index = cidx;
4d02d1b6 5245 if (get_amp_nid_(val))
5e26dfd0 5246 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5247 knew->private_value = val;
e9edcee0
TI
5248 return 0;
5249}
5250
0afe5f89
TI
5251static int add_control_with_pfx(struct alc_spec *spec, int type,
5252 const char *pfx, const char *dir,
66ceeb6b 5253 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5254{
5255 char name[32];
5256 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5257 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5258}
5259
66ceeb6b
TI
5260#define add_pb_vol_ctrl(spec, type, pfx, val) \
5261 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5262#define add_pb_sw_ctrl(spec, type, pfx, val) \
5263 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5264#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5265 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5266#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5267 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5268
e9edcee0
TI
5269#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5270#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5271#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5272#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5273#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5274#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5275#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5276#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5277#define ALC880_PIN_CD_NID 0x1c
5278
5279/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5280static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5281 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5282{
5283 hda_nid_t nid;
5284 int assigned[4];
5285 int i, j;
5286
5287 memset(assigned, 0, sizeof(assigned));
b0af0de5 5288 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5289
5290 /* check the pins hardwired to audio widget */
5291 for (i = 0; i < cfg->line_outs; i++) {
5292 nid = cfg->line_out_pins[i];
5293 if (alc880_is_fixed_pin(nid)) {
5294 int idx = alc880_fixed_pin_idx(nid);
dda14410 5295 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5296 assigned[idx] = 1;
5297 }
5298 }
5299 /* left pins can be connect to any audio widget */
5300 for (i = 0; i < cfg->line_outs; i++) {
5301 nid = cfg->line_out_pins[i];
5302 if (alc880_is_fixed_pin(nid))
5303 continue;
5304 /* search for an empty channel */
5305 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5306 if (!assigned[j]) {
dda14410 5307 spec->private_dac_nids[i] =
f12ab1e0 5308 alc880_idx_to_dac(j);
e9edcee0
TI
5309 assigned[j] = 1;
5310 break;
5311 }
5312 }
5313 }
5314 spec->multiout.num_dacs = cfg->line_outs;
5315 return 0;
5316}
5317
ce764ab2 5318static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5319 bool can_be_master)
5320{
ce764ab2
TI
5321 struct auto_pin_cfg *cfg = &spec->autocfg;
5322
5323 if (cfg->line_outs == 1 && !spec->multi_ios &&
5324 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5325 return "Master";
5326
5327 switch (cfg->line_out_type) {
5328 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5329 if (cfg->line_outs == 1)
5330 return "Speaker";
5331 break;
bcb2f0f5
TI
5332 case AUTO_PIN_HP_OUT:
5333 return "Headphone";
5334 default:
ce764ab2 5335 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5336 return "PCM";
5337 break;
5338 }
5339 return NULL;
5340}
5341
e9edcee0 5342/* add playback controls from the parsed DAC table */
df694daa
KY
5343static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5344 const struct auto_pin_cfg *cfg)
e9edcee0 5345{
ea734963 5346 static const char * const chname[4] = {
f12ab1e0
TI
5347 "Front", "Surround", NULL /*CLFE*/, "Side"
5348 };
ce764ab2 5349 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5350 hda_nid_t nid;
ce764ab2 5351 int i, err, noutputs;
e9edcee0 5352
ce764ab2
TI
5353 noutputs = cfg->line_outs;
5354 if (spec->multi_ios > 0)
5355 noutputs += spec->multi_ios;
5356
5357 for (i = 0; i < noutputs; i++) {
f12ab1e0 5358 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5359 continue;
5360 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5361 if (!pfx && i == 2) {
e9edcee0 5362 /* Center/LFE */
0afe5f89
TI
5363 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5364 "Center",
f12ab1e0
TI
5365 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5366 HDA_OUTPUT));
5367 if (err < 0)
e9edcee0 5368 return err;
0afe5f89
TI
5369 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5370 "LFE",
f12ab1e0
TI
5371 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5372 HDA_OUTPUT));
5373 if (err < 0)
e9edcee0 5374 return err;
0afe5f89
TI
5375 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5376 "Center",
f12ab1e0
TI
5377 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5378 HDA_INPUT));
5379 if (err < 0)
e9edcee0 5380 return err;
0afe5f89
TI
5381 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5382 "LFE",
f12ab1e0
TI
5383 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5384 HDA_INPUT));
5385 if (err < 0)
e9edcee0
TI
5386 return err;
5387 } else {
bcb2f0f5 5388 const char *name = pfx;
7e59e097
DH
5389 int index = i;
5390 if (!name) {
bcb2f0f5 5391 name = chname[i];
7e59e097
DH
5392 index = 0;
5393 }
bcb2f0f5 5394 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5395 name, index,
f12ab1e0
TI
5396 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5397 HDA_OUTPUT));
5398 if (err < 0)
e9edcee0 5399 return err;
bcb2f0f5 5400 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5401 name, index,
f12ab1e0
TI
5402 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5403 HDA_INPUT));
5404 if (err < 0)
e9edcee0
TI
5405 return err;
5406 }
5407 }
e9edcee0
TI
5408 return 0;
5409}
5410
8d88bc3d
TI
5411/* add playback controls for speaker and HP outputs */
5412static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5413 const char *pfx)
e9edcee0
TI
5414{
5415 hda_nid_t nid;
5416 int err;
5417
f12ab1e0 5418 if (!pin)
e9edcee0
TI
5419 return 0;
5420
5421 if (alc880_is_fixed_pin(pin)) {
5422 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5423 /* specify the DAC as the extra output */
f12ab1e0 5424 if (!spec->multiout.hp_nid)
e9edcee0 5425 spec->multiout.hp_nid = nid;
82bc955f
TI
5426 else
5427 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5428 /* control HP volume/switch on the output mixer amp */
5429 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5430 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5431 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5432 if (err < 0)
e9edcee0 5433 return err;
0afe5f89 5434 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5435 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5436 if (err < 0)
e9edcee0
TI
5437 return err;
5438 } else if (alc880_is_multi_pin(pin)) {
5439 /* set manual connection */
e9edcee0 5440 /* we have only a switch on HP-out PIN */
0afe5f89 5441 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5442 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5443 if (err < 0)
e9edcee0
TI
5444 return err;
5445 }
5446 return 0;
5447}
5448
5449/* create input playback/capture controls for the given pin */
f12ab1e0 5450static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5451 const char *ctlname, int ctlidx,
df694daa 5452 int idx, hda_nid_t mix_nid)
e9edcee0 5453{
df694daa 5454 int err;
e9edcee0 5455
66ceeb6b 5456 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5457 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5458 if (err < 0)
e9edcee0 5459 return err;
66ceeb6b 5460 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5461 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5462 if (err < 0)
e9edcee0
TI
5463 return err;
5464 return 0;
5465}
5466
05f5f477
TI
5467static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5468{
5469 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5470 return (pincap & AC_PINCAP_IN) != 0;
5471}
5472
e9edcee0 5473/* create playback/capture controls for input pins */
05f5f477
TI
5474static int alc_auto_create_input_ctls(struct hda_codec *codec,
5475 const struct auto_pin_cfg *cfg,
5476 hda_nid_t mixer,
5477 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5478{
05f5f477 5479 struct alc_spec *spec = codec->spec;
61b9b9b1 5480 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5481 int i, err, idx, type_idx = 0;
5482 const char *prev_label = NULL;
e9edcee0 5483
66ceeb6b 5484 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5485 hda_nid_t pin;
10a20af7 5486 const char *label;
05f5f477 5487
66ceeb6b 5488 pin = cfg->inputs[i].pin;
05f5f477
TI
5489 if (!alc_is_input_pin(codec, pin))
5490 continue;
5491
5322bf27
DH
5492 label = hda_get_autocfg_input_label(codec, cfg, i);
5493 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5494 type_idx++;
5495 else
5496 type_idx = 0;
5322bf27
DH
5497 prev_label = label;
5498
05f5f477
TI
5499 if (mixer) {
5500 idx = get_connection_index(codec, mixer, pin);
5501 if (idx >= 0) {
5502 err = new_analog_input(spec, pin,
10a20af7
TI
5503 label, type_idx,
5504 idx, mixer);
05f5f477
TI
5505 if (err < 0)
5506 return err;
5507 }
5508 }
5509
5510 if (!cap1)
5511 continue;
5512 idx = get_connection_index(codec, cap1, pin);
5513 if (idx < 0 && cap2)
5514 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5515 if (idx >= 0)
5516 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5517 }
5518 return 0;
5519}
5520
05f5f477
TI
5521static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5522 const struct auto_pin_cfg *cfg)
5523{
5524 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5525}
5526
f6c7e546
TI
5527static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5528 unsigned int pin_type)
5529{
5530 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5531 pin_type);
5532 /* unmute pin */
d260cdf6
TI
5533 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5534 AMP_OUT_UNMUTE);
f6c7e546
TI
5535}
5536
df694daa
KY
5537static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5538 hda_nid_t nid, int pin_type,
e9edcee0
TI
5539 int dac_idx)
5540{
f6c7e546 5541 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5542 /* need the manual connection? */
5543 if (alc880_is_multi_pin(nid)) {
5544 struct alc_spec *spec = codec->spec;
5545 int idx = alc880_multi_pin_idx(nid);
5546 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5547 AC_VERB_SET_CONNECT_SEL,
5548 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5549 }
5550}
5551
baba8ee9
TI
5552static int get_pin_type(int line_out_type)
5553{
5554 if (line_out_type == AUTO_PIN_HP_OUT)
5555 return PIN_HP;
5556 else
5557 return PIN_OUT;
5558}
5559
e9edcee0
TI
5560static void alc880_auto_init_multi_out(struct hda_codec *codec)
5561{
5562 struct alc_spec *spec = codec->spec;
5563 int i;
ea1fb29a 5564
e9edcee0
TI
5565 for (i = 0; i < spec->autocfg.line_outs; i++) {
5566 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5567 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5568 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5569 }
5570}
5571
8d88bc3d 5572static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5573{
5574 struct alc_spec *spec = codec->spec;
5575 hda_nid_t pin;
5576
82bc955f 5577 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5578 if (pin) /* connect to front */
5579 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5580 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5581 if (pin) /* connect to front */
5582 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5583}
5584
5585static void alc880_auto_init_analog_input(struct hda_codec *codec)
5586{
5587 struct alc_spec *spec = codec->spec;
66ceeb6b 5588 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5589 int i;
5590
66ceeb6b
TI
5591 for (i = 0; i < cfg->num_inputs; i++) {
5592 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5593 if (alc_is_input_pin(codec, nid)) {
30ea098f 5594 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5595 if (nid != ALC880_PIN_CD_NID &&
5596 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5597 snd_hda_codec_write(codec, nid, 0,
5598 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5599 AMP_OUT_MUTE);
5600 }
5601 }
5602}
5603
7f311a46
TI
5604static void alc880_auto_init_input_src(struct hda_codec *codec)
5605{
5606 struct alc_spec *spec = codec->spec;
5607 int c;
5608
5609 for (c = 0; c < spec->num_adc_nids; c++) {
5610 unsigned int mux_idx;
5611 const struct hda_input_mux *imux;
5612 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5613 imux = &spec->input_mux[mux_idx];
5614 if (!imux->num_items && mux_idx > 0)
5615 imux = &spec->input_mux[0];
5616 if (imux)
5617 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5618 AC_VERB_SET_CONNECT_SEL,
5619 imux->items[0].index);
5620 }
5621}
5622
ce764ab2
TI
5623static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5624
e9edcee0 5625/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5626/* return 1 if successful, 0 if the proper config is not found,
5627 * or a negative error code
5628 */
e9edcee0
TI
5629static int alc880_parse_auto_config(struct hda_codec *codec)
5630{
5631 struct alc_spec *spec = codec->spec;
757899ac 5632 int err;
4c6d72d1 5633 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5634
f12ab1e0
TI
5635 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5636 alc880_ignore);
5637 if (err < 0)
e9edcee0 5638 return err;
f12ab1e0 5639 if (!spec->autocfg.line_outs)
e9edcee0 5640 return 0; /* can't find valid BIOS pin config */
df694daa 5641
f12ab1e0 5642 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5643 if (err < 0)
5644 return err;
5645 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5646 if (err < 0)
5647 return err;
5648 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5649 if (err < 0)
5650 return err;
5651 err = alc880_auto_create_extra_out(spec,
5652 spec->autocfg.speaker_pins[0],
5653 "Speaker");
5654 if (err < 0)
5655 return err;
5656 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5657 "Headphone");
5658 if (err < 0)
5659 return err;
05f5f477 5660 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5661 if (err < 0)
e9edcee0
TI
5662 return err;
5663
5664 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5665
757899ac 5666 alc_auto_parse_digital(codec);
e9edcee0 5667
603c4019 5668 if (spec->kctls.list)
d88897ea 5669 add_mixer(spec, spec->kctls.list);
e9edcee0 5670
d88897ea 5671 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5672
a1e8d2da 5673 spec->num_mux_defs = 1;
61b9b9b1 5674 spec->input_mux = &spec->private_imux[0];
e9edcee0 5675
6227cdce 5676 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5677
e9edcee0
TI
5678 return 1;
5679}
5680
ae6b813a
TI
5681/* additional initialization for auto-configuration model */
5682static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5683{
f6c7e546 5684 struct alc_spec *spec = codec->spec;
e9edcee0 5685 alc880_auto_init_multi_out(codec);
8d88bc3d 5686 alc880_auto_init_extra_out(codec);
e9edcee0 5687 alc880_auto_init_analog_input(codec);
7f311a46 5688 alc880_auto_init_input_src(codec);
757899ac 5689 alc_auto_init_digital(codec);
f6c7e546 5690 if (spec->unsol_event)
7fb0d78f 5691 alc_inithook(codec);
e9edcee0
TI
5692}
5693
b59bdf3b
TI
5694/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5695 * one of two digital mic pins, e.g. on ALC272
5696 */
5697static void fixup_automic_adc(struct hda_codec *codec)
5698{
5699 struct alc_spec *spec = codec->spec;
5700 int i;
5701
5702 for (i = 0; i < spec->num_adc_nids; i++) {
5703 hda_nid_t cap = spec->capsrc_nids ?
5704 spec->capsrc_nids[i] : spec->adc_nids[i];
5705 int iidx, eidx;
5706
5707 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5708 if (iidx < 0)
5709 continue;
5710 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5711 if (eidx < 0)
5712 continue;
5713 spec->int_mic.mux_idx = iidx;
5714 spec->ext_mic.mux_idx = eidx;
5715 if (spec->capsrc_nids)
5716 spec->capsrc_nids += i;
5717 spec->adc_nids += i;
5718 spec->num_adc_nids = 1;
5719 return;
5720 }
5721 snd_printd(KERN_INFO "hda_codec: %s: "
5722 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5723 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5724 spec->auto_mic = 0; /* disable auto-mic to be sure */
5725}
5726
748cce43
TI
5727/* select or unmute the given capsrc route */
5728static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5729 int idx)
5730{
5731 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5732 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5733 HDA_AMP_MUTE, 0);
5734 } else {
5735 snd_hda_codec_write_cache(codec, cap, 0,
5736 AC_VERB_SET_CONNECT_SEL, idx);
5737 }
5738}
5739
840b64c0
TI
5740/* set the default connection to that pin */
5741static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5742{
5743 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5744 int i;
5745
eaa9b3a7
TI
5746 for (i = 0; i < spec->num_adc_nids; i++) {
5747 hda_nid_t cap = spec->capsrc_nids ?
5748 spec->capsrc_nids[i] : spec->adc_nids[i];
5749 int idx;
5750
5751 idx = get_connection_index(codec, cap, pin);
5752 if (idx < 0)
5753 continue;
748cce43 5754 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5755 return i; /* return the found index */
5756 }
5757 return -1; /* not found */
5758}
5759
5760/* choose the ADC/MUX containing the input pin and initialize the setup */
5761static void fixup_single_adc(struct hda_codec *codec)
5762{
5763 struct alc_spec *spec = codec->spec;
66ceeb6b 5764 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5765 int i;
5766
5767 /* search for the input pin; there must be only one */
66ceeb6b 5768 if (cfg->num_inputs != 1)
eaa9b3a7 5769 return;
66ceeb6b 5770 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5771 if (i >= 0) {
5772 /* use only this ADC */
5773 if (spec->capsrc_nids)
5774 spec->capsrc_nids += i;
5775 spec->adc_nids += i;
5776 spec->num_adc_nids = 1;
584c0c4c 5777 spec->single_input_src = 1;
eaa9b3a7
TI
5778 }
5779}
5780
840b64c0
TI
5781/* initialize dual adcs */
5782static void fixup_dual_adc_switch(struct hda_codec *codec)
5783{
5784 struct alc_spec *spec = codec->spec;
5785 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5786 init_capsrc_for_pin(codec, spec->int_mic.pin);
5787}
5788
584c0c4c
TI
5789/* initialize some special cases for input sources */
5790static void alc_init_special_input_src(struct hda_codec *codec)
5791{
5792 struct alc_spec *spec = codec->spec;
5793 if (spec->dual_adc_switch)
5794 fixup_dual_adc_switch(codec);
5795 else if (spec->single_input_src)
5796 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5797}
5798
b59bdf3b 5799static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5800{
b59bdf3b 5801 struct alc_spec *spec = codec->spec;
a9111321 5802 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5803 { alc_capture_mixer_nosrc1,
5804 alc_capture_mixer_nosrc2,
5805 alc_capture_mixer_nosrc3 },
5806 { alc_capture_mixer1,
5807 alc_capture_mixer2,
5808 alc_capture_mixer3 },
f9e336f6 5809 };
a23b688f 5810 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5811 int mux = 0;
840b64c0
TI
5812 int num_adcs = spec->num_adc_nids;
5813 if (spec->dual_adc_switch)
584c0c4c 5814 num_adcs = 1;
840b64c0 5815 else if (spec->auto_mic)
b59bdf3b 5816 fixup_automic_adc(codec);
eaa9b3a7
TI
5817 else if (spec->input_mux) {
5818 if (spec->input_mux->num_items > 1)
5819 mux = 1;
5820 else if (spec->input_mux->num_items == 1)
5821 fixup_single_adc(codec);
5822 }
840b64c0 5823 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5824 }
f9e336f6
TI
5825}
5826
6694635d 5827/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5828static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5829 int num_nids)
5830{
5831 struct alc_spec *spec = codec->spec;
66ceeb6b 5832 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5833 int n;
5834 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5835
5836 for (n = 0; n < num_nids; n++) {
5837 hda_nid_t adc, cap;
5838 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5839 int nconns, i, j;
5840
5841 adc = nids[n];
5842 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5843 continue;
5844 cap = adc;
5845 nconns = snd_hda_get_connections(codec, cap, conn,
5846 ARRAY_SIZE(conn));
5847 if (nconns == 1) {
5848 cap = conn[0];
5849 nconns = snd_hda_get_connections(codec, cap, conn,
5850 ARRAY_SIZE(conn));
5851 }
5852 if (nconns <= 0)
5853 continue;
5854 if (!fallback_adc) {
5855 fallback_adc = adc;
5856 fallback_cap = cap;
5857 }
66ceeb6b
TI
5858 for (i = 0; i < cfg->num_inputs; i++) {
5859 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5860 for (j = 0; j < nconns; j++) {
5861 if (conn[j] == nid)
5862 break;
5863 }
5864 if (j >= nconns)
5865 break;
5866 }
66ceeb6b 5867 if (i >= cfg->num_inputs) {
6694635d
TI
5868 int num_adcs = spec->num_adc_nids;
5869 spec->private_adc_nids[num_adcs] = adc;
5870 spec->private_capsrc_nids[num_adcs] = cap;
5871 spec->num_adc_nids++;
5872 spec->adc_nids = spec->private_adc_nids;
5873 if (adc != cap)
5874 spec->capsrc_nids = spec->private_capsrc_nids;
5875 }
5876 }
5877 if (!spec->num_adc_nids) {
5878 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5879 " using fallback 0x%x\n",
5880 codec->chip_name, fallback_adc);
6694635d
TI
5881 spec->private_adc_nids[0] = fallback_adc;
5882 spec->adc_nids = spec->private_adc_nids;
5883 if (fallback_adc != fallback_cap) {
5884 spec->private_capsrc_nids[0] = fallback_cap;
5885 spec->capsrc_nids = spec->private_adc_nids;
5886 }
5887 }
5888}
5889
67d634c0 5890#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5891#define set_beep_amp(spec, nid, idx, dir) \
5892 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5893
a9111321 5894static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5895 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5896 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5897 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
e096c8e6 5898 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5899 {}
5900};
5901
5902static inline int has_cdefine_beep(struct hda_codec *codec)
5903{
5904 struct alc_spec *spec = codec->spec;
5905 const struct snd_pci_quirk *q;
5906 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5907 if (q)
5908 return q->value;
5909 return spec->cdefine.enable_pcbeep;
5910}
67d634c0
TI
5911#else
5912#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5913#define has_cdefine_beep(codec) 0
67d634c0 5914#endif
45bdd1c1
TI
5915
5916/*
5917 * OK, here we have finally the patch for ALC880
5918 */
5919
1da177e4
LT
5920static int patch_alc880(struct hda_codec *codec)
5921{
5922 struct alc_spec *spec;
5923 int board_config;
df694daa 5924 int err;
1da177e4 5925
e560d8d8 5926 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5927 if (spec == NULL)
5928 return -ENOMEM;
5929
5930 codec->spec = spec;
5931
f5fcc13c
TI
5932 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5933 alc880_models,
5934 alc880_cfg_tbl);
5935 if (board_config < 0) {
9a11f1aa
TI
5936 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5937 codec->chip_name);
e9edcee0 5938 board_config = ALC880_AUTO;
1da177e4 5939 }
1da177e4 5940
e9edcee0
TI
5941 if (board_config == ALC880_AUTO) {
5942 /* automatic parse from the BIOS config */
5943 err = alc880_parse_auto_config(codec);
5944 if (err < 0) {
5945 alc_free(codec);
5946 return err;
f12ab1e0 5947 } else if (!err) {
9c7f852e
TI
5948 printk(KERN_INFO
5949 "hda_codec: Cannot set up configuration "
5950 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5951 board_config = ALC880_3ST;
5952 }
1da177e4
LT
5953 }
5954
680cd536
KK
5955 err = snd_hda_attach_beep_device(codec, 0x1);
5956 if (err < 0) {
5957 alc_free(codec);
5958 return err;
5959 }
5960
df694daa 5961 if (board_config != ALC880_AUTO)
e9c364c0 5962 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5963
1da177e4
LT
5964 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5965 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5966 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5967
1da177e4
LT
5968 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5969 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5970
f12ab1e0 5971 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5972 /* check whether NID 0x07 is valid */
54d17403 5973 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5974 /* get type */
a22d543a 5975 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5976 if (wcap != AC_WID_AUD_IN) {
5977 spec->adc_nids = alc880_adc_nids_alt;
5978 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5979 } else {
5980 spec->adc_nids = alc880_adc_nids;
5981 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5982 }
5983 }
b59bdf3b 5984 set_capture_mixer(codec);
45bdd1c1 5985 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5986
2134ea4f
TI
5987 spec->vmaster_nid = 0x0c;
5988
1da177e4 5989 codec->patch_ops = alc_patch_ops;
e9edcee0 5990 if (board_config == ALC880_AUTO)
ae6b813a 5991 spec->init_hook = alc880_auto_init;
cb53c626
TI
5992#ifdef CONFIG_SND_HDA_POWER_SAVE
5993 if (!spec->loopback.amplist)
5994 spec->loopback.amplist = alc880_loopbacks;
5995#endif
1da177e4
LT
5996
5997 return 0;
5998}
5999
e9edcee0 6000
1da177e4
LT
6001/*
6002 * ALC260 support
6003 */
6004
4c6d72d1 6005static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6006 /* front */
6007 0x02,
6008};
6009
4c6d72d1 6010static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6011 /* ADC0 */
6012 0x04,
6013};
6014
4c6d72d1 6015static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6016 /* ADC1 */
6017 0x05,
6018};
6019
d57fdac0
JW
6020/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6021 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6022 */
4c6d72d1 6023static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6024 /* ADC0, ADC1 */
6025 0x04, 0x05
6026};
6027
e9edcee0
TI
6028#define ALC260_DIGOUT_NID 0x03
6029#define ALC260_DIGIN_NID 0x06
6030
a9111321 6031static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6032 .num_items = 4,
6033 .items = {
6034 { "Mic", 0x0 },
6035 { "Front Mic", 0x1 },
6036 { "Line", 0x2 },
6037 { "CD", 0x4 },
6038 },
6039};
6040
17e7aec6 6041/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6042 * headphone jack and the internal CD lines since these are the only pins at
6043 * which audio can appear. For flexibility, also allow the option of
6044 * recording the mixer output on the second ADC (ADC0 doesn't have a
6045 * connection to the mixer output).
a9430dd8 6046 */
a9111321 6047static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6048 {
6049 .num_items = 3,
6050 .items = {
6051 { "Mic/Line", 0x0 },
6052 { "CD", 0x4 },
6053 { "Headphone", 0x2 },
6054 },
a9430dd8 6055 },
a1e8d2da
JW
6056 {
6057 .num_items = 4,
6058 .items = {
6059 { "Mic/Line", 0x0 },
6060 { "CD", 0x4 },
6061 { "Headphone", 0x2 },
6062 { "Mixer", 0x5 },
6063 },
6064 },
6065
a9430dd8
JW
6066};
6067
a1e8d2da
JW
6068/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6069 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6070 */
a9111321 6071static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6072 {
6073 .num_items = 4,
6074 .items = {
6075 { "Mic", 0x0 },
6076 { "Line", 0x2 },
6077 { "CD", 0x4 },
6078 { "Headphone", 0x5 },
6079 },
6080 },
6081 {
6082 .num_items = 5,
6083 .items = {
6084 { "Mic", 0x0 },
6085 { "Line", 0x2 },
6086 { "CD", 0x4 },
6087 { "Headphone", 0x6 },
6088 { "Mixer", 0x5 },
6089 },
0bfc90e9
JW
6090 },
6091};
cc959489
MS
6092
6093/* Maxdata Favorit 100XS */
a9111321 6094static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6095 {
6096 .num_items = 2,
6097 .items = {
6098 { "Line/Mic", 0x0 },
6099 { "CD", 0x4 },
6100 },
6101 },
6102 {
6103 .num_items = 3,
6104 .items = {
6105 { "Line/Mic", 0x0 },
6106 { "CD", 0x4 },
6107 { "Mixer", 0x5 },
6108 },
6109 },
6110};
6111
1da177e4
LT
6112/*
6113 * This is just place-holder, so there's something for alc_build_pcms to look
6114 * at when it calculates the maximum number of channels. ALC260 has no mixer
6115 * element which allows changing the channel mode, so the verb list is
6116 * never used.
6117 */
a9111321 6118static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6119 { 2, NULL },
6120};
6121
df694daa
KY
6122
6123/* Mixer combinations
6124 *
6125 * basic: base_output + input + pc_beep + capture
6126 * HP: base_output + input + capture_alt
6127 * HP_3013: hp_3013 + input + capture
6128 * fujitsu: fujitsu + capture
0bfc90e9 6129 * acer: acer + capture
df694daa
KY
6130 */
6131
a9111321 6132static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6133 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6134 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6136 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6137 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6138 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6139 { } /* end */
f12ab1e0 6140};
1da177e4 6141
a9111321 6142static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6143 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6144 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6145 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6146 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6147 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6148 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6149 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6151 { } /* end */
6152};
6153
bec15c3a 6154/* update HP, line and mono out pins according to the master switch */
e9427969 6155static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a
TI
6156{
6157 struct alc_spec *spec = codec->spec;
e9427969
TI
6158
6159 /* change HP pins */
6160 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
6161 spec->autocfg.hp_pins, spec->master_mute, true);
6162 update_speakers(codec);
bec15c3a
TI
6163}
6164
6165static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6166 struct snd_ctl_elem_value *ucontrol)
6167{
6168 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6169 struct alc_spec *spec = codec->spec;
e9427969 6170 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6171 return 0;
6172}
6173
6174static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6175 struct snd_ctl_elem_value *ucontrol)
6176{
6177 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6178 struct alc_spec *spec = codec->spec;
e9427969 6179 int val = !*ucontrol->value.integer.value;
bec15c3a 6180
e9427969 6181 if (val == spec->master_mute)
bec15c3a 6182 return 0;
e9427969
TI
6183 spec->master_mute = val;
6184 alc260_hp_master_update(codec);
bec15c3a
TI
6185 return 1;
6186}
6187
a9111321 6188static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6189 {
6190 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6191 .name = "Master Playback Switch",
5b0cb1d8 6192 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6193 .info = snd_ctl_boolean_mono_info,
6194 .get = alc260_hp_master_sw_get,
6195 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6196 },
6197 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6198 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6199 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6200 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6201 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6202 HDA_OUTPUT),
6203 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6204 { } /* end */
6205};
6206
a9111321 6207static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6208 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6209 {},
6210};
6211
e9427969 6212static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6213{
6214 struct alc_spec *spec = codec->spec;
bec15c3a 6215
e9427969
TI
6216 spec->autocfg.hp_pins[0] = 0x0f;
6217 spec->autocfg.speaker_pins[0] = 0x10;
6218 spec->autocfg.speaker_pins[1] = 0x11;
6219 spec->automute = 1;
6220 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6221}
6222
a9111321 6223static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6224 {
6225 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6226 .name = "Master Playback Switch",
5b0cb1d8 6227 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6228 .info = snd_ctl_boolean_mono_info,
6229 .get = alc260_hp_master_sw_get,
6230 .put = alc260_hp_master_sw_put,
bec15c3a 6231 },
df694daa
KY
6232 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6233 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6234 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6235 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6236 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6237 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6238 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6239 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6240 { } /* end */
6241};
6242
e9427969
TI
6243static void alc260_hp_3013_setup(struct hda_codec *codec)
6244{
6245 struct alc_spec *spec = codec->spec;
6246
6247 spec->autocfg.hp_pins[0] = 0x15;
6248 spec->autocfg.speaker_pins[0] = 0x10;
6249 spec->autocfg.speaker_pins[1] = 0x11;
6250 spec->automute = 1;
6251 spec->automute_mode = ALC_AUTOMUTE_PIN;
6252}
6253
a9111321 6254static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6255 .ops = &snd_hda_bind_vol,
6256 .values = {
6257 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6258 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6259 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6260 0
6261 },
6262};
6263
a9111321 6264static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6265 .ops = &snd_hda_bind_sw,
6266 .values = {
6267 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6268 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6269 0
6270 },
6271};
6272
a9111321 6273static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6274 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6275 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6276 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6278 { } /* end */
6279};
6280
a9111321 6281static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6282 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6283 {},
6284};
6285
e9427969 6286static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6287{
6288 struct alc_spec *spec = codec->spec;
bec15c3a 6289
e9427969
TI
6290 spec->autocfg.hp_pins[0] = 0x10;
6291 spec->autocfg.speaker_pins[0] = 0x0f;
6292 spec->autocfg.speaker_pins[1] = 0x11;
6293 spec->autocfg.speaker_pins[2] = 0x15;
6294 spec->automute = 1;
6295 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6296}
6297
6298/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6299 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6300 */
a9111321 6301static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6302 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6303 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6304 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6305 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6306 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6307 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6308 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6309 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6310 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6311 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6312 { } /* end */
6313};
6314
a1e8d2da
JW
6315/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6316 * versions of the ALC260 don't act on requests to enable mic bias from NID
6317 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6318 * datasheet doesn't mention this restriction. At this stage it's not clear
6319 * whether this behaviour is intentional or is a hardware bug in chip
6320 * revisions available in early 2006. Therefore for now allow the
6321 * "Headphone Jack Mode" control to span all choices, but if it turns out
6322 * that the lack of mic bias for this NID is intentional we could change the
6323 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6324 *
6325 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6326 * don't appear to make the mic bias available from the "line" jack, even
6327 * though the NID used for this jack (0x14) can supply it. The theory is
6328 * that perhaps Acer have included blocking capacitors between the ALC260
6329 * and the output jack. If this turns out to be the case for all such
6330 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6331 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6332 *
6333 * The C20x Tablet series have a mono internal speaker which is controlled
6334 * via the chip's Mono sum widget and pin complex, so include the necessary
6335 * controls for such models. On models without a "mono speaker" the control
6336 * won't do anything.
a1e8d2da 6337 */
a9111321 6338static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6339 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6340 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6341 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6342 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6343 HDA_OUTPUT),
31bffaa9 6344 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6345 HDA_INPUT),
0bfc90e9
JW
6346 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6347 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6348 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6349 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6350 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6351 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6352 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6353 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6354 { } /* end */
6355};
6356
cc959489
MS
6357/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6358 */
a9111321 6359static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6360 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6361 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6362 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6363 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6364 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6365 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6366 { } /* end */
6367};
6368
bc9f98a9
KY
6369/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6370 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6371 */
a9111321 6372static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6373 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6374 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6376 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6377 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6378 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6379 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6380 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6381 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6382 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6383 { } /* end */
6384};
6385
6386/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6387 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6388 */
a9111321 6389static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6390 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6391 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6393 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6394 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6395 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6396 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6397 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6398 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6399 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6400 { } /* end */
6401};
6402
df694daa
KY
6403/*
6404 * initialization verbs
6405 */
a9111321 6406static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6407 /* Line In pin widget for input */
05acb863 6408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6409 /* CD pin widget for input */
05acb863 6410 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6411 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6412 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6413 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6414 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6415 /* LINE-2 is used for line-out in rear */
05acb863 6416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6417 /* select line-out */
fd56f2db 6418 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6419 /* LINE-OUT pin */
05acb863 6420 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6421 /* enable HP */
05acb863 6422 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6423 /* enable Mono */
05acb863
TI
6424 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6425 /* mute capture amp left and right */
16ded525 6426 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6427 /* set connection select to line in (default select for this ADC) */
6428 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6429 /* mute capture amp left and right */
6430 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6431 /* set connection select to line in (default select for this ADC) */
6432 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6433 /* set vol=0 Line-Out mixer amp left and right */
6434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6435 /* unmute pin widget amp left and right (no gain on this amp) */
6436 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6437 /* set vol=0 HP mixer amp left and right */
6438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6439 /* unmute pin widget amp left and right (no gain on this amp) */
6440 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6441 /* set vol=0 Mono mixer amp left and right */
6442 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6443 /* unmute pin widget amp left and right (no gain on this amp) */
6444 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6445 /* unmute LINE-2 out pin */
6446 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6447 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6448 * Line In 2 = 0x03
6449 */
cb53c626
TI
6450 /* mute analog inputs */
6451 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6452 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6456 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6457 /* mute Front out path */
6458 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6459 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6460 /* mute Headphone out path */
6461 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6463 /* mute Mono out path */
6464 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6465 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6466 { }
6467};
6468
474167d6 6469#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6470static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6471 /* Headphone and output */
6472 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6473 /* mono output */
6474 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6475 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6476 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6477 /* Mic2 (front panel) pin widget for input and vref at 80% */
6478 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6479 /* Line In pin widget for input */
6480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6481 /* Line-2 pin widget for output */
6482 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6483 /* CD pin widget for input */
6484 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6485 /* unmute amp left and right */
6486 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6487 /* set connection select to line in (default select for this ADC) */
6488 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6489 /* unmute Line-Out mixer amp left and right (volume = 0) */
6490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6491 /* mute pin widget amp left and right (no gain on this amp) */
6492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6493 /* unmute HP mixer amp left and right (volume = 0) */
6494 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6495 /* mute pin widget amp left and right (no gain on this amp) */
6496 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6497 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6498 * Line In 2 = 0x03
6499 */
cb53c626
TI
6500 /* mute analog inputs */
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6506 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6507 /* Unmute Front out path */
6508 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6509 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6510 /* Unmute Headphone out path */
6511 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6512 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6513 /* Unmute Mono out path */
6514 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6515 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6516 { }
6517};
474167d6 6518#endif
df694daa 6519
a9111321 6520static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6521 /* Line out and output */
6522 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6523 /* mono output */
6524 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6525 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6526 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6527 /* Mic2 (front panel) pin widget for input and vref at 80% */
6528 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6529 /* Line In pin widget for input */
6530 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6531 /* Headphone pin widget for output */
6532 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6533 /* CD pin widget for input */
6534 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6535 /* unmute amp left and right */
6536 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6537 /* set connection select to line in (default select for this ADC) */
6538 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6539 /* unmute Line-Out mixer amp left and right (volume = 0) */
6540 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6541 /* mute pin widget amp left and right (no gain on this amp) */
6542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6543 /* unmute HP mixer amp left and right (volume = 0) */
6544 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6545 /* mute pin widget amp left and right (no gain on this amp) */
6546 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6547 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6548 * Line In 2 = 0x03
6549 */
cb53c626
TI
6550 /* mute analog inputs */
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6556 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6557 /* Unmute Front out path */
6558 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6559 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6560 /* Unmute Headphone out path */
6561 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6562 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6563 /* Unmute Mono out path */
6564 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6565 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6566 { }
6567};
6568
a9430dd8 6569/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6570 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6571 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6572 */
a9111321 6573static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6574 /* Disable all GPIOs */
6575 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6576 /* Internal speaker is connected to headphone pin */
6577 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6578 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6579 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6580 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6581 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6582 /* Ensure all other unused pins are disabled and muted. */
6583 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6584 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6585 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6586 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6587 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6588 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6591
6592 /* Disable digital (SPDIF) pins */
6593 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6594 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6595
ea1fb29a 6596 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6597 * when acting as an output.
6598 */
6599 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6600
f7ace40d 6601 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6602 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6603 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6605 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6606 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6607 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6608 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6609 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6610 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6611
f7ace40d
JW
6612 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6613 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6614 /* Unmute Line1 pin widget output buffer since it starts as an output.
6615 * If the pin mode is changed by the user the pin mode control will
6616 * take care of enabling the pin's input/output buffers as needed.
6617 * Therefore there's no need to enable the input buffer at this
6618 * stage.
cdcd9268 6619 */
f7ace40d 6620 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6621 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6622 * mixer ctrl)
6623 */
f7ace40d
JW
6624 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6625
6626 /* Mute capture amp left and right */
6627 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6628 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6629 * in (on mic1 pin)
6630 */
6631 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6632
6633 /* Do the same for the second ADC: mute capture input amp and
6634 * set ADC connection to line in (on mic1 pin)
6635 */
6636 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6637 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6638
6639 /* Mute all inputs to mixer widget (even unconnected ones) */
6640 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6641 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6645 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6647 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6648
6649 { }
a9430dd8
JW
6650};
6651
0bfc90e9
JW
6652/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6653 * similar laptops (adapted from Fujitsu init verbs).
6654 */
a9111321 6655static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6656 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6657 * the headphone jack. Turn this on and rely on the standard mute
6658 * methods whenever the user wants to turn these outputs off.
6659 */
6660 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6661 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6662 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6663 /* Internal speaker/Headphone jack is connected to Line-out pin */
6664 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6665 /* Internal microphone/Mic jack is connected to Mic1 pin */
6666 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6667 /* Line In jack is connected to Line1 pin */
6668 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6669 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6670 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6671 /* Ensure all other unused pins are disabled and muted. */
6672 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6673 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6674 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6675 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6676 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6677 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6678 /* Disable digital (SPDIF) pins */
6679 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6680 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6681
ea1fb29a 6682 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6683 * bus when acting as outputs.
6684 */
6685 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6686 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6687
6688 /* Start with output sum widgets muted and their output gains at min */
6689 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6690 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6691 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6692 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6693 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6694 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6695 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6696 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6697 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6698
f12ab1e0
TI
6699 /* Unmute Line-out pin widget amp left and right
6700 * (no equiv mixer ctrl)
6701 */
0bfc90e9 6702 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6703 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6704 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6705 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6706 * inputs. If the pin mode is changed by the user the pin mode control
6707 * will take care of enabling the pin's input/output buffers as needed.
6708 * Therefore there's no need to enable the input buffer at this
6709 * stage.
6710 */
6711 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6712 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6713
6714 /* Mute capture amp left and right */
6715 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6716 /* Set ADC connection select to match default mixer setting - mic
6717 * (on mic1 pin)
6718 */
6719 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6720
6721 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6722 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6723 */
6724 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6725 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6726
6727 /* Mute all inputs to mixer widget (even unconnected ones) */
6728 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6729 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6732 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6734 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6736
6737 { }
6738};
6739
cc959489
MS
6740/* Initialisation sequence for Maxdata Favorit 100XS
6741 * (adapted from Acer init verbs).
6742 */
a9111321 6743static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6744 /* GPIO 0 enables the output jack.
6745 * Turn this on and rely on the standard mute
6746 * methods whenever the user wants to turn these outputs off.
6747 */
6748 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6749 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6750 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6751 /* Line/Mic input jack is connected to Mic1 pin */
6752 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6753 /* Ensure all other unused pins are disabled and muted. */
6754 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6755 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6756 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6757 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6759 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6764 /* Disable digital (SPDIF) pins */
6765 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6766 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6767
6768 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6769 * bus when acting as outputs.
6770 */
6771 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6772 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6773
6774 /* Start with output sum widgets muted and their output gains at min */
6775 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6776 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6778 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6781 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6782 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6783 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6784
6785 /* Unmute Line-out pin widget amp left and right
6786 * (no equiv mixer ctrl)
6787 */
6788 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6789 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6790 * inputs. If the pin mode is changed by the user the pin mode control
6791 * will take care of enabling the pin's input/output buffers as needed.
6792 * Therefore there's no need to enable the input buffer at this
6793 * stage.
6794 */
6795 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6796
6797 /* Mute capture amp left and right */
6798 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6799 /* Set ADC connection select to match default mixer setting - mic
6800 * (on mic1 pin)
6801 */
6802 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6803
6804 /* Do similar with the second ADC: mute capture input amp and
6805 * set ADC connection to mic to match ALSA's default state.
6806 */
6807 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6809
6810 /* Mute all inputs to mixer widget (even unconnected ones) */
6811 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6812 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6813 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6814 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6819
6820 { }
6821};
6822
a9111321 6823static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6824 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6825 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6826 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6827 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6828 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6829 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6830 {}
6831};
6832
a9111321 6833static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6834 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6835 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6836 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6837
6838 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6839 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6840 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6841
6842 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6843 {}
6844};
6845
6846/* toggle speaker-output according to the hp-jack state */
6847static void alc260_replacer_672v_automute(struct hda_codec *codec)
6848{
6849 unsigned int present;
6850
6851 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6852 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6853 if (present) {
82beb8fd
TI
6854 snd_hda_codec_write_cache(codec, 0x01, 0,
6855 AC_VERB_SET_GPIO_DATA, 1);
6856 snd_hda_codec_write_cache(codec, 0x0f, 0,
6857 AC_VERB_SET_PIN_WIDGET_CONTROL,
6858 PIN_HP);
bc9f98a9 6859 } else {
82beb8fd
TI
6860 snd_hda_codec_write_cache(codec, 0x01, 0,
6861 AC_VERB_SET_GPIO_DATA, 0);
6862 snd_hda_codec_write_cache(codec, 0x0f, 0,
6863 AC_VERB_SET_PIN_WIDGET_CONTROL,
6864 PIN_OUT);
bc9f98a9
KY
6865 }
6866}
6867
6868static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6869 unsigned int res)
6870{
6871 if ((res >> 26) == ALC880_HP_EVENT)
6872 alc260_replacer_672v_automute(codec);
6873}
6874
a9111321 6875static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6876 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6878 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6879 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6880 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6881 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6882 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6883 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6884 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6885 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6886 {}
6887};
6888
7cf51e48
JW
6889/* Test configuration for debugging, modelled after the ALC880 test
6890 * configuration.
6891 */
6892#ifdef CONFIG_SND_DEBUG
4c6d72d1 6893static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6894 0x02,
6895};
4c6d72d1 6896static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6897 0x04, 0x05,
6898};
a1e8d2da 6899/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6900 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6901 * is NID 0x04.
17e7aec6 6902 */
a9111321 6903static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6904 {
6905 .num_items = 7,
6906 .items = {
6907 { "MIC1 pin", 0x0 },
6908 { "MIC2 pin", 0x1 },
6909 { "LINE1 pin", 0x2 },
6910 { "LINE2 pin", 0x3 },
6911 { "CD pin", 0x4 },
6912 { "LINE-OUT pin", 0x5 },
6913 { "HP-OUT pin", 0x6 },
6914 },
6915 },
6916 {
6917 .num_items = 8,
6918 .items = {
6919 { "MIC1 pin", 0x0 },
6920 { "MIC2 pin", 0x1 },
6921 { "LINE1 pin", 0x2 },
6922 { "LINE2 pin", 0x3 },
6923 { "CD pin", 0x4 },
6924 { "Mixer", 0x5 },
6925 { "LINE-OUT pin", 0x6 },
6926 { "HP-OUT pin", 0x7 },
6927 },
7cf51e48
JW
6928 },
6929};
a9111321 6930static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6931 /* Output driver widgets */
6932 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6933 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6934 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6935 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6936 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6937 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6938
a1e8d2da
JW
6939 /* Modes for retasking pin widgets
6940 * Note: the ALC260 doesn't seem to act on requests to enable mic
6941 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6942 * mention this restriction. At this stage it's not clear whether
6943 * this behaviour is intentional or is a hardware bug in chip
6944 * revisions available at least up until early 2006. Therefore for
6945 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6946 * choices, but if it turns out that the lack of mic bias for these
6947 * NIDs is intentional we could change their modes from
6948 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6949 */
7cf51e48
JW
6950 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6951 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6952 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6953 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6954 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6955 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6956
6957 /* Loopback mixer controls */
6958 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6959 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6960 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6961 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6962 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6963 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6964 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6965 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6966 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6967 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6968 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6969 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6970 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6971 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6972
6973 /* Controls for GPIO pins, assuming they are configured as outputs */
6974 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6975 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6976 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6977 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6978
92621f13
JW
6979 /* Switches to allow the digital IO pins to be enabled. The datasheet
6980 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6981 * make this output available should provide clarification.
92621f13
JW
6982 */
6983 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6984 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6985
f8225f6d
JW
6986 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6987 * this output to turn on an external amplifier.
6988 */
6989 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6990 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6991
7cf51e48
JW
6992 { } /* end */
6993};
a9111321 6994static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6995 /* Enable all GPIOs as outputs with an initial value of 0 */
6996 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6997 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6998 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6999
7cf51e48
JW
7000 /* Enable retasking pins as output, initially without power amp */
7001 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7002 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7003 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7004 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7005 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7006 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7007
92621f13
JW
7008 /* Disable digital (SPDIF) pins initially, but users can enable
7009 * them via a mixer switch. In the case of SPDIF-out, this initverb
7010 * payload also sets the generation to 0, output to be in "consumer"
7011 * PCM format, copyright asserted, no pre-emphasis and no validity
7012 * control.
7013 */
7cf51e48
JW
7014 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7015 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7016
ea1fb29a 7017 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7018 * OUT1 sum bus when acting as an output.
7019 */
7020 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7021 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7022 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7023 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7024
7025 /* Start with output sum widgets muted and their output gains at min */
7026 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7027 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7030 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7032 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7033 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7034 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7035
cdcd9268
JW
7036 /* Unmute retasking pin widget output buffers since the default
7037 * state appears to be output. As the pin mode is changed by the
7038 * user the pin mode control will take care of enabling the pin's
7039 * input/output buffers as needed.
7040 */
7cf51e48
JW
7041 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7042 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7043 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7044 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7045 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7046 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7047 /* Also unmute the mono-out pin widget */
7048 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7049
7cf51e48
JW
7050 /* Mute capture amp left and right */
7051 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7052 /* Set ADC connection select to match default mixer setting (mic1
7053 * pin)
7cf51e48
JW
7054 */
7055 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7056
7057 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7058 * set ADC connection to mic1 pin
7cf51e48
JW
7059 */
7060 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7061 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7062
7063 /* Mute all inputs to mixer widget (even unconnected ones) */
7064 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7065 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7072
7073 { }
7074};
7075#endif
7076
6330079f
TI
7077#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7078#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7079
a3bcba38
TI
7080#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7081#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7082
df694daa
KY
7083/*
7084 * for BIOS auto-configuration
7085 */
16ded525 7086
df694daa 7087static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7088 const char *pfx, int *vol_bits)
df694daa
KY
7089{
7090 hda_nid_t nid_vol;
7091 unsigned long vol_val, sw_val;
df694daa
KY
7092 int err;
7093
7094 if (nid >= 0x0f && nid < 0x11) {
7095 nid_vol = nid - 0x7;
7096 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7097 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7098 } else if (nid == 0x11) {
7099 nid_vol = nid - 0x7;
7100 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7101 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7102 } else if (nid >= 0x12 && nid <= 0x15) {
7103 nid_vol = 0x08;
7104 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7105 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7106 } else
7107 return 0; /* N/A */
ea1fb29a 7108
863b4518
TI
7109 if (!(*vol_bits & (1 << nid_vol))) {
7110 /* first control for the volume widget */
0afe5f89 7111 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7112 if (err < 0)
7113 return err;
7114 *vol_bits |= (1 << nid_vol);
7115 }
0afe5f89 7116 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7117 if (err < 0)
df694daa
KY
7118 return err;
7119 return 1;
7120}
7121
7122/* add playback controls from the parsed DAC table */
7123static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7124 const struct auto_pin_cfg *cfg)
7125{
7126 hda_nid_t nid;
7127 int err;
863b4518 7128 int vols = 0;
df694daa
KY
7129
7130 spec->multiout.num_dacs = 1;
7131 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7132 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7133
7134 nid = cfg->line_out_pins[0];
7135 if (nid) {
23112d6d
TI
7136 const char *pfx;
7137 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7138 pfx = "Master";
7139 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7140 pfx = "Speaker";
7141 else
7142 pfx = "Front";
7143 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7144 if (err < 0)
7145 return err;
7146 }
7147
82bc955f 7148 nid = cfg->speaker_pins[0];
df694daa 7149 if (nid) {
863b4518 7150 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7151 if (err < 0)
7152 return err;
7153 }
7154
eb06ed8f 7155 nid = cfg->hp_pins[0];
df694daa 7156 if (nid) {
863b4518
TI
7157 err = alc260_add_playback_controls(spec, nid, "Headphone",
7158 &vols);
df694daa
KY
7159 if (err < 0)
7160 return err;
7161 }
f12ab1e0 7162 return 0;
df694daa
KY
7163}
7164
7165/* create playback/capture controls for input pins */
05f5f477 7166static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7167 const struct auto_pin_cfg *cfg)
7168{
05f5f477 7169 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7170}
7171
7172static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7173 hda_nid_t nid, int pin_type,
7174 int sel_idx)
7175{
f6c7e546 7176 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7177 /* need the manual connection? */
7178 if (nid >= 0x12) {
7179 int idx = nid - 0x12;
7180 snd_hda_codec_write(codec, idx + 0x0b, 0,
7181 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7182 }
7183}
7184
7185static void alc260_auto_init_multi_out(struct hda_codec *codec)
7186{
7187 struct alc_spec *spec = codec->spec;
7188 hda_nid_t nid;
7189
f12ab1e0 7190 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7191 if (nid) {
7192 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7193 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7194 }
ea1fb29a 7195
82bc955f 7196 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7197 if (nid)
7198 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7199
eb06ed8f 7200 nid = spec->autocfg.hp_pins[0];
df694daa 7201 if (nid)
baba8ee9 7202 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7203}
df694daa
KY
7204
7205#define ALC260_PIN_CD_NID 0x16
7206static void alc260_auto_init_analog_input(struct hda_codec *codec)
7207{
7208 struct alc_spec *spec = codec->spec;
66ceeb6b 7209 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7210 int i;
7211
66ceeb6b
TI
7212 for (i = 0; i < cfg->num_inputs; i++) {
7213 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7214 if (nid >= 0x12) {
30ea098f 7215 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7216 if (nid != ALC260_PIN_CD_NID &&
7217 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7218 snd_hda_codec_write(codec, nid, 0,
7219 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7220 AMP_OUT_MUTE);
7221 }
7222 }
7223}
7224
7f311a46
TI
7225#define alc260_auto_init_input_src alc880_auto_init_input_src
7226
df694daa
KY
7227/*
7228 * generic initialization of ADC, input mixers and output mixers
7229 */
a9111321 7230static const struct hda_verb alc260_volume_init_verbs[] = {
df694daa
KY
7231 /*
7232 * Unmute ADC0-1 and set the default input to mic-in
7233 */
7234 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7235 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7236 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7237 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7238
df694daa
KY
7239 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7240 * mixer widget
f12ab1e0
TI
7241 * Note: PASD motherboards uses the Line In 2 as the input for
7242 * front panel mic (mic 2)
df694daa
KY
7243 */
7244 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7245 /* mute analog inputs */
7246 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7247 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7251
7252 /*
7253 * Set up output mixers (0x08 - 0x0a)
7254 */
7255 /* set vol=0 to output mixers */
7256 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7257 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7258 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7259 /* set up input amps for analog loopback */
7260 /* Amp Indices: DAC = 0, mixer = 1 */
7261 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7262 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7263 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7264 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7265 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7266 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7267
df694daa
KY
7268 { }
7269};
7270
7271static int alc260_parse_auto_config(struct hda_codec *codec)
7272{
7273 struct alc_spec *spec = codec->spec;
df694daa 7274 int err;
4c6d72d1 7275 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7276
f12ab1e0
TI
7277 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7278 alc260_ignore);
7279 if (err < 0)
df694daa 7280 return err;
f12ab1e0
TI
7281 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7282 if (err < 0)
4a471b7d 7283 return err;
603c4019 7284 if (!spec->kctls.list)
df694daa 7285 return 0; /* can't find valid BIOS pin config */
05f5f477 7286 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7287 if (err < 0)
df694daa
KY
7288 return err;
7289
7290 spec->multiout.max_channels = 2;
7291
0852d7a6 7292 if (spec->autocfg.dig_outs)
df694daa 7293 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7294 if (spec->kctls.list)
d88897ea 7295 add_mixer(spec, spec->kctls.list);
df694daa 7296
d88897ea 7297 add_verb(spec, alc260_volume_init_verbs);
df694daa 7298
a1e8d2da 7299 spec->num_mux_defs = 1;
61b9b9b1 7300 spec->input_mux = &spec->private_imux[0];
df694daa 7301
6227cdce 7302 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7303
df694daa
KY
7304 return 1;
7305}
7306
ae6b813a
TI
7307/* additional initialization for auto-configuration model */
7308static void alc260_auto_init(struct hda_codec *codec)
df694daa 7309{
f6c7e546 7310 struct alc_spec *spec = codec->spec;
df694daa
KY
7311 alc260_auto_init_multi_out(codec);
7312 alc260_auto_init_analog_input(codec);
7f311a46 7313 alc260_auto_init_input_src(codec);
757899ac 7314 alc_auto_init_digital(codec);
f6c7e546 7315 if (spec->unsol_event)
7fb0d78f 7316 alc_inithook(codec);
df694daa
KY
7317}
7318
cb53c626 7319#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7320static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7321 { 0x07, HDA_INPUT, 0 },
7322 { 0x07, HDA_INPUT, 1 },
7323 { 0x07, HDA_INPUT, 2 },
7324 { 0x07, HDA_INPUT, 3 },
7325 { 0x07, HDA_INPUT, 4 },
7326 { } /* end */
7327};
7328#endif
7329
fc091769
TI
7330/*
7331 * Pin config fixes
7332 */
7333enum {
7334 PINFIX_HP_DC5750,
7335};
7336
fc091769
TI
7337static const struct alc_fixup alc260_fixups[] = {
7338 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7339 .type = ALC_FIXUP_PINS,
7340 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7341 { 0x11, 0x90130110 }, /* speaker */
7342 { }
7343 }
fc091769
TI
7344 },
7345};
7346
a9111321 7347static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7348 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7349 {}
7350};
7351
df694daa
KY
7352/*
7353 * ALC260 configurations
7354 */
ea734963 7355static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7356 [ALC260_BASIC] = "basic",
7357 [ALC260_HP] = "hp",
7358 [ALC260_HP_3013] = "hp-3013",
2922c9af 7359 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7360 [ALC260_FUJITSU_S702X] = "fujitsu",
7361 [ALC260_ACER] = "acer",
bc9f98a9
KY
7362 [ALC260_WILL] = "will",
7363 [ALC260_REPLACER_672V] = "replacer",
cc959489 7364 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7365#ifdef CONFIG_SND_DEBUG
f5fcc13c 7366 [ALC260_TEST] = "test",
7cf51e48 7367#endif
f5fcc13c
TI
7368 [ALC260_AUTO] = "auto",
7369};
7370
a9111321 7371static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7372 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7373 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7374 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7375 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7376 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7377 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7378 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7379 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7380 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7381 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7382 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7383 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7384 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7385 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7386 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7387 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7388 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7389 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7390 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7391 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7392 {}
7393};
7394
a9111321 7395static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7396 [ALC260_BASIC] = {
7397 .mixers = { alc260_base_output_mixer,
45bdd1c1 7398 alc260_input_mixer },
df694daa
KY
7399 .init_verbs = { alc260_init_verbs },
7400 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7401 .dac_nids = alc260_dac_nids,
f9e336f6 7402 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7403 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7404 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7405 .channel_mode = alc260_modes,
7406 .input_mux = &alc260_capture_source,
7407 },
7408 [ALC260_HP] = {
bec15c3a 7409 .mixers = { alc260_hp_output_mixer,
f9e336f6 7410 alc260_input_mixer },
bec15c3a
TI
7411 .init_verbs = { alc260_init_verbs,
7412 alc260_hp_unsol_verbs },
df694daa
KY
7413 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7414 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7415 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7416 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7417 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7418 .channel_mode = alc260_modes,
7419 .input_mux = &alc260_capture_source,
e9427969
TI
7420 .unsol_event = alc_sku_unsol_event,
7421 .setup = alc260_hp_setup,
7422 .init_hook = alc_inithook,
df694daa 7423 },
3f878308
KY
7424 [ALC260_HP_DC7600] = {
7425 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7426 alc260_input_mixer },
3f878308
KY
7427 .init_verbs = { alc260_init_verbs,
7428 alc260_hp_dc7600_verbs },
7429 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7430 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7431 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7432 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7433 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7434 .channel_mode = alc260_modes,
7435 .input_mux = &alc260_capture_source,
e9427969
TI
7436 .unsol_event = alc_sku_unsol_event,
7437 .setup = alc260_hp_3012_setup,
7438 .init_hook = alc_inithook,
3f878308 7439 },
df694daa
KY
7440 [ALC260_HP_3013] = {
7441 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7442 alc260_input_mixer },
bec15c3a
TI
7443 .init_verbs = { alc260_hp_3013_init_verbs,
7444 alc260_hp_3013_unsol_verbs },
df694daa
KY
7445 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7446 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7447 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7448 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7449 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7450 .channel_mode = alc260_modes,
7451 .input_mux = &alc260_capture_source,
e9427969
TI
7452 .unsol_event = alc_sku_unsol_event,
7453 .setup = alc260_hp_3013_setup,
7454 .init_hook = alc_inithook,
df694daa
KY
7455 },
7456 [ALC260_FUJITSU_S702X] = {
f9e336f6 7457 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7458 .init_verbs = { alc260_fujitsu_init_verbs },
7459 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7460 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7461 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7462 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7463 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7464 .channel_mode = alc260_modes,
a1e8d2da
JW
7465 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7466 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7467 },
0bfc90e9 7468 [ALC260_ACER] = {
f9e336f6 7469 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7470 .init_verbs = { alc260_acer_init_verbs },
7471 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7472 .dac_nids = alc260_dac_nids,
7473 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7474 .adc_nids = alc260_dual_adc_nids,
7475 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7476 .channel_mode = alc260_modes,
a1e8d2da
JW
7477 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7478 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7479 },
cc959489
MS
7480 [ALC260_FAVORIT100] = {
7481 .mixers = { alc260_favorit100_mixer },
7482 .init_verbs = { alc260_favorit100_init_verbs },
7483 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7484 .dac_nids = alc260_dac_nids,
7485 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7486 .adc_nids = alc260_dual_adc_nids,
7487 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7488 .channel_mode = alc260_modes,
7489 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7490 .input_mux = alc260_favorit100_capture_sources,
7491 },
bc9f98a9 7492 [ALC260_WILL] = {
f9e336f6 7493 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7494 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7495 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7496 .dac_nids = alc260_dac_nids,
7497 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7498 .adc_nids = alc260_adc_nids,
7499 .dig_out_nid = ALC260_DIGOUT_NID,
7500 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7501 .channel_mode = alc260_modes,
7502 .input_mux = &alc260_capture_source,
7503 },
7504 [ALC260_REPLACER_672V] = {
f9e336f6 7505 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7506 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7507 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7508 .dac_nids = alc260_dac_nids,
7509 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7510 .adc_nids = alc260_adc_nids,
7511 .dig_out_nid = ALC260_DIGOUT_NID,
7512 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7513 .channel_mode = alc260_modes,
7514 .input_mux = &alc260_capture_source,
7515 .unsol_event = alc260_replacer_672v_unsol_event,
7516 .init_hook = alc260_replacer_672v_automute,
7517 },
7cf51e48
JW
7518#ifdef CONFIG_SND_DEBUG
7519 [ALC260_TEST] = {
f9e336f6 7520 .mixers = { alc260_test_mixer },
7cf51e48
JW
7521 .init_verbs = { alc260_test_init_verbs },
7522 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7523 .dac_nids = alc260_test_dac_nids,
7524 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7525 .adc_nids = alc260_test_adc_nids,
7526 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7527 .channel_mode = alc260_modes,
a1e8d2da
JW
7528 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7529 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7530 },
7531#endif
df694daa
KY
7532};
7533
7534static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7535{
7536 struct alc_spec *spec;
df694daa 7537 int err, board_config;
1da177e4 7538
e560d8d8 7539 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7540 if (spec == NULL)
7541 return -ENOMEM;
7542
7543 codec->spec = spec;
7544
f5fcc13c
TI
7545 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7546 alc260_models,
7547 alc260_cfg_tbl);
7548 if (board_config < 0) {
9a11f1aa 7549 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7550 codec->chip_name);
df694daa 7551 board_config = ALC260_AUTO;
16ded525 7552 }
1da177e4 7553
b5bfbc67
TI
7554 if (board_config == ALC260_AUTO) {
7555 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7556 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7557 }
fc091769 7558
df694daa
KY
7559 if (board_config == ALC260_AUTO) {
7560 /* automatic parse from the BIOS config */
7561 err = alc260_parse_auto_config(codec);
7562 if (err < 0) {
7563 alc_free(codec);
7564 return err;
f12ab1e0 7565 } else if (!err) {
9c7f852e
TI
7566 printk(KERN_INFO
7567 "hda_codec: Cannot set up configuration "
7568 "from BIOS. Using base mode...\n");
df694daa
KY
7569 board_config = ALC260_BASIC;
7570 }
a9430dd8 7571 }
e9edcee0 7572
680cd536
KK
7573 err = snd_hda_attach_beep_device(codec, 0x1);
7574 if (err < 0) {
7575 alc_free(codec);
7576 return err;
7577 }
7578
df694daa 7579 if (board_config != ALC260_AUTO)
e9c364c0 7580 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7581
1da177e4
LT
7582 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7583 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7584 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7585
a3bcba38
TI
7586 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7587 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7588
4ef0ef19
TI
7589 if (!spec->adc_nids && spec->input_mux) {
7590 /* check whether NID 0x04 is valid */
7591 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7592 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7593 /* get type */
7594 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7595 spec->adc_nids = alc260_adc_nids_alt;
7596 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7597 } else {
7598 spec->adc_nids = alc260_adc_nids;
7599 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7600 }
7601 }
b59bdf3b 7602 set_capture_mixer(codec);
45bdd1c1 7603 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7604
b5bfbc67 7605 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7606
2134ea4f
TI
7607 spec->vmaster_nid = 0x08;
7608
1da177e4 7609 codec->patch_ops = alc_patch_ops;
df694daa 7610 if (board_config == ALC260_AUTO)
ae6b813a 7611 spec->init_hook = alc260_auto_init;
1c716153 7612 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7613#ifdef CONFIG_SND_HDA_POWER_SAVE
7614 if (!spec->loopback.amplist)
7615 spec->loopback.amplist = alc260_loopbacks;
7616#endif
1da177e4
LT
7617
7618 return 0;
7619}
7620
e9edcee0 7621
1da177e4 7622/*
4953550a 7623 * ALC882/883/885/888/889 support
1da177e4
LT
7624 *
7625 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7626 * configuration. Each pin widget can choose any input DACs and a mixer.
7627 * Each ADC is connected from a mixer of all inputs. This makes possible
7628 * 6-channel independent captures.
7629 *
7630 * In addition, an independent DAC for the multi-playback (not used in this
7631 * driver yet).
7632 */
df694daa
KY
7633#define ALC882_DIGOUT_NID 0x06
7634#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7635#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7636#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7637#define ALC1200_DIGOUT_NID 0x10
7638
1da177e4 7639
a9111321 7640static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7641 { 8, NULL }
7642};
7643
4953550a 7644/* DACs */
4c6d72d1 7645static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7646 /* front, rear, clfe, rear_surr */
7647 0x02, 0x03, 0x04, 0x05
7648};
4953550a 7649#define alc883_dac_nids alc882_dac_nids
1da177e4 7650
4953550a 7651/* ADCs */
df694daa
KY
7652#define alc882_adc_nids alc880_adc_nids
7653#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7654#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7655static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7656static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7657#define alc889_adc_nids alc880_adc_nids
1da177e4 7658
4c6d72d1
TI
7659static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7660static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7661#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7662static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7663#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7664
1da177e4
LT
7665/* input MUX */
7666/* FIXME: should be a matrix-type input source selection */
7667
a9111321 7668static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7669 .num_items = 4,
7670 .items = {
7671 { "Mic", 0x0 },
7672 { "Front Mic", 0x1 },
7673 { "Line", 0x2 },
7674 { "CD", 0x4 },
7675 },
7676};
41d5545d 7677
4953550a
TI
7678#define alc883_capture_source alc882_capture_source
7679
a9111321 7680static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7681 .num_items = 3,
7682 .items = {
7683 { "Front Mic", 0x0 },
7684 { "Mic", 0x3 },
7685 { "Line", 0x2 },
7686 },
7687};
7688
a9111321 7689static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7690 .num_items = 3,
7691 .items = {
7692 { "Mic", 0x1 },
b8f171e7 7693 { "Line", 0x7 },
41d5545d
KS
7694 { "CD", 0x4 },
7695 },
7696};
7697
a9111321 7698static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7699 .num_items = 2,
7700 .items = {
7701 { "Line", 0x2 },
7702 { "CD", 0x4 },
7703 },
7704};
7705
a9111321 7706static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7707 .num_items = 4,
7708 .items = {
7709 { "Mic", 0x1 },
7710 { "Front Mic", 0x0 },
7711 { "Line", 0x2 },
7712 { "CD", 0x4 },
7713 },
7714};
7715
a9111321 7716static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7717 .num_items = 2,
7718 .items = {
7719 { "Mic", 0x1 },
7720 { "Line", 0x2 },
7721 },
7722};
7723
a9111321 7724static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7725 .num_items = 4,
7726 .items = {
7727 { "Mic", 0x0 },
28c4edb7 7728 { "Internal Mic", 0x1 },
4953550a
TI
7729 { "Line", 0x2 },
7730 { "CD", 0x4 },
7731 },
7732};
7733
a9111321 7734static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7735 .num_items = 2,
7736 .items = {
7737 { "Mic", 0x0 },
28c4edb7 7738 { "Internal Mic", 0x1 },
4953550a
TI
7739 },
7740};
7741
a9111321 7742static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7743 .num_items = 3,
7744 .items = {
7745 { "Mic", 0x0 },
7746 { "Front Mic", 0x1 },
7747 { "Line", 0x4 },
7748 },
7749};
7750
a9111321 7751static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7752 .num_items = 2,
7753 .items = {
7754 { "Mic", 0x0 },
7755 { "Line", 0x2 },
7756 },
7757};
7758
a9111321 7759static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7760 .num_items = 2,
7761 .items = {
7762 { "Mic", 0x0 },
7763 /* Front Mic (0x01) unused */
7764 { "Line", 0x2 },
7765 /* Line 2 (0x03) unused */
af901ca1 7766 /* CD (0x04) unused? */
4953550a
TI
7767 },
7768};
7769
a9111321 7770static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7771 .num_items = 2,
7772 .items = {
7773 { "Mic", 0x01 },
7774 { "Line", 0x2 }, /* Not sure! */
7775 },
7776};
7777
4953550a
TI
7778/*
7779 * 2ch mode
7780 */
a9111321 7781static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7782 { 2, NULL }
7783};
7784
272a527c
KY
7785/*
7786 * 2ch mode
7787 */
a9111321 7788static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7789 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7790 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7791 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7792 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7793 { } /* end */
7794};
7795
4953550a
TI
7796/*
7797 * 4ch mode
7798 */
a9111321 7799static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7800 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7801 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7804 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7805 { } /* end */
7806};
7807
272a527c
KY
7808/*
7809 * 6ch mode
7810 */
a9111321 7811static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7812 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7813 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7814 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7815 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7816 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7817 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7818 { } /* end */
7819};
7820
a9111321 7821static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7822 { 2, alc882_3ST_ch2_init },
4953550a 7823 { 4, alc882_3ST_ch4_init },
272a527c
KY
7824 { 6, alc882_3ST_ch6_init },
7825};
7826
4953550a
TI
7827#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7828
a65cc60f 7829/*
7830 * 2ch mode
7831 */
a9111321 7832static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7833 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7834 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7835 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7836 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7837 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 { } /* end */
7839};
7840
7841/*
7842 * 4ch mode
7843 */
a9111321 7844static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7845 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7846 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7847 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7848 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7849 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7850 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7851 { } /* end */
7852};
7853
7854/*
7855 * 6ch mode
7856 */
a9111321 7857static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7858 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7859 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7861 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7864 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7865 { } /* end */
7866};
7867
a9111321 7868static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7869 { 2, alc883_3ST_ch2_clevo_init },
7870 { 4, alc883_3ST_ch4_clevo_init },
7871 { 6, alc883_3ST_ch6_clevo_init },
7872};
7873
7874
df694daa
KY
7875/*
7876 * 6ch mode
7877 */
a9111321 7878static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7879 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7880 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7882 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7883 { } /* end */
7884};
7885
7886/*
7887 * 8ch mode
7888 */
a9111321 7889static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7890 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7891 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { } /* end */
7895};
7896
a9111321 7897static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7898 { 6, alc882_sixstack_ch6_init },
7899 { 8, alc882_sixstack_ch8_init },
7900};
7901
76e6f5a9
RH
7902
7903/* Macbook Air 2,1 */
7904
a9111321 7905static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7906 { 2, NULL },
7907};
7908
87350ad0 7909/*
def319f9 7910 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7911 */
7912
7913/*
7914 * 2ch mode
7915 */
a9111321 7916static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7917 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7918 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7919 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7920 { } /* end */
7921};
7922
7923/*
a3f730af 7924 * 4ch mode
87350ad0 7925 */
a9111321 7926static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7927 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7928 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7929 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7930 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7931 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7932 { } /* end */
7933};
7934
a9111321 7935static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7936 { 2, alc885_mbp_ch2_init },
a3f730af 7937 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7938};
7939
92b9de83
KS
7940/*
7941 * 2ch
7942 * Speakers/Woofer/HP = Front
7943 * LineIn = Input
7944 */
a9111321 7945static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7947 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7948 { } /* end */
7949};
7950
7951/*
7952 * 6ch mode
7953 * Speakers/HP = Front
7954 * Woofer = LFE
7955 * LineIn = Surround
7956 */
a9111321 7957static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
7958 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7959 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7960 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7961 { } /* end */
7962};
7963
a9111321 7964static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
7965 { 2, alc885_mb5_ch2_init },
7966 { 6, alc885_mb5_ch6_init },
7967};
87350ad0 7968
d01aecdf 7969#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7970
7971/*
7972 * 2ch mode
7973 */
a9111321 7974static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
7975 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7977 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7978 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7979 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7980 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7981 { } /* end */
7982};
7983
7984/*
7985 * 4ch mode
7986 */
a9111321 7987static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
7988 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7989 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7990 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7991 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7992 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7993 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7994 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7995 { } /* end */
7996};
7997
7998/*
7999 * 6ch mode
8000 */
a9111321 8001static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8002 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8003 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8004 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8005 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8006 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8007 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8008 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8009 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8010 { } /* end */
8011};
8012
8013/*
8014 * 8ch mode
8015 */
a9111321 8016static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8017 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8018 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8019 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8020 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8021 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8022 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8023 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8026 { } /* end */
8027};
8028
a9111321 8029static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8030 { 2, alc883_4ST_ch2_init },
8031 { 4, alc883_4ST_ch4_init },
8032 { 6, alc883_4ST_ch6_init },
8033 { 8, alc883_4ST_ch8_init },
8034};
8035
8036
8037/*
8038 * 2ch mode
8039 */
a9111321 8040static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8041 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8042 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8043 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8044 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8045 { } /* end */
8046};
8047
8048/*
8049 * 4ch mode
8050 */
a9111321 8051static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8052 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8053 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8055 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8056 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8057 { } /* end */
8058};
8059
8060/*
8061 * 6ch mode
8062 */
a9111321 8063static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8064 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8065 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8066 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8067 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8070 { } /* end */
8071};
8072
a9111321 8073static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8074 { 2, alc883_3ST_ch2_intel_init },
8075 { 4, alc883_3ST_ch4_intel_init },
8076 { 6, alc883_3ST_ch6_intel_init },
8077};
8078
dd7714c9
WF
8079/*
8080 * 2ch mode
8081 */
a9111321 8082static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8083 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8084 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8085 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8086 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8087 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8088 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8089 { } /* end */
8090};
8091
87a8c370
JK
8092/*
8093 * 6ch mode
8094 */
a9111321 8095static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8096 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8097 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8098 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8099 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8100 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8101 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { } /* end */
8103};
8104
8105/*
8106 * 8ch mode
8107 */
a9111321 8108static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8109 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8110 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8111 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8112 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8113 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8114 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8115 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8116 { } /* end */
8117};
8118
a9111321 8119static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8120 { 2, alc889_ch2_intel_init },
87a8c370
JK
8121 { 6, alc889_ch6_intel_init },
8122 { 8, alc889_ch8_intel_init },
8123};
8124
4953550a
TI
8125/*
8126 * 6ch mode
8127 */
a9111321 8128static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8129 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8130 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8131 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8132 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8133 { } /* end */
8134};
8135
8136/*
8137 * 8ch mode
8138 */
a9111321 8139static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8140 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8141 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8142 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8143 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8144 { } /* end */
8145};
8146
a9111321 8147static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8148 { 6, alc883_sixstack_ch6_init },
8149 { 8, alc883_sixstack_ch8_init },
8150};
8151
8152
1da177e4
LT
8153/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8154 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8155 */
a9111321 8156static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8159 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8160 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8161 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8162 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8163 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8164 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8165 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8166 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8167 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8168 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8169 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8172 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8173 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8174 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8175 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8176 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8177 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8178 { } /* end */
8179};
8180
76e6f5a9
RH
8181/* Macbook Air 2,1 same control for HP and internal Speaker */
8182
a9111321 8183static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8184 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8185 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8186 { }
8187};
8188
8189
a9111321 8190static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8192 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8194 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8195 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8196 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8197 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8199 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8200 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8201 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8202 { } /* end */
8203};
41d5545d 8204
a9111321 8205static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8206 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8207 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8208 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8209 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8210 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8211 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8213 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8215 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8217 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8218 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8220 { } /* end */
8221};
92b9de83 8222
a9111321 8223static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8224 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8225 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8226 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8227 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8228 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8229 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8230 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8231 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8233 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8234 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8235 { } /* end */
8236};
8237
a9111321 8238static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8241 { } /* end */
8242};
8243
8244
a9111321 8245static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8246 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8247 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8248 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8249 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8250 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8251 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8252 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8253 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8255 { } /* end */
8256};
8257
a9111321 8258static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8259 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8260 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8261 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8262 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8263 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8264 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8265 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8268 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8269 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8271 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8272 { } /* end */
8273};
8274
8275/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8276 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8277 */
a9111321 8278static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8279 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8280 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8281 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8282 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8283 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8284 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8287 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8288 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8289 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8290 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8291 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8292 { } /* end */
8293};
8294
a9111321 8295static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8296 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8297 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8298 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8299 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8300 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8302 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8303 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8304 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8305 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8306 { } /* end */
8307};
8308
a9111321 8309static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8310 {
8311 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8312 .name = "Channel Mode",
8313 .info = alc_ch_mode_info,
8314 .get = alc_ch_mode_get,
8315 .put = alc_ch_mode_put,
8316 },
8317 { } /* end */
8318};
8319
a9111321 8320static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8321 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8322 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8323 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8324 /* Rear mixer */
05acb863
TI
8325 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8326 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8327 /* CLFE mixer */
05acb863
TI
8328 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8329 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8330 /* Side mixer */
05acb863
TI
8331 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8332 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8333
e9edcee0 8334 /* Front Pin: output 0 (0x0c) */
05acb863 8335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8337 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8338 /* Rear Pin: output 1 (0x0d) */
05acb863 8339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8342 /* CLFE Pin: output 2 (0x0e) */
05acb863 8343 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8344 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8345 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8346 /* Side Pin: output 3 (0x0f) */
05acb863 8347 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8348 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8349 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8350 /* Mic (rear) pin: input vref at 80% */
16ded525 8351 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8352 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8353 /* Front Mic pin: input vref at 80% */
16ded525 8354 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8355 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8356 /* Line In pin: input */
05acb863 8357 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8358 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8359 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8360 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8361 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8362 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8363 /* CD pin widget for input */
05acb863 8364 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8365
8366 /* FIXME: use matrix-type input source selection */
8367 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8368 /* Input mixer2 */
05acb863 8369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8370 /* Input mixer3 */
05acb863 8371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8372 /* ADC2: mute amp left and right */
8373 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8374 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8375 /* ADC3: mute amp left and right */
8376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8377 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8378
8379 { }
8380};
8381
a9111321 8382static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8383 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8384 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8385 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8388 /* ADC1: mute amp left and right */
8389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8390 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8391 { }
8392};
8393
a9111321 8394static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8395 /* change to EAPD mode */
8396 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8397 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8398 { }
4b146cb0
TI
8399};
8400
a9111321 8401static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8402 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8403 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8404 { }
8405};
8406
a9111321 8407static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8408 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8409 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8410 {}
8411};
87a8c370 8412
a9111321 8413static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8414 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8417 /* Rear mixer */
88102f3f
KY
8418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8420 /* CLFE mixer */
88102f3f
KY
8421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8422 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8423 /* Side mixer */
88102f3f
KY
8424 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8426
8427 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8428 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8431 /* Front Pin: output 0 (0x0c) */
8432 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8433 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8434 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8435 /* Rear Pin: output 1 (0x0d) */
8436 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8437 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8438 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8439 /* CLFE Pin: output 2 (0x0e) */
8440 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8441 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8442 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8443 /* Side Pin: output 3 (0x0f) */
8444 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8445 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8446 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8447 /* Mic (rear) pin: input vref at 80% */
8448 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8449 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8450 /* Front Mic pin: input vref at 80% */
8451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8453 /* Line In pin: input */
8454 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8455 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8456
8457 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8458 /* Input mixer1 */
88102f3f 8459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8460 /* Input mixer2 */
8461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8462 /* Input mixer3 */
88102f3f 8463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8464 /* ADC2: mute amp left and right */
8465 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8466 /* ADC3: mute amp left and right */
8467 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8468
8469 { }
8470};
8471
a9111321 8472static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8474 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8475 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8476 { }
8477};
8478
8479
8480/* Unmute Selector 24h and set the default input to front mic */
a9111321 8481static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8482 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8484 { }
8485};
8486
8487
4953550a
TI
8488#define alc883_init_verbs alc882_base_init_verbs
8489
9102cd1c 8490/* Mac Pro test */
a9111321 8491static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8492 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8494 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8495 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8496 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8497 /* FIXME: this looks suspicious...
d355c82a
JK
8498 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8499 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8500 */
9102cd1c
TD
8501 { } /* end */
8502};
8503
a9111321 8504static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8505 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8506 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8507 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8509 /* Front Pin: output 0 (0x0c) */
8510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8512 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8513 /* Front Mic pin: input vref at 80% */
8514 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8515 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8516 /* Speaker: output */
8517 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8518 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8519 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8520 /* Headphone output (output 0 - 0x0c) */
8521 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8522 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8523 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8524
8525 /* FIXME: use matrix-type input source selection */
8526 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8527 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8528 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8529 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8532 /* Input mixer2 */
8533 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8534 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8536 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8537 /* Input mixer3 */
8538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8542 /* ADC1: mute amp left and right */
8543 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8545 /* ADC2: mute amp left and right */
8546 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8547 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8548 /* ADC3: mute amp left and right */
8549 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8550 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8551
8552 { }
8553};
f12ab1e0 8554
41d5545d 8555/* Macbook 5,1 */
a9111321 8556static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8557 /* DACs */
8558 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8559 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8561 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8562 /* Front mixer */
41d5545d
KS
8563 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8564 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8566 /* Surround mixer */
8567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8568 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8569 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8570 /* LFE mixer */
8571 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8572 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8574 /* HP mixer */
8575 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8576 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8577 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8578 /* Front Pin (0x0c) */
41d5545d
KS
8579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8581 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8582 /* LFE Pin (0x0e) */
8583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8586 /* HP Pin (0x0f) */
41d5545d
KS
8587 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8590 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8591 /* Front Mic pin: input vref at 80% */
8592 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8593 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8594 /* Line In pin */
8595 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8596 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8597
b8f171e7
AM
8598 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8601 { }
8602};
8603
e458b1fa 8604/* Macmini 3,1 */
a9111321 8605static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8606 /* DACs */
8607 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8610 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8611 /* Front mixer */
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8615 /* Surround mixer */
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8618 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8619 /* LFE mixer */
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8623 /* HP mixer */
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8627 /* Front Pin (0x0c) */
8628 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8629 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8630 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8631 /* LFE Pin (0x0e) */
8632 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8633 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8634 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8635 /* HP Pin (0x0f) */
8636 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8637 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8638 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8639 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8640 /* Line In pin */
8641 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8642 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8643
8644 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8645 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8648 { }
8649};
8650
76e6f5a9 8651
a9111321 8652static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8653 /*Internal and HP Speaker Mixer*/
8654 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8655 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8657 /*Internal Speaker Pin (0x0c)*/
8658 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8659 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8660 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8661 /* HP Pin: output 0 (0x0e) */
8662 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8663 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8664 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8666 /* Line in (is hp when jack connected)*/
8667 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8668 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8669
8670 { }
8671 };
8672
8673
87350ad0 8674/* Macbook Pro rev3 */
a9111321 8675static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8676 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8677 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8678 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8680 /* Rear mixer */
8681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8684 /* HP mixer */
8685 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8686 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8688 /* Front Pin: output 0 (0x0c) */
8689 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8690 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8691 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8692 /* HP Pin: output 0 (0x0e) */
87350ad0 8693 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8695 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8696 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8697 /* Mic (rear) pin: input vref at 80% */
8698 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8699 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8700 /* Front Mic pin: input vref at 80% */
8701 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8702 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8703 /* Line In pin: use output 1 when in LineOut mode */
8704 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8705 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8706 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8707
8708 /* FIXME: use matrix-type input source selection */
8709 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8710 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8711 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8712 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8713 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8714 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8715 /* Input mixer2 */
8716 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8717 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8720 /* Input mixer3 */
8721 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8722 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8725 /* ADC1: mute amp left and right */
8726 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8728 /* ADC2: mute amp left and right */
8729 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8730 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8731 /* ADC3: mute amp left and right */
8732 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8733 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8734
8735 { }
8736};
8737
4b7e1803 8738/* iMac 9,1 */
a9111321 8739static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8740 /* Internal Speaker Pin (0x0c) */
8741 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8742 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8745 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8746 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8747 /* HP Pin: Rear */
4b7e1803
JM
8748 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8750 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8751 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8752 /* Line in Rear */
8753 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8754 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8755 /* Front Mic pin: input vref at 80% */
8756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8758 /* Rear mixer */
8759 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8760 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8762 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8763 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8766 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8771 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8775 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8776 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8781 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8783 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8784 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8785 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8786 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8787 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8788 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8789 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8790 { }
8791};
8792
c54728d8 8793/* iMac 24 mixer. */
a9111321 8794static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8795 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8796 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8797 { } /* end */
8798};
8799
8800/* iMac 24 init verbs. */
a9111321 8801static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8802 /* Internal speakers: output 0 (0x0c) */
8803 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8804 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8805 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8806 /* Internal speakers: output 0 (0x0c) */
8807 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8808 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8809 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8810 /* Headphone: output 0 (0x0c) */
8811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8813 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8815 /* Front Mic: input vref at 80% */
8816 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8818 { }
8819};
8820
8821/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8822static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8823{
a9fd4f3f 8824 struct alc_spec *spec = codec->spec;
c54728d8 8825
a9fd4f3f
TI
8826 spec->autocfg.hp_pins[0] = 0x14;
8827 spec->autocfg.speaker_pins[0] = 0x18;
8828 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8829 spec->automute = 1;
8830 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8831}
8832
9d54f08b
TI
8833#define alc885_mb5_setup alc885_imac24_setup
8834#define alc885_macmini3_setup alc885_imac24_setup
8835
76e6f5a9
RH
8836/* Macbook Air 2,1 */
8837static void alc885_mba21_setup(struct hda_codec *codec)
8838{
8839 struct alc_spec *spec = codec->spec;
8840
8841 spec->autocfg.hp_pins[0] = 0x14;
8842 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8843 spec->automute = 1;
8844 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8845}
8846
8847
8848
4f5d1706 8849static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8850{
a9fd4f3f 8851 struct alc_spec *spec = codec->spec;
87350ad0 8852
a9fd4f3f
TI
8853 spec->autocfg.hp_pins[0] = 0x15;
8854 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8855 spec->automute = 1;
8856 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8857}
8858
9d54f08b 8859static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8860{
9d54f08b 8861 struct alc_spec *spec = codec->spec;
4b7e1803 8862
9d54f08b 8863 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8864 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8865 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8866 spec->automute = 1;
8867 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8868}
87350ad0 8869
a9111321 8870static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8871 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8872 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8873
8874 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8875 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8876
272a527c
KY
8877 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8878 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8879 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8880
8881 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8882 { } /* end */
8883};
8884
8885/* toggle speaker-output according to the hp-jack state */
8886static void alc882_targa_automute(struct hda_codec *codec)
8887{
a9fd4f3f 8888 struct alc_spec *spec = codec->spec;
d922b51d 8889 alc_hp_automute(codec);
82beb8fd 8890 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8891 spec->jack_present ? 1 : 3);
8892}
8893
4f5d1706 8894static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8895{
8896 struct alc_spec *spec = codec->spec;
8897
8898 spec->autocfg.hp_pins[0] = 0x14;
8899 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8900 spec->automute = 1;
8901 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8902}
8903
8904static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8905{
a9fd4f3f 8906 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8907 alc882_targa_automute(codec);
272a527c
KY
8908}
8909
a9111321 8910static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8911 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8912 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8913
8914 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8915 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8916 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8917
272a527c
KY
8918 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8919 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8920 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8921
8922 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8923 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8924 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8925 { } /* end */
8926};
8927
a9111321 8928static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8929 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8930 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8931
8932 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8933 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8935
914759b7
TI
8936 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8937 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8938 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8939
8940 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8941 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8942 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8943 { } /* end */
8944};
8945
9102cd1c
TD
8946static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8947{
8948 unsigned int gpiostate, gpiomask, gpiodir;
8949
8950 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8951 AC_VERB_GET_GPIO_DATA, 0);
8952
8953 if (!muted)
8954 gpiostate |= (1 << pin);
8955 else
8956 gpiostate &= ~(1 << pin);
8957
8958 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8959 AC_VERB_GET_GPIO_MASK, 0);
8960 gpiomask |= (1 << pin);
8961
8962 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8963 AC_VERB_GET_GPIO_DIRECTION, 0);
8964 gpiodir |= (1 << pin);
8965
8966
8967 snd_hda_codec_write(codec, codec->afg, 0,
8968 AC_VERB_SET_GPIO_MASK, gpiomask);
8969 snd_hda_codec_write(codec, codec->afg, 0,
8970 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8971
8972 msleep(1);
8973
8974 snd_hda_codec_write(codec, codec->afg, 0,
8975 AC_VERB_SET_GPIO_DATA, gpiostate);
8976}
8977
7debbe51
TI
8978/* set up GPIO at initialization */
8979static void alc885_macpro_init_hook(struct hda_codec *codec)
8980{
8981 alc882_gpio_mute(codec, 0, 0);
8982 alc882_gpio_mute(codec, 1, 0);
8983}
8984
8985/* set up GPIO and update auto-muting at initialization */
8986static void alc885_imac24_init_hook(struct hda_codec *codec)
8987{
8988 alc885_macpro_init_hook(codec);
d922b51d 8989 alc_hp_automute(codec);
7debbe51
TI
8990}
8991
df694daa
KY
8992/*
8993 * generic initialization of ADC, input mixers and output mixers
8994 */
a9111321 8995static const struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8996 /*
8997 * Unmute ADC0-2 and set the default input to mic-in
8998 */
4953550a
TI
8999 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9000 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9001 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9002 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 9003
4953550a
TI
9004 /*
9005 * Set up output mixers (0x0c - 0x0f)
9006 */
9007 /* set vol=0 to output mixers */
9008 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9009 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9010 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9011 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9012 /* set up input amps for analog loopback */
9013 /* Amp Indices: DAC = 0, mixer = 1 */
9014 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9015 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9016 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9017 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9018 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9019 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9021 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9022 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9023 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9024
4953550a
TI
9025 /* FIXME: use matrix-type input source selection */
9026 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9027 /* Input mixer2 */
88102f3f 9028 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9029 /* Input mixer3 */
88102f3f 9030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9031 { }
9c7f852e
TI
9032};
9033
eb4c41d3 9034/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9035static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9036 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9037 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9038 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9039 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9040 { } /* end */
9041};
9042
9043/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9044static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9045 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9046 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9047 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9048 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9049 { } /* end */
9050};
9051
9052/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9053static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9054 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9055 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9056 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9057 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9058 { } /* end */
9059};
9060
9061/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9062static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9063 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9064 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9065 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9066 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9067 { } /* end */
9068};
9069
a9111321 9070static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9071 { 2, alc889A_mb31_ch2_init },
9072 { 4, alc889A_mb31_ch4_init },
9073 { 5, alc889A_mb31_ch5_init },
9074 { 6, alc889A_mb31_ch6_init },
9075};
9076
a9111321 9077static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9078 /* eanable EAPD on medion laptop */
9079 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9080 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9081 { }
9082};
9083
4953550a 9084#define alc883_base_mixer alc882_base_mixer
834be88d 9085
a9111321 9086static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9087 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9088 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9089 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9090 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9091 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9092 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9093 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9095 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9096 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9097 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9098 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9099 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9100 { } /* end */
9101};
9102
a9111321 9103static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9104 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9105 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9106 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9107 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9109 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9110 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9111 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9112 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9113 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9114 { } /* end */
9115};
9116
a9111321 9117static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9119 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9123 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9125 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9126 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9128 { } /* end */
9129};
9130
a9111321 9131static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9132 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9133 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9134 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9135 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9136 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9137 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9138 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9139 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9140 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9141 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9142 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9143 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9144 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9145 { } /* end */
9146};
df694daa 9147
a9111321 9148static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9149 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9150 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9151 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9154 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9155 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9156 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 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("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9166 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9167 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9168 { } /* end */
9169};
9170
a9111321 9171static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9172 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9173 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9174 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9176 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9177 HDA_OUTPUT),
9178 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9179 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9180 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9181 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9182 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9183 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9185 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9190 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9192 { } /* end */
9193};
9194
a9111321 9195static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9201 HDA_OUTPUT),
9202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9204 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9205 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9206 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9207 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9214 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9216 { } /* end */
9217};
9218
a9111321 9219static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9239 { } /* end */
9240};
9241
a9111321 9242static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9245 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9246 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9247 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9248 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9249 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9250 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9251 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9252 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9253 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9254 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9255 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9256 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9260 { } /* end */
f12ab1e0 9261};
ccc656ce 9262
a9111321 9263static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9264 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9265 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9266 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9267 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9268 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9269 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9270 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9273 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9275 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9276 { } /* end */
f12ab1e0 9277};
ccc656ce 9278
a9111321 9279static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9280 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9281 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9282 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9283 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9284 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9285 { } /* end */
9286};
9287
a9111321 9288static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9289 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9290 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9291 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9292 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9295 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9296 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9297 { } /* end */
f12ab1e0 9298};
bc9f98a9 9299
a9111321 9300static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9301 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9302 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9303 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9304 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9305 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9306 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9308 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9309 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9310 { } /* end */
ea1fb29a 9311};
272a527c 9312
a9111321 9313static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9314 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9315 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9316 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9317 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9318 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9319 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9320 { } /* end */
9321};
9322
a9111321 9323static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9324 /* Unmute front mixer */
9325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9326 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9327
9328 /* Set speaker pin to front mixer */
9329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9330
9331 /* Init headphone pin */
9332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9333 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9334 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9335 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9336
9337 { } /* end */
9338};
9339
9340/* toggle speaker-output according to the hp-jack state */
9341static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9342{
9343 struct alc_spec *spec = codec->spec;
9344
9345 spec->autocfg.hp_pins[0] = 0x1a;
9346 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9347 spec->automute = 1;
9348 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9349}
9350
a9111321 9351static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9352 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9353 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9354 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9355 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9356 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9357 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9358 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9360 { } /* end */
d1a991a6 9361};
2880a867 9362
a9111321 9363static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9364 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9365 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9366 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9367 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9368 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9369 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9371 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9372 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9373 { } /* end */
9374};
9375
a9111321 9376static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9377 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9378 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9379 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9380 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9381 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9382 0x0d, 1, 0x0, HDA_OUTPUT),
9383 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9384 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9385 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9386 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9387 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9390 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9391 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9393 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9394 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9395 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9396 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9397 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9398 { } /* end */
9399};
9400
a9111321 9401static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9402 /* Output mixers */
9403 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9404 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9405 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9406 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9407 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9408 HDA_OUTPUT),
9409 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9410 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9411 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9412 /* Output switches */
9413 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9414 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9415 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9416 /* Boost mixers */
5f99f86a
DH
9417 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9418 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9419 /* Input mixers */
9420 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9421 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9422 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9423 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9424 { } /* end */
9425};
9426
a9111321 9427static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9428 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9429 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9431 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9432 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9433 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9434 { } /* end */
9435};
9436
a9111321 9437static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9438 .ops = &snd_hda_bind_vol,
9439 .values = {
9440 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9441 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9442 0
9443 },
9444};
9445
a9111321 9446static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9447 .ops = &snd_hda_bind_sw,
9448 .values = {
9449 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9450 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9451 0
9452 },
9453};
9454
a9111321 9455static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9456 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9457 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9458 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9462 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9463 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9464 { } /* end */
9465};
df694daa 9466
a9111321 9467static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9468 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9469 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9470 {
9471 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9472 /* .name = "Capture Source", */
9473 .name = "Input Source",
9474 .count = 1,
9475 .info = alc_mux_enum_info,
9476 .get = alc_mux_enum_get,
9477 .put = alc_mux_enum_put,
9478 },
9479 { } /* end */
9480};
9c7f852e 9481
a9111321 9482static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9483 {
9484 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9485 .name = "Channel Mode",
9486 .info = alc_ch_mode_info,
9487 .get = alc_ch_mode_get,
9488 .put = alc_ch_mode_put,
9489 },
9490 { } /* end */
9c7f852e
TI
9491};
9492
a8848bd6 9493/* toggle speaker-output according to the hp-jack state */
4f5d1706 9494static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9495{
a9fd4f3f 9496 struct alc_spec *spec = codec->spec;
a8848bd6 9497
a9fd4f3f
TI
9498 spec->autocfg.hp_pins[0] = 0x15;
9499 spec->autocfg.speaker_pins[0] = 0x14;
9500 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9501 spec->automute = 1;
9502 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9503}
9504
a9111321 9505static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9506 /* HP */
9507 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9509 /* Subwoofer */
9510 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9511 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9512
9513 /* enable unsolicited event */
9514 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9515 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9516
9517 { } /* end */
9518};
9519
a9111321 9520static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9521 /* HP */
9522 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9524 /* Int speaker */
9525 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9526
9527 /* enable unsolicited event */
9528 /*
9529 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9530 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9531 */
9532
9533 { } /* end */
9534};
9535
a9111321 9536static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9537 /* HP */
9538 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9539 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9540 /* Int speaker */
9541 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9542 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9543
9544 /* enable unsolicited event */
9545 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9546 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9547
9548 { } /* end */
9549};
9550
a9111321 9551static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9552 /* HP */
9553 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9554 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9555 /* Subwoofer */
9556 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9558
9559 /* enable unsolicited event */
9560 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9561
9562 { } /* end */
9563};
9564
a9111321 9565static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9568
9569 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9570 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9571
64a8be74
DH
9572/* Connect Line-Out side jack (SPDIF) to Side */
9573 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9574 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9575 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9576/* Connect Mic jack to CLFE */
9577 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9578 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9579 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9580/* Connect Line-in jack to Surround */
9581 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9582 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9583 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9584/* Connect HP out jack to Front */
9585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9586 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9587 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9588
9589 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9590
9591 { } /* end */
9592};
9593
a9111321 9594static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9595 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9596 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9597 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9598 { } /* end */
9599};
9600
a9111321 9601static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9602 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9604 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9605 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9606 { } /* end */
9607};
9608
a9111321 9609static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9612 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9613 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9614 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9615 { } /* end */
9616};
9617
a9111321 9618static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9619 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9620 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9621
9622 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9623
9624 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9626 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9628 { } /* end */
9629};
9630
a9111321 9631static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9632 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9633 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9634 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9635 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9636 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9638 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9639 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9640 { } /* end */
9641};
9642
a9111321 9643static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9645 { }
9646};
9647
a9111321 9648static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9649 /* HP */
9650 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9652
9653 /* enable unsolicited event */
9654 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9655
9656 { } /* end */
9657};
9658
4f5d1706 9659static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9660{
a9fd4f3f 9661 struct alc_spec *spec = codec->spec;
8718b700 9662
a9fd4f3f
TI
9663 spec->autocfg.hp_pins[0] = 0x1b;
9664 spec->autocfg.speaker_pins[0] = 0x14;
9665 spec->autocfg.speaker_pins[1] = 0x16;
9666 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9667 spec->automute = 1;
9668 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9669}
9670
a9111321 9671static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9672 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9673 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9674 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9675 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9676 { } /* end */
5795b9e6
CM
9677};
9678
3ea0d7cf
HRK
9679/*
9680 * 2ch mode
9681 */
a9111321 9682static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9683 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9684 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9685 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9686 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9687 { } /* end */
8341de60
CM
9688};
9689
3ea0d7cf
HRK
9690/*
9691 * 4ch mode
9692 */
a9111321 9693static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9694 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9695 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9696 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9697 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9698 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9699 { } /* end */
9700};
9701
9702/*
9703 * 6ch mode
9704 */
a9111321 9705static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9706 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9707 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9708 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9709 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9710 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9711 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9712 { } /* end */
8341de60
CM
9713};
9714
a9111321 9715static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9716 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9717 { 4, alc888_3st_hp_4ch_init },
4723c022 9718 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9719};
9720
e6a5e1b7 9721static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9722{
e6a5e1b7 9723 struct alc_spec *spec = codec->spec;
47fd830a 9724
e6a5e1b7
TI
9725 spec->autocfg.hp_pins[0] = 0x1b;
9726 spec->autocfg.line_out_pins[0] = 0x14;
9727 spec->autocfg.speaker_pins[0] = 0x15;
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9730}
9731
272a527c 9732/* toggle speaker-output according to the hp-jack state */
dc427170 9733static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9734{
a9fd4f3f 9735 struct alc_spec *spec = codec->spec;
272a527c 9736
a9fd4f3f
TI
9737 spec->autocfg.hp_pins[0] = 0x14;
9738 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9739 spec->automute = 1;
9740 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9741}
9742
ccc656ce 9743/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9744#define alc883_targa_init_hook alc882_targa_init_hook
9745#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9746
4f5d1706 9747static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9748{
a9fd4f3f
TI
9749 struct alc_spec *spec = codec->spec;
9750
9751 spec->autocfg.hp_pins[0] = 0x15;
9752 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9753 spec->automute = 1;
9754 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9755}
9756
9757static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9758{
d922b51d 9759 alc_hp_automute(codec);
eeb43387 9760 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9761}
9762
9763static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9764 unsigned int res)
9765{
0c4cc443 9766 switch (res >> 26) {
0c4cc443 9767 case ALC880_MIC_EVENT:
eeb43387 9768 alc88x_simple_mic_automute(codec);
0c4cc443 9769 break;
a9fd4f3f 9770 default:
d922b51d 9771 alc_sku_unsol_event(codec, res);
a9fd4f3f 9772 break;
0c4cc443 9773 }
368c7a95
J
9774}
9775
fb97dc67 9776/* toggle speaker-output according to the hp-jack state */
4f5d1706 9777static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9778{
a9fd4f3f 9779 struct alc_spec *spec = codec->spec;
fb97dc67 9780
a9fd4f3f
TI
9781 spec->autocfg.hp_pins[0] = 0x14;
9782 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9783 spec->automute = 1;
9784 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9785}
9786
4f5d1706 9787static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9788{
a9fd4f3f 9789 struct alc_spec *spec = codec->spec;
189609ae 9790
a9fd4f3f
TI
9791 spec->autocfg.hp_pins[0] = 0x1b;
9792 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9793 spec->automute = 1;
9794 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9795}
9796
e6a5e1b7 9797static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9798{
e6a5e1b7 9799 struct alc_spec *spec = codec->spec;
bc9f98a9 9800
e6a5e1b7
TI
9801 spec->autocfg.hp_pins[0] = 0x1b;
9802 spec->autocfg.line_out_pins[0] = 0x14;
9803 spec->autocfg.speaker_pins[0] = 0x15;
9804 spec->automute = 1;
9805 spec->detect_line = 1;
9806 spec->automute_lines = 1;
9807 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9808}
9809
676a9b53 9810/* toggle speaker-output according to the hp-jack state */
4f5d1706 9811static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9812{
a9fd4f3f 9813 struct alc_spec *spec = codec->spec;
676a9b53 9814
a9fd4f3f
TI
9815 spec->autocfg.hp_pins[0] = 0x14;
9816 spec->autocfg.speaker_pins[0] = 0x15;
9817 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9818 spec->automute = 1;
9819 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9820}
9821
a9111321 9822static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9823 /* HP Pin: output 0 (0x0c) */
9824 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9825 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9826 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9827 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9829 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9830 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9831 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9832 /* eanable EAPD on medion laptop */
9833 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9834 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9835 /* enable unsolicited event */
9836 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9837 { }
9838};
9839
4f5d1706 9840static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9841{
a9fd4f3f 9842 struct alc_spec *spec = codec->spec;
5795b9e6 9843
a9fd4f3f
TI
9844 spec->autocfg.hp_pins[0] = 0x1b;
9845 spec->autocfg.speaker_pins[0] = 0x14;
9846 spec->autocfg.speaker_pins[1] = 0x15;
9847 spec->autocfg.speaker_pins[2] = 0x16;
9848 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9849 spec->automute = 1;
9850 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9851}
9852
4f5d1706 9853static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9854{
a9fd4f3f 9855 struct alc_spec *spec = codec->spec;
e2757d5e 9856
a9fd4f3f
TI
9857 spec->autocfg.hp_pins[0] = 0x1b;
9858 spec->autocfg.speaker_pins[0] = 0x14;
9859 spec->autocfg.speaker_pins[1] = 0x15;
9860 spec->autocfg.speaker_pins[2] = 0x16;
9861 spec->autocfg.speaker_pins[3] = 0x17;
9862 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9863 spec->automute = 1;
9864 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9865}
9866
4f5d1706 9867static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9868{
9869 struct alc_spec *spec = codec->spec;
9870
9871 spec->autocfg.hp_pins[0] = 0x15;
9872 spec->autocfg.speaker_pins[0] = 0x14;
9873 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9874 spec->automute = 1;
9875 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9876}
9877
a9111321 9878static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9879 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9880 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9881 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9882 /* enable unsolicited event */
9883 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9884 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9885 { } /* end */
9886};
9887
4f5d1706 9888static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9889{
a9fd4f3f 9890 struct alc_spec *spec = codec->spec;
e2757d5e 9891
a9fd4f3f
TI
9892 spec->autocfg.hp_pins[0] = 0x1b;
9893 spec->autocfg.speaker_pins[0] = 0x14;
9894 spec->autocfg.speaker_pins[1] = 0x15;
9895 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9896 spec->ext_mic.pin = 0x18;
9897 spec->int_mic.pin = 0x19;
9898 spec->ext_mic.mux_idx = 0;
9899 spec->int_mic.mux_idx = 1;
9900 spec->auto_mic = 1;
d922b51d
TI
9901 spec->automute = 1;
9902 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9903}
9904
a9111321 9905static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9906 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9907 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9908 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9910 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9911 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9912 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9913 /* enable unsolicited event */
9914 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9915 { } /* end */
9916};
9917
e2757d5e
KY
9918static void alc883_eee1601_inithook(struct hda_codec *codec)
9919{
a9fd4f3f
TI
9920 struct alc_spec *spec = codec->spec;
9921
9922 spec->autocfg.hp_pins[0] = 0x14;
9923 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9924 alc_hp_automute(codec);
e2757d5e
KY
9925}
9926
a9111321 9927static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9928 /* Init rear pin (used as headphone output) */
9929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9930 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9931 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9932 /* Init line pin (used as output in 4ch and 6ch mode) */
9933 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9934 /* Init line 2 pin (used as headphone out by default) */
9935 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9936 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9937 { } /* end */
9938};
9939
9940/* Mute speakers according to the headphone jack state */
9941static void alc889A_mb31_automute(struct hda_codec *codec)
9942{
9943 unsigned int present;
9944
9945 /* Mute only in 2ch or 4ch mode */
9946 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9947 == 0x00) {
864f92be 9948 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9949 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9950 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9951 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9952 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9953 }
9954}
9955
9956static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9957{
9958 if ((res >> 26) == ALC880_HP_EVENT)
9959 alc889A_mb31_automute(codec);
9960}
9961
4953550a 9962
cb53c626 9963#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9964#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9965#endif
9966
def319f9 9967/* pcm configuration: identical with ALC880 */
4953550a
TI
9968#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9969#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9970#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9971#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9972
4c6d72d1 9973static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9974 ALC1200_DIGOUT_NID, 0,
9975};
9976
4c6d72d1 9977static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9978 ALC883_DIGOUT_NID, 0,
9979};
9c7f852e
TI
9980
9981/*
9982 * configuration and preset
9983 */
ea734963 9984static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9985 [ALC882_3ST_DIG] = "3stack-dig",
9986 [ALC882_6ST_DIG] = "6stack-dig",
9987 [ALC882_ARIMA] = "arima",
9988 [ALC882_W2JC] = "w2jc",
9989 [ALC882_TARGA] = "targa",
9990 [ALC882_ASUS_A7J] = "asus-a7j",
9991 [ALC882_ASUS_A7M] = "asus-a7m",
9992 [ALC885_MACPRO] = "macpro",
9993 [ALC885_MB5] = "mb5",
e458b1fa 9994 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9995 [ALC885_MBA21] = "mba21",
4953550a
TI
9996 [ALC885_MBP3] = "mbp3",
9997 [ALC885_IMAC24] = "imac24",
4b7e1803 9998 [ALC885_IMAC91] = "imac91",
4953550a 9999 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10000 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10001 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10002 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10003 [ALC883_TARGA_DIG] = "targa-dig",
10004 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10005 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10006 [ALC883_ACER] = "acer",
2880a867 10007 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10008 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10009 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10010 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10011 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10012 [ALC883_MEDION] = "medion",
7ad7b218 10013 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10014 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10015 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10016 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10017 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10018 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10019 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10020 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10021 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10022 [ALC883_MITAC] = "mitac",
a65cc60f 10023 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10024 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10025 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10026 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10027 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10028 [ALC889A_INTEL] = "intel-alc889a",
10029 [ALC889_INTEL] = "intel-x58",
3ab90935 10030 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10031 [ALC889A_MB31] = "mb31",
3e1647c5 10032 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10033 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10034};
10035
a9111321 10036static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10037 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10038
ac3e3741 10039 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10040 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10041 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10042 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10043 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10044 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10045 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10046 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10047 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10048 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10049 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10050 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10051 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10052 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10053 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10054 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10055 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10056 ALC888_ACER_ASPIRE_6530G),
cc374c47 10057 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10058 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10059 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10060 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10061 /* default Acer -- disabled as it causes more problems.
10062 * model=auto should work fine now
10063 */
10064 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10065
5795b9e6 10066 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10067
25985edc 10068 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10069 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10070 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10071 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10072 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10073 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10074
10075 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10076 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10077 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10078 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10079 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10080 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10081 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10082 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10083 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10084 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10085 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10086
10087 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10088 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10089 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10090 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10091 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10092 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10093 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10094 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10095 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10096
6f3bf657 10097 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10098 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10099 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10100 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10101 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10102 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10103 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10104 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10105 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10106 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10107 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10108 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10109 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10110 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10111 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10112 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10113 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10114 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10115 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10116 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10117 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10118 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10119 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10120 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10121 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10122 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10123 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10124 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10125 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10126 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10127 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10128
ac3e3741 10129 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10130 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10131 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10132 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10133 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10134 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10135 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10136 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10137 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10138 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10139 ALC883_FUJITSU_PI2515),
bfb53037 10140 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10141 ALC888_FUJITSU_XA3530),
272a527c 10142 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10143 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10144 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10145 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10146 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10147 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10148 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10149 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10150
17bba1b7
J
10151 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10152 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10153 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10154 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10155 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10156 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10157 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10158
4953550a 10159 {}
f3cd3f5d
WF
10160};
10161
4953550a 10162/* codec SSID table for Intel Mac */
a9111321 10163static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10164 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10165 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10166 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10167 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10168 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10169 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10170 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10171 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10172 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10173 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10174 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10175 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10176 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10177 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10178 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10179 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10180 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10181 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10182 * so apparently no perfect solution yet
4953550a
TI
10183 */
10184 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10185 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10186 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10187 {} /* terminator */
b25c9da1
WF
10188};
10189
a9111321 10190static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10191 [ALC882_3ST_DIG] = {
10192 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10193 .init_verbs = { alc882_base_init_verbs,
10194 alc882_adc1_init_verbs },
4953550a
TI
10195 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10196 .dac_nids = alc882_dac_nids,
10197 .dig_out_nid = ALC882_DIGOUT_NID,
10198 .dig_in_nid = ALC882_DIGIN_NID,
10199 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10200 .channel_mode = alc882_ch_modes,
10201 .need_dac_fix = 1,
10202 .input_mux = &alc882_capture_source,
10203 },
10204 [ALC882_6ST_DIG] = {
10205 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10206 .init_verbs = { alc882_base_init_verbs,
10207 alc882_adc1_init_verbs },
4953550a
TI
10208 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10209 .dac_nids = alc882_dac_nids,
10210 .dig_out_nid = ALC882_DIGOUT_NID,
10211 .dig_in_nid = ALC882_DIGIN_NID,
10212 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10213 .channel_mode = alc882_sixstack_modes,
10214 .input_mux = &alc882_capture_source,
10215 },
10216 [ALC882_ARIMA] = {
10217 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10218 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10219 alc882_eapd_verbs },
4953550a
TI
10220 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10221 .dac_nids = alc882_dac_nids,
10222 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10223 .channel_mode = alc882_sixstack_modes,
10224 .input_mux = &alc882_capture_source,
10225 },
10226 [ALC882_W2JC] = {
10227 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10228 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10229 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10230 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10231 .dac_nids = alc882_dac_nids,
10232 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10233 .channel_mode = alc880_threestack_modes,
10234 .need_dac_fix = 1,
10235 .input_mux = &alc882_capture_source,
10236 .dig_out_nid = ALC882_DIGOUT_NID,
10237 },
76e6f5a9
RH
10238 [ALC885_MBA21] = {
10239 .mixers = { alc885_mba21_mixer },
10240 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10241 .num_dacs = 2,
10242 .dac_nids = alc882_dac_nids,
10243 .channel_mode = alc885_mba21_ch_modes,
10244 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10245 .input_mux = &alc882_capture_source,
d922b51d 10246 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10247 .setup = alc885_mba21_setup,
d922b51d 10248 .init_hook = alc_hp_automute,
76e6f5a9 10249 },
4953550a
TI
10250 [ALC885_MBP3] = {
10251 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10252 .init_verbs = { alc885_mbp3_init_verbs,
10253 alc880_gpio1_init_verbs },
be0ae923 10254 .num_dacs = 2,
4953550a 10255 .dac_nids = alc882_dac_nids,
be0ae923
TI
10256 .hp_nid = 0x04,
10257 .channel_mode = alc885_mbp_4ch_modes,
10258 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10259 .input_mux = &alc882_capture_source,
10260 .dig_out_nid = ALC882_DIGOUT_NID,
10261 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10262 .unsol_event = alc_sku_unsol_event,
4f5d1706 10263 .setup = alc885_mbp3_setup,
d922b51d 10264 .init_hook = alc_hp_automute,
4953550a
TI
10265 },
10266 [ALC885_MB5] = {
10267 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10268 .init_verbs = { alc885_mb5_init_verbs,
10269 alc880_gpio1_init_verbs },
10270 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10271 .dac_nids = alc882_dac_nids,
10272 .channel_mode = alc885_mb5_6ch_modes,
10273 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10274 .input_mux = &mb5_capture_source,
10275 .dig_out_nid = ALC882_DIGOUT_NID,
10276 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10277 .unsol_event = alc_sku_unsol_event,
9d54f08b 10278 .setup = alc885_mb5_setup,
d922b51d 10279 .init_hook = alc_hp_automute,
4953550a 10280 },
e458b1fa
LY
10281 [ALC885_MACMINI3] = {
10282 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10283 .init_verbs = { alc885_macmini3_init_verbs,
10284 alc880_gpio1_init_verbs },
10285 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10286 .dac_nids = alc882_dac_nids,
10287 .channel_mode = alc885_macmini3_6ch_modes,
10288 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10289 .input_mux = &macmini3_capture_source,
10290 .dig_out_nid = ALC882_DIGOUT_NID,
10291 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10292 .unsol_event = alc_sku_unsol_event,
9d54f08b 10293 .setup = alc885_macmini3_setup,
d922b51d 10294 .init_hook = alc_hp_automute,
e458b1fa 10295 },
4953550a
TI
10296 [ALC885_MACPRO] = {
10297 .mixers = { alc882_macpro_mixer },
10298 .init_verbs = { alc882_macpro_init_verbs },
10299 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10300 .dac_nids = alc882_dac_nids,
10301 .dig_out_nid = ALC882_DIGOUT_NID,
10302 .dig_in_nid = ALC882_DIGIN_NID,
10303 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10304 .channel_mode = alc882_ch_modes,
10305 .input_mux = &alc882_capture_source,
10306 .init_hook = alc885_macpro_init_hook,
10307 },
10308 [ALC885_IMAC24] = {
10309 .mixers = { alc885_imac24_mixer },
10310 .init_verbs = { alc885_imac24_init_verbs },
10311 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10312 .dac_nids = alc882_dac_nids,
10313 .dig_out_nid = ALC882_DIGOUT_NID,
10314 .dig_in_nid = ALC882_DIGIN_NID,
10315 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10316 .channel_mode = alc882_ch_modes,
10317 .input_mux = &alc882_capture_source,
d922b51d 10318 .unsol_event = alc_sku_unsol_event,
4f5d1706 10319 .setup = alc885_imac24_setup,
4953550a
TI
10320 .init_hook = alc885_imac24_init_hook,
10321 },
4b7e1803 10322 [ALC885_IMAC91] = {
b7cccc52 10323 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10324 .init_verbs = { alc885_imac91_init_verbs,
10325 alc880_gpio1_init_verbs },
10326 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10327 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10328 .channel_mode = alc885_mba21_ch_modes,
10329 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10330 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10331 .dig_out_nid = ALC882_DIGOUT_NID,
10332 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10333 .unsol_event = alc_sku_unsol_event,
9d54f08b 10334 .setup = alc885_imac91_setup,
d922b51d 10335 .init_hook = alc_hp_automute,
4b7e1803 10336 },
4953550a
TI
10337 [ALC882_TARGA] = {
10338 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10339 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10340 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10341 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10342 .dac_nids = alc882_dac_nids,
10343 .dig_out_nid = ALC882_DIGOUT_NID,
10344 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10345 .adc_nids = alc882_adc_nids,
10346 .capsrc_nids = alc882_capsrc_nids,
10347 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10348 .channel_mode = alc882_3ST_6ch_modes,
10349 .need_dac_fix = 1,
10350 .input_mux = &alc882_capture_source,
d922b51d 10351 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10352 .setup = alc882_targa_setup,
10353 .init_hook = alc882_targa_automute,
4953550a
TI
10354 },
10355 [ALC882_ASUS_A7J] = {
10356 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10357 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10358 alc882_asus_a7j_verbs},
4953550a
TI
10359 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10360 .dac_nids = alc882_dac_nids,
10361 .dig_out_nid = ALC882_DIGOUT_NID,
10362 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10363 .adc_nids = alc882_adc_nids,
10364 .capsrc_nids = alc882_capsrc_nids,
10365 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10366 .channel_mode = alc882_3ST_6ch_modes,
10367 .need_dac_fix = 1,
10368 .input_mux = &alc882_capture_source,
10369 },
10370 [ALC882_ASUS_A7M] = {
10371 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10372 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10373 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10374 alc882_asus_a7m_verbs },
10375 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10376 .dac_nids = alc882_dac_nids,
10377 .dig_out_nid = ALC882_DIGOUT_NID,
10378 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10379 .channel_mode = alc880_threestack_modes,
10380 .need_dac_fix = 1,
10381 .input_mux = &alc882_capture_source,
10382 },
9c7f852e
TI
10383 [ALC883_3ST_2ch_DIG] = {
10384 .mixers = { alc883_3ST_2ch_mixer },
10385 .init_verbs = { alc883_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
10388 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10389 .dig_in_nid = ALC883_DIGIN_NID,
10390 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10391 .channel_mode = alc883_3ST_2ch_modes,
10392 .input_mux = &alc883_capture_source,
10393 },
10394 [ALC883_3ST_6ch_DIG] = {
10395 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10396 .init_verbs = { alc883_init_verbs },
10397 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10398 .dac_nids = alc883_dac_nids,
10399 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10400 .dig_in_nid = ALC883_DIGIN_NID,
10401 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10402 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10403 .need_dac_fix = 1,
9c7f852e 10404 .input_mux = &alc883_capture_source,
f12ab1e0 10405 },
9c7f852e
TI
10406 [ALC883_3ST_6ch] = {
10407 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10408 .init_verbs = { alc883_init_verbs },
10409 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10410 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10411 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10412 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10413 .need_dac_fix = 1,
9c7f852e 10414 .input_mux = &alc883_capture_source,
f12ab1e0 10415 },
17bba1b7
J
10416 [ALC883_3ST_6ch_INTEL] = {
10417 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10418 .init_verbs = { alc883_init_verbs },
10419 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10420 .dac_nids = alc883_dac_nids,
10421 .dig_out_nid = ALC883_DIGOUT_NID,
10422 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10423 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10424 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10425 .channel_mode = alc883_3ST_6ch_intel_modes,
10426 .need_dac_fix = 1,
10427 .input_mux = &alc883_3stack_6ch_intel,
10428 },
87a8c370
JK
10429 [ALC889A_INTEL] = {
10430 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10431 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10432 alc_hp15_unsol_verbs },
87a8c370
JK
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10436 .adc_nids = alc889_adc_nids,
10437 .dig_out_nid = ALC883_DIGOUT_NID,
10438 .dig_in_nid = ALC883_DIGIN_NID,
10439 .slave_dig_outs = alc883_slave_dig_outs,
10440 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10441 .channel_mode = alc889_8ch_intel_modes,
10442 .capsrc_nids = alc889_capsrc_nids,
10443 .input_mux = &alc889_capture_source,
4f5d1706 10444 .setup = alc889_automute_setup,
d922b51d
TI
10445 .init_hook = alc_hp_automute,
10446 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10447 .need_dac_fix = 1,
10448 },
10449 [ALC889_INTEL] = {
10450 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10451 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10452 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10453 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10454 .dac_nids = alc883_dac_nids,
10455 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10456 .adc_nids = alc889_adc_nids,
10457 .dig_out_nid = ALC883_DIGOUT_NID,
10458 .dig_in_nid = ALC883_DIGIN_NID,
10459 .slave_dig_outs = alc883_slave_dig_outs,
10460 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10461 .channel_mode = alc889_8ch_intel_modes,
10462 .capsrc_nids = alc889_capsrc_nids,
10463 .input_mux = &alc889_capture_source,
4f5d1706 10464 .setup = alc889_automute_setup,
6732bd0d 10465 .init_hook = alc889_intel_init_hook,
d922b51d 10466 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10467 .need_dac_fix = 1,
10468 },
9c7f852e
TI
10469 [ALC883_6ST_DIG] = {
10470 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10471 .init_verbs = { alc883_init_verbs },
10472 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10473 .dac_nids = alc883_dac_nids,
10474 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10475 .dig_in_nid = ALC883_DIGIN_NID,
10476 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10477 .channel_mode = alc883_sixstack_modes,
10478 .input_mux = &alc883_capture_source,
10479 },
ccc656ce 10480 [ALC883_TARGA_DIG] = {
c259249f 10481 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10482 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10483 alc883_targa_verbs},
ccc656ce
KY
10484 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10485 .dac_nids = alc883_dac_nids,
10486 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10487 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10488 .channel_mode = alc883_3ST_6ch_modes,
10489 .need_dac_fix = 1,
10490 .input_mux = &alc883_capture_source,
c259249f 10491 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10492 .setup = alc882_targa_setup,
10493 .init_hook = alc882_targa_automute,
ccc656ce
KY
10494 },
10495 [ALC883_TARGA_2ch_DIG] = {
c259249f 10496 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10497 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10498 alc883_targa_verbs},
ccc656ce
KY
10499 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10500 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10501 .adc_nids = alc883_adc_nids_alt,
10502 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10503 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10504 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10505 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10506 .channel_mode = alc883_3ST_2ch_modes,
10507 .input_mux = &alc883_capture_source,
c259249f 10508 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10509 .setup = alc882_targa_setup,
10510 .init_hook = alc882_targa_automute,
ccc656ce 10511 },
64a8be74 10512 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10513 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10514 alc883_chmode_mixer },
64a8be74 10515 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10516 alc883_targa_verbs },
64a8be74
DH
10517 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10518 .dac_nids = alc883_dac_nids,
10519 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10520 .adc_nids = alc883_adc_nids_rev,
10521 .capsrc_nids = alc883_capsrc_nids_rev,
10522 .dig_out_nid = ALC883_DIGOUT_NID,
10523 .dig_in_nid = ALC883_DIGIN_NID,
10524 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10525 .channel_mode = alc883_4ST_8ch_modes,
10526 .need_dac_fix = 1,
10527 .input_mux = &alc883_capture_source,
c259249f 10528 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10529 .setup = alc882_targa_setup,
10530 .init_hook = alc882_targa_automute,
64a8be74 10531 },
bab282b9 10532 [ALC883_ACER] = {
676a9b53 10533 .mixers = { alc883_base_mixer },
bab282b9
VA
10534 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10535 * and the headphone jack. Turn this on and rely on the
10536 * standard mute methods whenever the user wants to turn
10537 * these outputs off.
10538 */
10539 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10540 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10541 .dac_nids = alc883_dac_nids,
bab282b9
VA
10542 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10543 .channel_mode = alc883_3ST_2ch_modes,
10544 .input_mux = &alc883_capture_source,
10545 },
2880a867 10546 [ALC883_ACER_ASPIRE] = {
676a9b53 10547 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10548 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10549 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10550 .dac_nids = alc883_dac_nids,
10551 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10552 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10553 .channel_mode = alc883_3ST_2ch_modes,
10554 .input_mux = &alc883_capture_source,
d922b51d 10555 .unsol_event = alc_sku_unsol_event,
4f5d1706 10556 .setup = alc883_acer_aspire_setup,
d922b51d 10557 .init_hook = alc_hp_automute,
d1a991a6 10558 },
5b2d1eca 10559 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10560 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10561 alc883_chmode_mixer },
10562 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10563 alc888_acer_aspire_4930g_verbs },
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10567 .adc_nids = alc883_adc_nids_rev,
10568 .capsrc_nids = alc883_capsrc_nids_rev,
10569 .dig_out_nid = ALC883_DIGOUT_NID,
10570 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10571 .channel_mode = alc883_3ST_6ch_modes,
10572 .need_dac_fix = 1,
973b8cb0 10573 .const_channel_count = 6,
5b2d1eca 10574 .num_mux_defs =
ef8ef5fb
VP
10575 ARRAY_SIZE(alc888_2_capture_sources),
10576 .input_mux = alc888_2_capture_sources,
d922b51d 10577 .unsol_event = alc_sku_unsol_event,
4f5d1706 10578 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10579 .init_hook = alc_hp_automute,
d2fd4b09
TV
10580 },
10581 [ALC888_ACER_ASPIRE_6530G] = {
10582 .mixers = { alc888_acer_aspire_6530_mixer },
10583 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10584 alc888_acer_aspire_6530g_verbs },
10585 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10586 .dac_nids = alc883_dac_nids,
10587 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10588 .adc_nids = alc883_adc_nids_rev,
10589 .capsrc_nids = alc883_capsrc_nids_rev,
10590 .dig_out_nid = ALC883_DIGOUT_NID,
10591 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10592 .channel_mode = alc883_3ST_2ch_modes,
10593 .num_mux_defs =
10594 ARRAY_SIZE(alc888_2_capture_sources),
10595 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10596 .unsol_event = alc_sku_unsol_event,
4f5d1706 10597 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10598 .init_hook = alc_hp_automute,
5b2d1eca 10599 },
3b315d70 10600 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10601 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10602 alc883_chmode_mixer },
10603 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10604 alc889_acer_aspire_8930g_verbs,
10605 alc889_eapd_verbs},
3b315d70
HM
10606 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10607 .dac_nids = alc883_dac_nids,
018df418
HM
10608 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10609 .adc_nids = alc889_adc_nids,
10610 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10611 .dig_out_nid = ALC883_DIGOUT_NID,
10612 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10613 .channel_mode = alc883_3ST_6ch_modes,
10614 .need_dac_fix = 1,
10615 .const_channel_count = 6,
10616 .num_mux_defs =
018df418
HM
10617 ARRAY_SIZE(alc889_capture_sources),
10618 .input_mux = alc889_capture_sources,
d922b51d 10619 .unsol_event = alc_sku_unsol_event,
4f5d1706 10620 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10621 .init_hook = alc_hp_automute,
f5de24b0 10622#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10623 .power_hook = alc_power_eapd,
f5de24b0 10624#endif
3b315d70 10625 },
fc86f954
DK
10626 [ALC888_ACER_ASPIRE_7730G] = {
10627 .mixers = { alc883_3ST_6ch_mixer,
10628 alc883_chmode_mixer },
10629 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10630 alc888_acer_aspire_7730G_verbs },
10631 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10632 .dac_nids = alc883_dac_nids,
10633 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10634 .adc_nids = alc883_adc_nids_rev,
10635 .capsrc_nids = alc883_capsrc_nids_rev,
10636 .dig_out_nid = ALC883_DIGOUT_NID,
10637 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10638 .channel_mode = alc883_3ST_6ch_modes,
10639 .need_dac_fix = 1,
10640 .const_channel_count = 6,
10641 .input_mux = &alc883_capture_source,
d922b51d 10642 .unsol_event = alc_sku_unsol_event,
d9477207 10643 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10644 .init_hook = alc_hp_automute,
fc86f954 10645 },
c07584c8
TD
10646 [ALC883_MEDION] = {
10647 .mixers = { alc883_fivestack_mixer,
10648 alc883_chmode_mixer },
10649 .init_verbs = { alc883_init_verbs,
b373bdeb 10650 alc883_medion_eapd_verbs },
c07584c8
TD
10651 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10652 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10653 .adc_nids = alc883_adc_nids_alt,
10654 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10655 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10656 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10657 .channel_mode = alc883_sixstack_modes,
10658 .input_mux = &alc883_capture_source,
b373bdeb 10659 },
7ad7b218
MC
10660 [ALC883_MEDION_WIM2160] = {
10661 .mixers = { alc883_medion_wim2160_mixer },
10662 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10663 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10664 .dac_nids = alc883_dac_nids,
10665 .dig_out_nid = ALC883_DIGOUT_NID,
10666 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10667 .adc_nids = alc883_adc_nids,
10668 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10669 .channel_mode = alc883_3ST_2ch_modes,
10670 .input_mux = &alc883_capture_source,
d922b51d 10671 .unsol_event = alc_sku_unsol_event,
7ad7b218 10672 .setup = alc883_medion_wim2160_setup,
d922b51d 10673 .init_hook = alc_hp_automute,
7ad7b218 10674 },
b373bdeb 10675 [ALC883_LAPTOP_EAPD] = {
676a9b53 10676 .mixers = { alc883_base_mixer },
b373bdeb
AN
10677 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10678 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10679 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10680 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10681 .channel_mode = alc883_3ST_2ch_modes,
10682 .input_mux = &alc883_capture_source,
10683 },
a65cc60f 10684 [ALC883_CLEVO_M540R] = {
10685 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10686 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10687 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10688 .dac_nids = alc883_dac_nids,
10689 .dig_out_nid = ALC883_DIGOUT_NID,
10690 .dig_in_nid = ALC883_DIGIN_NID,
10691 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10692 .channel_mode = alc883_3ST_6ch_clevo_modes,
10693 .need_dac_fix = 1,
10694 .input_mux = &alc883_capture_source,
10695 /* This machine has the hardware HP auto-muting, thus
10696 * we need no software mute via unsol event
10697 */
10698 },
0c4cc443
HRK
10699 [ALC883_CLEVO_M720] = {
10700 .mixers = { alc883_clevo_m720_mixer },
10701 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10703 .dac_nids = alc883_dac_nids,
10704 .dig_out_nid = ALC883_DIGOUT_NID,
10705 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10706 .channel_mode = alc883_3ST_2ch_modes,
10707 .input_mux = &alc883_capture_source,
0c4cc443 10708 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10709 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10710 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10711 },
bc9f98a9
KY
10712 [ALC883_LENOVO_101E_2ch] = {
10713 .mixers = { alc883_lenovo_101e_2ch_mixer},
10714 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10715 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10716 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10717 .adc_nids = alc883_adc_nids_alt,
10718 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10719 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10720 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10721 .channel_mode = alc883_3ST_2ch_modes,
10722 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10723 .setup = alc883_lenovo_101e_setup,
10724 .unsol_event = alc_sku_unsol_event,
10725 .init_hook = alc_inithook,
bc9f98a9 10726 },
272a527c
KY
10727 [ALC883_LENOVO_NB0763] = {
10728 .mixers = { alc883_lenovo_nb0763_mixer },
10729 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10730 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10731 .dac_nids = alc883_dac_nids,
272a527c
KY
10732 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10733 .channel_mode = alc883_3ST_2ch_modes,
10734 .need_dac_fix = 1,
10735 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10736 .unsol_event = alc_sku_unsol_event,
dc427170 10737 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10738 .init_hook = alc_hp_automute,
272a527c
KY
10739 },
10740 [ALC888_LENOVO_MS7195_DIG] = {
10741 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10742 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10743 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10744 .dac_nids = alc883_dac_nids,
10745 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10746 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10747 .channel_mode = alc883_3ST_6ch_modes,
10748 .need_dac_fix = 1,
10749 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10750 .unsol_event = alc_sku_unsol_event,
10751 .setup = alc888_lenovo_ms7195_setup,
10752 .init_hook = alc_inithook,
189609ae
KY
10753 },
10754 [ALC883_HAIER_W66] = {
c259249f 10755 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10756 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10757 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10758 .dac_nids = alc883_dac_nids,
10759 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10760 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10761 .channel_mode = alc883_3ST_2ch_modes,
10762 .input_mux = &alc883_capture_source,
d922b51d 10763 .unsol_event = alc_sku_unsol_event,
4f5d1706 10764 .setup = alc883_haier_w66_setup,
d922b51d 10765 .init_hook = alc_hp_automute,
eea6419e 10766 },
4723c022 10767 [ALC888_3ST_HP] = {
eea6419e 10768 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10769 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10770 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10771 .dac_nids = alc883_dac_nids,
4723c022
CM
10772 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10773 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10774 .need_dac_fix = 1,
10775 .input_mux = &alc883_capture_source,
d922b51d 10776 .unsol_event = alc_sku_unsol_event,
4f5d1706 10777 .setup = alc888_3st_hp_setup,
d922b51d 10778 .init_hook = alc_hp_automute,
8341de60 10779 },
5795b9e6 10780 [ALC888_6ST_DELL] = {
f24dbdc6 10781 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10782 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10783 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10784 .dac_nids = alc883_dac_nids,
10785 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10786 .dig_in_nid = ALC883_DIGIN_NID,
10787 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10788 .channel_mode = alc883_sixstack_modes,
10789 .input_mux = &alc883_capture_source,
d922b51d 10790 .unsol_event = alc_sku_unsol_event,
4f5d1706 10791 .setup = alc888_6st_dell_setup,
d922b51d 10792 .init_hook = alc_hp_automute,
5795b9e6 10793 },
a8848bd6
AS
10794 [ALC883_MITAC] = {
10795 .mixers = { alc883_mitac_mixer },
10796 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10797 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10798 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10799 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10800 .channel_mode = alc883_3ST_2ch_modes,
10801 .input_mux = &alc883_capture_source,
d922b51d 10802 .unsol_event = alc_sku_unsol_event,
4f5d1706 10803 .setup = alc883_mitac_setup,
d922b51d 10804 .init_hook = alc_hp_automute,
a8848bd6 10805 },
fb97dc67
J
10806 [ALC883_FUJITSU_PI2515] = {
10807 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10808 .init_verbs = { alc883_init_verbs,
10809 alc883_2ch_fujitsu_pi2515_verbs},
10810 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10811 .dac_nids = alc883_dac_nids,
10812 .dig_out_nid = ALC883_DIGOUT_NID,
10813 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10814 .channel_mode = alc883_3ST_2ch_modes,
10815 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10816 .unsol_event = alc_sku_unsol_event,
4f5d1706 10817 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10818 .init_hook = alc_hp_automute,
fb97dc67 10819 },
ef8ef5fb
VP
10820 [ALC888_FUJITSU_XA3530] = {
10821 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10822 .init_verbs = { alc883_init_verbs,
10823 alc888_fujitsu_xa3530_verbs },
10824 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10825 .dac_nids = alc883_dac_nids,
10826 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10827 .adc_nids = alc883_adc_nids_rev,
10828 .capsrc_nids = alc883_capsrc_nids_rev,
10829 .dig_out_nid = ALC883_DIGOUT_NID,
10830 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10831 .channel_mode = alc888_4ST_8ch_intel_modes,
10832 .num_mux_defs =
10833 ARRAY_SIZE(alc888_2_capture_sources),
10834 .input_mux = alc888_2_capture_sources,
d922b51d 10835 .unsol_event = alc_sku_unsol_event,
4f5d1706 10836 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10837 .init_hook = alc_hp_automute,
ef8ef5fb 10838 },
e2757d5e
KY
10839 [ALC888_LENOVO_SKY] = {
10840 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10841 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10842 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10843 .dac_nids = alc883_dac_nids,
10844 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10845 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10846 .channel_mode = alc883_sixstack_modes,
10847 .need_dac_fix = 1,
10848 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10849 .unsol_event = alc_sku_unsol_event,
4f5d1706 10850 .setup = alc888_lenovo_sky_setup,
d922b51d 10851 .init_hook = alc_hp_automute,
e2757d5e
KY
10852 },
10853 [ALC888_ASUS_M90V] = {
10854 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10855 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10856 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10857 .dac_nids = alc883_dac_nids,
10858 .dig_out_nid = ALC883_DIGOUT_NID,
10859 .dig_in_nid = ALC883_DIGIN_NID,
10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10861 .channel_mode = alc883_3ST_6ch_modes,
10862 .need_dac_fix = 1,
10863 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10864 .unsol_event = alc_sku_unsol_event,
10865 .setup = alc883_mode2_setup,
10866 .init_hook = alc_inithook,
e2757d5e
KY
10867 },
10868 [ALC888_ASUS_EEE1601] = {
10869 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10870 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10871 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10873 .dac_nids = alc883_dac_nids,
10874 .dig_out_nid = ALC883_DIGOUT_NID,
10875 .dig_in_nid = ALC883_DIGIN_NID,
10876 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10877 .channel_mode = alc883_3ST_2ch_modes,
10878 .need_dac_fix = 1,
10879 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10880 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10881 .init_hook = alc883_eee1601_inithook,
10882 },
3ab90935
WF
10883 [ALC1200_ASUS_P5Q] = {
10884 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10885 .init_verbs = { alc883_init_verbs },
10886 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10887 .dac_nids = alc883_dac_nids,
10888 .dig_out_nid = ALC1200_DIGOUT_NID,
10889 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10890 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10891 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10892 .channel_mode = alc883_sixstack_modes,
10893 .input_mux = &alc883_capture_source,
10894 },
eb4c41d3
TS
10895 [ALC889A_MB31] = {
10896 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10897 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10898 alc880_gpio1_init_verbs },
10899 .adc_nids = alc883_adc_nids,
10900 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10901 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10902 .dac_nids = alc883_dac_nids,
10903 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904 .channel_mode = alc889A_mb31_6ch_modes,
10905 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10906 .input_mux = &alc889A_mb31_capture_source,
10907 .dig_out_nid = ALC883_DIGOUT_NID,
10908 .unsol_event = alc889A_mb31_unsol_event,
10909 .init_hook = alc889A_mb31_automute,
10910 },
3e1647c5
GG
10911 [ALC883_SONY_VAIO_TT] = {
10912 .mixers = { alc883_vaiott_mixer },
10913 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10914 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10915 .dac_nids = alc883_dac_nids,
10916 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10917 .channel_mode = alc883_3ST_2ch_modes,
10918 .input_mux = &alc883_capture_source,
d922b51d 10919 .unsol_event = alc_sku_unsol_event,
4f5d1706 10920 .setup = alc883_vaiott_setup,
d922b51d 10921 .init_hook = alc_hp_automute,
3e1647c5 10922 },
9c7f852e
TI
10923};
10924
10925
4953550a
TI
10926/*
10927 * Pin config fixes
10928 */
10929enum {
954a29c8 10930 PINFIX_ABIT_AW9D_MAX,
32eea388 10931 PINFIX_LENOVO_Y530,
954a29c8 10932 PINFIX_PB_M5210,
c3d226ab 10933 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10934};
10935
f8f25ba3
TI
10936static const struct alc_fixup alc882_fixups[] = {
10937 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10938 .type = ALC_FIXUP_PINS,
10939 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10940 { 0x15, 0x01080104 }, /* side */
10941 { 0x16, 0x01011012 }, /* rear */
10942 { 0x17, 0x01016011 }, /* clfe */
10943 { }
10944 }
f8f25ba3 10945 },
32eea388
DH
10946 [PINFIX_LENOVO_Y530] = {
10947 .type = ALC_FIXUP_PINS,
10948 .v.pins = (const struct alc_pincfg[]) {
10949 { 0x15, 0x99130112 }, /* rear int speakers */
10950 { 0x16, 0x99130111 }, /* subwoofer */
10951 { }
10952 }
10953 },
954a29c8 10954 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10955 .type = ALC_FIXUP_VERBS,
10956 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10957 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10958 {}
10959 }
954a29c8 10960 },
c3d226ab 10961 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10962 .type = ALC_FIXUP_SKU,
10963 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10964 },
4953550a
TI
10965};
10966
a9111321 10967static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10968 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10969 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10970 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10971 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10972 {}
10973};
10974
9c7f852e
TI
10975/*
10976 * BIOS auto configuration
10977 */
05f5f477
TI
10978static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10979 const struct auto_pin_cfg *cfg)
10980{
10981 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10982}
10983
4953550a 10984static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10985 hda_nid_t nid, int pin_type,
489008cd 10986 hda_nid_t dac)
9c7f852e 10987{
f12ab1e0
TI
10988 int idx;
10989
489008cd 10990 /* set as output */
f6c7e546 10991 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10992
10993 if (dac == 0x25)
9c7f852e 10994 idx = 4;
489008cd
TI
10995 else if (dac >= 0x02 && dac <= 0x05)
10996 idx = dac - 2;
f9700d5a 10997 else
489008cd 10998 return;
9c7f852e 10999 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11000}
11001
4953550a 11002static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11003{
11004 struct alc_spec *spec = codec->spec;
11005 int i;
11006
11007 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11008 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11009 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11010 if (nid)
4953550a 11011 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11012 spec->multiout.dac_nids[i]);
9c7f852e
TI
11013 }
11014}
11015
4953550a 11016static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11017{
11018 struct alc_spec *spec = codec->spec;
489008cd 11019 hda_nid_t pin, dac;
5855fb80 11020 int i;
9c7f852e 11021
0a3fabe3
DH
11022 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11023 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11024 pin = spec->autocfg.hp_pins[i];
11025 if (!pin)
11026 break;
11027 dac = spec->multiout.hp_nid;
11028 if (!dac)
11029 dac = spec->multiout.dac_nids[0]; /* to front */
11030 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11031 }
489008cd 11032 }
0a3fabe3
DH
11033
11034 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11035 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11036 pin = spec->autocfg.speaker_pins[i];
11037 if (!pin)
11038 break;
11039 dac = spec->multiout.extra_out_nid[0];
11040 if (!dac)
11041 dac = spec->multiout.dac_nids[0]; /* to front */
11042 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11043 }
489008cd 11044 }
9c7f852e
TI
11045}
11046
4953550a 11047static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11048{
11049 struct alc_spec *spec = codec->spec;
66ceeb6b 11050 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11051 int i;
11052
66ceeb6b
TI
11053 for (i = 0; i < cfg->num_inputs; i++) {
11054 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11055 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11056 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11057 snd_hda_codec_write(codec, nid, 0,
11058 AC_VERB_SET_AMP_GAIN_MUTE,
11059 AMP_OUT_MUTE);
11060 }
11061}
11062
11063static void alc882_auto_init_input_src(struct hda_codec *codec)
11064{
11065 struct alc_spec *spec = codec->spec;
11066 int c;
11067
11068 for (c = 0; c < spec->num_adc_nids; c++) {
11069 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11070 hda_nid_t nid = spec->capsrc_nids[c];
11071 unsigned int mux_idx;
11072 const struct hda_input_mux *imux;
11073 int conns, mute, idx, item;
11074
10696aa0
TI
11075 /* mute ADC */
11076 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11077 AC_VERB_SET_AMP_GAIN_MUTE,
11078 AMP_IN_MUTE(0));
11079
4953550a
TI
11080 conns = snd_hda_get_connections(codec, nid, conn_list,
11081 ARRAY_SIZE(conn_list));
11082 if (conns < 0)
11083 continue;
11084 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11085 imux = &spec->input_mux[mux_idx];
5311114d
TI
11086 if (!imux->num_items && mux_idx > 0)
11087 imux = &spec->input_mux[0];
4953550a
TI
11088 for (idx = 0; idx < conns; idx++) {
11089 /* if the current connection is the selected one,
11090 * unmute it as default - otherwise mute it
11091 */
11092 mute = AMP_IN_MUTE(idx);
11093 for (item = 0; item < imux->num_items; item++) {
11094 if (imux->items[item].index == idx) {
11095 if (spec->cur_mux[c] == item)
11096 mute = AMP_IN_UNMUTE(idx);
11097 break;
11098 }
11099 }
11100 /* check if we have a selector or mixer
11101 * we could check for the widget type instead, but
11102 * just check for Amp-In presence (in case of mixer
11103 * without amp-in there is something wrong, this
11104 * function shouldn't be used or capsrc nid is wrong)
11105 */
11106 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11107 snd_hda_codec_write(codec, nid, 0,
11108 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11109 mute);
11110 else if (mute != AMP_IN_MUTE(idx))
11111 snd_hda_codec_write(codec, nid, 0,
11112 AC_VERB_SET_CONNECT_SEL,
11113 idx);
9c7f852e
TI
11114 }
11115 }
11116}
11117
4953550a
TI
11118/* add mic boosts if needed */
11119static int alc_auto_add_mic_boost(struct hda_codec *codec)
11120{
11121 struct alc_spec *spec = codec->spec;
66ceeb6b 11122 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11123 int i, err;
53e8c323 11124 int type_idx = 0;
4953550a 11125 hda_nid_t nid;
5322bf27 11126 const char *prev_label = NULL;
4953550a 11127
66ceeb6b 11128 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11129 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11130 break;
11131 nid = cfg->inputs[i].pin;
11132 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11133 const char *label;
11134 char boost_label[32];
11135
11136 label = hda_get_autocfg_input_label(codec, cfg, i);
11137 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11138 type_idx++;
11139 else
11140 type_idx = 0;
5322bf27
DH
11141 prev_label = label;
11142
11143 snprintf(boost_label, sizeof(boost_label),
11144 "%s Boost Volume", label);
11145 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11146 boost_label, type_idx,
4953550a 11147 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11148 if (err < 0)
11149 return err;
11150 }
4953550a
TI
11151 }
11152 return 0;
11153}
f511b01c 11154
9c7f852e 11155/* almost identical with ALC880 parser... */
4953550a 11156static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11157{
11158 struct alc_spec *spec = codec->spec;
4c6d72d1 11159 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11160 int err;
9c7f852e 11161
05f5f477
TI
11162 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11163 alc882_ignore);
9c7f852e
TI
11164 if (err < 0)
11165 return err;
05f5f477
TI
11166 if (!spec->autocfg.line_outs)
11167 return 0; /* can't find valid BIOS pin config */
776e184e 11168
05f5f477 11169 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11170 if (err < 0)
11171 return err;
11172 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11173 if (err < 0)
11174 return err;
569ed348 11175 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11176 if (err < 0)
11177 return err;
11178 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11179 "Headphone");
05f5f477
TI
11180 if (err < 0)
11181 return err;
11182 err = alc880_auto_create_extra_out(spec,
11183 spec->autocfg.speaker_pins[0],
11184 "Speaker");
11185 if (err < 0)
11186 return err;
05f5f477 11187 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11188 if (err < 0)
11189 return err;
11190
05f5f477
TI
11191 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11192
757899ac 11193 alc_auto_parse_digital(codec);
05f5f477
TI
11194
11195 if (spec->kctls.list)
11196 add_mixer(spec, spec->kctls.list);
11197
11198 add_verb(spec, alc883_auto_init_verbs);
4953550a 11199 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11200 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11201 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11202
05f5f477
TI
11203 spec->num_mux_defs = 1;
11204 spec->input_mux = &spec->private_imux[0];
11205
6227cdce 11206 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11207
11208 err = alc_auto_add_mic_boost(codec);
11209 if (err < 0)
11210 return err;
61b9b9b1 11211
776e184e 11212 return 1; /* config found */
9c7f852e
TI
11213}
11214
11215/* additional initialization for auto-configuration model */
4953550a 11216static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11217{
f6c7e546 11218 struct alc_spec *spec = codec->spec;
4953550a
TI
11219 alc882_auto_init_multi_out(codec);
11220 alc882_auto_init_hp_out(codec);
11221 alc882_auto_init_analog_input(codec);
11222 alc882_auto_init_input_src(codec);
757899ac 11223 alc_auto_init_digital(codec);
f6c7e546 11224 if (spec->unsol_event)
7fb0d78f 11225 alc_inithook(codec);
9c7f852e
TI
11226}
11227
4953550a 11228static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11229{
11230 struct alc_spec *spec;
11231 int err, board_config;
11232
11233 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11234 if (spec == NULL)
11235 return -ENOMEM;
11236
11237 codec->spec = spec;
11238
4953550a
TI
11239 switch (codec->vendor_id) {
11240 case 0x10ec0882:
11241 case 0x10ec0885:
11242 break;
11243 default:
11244 /* ALC883 and variants */
11245 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11246 break;
11247 }
2c3bf9ab 11248
4953550a
TI
11249 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11250 alc882_models,
11251 alc882_cfg_tbl);
11252
11253 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11254 board_config = snd_hda_check_board_codec_sid_config(codec,
11255 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11256
11257 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11258 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11259 codec->chip_name);
11260 board_config = ALC882_AUTO;
9c7f852e
TI
11261 }
11262
b5bfbc67
TI
11263 if (board_config == ALC882_AUTO) {
11264 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11265 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11266 }
4953550a 11267
90622917
DH
11268 alc_auto_parse_customize_define(codec);
11269
4953550a 11270 if (board_config == ALC882_AUTO) {
9c7f852e 11271 /* automatic parse from the BIOS config */
4953550a 11272 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11273 if (err < 0) {
11274 alc_free(codec);
11275 return err;
f12ab1e0 11276 } else if (!err) {
9c7f852e
TI
11277 printk(KERN_INFO
11278 "hda_codec: Cannot set up configuration "
11279 "from BIOS. Using base mode...\n");
4953550a 11280 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11281 }
11282 }
11283
dc1eae25 11284 if (has_cdefine_beep(codec)) {
8af2591d
TI
11285 err = snd_hda_attach_beep_device(codec, 0x1);
11286 if (err < 0) {
11287 alc_free(codec);
11288 return err;
11289 }
680cd536
KK
11290 }
11291
4953550a 11292 if (board_config != ALC882_AUTO)
e9c364c0 11293 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11294
4953550a
TI
11295 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11296 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11297 /* FIXME: setup DAC5 */
11298 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11299 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11300
11301 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11302 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11303
4953550a 11304 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11305 int i, j;
4953550a
TI
11306 spec->num_adc_nids = 0;
11307 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11308 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11309 hda_nid_t cap;
d11f74c6 11310 hda_nid_t items[16];
4953550a
TI
11311 hda_nid_t nid = alc882_adc_nids[i];
11312 unsigned int wcap = get_wcaps(codec, nid);
11313 /* get type */
a22d543a 11314 wcap = get_wcaps_type(wcap);
4953550a
TI
11315 if (wcap != AC_WID_AUD_IN)
11316 continue;
11317 spec->private_adc_nids[spec->num_adc_nids] = nid;
11318 err = snd_hda_get_connections(codec, nid, &cap, 1);
11319 if (err < 0)
11320 continue;
d11f74c6
TI
11321 err = snd_hda_get_connections(codec, cap, items,
11322 ARRAY_SIZE(items));
11323 if (err < 0)
11324 continue;
11325 for (j = 0; j < imux->num_items; j++)
11326 if (imux->items[j].index >= err)
11327 break;
11328 if (j < imux->num_items)
11329 continue;
4953550a
TI
11330 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11331 spec->num_adc_nids++;
61b9b9b1 11332 }
4953550a
TI
11333 spec->adc_nids = spec->private_adc_nids;
11334 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11335 }
11336
b59bdf3b 11337 set_capture_mixer(codec);
da00c244 11338
dc1eae25 11339 if (has_cdefine_beep(codec))
da00c244 11340 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11341
b5bfbc67 11342 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11343
2134ea4f
TI
11344 spec->vmaster_nid = 0x0c;
11345
9c7f852e 11346 codec->patch_ops = alc_patch_ops;
4953550a
TI
11347 if (board_config == ALC882_AUTO)
11348 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11349
11350 alc_init_jacks(codec);
cb53c626
TI
11351#ifdef CONFIG_SND_HDA_POWER_SAVE
11352 if (!spec->loopback.amplist)
4953550a 11353 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11354#endif
9c7f852e
TI
11355
11356 return 0;
11357}
11358
4953550a 11359
9c7f852e
TI
11360/*
11361 * ALC262 support
11362 */
11363
11364#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11365#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11366
11367#define alc262_dac_nids alc260_dac_nids
11368#define alc262_adc_nids alc882_adc_nids
11369#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11370#define alc262_capsrc_nids alc882_capsrc_nids
11371#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11372
11373#define alc262_modes alc260_modes
11374#define alc262_capture_source alc882_capture_source
11375
4c6d72d1 11376static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11377 /* ADC0 */
11378 0x09
11379};
11380
4c6d72d1 11381static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11382
a9111321 11383static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11384 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11385 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11386 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11387 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11388 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11389 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11391 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11392 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11393 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11394 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11395 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11396 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11397 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11398 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11400 { } /* end */
11401};
11402
ce875f07 11403/* update HP, line and mono-out pins according to the master switch */
e9427969 11404#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11405
e9427969 11406static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11407{
11408 struct alc_spec *spec = codec->spec;
864f92be 11409
e9427969
TI
11410 spec->autocfg.hp_pins[0] = 0x1b;
11411 spec->autocfg.speaker_pins[0] = 0x16;
11412 spec->automute = 1;
11413 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11414}
11415
e9427969 11416static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11417{
11418 struct alc_spec *spec = codec->spec;
864f92be 11419
e9427969
TI
11420 spec->autocfg.hp_pins[0] = 0x15;
11421 spec->autocfg.speaker_pins[0] = 0x16;
11422 spec->automute = 1;
11423 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11424}
11425
b72519b5 11426#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11427#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11428
b72519b5
TI
11429#define ALC262_HP_MASTER_SWITCH \
11430 { \
11431 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11432 .name = "Master Playback Switch", \
11433 .info = snd_ctl_boolean_mono_info, \
11434 .get = alc262_hp_master_sw_get, \
11435 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11436 }, \
11437 { \
11438 .iface = NID_MAPPING, \
11439 .name = "Master Playback Switch", \
11440 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11441 }
11442
5b0cb1d8 11443
a9111321 11444static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11445 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11446 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11448 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11449 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11450 HDA_OUTPUT),
11451 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11452 HDA_OUTPUT),
9c7f852e
TI
11453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11455 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11456 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11457 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11458 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11459 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11460 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11461 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11462 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11463 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11464 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11465 { } /* end */
11466};
11467
a9111321 11468static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11469 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11470 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11471 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11472 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11474 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11475 HDA_OUTPUT),
11476 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11477 HDA_OUTPUT),
cd7509a4
KY
11478 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11479 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11480 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11481 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11482 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11483 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11484 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11485 { } /* end */
11486};
11487
a9111321 11488static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11489 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11490 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11491 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11492 { } /* end */
11493};
11494
66d2a9d6 11495/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11496static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11497{
11498 struct alc_spec *spec = codec->spec;
66d2a9d6 11499
a9fd4f3f 11500 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11501 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11502 spec->automute = 1;
11503 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11504}
11505
a9111321 11506static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11507 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11509 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11513 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11514 { } /* end */
11515};
11516
a9111321 11517static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11518 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11519 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11520
11521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11522 { }
11523};
11524
a9111321 11525static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11526 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11527 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11528 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11529 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11530 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11531 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11532 { } /* end */
11533};
11534
a9111321 11535static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11536 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11537 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11538 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11539 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11540 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11541 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11542 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11546 {}
11547};
11548
a9111321 11549static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11550 .num_items = 1,
11551 .items = {
11552 { "Line", 0x1 },
11553 },
11554};
11555
42171c17 11556/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11557#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11558#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11559#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11560
11561#define ALC262_HIPPO_MASTER_SWITCH \
11562 { \
11563 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11564 .name = "Master Playback Switch", \
11565 .info = snd_ctl_boolean_mono_info, \
11566 .get = alc262_hippo_master_sw_get, \
11567 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11568 }, \
11569 { \
11570 .iface = NID_MAPPING, \
11571 .name = "Master Playback Switch", \
11572 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11573 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11574 }
42171c17 11575
a9111321 11576static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11577 ALC262_HIPPO_MASTER_SWITCH,
11578 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11579 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11580 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11581 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11582 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11585 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11586 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11587 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11588 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11589 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11590 { } /* end */
11591};
11592
a9111321 11593static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11594 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11595 ALC262_HIPPO_MASTER_SWITCH,
11596 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11597 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11602 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11605 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11606 { } /* end */
11607};
11608
11609/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11610static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11611{
11612 struct alc_spec *spec = codec->spec;
11613
11614 spec->autocfg.hp_pins[0] = 0x15;
11615 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11616 spec->automute = 1;
11617 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11618}
11619
4f5d1706 11620static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11621{
11622 struct alc_spec *spec = codec->spec;
11623
11624 spec->autocfg.hp_pins[0] = 0x1b;
11625 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11626 spec->automute = 1;
11627 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11628}
11629
11630
a9111321 11631static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11632 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11633 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11634 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11635 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11636 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11637 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11638 { } /* end */
11639};
11640
a9111321 11641static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11642 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11643 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11644 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11645 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11646 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11647 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11648 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11649 { } /* end */
11650};
272a527c 11651
a9111321 11652static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11653 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11654 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11655 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11656 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11658 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11661 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11665 { } /* end */
11666};
11667
a9111321 11668static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11669 /* Headphone automute */
11670 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11671 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11672 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11673
11674 /* P11 AUX_IN, white 4-pin connector */
11675 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11676 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11677 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11678 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11679
11680 {}
11681};
11682
11683/* unsolicited event for HP jack sensing */
4f5d1706 11684static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11685{
a9fd4f3f 11686 struct alc_spec *spec = codec->spec;
ba340e82 11687
a9fd4f3f
TI
11688 spec->autocfg.hp_pins[0] = 0x1b;
11689 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11690 spec->automute = 1;
11691 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11692}
11693
ba340e82 11694
9c7f852e
TI
11695#define alc262_capture_mixer alc882_capture_mixer
11696#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11697
11698/*
11699 * generic initialization of ADC, input mixers and output mixers
11700 */
a9111321 11701static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11702 /*
11703 * Unmute ADC0-2 and set the default input to mic-in
11704 */
11705 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11707 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11708 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11709 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11710 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11711
cb53c626 11712 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11713 * mixer widget
f12ab1e0
TI
11714 * Note: PASD motherboards uses the Line In 2 as the input for
11715 * front panel mic (mic 2)
9c7f852e
TI
11716 */
11717 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11718 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11719 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11723
11724 /*
df694daa
KY
11725 * Set up output mixers (0x0c - 0x0e)
11726 */
11727 /* set vol=0 to output mixers */
11728 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11730 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11731 /* set up input amps for analog loopback */
11732 /* Amp Indices: DAC = 0, mixer = 1 */
11733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11737 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11739
11740 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11742 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11744 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11746
11747 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11749 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11750 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11751 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11752
df694daa
KY
11753 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11754 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11755
df694daa
KY
11756 /* FIXME: use matrix-type input source selection */
11757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11763 /* Input mixer2 */
11764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11768 /* Input mixer3 */
11769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11773
11774 { }
11775};
1da177e4 11776
a9111321 11777static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11778 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11779 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11780 { }
11781};
11782
a9111321 11783static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11784 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11786 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11787
11788 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11789 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11790 {}
11791};
11792
a9111321 11793static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11795 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11796 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11797
11798 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11799 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11800 {}
272a527c
KY
11801};
11802
a9111321 11803static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11804 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11805 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11806 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11807 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11808 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11809 { } /* end */
11810};
11811
a9111321 11812static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11813 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11814 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11815 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11816 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11817 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11818 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11819 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11820 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11821 {}
11822};
11823
4f5d1706 11824static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11825{
a9fd4f3f
TI
11826 struct alc_spec *spec = codec->spec;
11827
11828 spec->autocfg.hp_pins[0] = 0x15;
11829 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11830 spec->ext_mic.pin = 0x18;
11831 spec->ext_mic.mux_idx = 0;
11832 spec->int_mic.pin = 0x12;
11833 spec->int_mic.mux_idx = 9;
11834 spec->auto_mic = 1;
d922b51d
TI
11835 spec->automute = 1;
11836 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11837}
11838
e8f9ae2a
PT
11839/*
11840 * nec model
11841 * 0x15 = headphone
11842 * 0x16 = internal speaker
11843 * 0x18 = external mic
11844 */
11845
a9111321 11846static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11847 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11848 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11849
11850 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11851 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11852 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11853
11854 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11855 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11856 { } /* end */
11857};
11858
a9111321 11859static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11860 /* Unmute Speaker */
11861 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11862
11863 /* Headphone */
11864 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11865 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11866
11867 /* External mic to headphone */
11868 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11869 /* External mic to speaker */
11870 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11871 {}
11872};
11873
834be88d
TI
11874/*
11875 * fujitsu model
5d9fab2d
TV
11876 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11877 * 0x1b = port replicator headphone out
834be88d
TI
11878 */
11879
11880#define ALC_HP_EVENT 0x37
11881
a9111321 11882static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11884 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11885 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11886 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11887 {}
11888};
11889
a9111321 11890static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11891 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11893 {}
11894};
11895
a9111321 11896static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11897 /* Front Mic pin: input vref at 50% */
11898 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11899 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11900 {}
11901};
11902
a9111321 11903static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11904 .num_items = 3,
834be88d
TI
11905 .items = {
11906 { "Mic", 0x0 },
28c4edb7 11907 { "Internal Mic", 0x1 },
834be88d
TI
11908 { "CD", 0x4 },
11909 },
11910};
11911
a9111321 11912static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11913 .num_items = 5,
11914 .items = {
11915 { "Mic", 0x0 },
accbe498 11916 { "Front Mic", 0x1 },
9c7f852e
TI
11917 { "Line", 0x2 },
11918 { "CD", 0x4 },
11919 { "AUX IN", 0x6 },
11920 },
11921};
11922
a9111321 11923static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11924 .num_items = 4,
11925 .items = {
11926 { "Mic", 0x0 },
11927 { "Front Mic", 0x2 },
11928 { "Line", 0x1 },
11929 { "CD", 0x4 },
11930 },
11931};
11932
0f0f391c 11933static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11934{
11935 struct alc_spec *spec = codec->spec;
834be88d 11936
0f0f391c
TI
11937 spec->autocfg.hp_pins[0] = 0x14;
11938 spec->autocfg.hp_pins[1] = 0x1b;
11939 spec->autocfg.speaker_pins[0] = 0x15;
11940 spec->automute = 1;
11941 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11942}
11943
834be88d 11944/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11945static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11946 .ops = &snd_hda_bind_vol,
11947 .values = {
11948 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11949 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11950 0
11951 },
11952};
834be88d 11953
a9111321 11954static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11955 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11956 {
11957 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11958 .name = "Master Playback Switch",
0f0f391c
TI
11959 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11960 .info = snd_ctl_boolean_mono_info,
11961 .get = alc262_hp_master_sw_get,
11962 .put = alc262_hp_master_sw_put,
834be88d 11963 },
5b0cb1d8
JK
11964 {
11965 .iface = NID_MAPPING,
11966 .name = "Master Playback Switch",
11967 .private_value = 0x1b,
11968 },
834be88d
TI
11969 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11970 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11971 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11972 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11974 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11975 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11976 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11977 { } /* end */
11978};
11979
0f0f391c 11980static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11981{
0f0f391c 11982 struct alc_spec *spec = codec->spec;
0e31daf7 11983
0f0f391c
TI
11984 spec->autocfg.hp_pins[0] = 0x1b;
11985 spec->autocfg.speaker_pins[0] = 0x14;
11986 spec->autocfg.speaker_pins[1] = 0x16;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11989}
11990
a9111321 11991static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11992 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11993 {
11994 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11995 .name = "Master Playback Switch",
0f0f391c
TI
11996 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11997 .info = snd_ctl_boolean_mono_info,
11998 .get = alc262_hp_master_sw_get,
11999 .put = alc262_hp_master_sw_put,
0e31daf7
J
12000 },
12001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12003 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12005 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12006 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12007 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12008 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12009 { } /* end */
12010};
12011
a9111321 12012static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12013 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12014 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12015 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12016 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12018 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12019 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12020 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12021 { } /* end */
12022};
12023
304dcaac 12024/* additional init verbs for Benq laptops */
a9111321 12025static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12026 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12027 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12028 {}
12029};
12030
a9111321 12031static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12032 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12033 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12034
12035 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12036 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12037 {}
12038};
12039
f651b50b 12040/* Samsung Q1 Ultra Vista model setup */
a9111321 12041static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12042 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12043 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12048 { } /* end */
12049};
12050
a9111321 12051static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12052 /* output mixer */
12053 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12054 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12056 /* speaker */
12057 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12058 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12059 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12060 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12061 /* HP */
f651b50b 12062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12063 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12064 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12065 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12066 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12067 /* internal mic */
12068 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12069 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12070 /* ADC, choose mic */
12071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12072 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12073 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12081 {}
12082};
12083
f651b50b
TD
12084/* mute/unmute internal speaker according to the hp jack and mute state */
12085static void alc262_ultra_automute(struct hda_codec *codec)
12086{
12087 struct alc_spec *spec = codec->spec;
12088 unsigned int mute;
f651b50b 12089
bb9f76cd
TI
12090 mute = 0;
12091 /* auto-mute only when HP is used as HP */
12092 if (!spec->cur_mux[0]) {
864f92be 12093 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12094 if (spec->jack_present)
12095 mute = HDA_AMP_MUTE;
f651b50b 12096 }
bb9f76cd
TI
12097 /* mute/unmute internal speaker */
12098 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12099 HDA_AMP_MUTE, mute);
12100 /* mute/unmute HP */
12101 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12102 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12103}
12104
12105/* unsolicited event for HP jack sensing */
12106static void alc262_ultra_unsol_event(struct hda_codec *codec,
12107 unsigned int res)
12108{
12109 if ((res >> 26) != ALC880_HP_EVENT)
12110 return;
12111 alc262_ultra_automute(codec);
12112}
12113
a9111321 12114static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12115 .num_items = 2,
12116 .items = {
12117 { "Mic", 0x1 },
12118 { "Headphone", 0x7 },
12119 },
12120};
12121
12122static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12123 struct snd_ctl_elem_value *ucontrol)
12124{
12125 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12126 struct alc_spec *spec = codec->spec;
12127 int ret;
12128
54cbc9ab 12129 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12130 if (!ret)
12131 return 0;
12132 /* reprogram the HP pin as mic or HP according to the input source */
12133 snd_hda_codec_write_cache(codec, 0x15, 0,
12134 AC_VERB_SET_PIN_WIDGET_CONTROL,
12135 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12136 alc262_ultra_automute(codec); /* mute/unmute HP */
12137 return ret;
12138}
12139
a9111321 12140static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12141 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12142 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12143 {
12144 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12145 .name = "Capture Source",
54cbc9ab
TI
12146 .info = alc_mux_enum_info,
12147 .get = alc_mux_enum_get,
bb9f76cd
TI
12148 .put = alc262_ultra_mux_enum_put,
12149 },
5b0cb1d8
JK
12150 {
12151 .iface = NID_MAPPING,
12152 .name = "Capture Source",
12153 .private_value = 0x15,
12154 },
bb9f76cd
TI
12155 { } /* end */
12156};
12157
c3fc1f50
TI
12158/* We use two mixers depending on the output pin; 0x16 is a mono output
12159 * and thus it's bound with a different mixer.
12160 * This function returns which mixer amp should be used.
12161 */
12162static int alc262_check_volbit(hda_nid_t nid)
12163{
12164 if (!nid)
12165 return 0;
12166 else if (nid == 0x16)
12167 return 2;
12168 else
12169 return 1;
12170}
12171
12172static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12173 const char *pfx, int *vbits, int idx)
c3fc1f50 12174{
c3fc1f50
TI
12175 unsigned long val;
12176 int vbit;
12177
12178 vbit = alc262_check_volbit(nid);
12179 if (!vbit)
12180 return 0;
12181 if (*vbits & vbit) /* a volume control for this mixer already there */
12182 return 0;
12183 *vbits |= vbit;
c3fc1f50
TI
12184 if (vbit == 2)
12185 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12186 else
12187 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12188 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12189}
12190
12191static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12192 const char *pfx, int idx)
c3fc1f50 12193{
c3fc1f50
TI
12194 unsigned long val;
12195
12196 if (!nid)
12197 return 0;
c3fc1f50
TI
12198 if (nid == 0x16)
12199 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12200 else
12201 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12202 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12203}
12204
df694daa 12205/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12206static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12207 const struct auto_pin_cfg *cfg)
df694daa 12208{
c3fc1f50
TI
12209 const char *pfx;
12210 int vbits;
033688a5 12211 int i, err;
df694daa
KY
12212
12213 spec->multiout.num_dacs = 1; /* only use one dac */
12214 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12215 spec->private_dac_nids[0] = 2;
df694daa 12216
ce764ab2 12217 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12218 if (!pfx)
c3fc1f50 12219 pfx = "Front";
033688a5
TI
12220 for (i = 0; i < 2; i++) {
12221 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12222 if (err < 0)
12223 return err;
12224 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12225 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12226 "Speaker", i);
12227 if (err < 0)
12228 return err;
12229 }
12230 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12231 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12232 "Headphone", i);
12233 if (err < 0)
12234 return err;
12235 }
12236 }
df694daa 12237
c3fc1f50
TI
12238 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12239 alc262_check_volbit(cfg->speaker_pins[0]) |
12240 alc262_check_volbit(cfg->hp_pins[0]);
12241 if (vbits == 1 || vbits == 2)
12242 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12243 vbits = 0;
033688a5
TI
12244 for (i = 0; i < 2; i++) {
12245 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12246 &vbits, i);
12247 if (err < 0)
12248 return err;
12249 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12250 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12251 "Speaker", &vbits, i);
12252 if (err < 0)
12253 return err;
12254 }
12255 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12256 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12257 "Headphone", &vbits, i);
12258 if (err < 0)
12259 return err;
12260 }
12261 }
f12ab1e0 12262 return 0;
df694daa
KY
12263}
12264
05f5f477 12265#define alc262_auto_create_input_ctls \
eaa9b3a7 12266 alc882_auto_create_input_ctls
df694daa
KY
12267
12268/*
12269 * generic initialization of ADC, input mixers and output mixers
12270 */
a9111321 12271static const struct hda_verb alc262_volume_init_verbs[] = {
df694daa
KY
12272 /*
12273 * Unmute ADC0-2 and set the default input to mic-in
12274 */
12275 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12276 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12277 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12278 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12279 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12280 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12281
cb53c626 12282 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12283 * mixer widget
f12ab1e0
TI
12284 * Note: PASD motherboards uses the Line In 2 as the input for
12285 * front panel mic (mic 2)
df694daa
KY
12286 */
12287 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12288 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12289 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12293
12294 /*
12295 * Set up output mixers (0x0c - 0x0f)
12296 */
12297 /* set vol=0 to output mixers */
12298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12299 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12300 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12301
df694daa
KY
12302 /* set up input amps for analog loopback */
12303 /* Amp Indices: DAC = 0, mixer = 1 */
12304 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12305 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12306 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12309 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12310
12311 /* FIXME: use matrix-type input source selection */
12312 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12313 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12314 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12315 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12318 /* Input mixer2 */
12319 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12320 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12323 /* Input mixer3 */
12324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12325 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12328
12329 { }
12330};
12331
a9111321 12332static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12333 /*
12334 * Unmute ADC0-2 and set the default input to mic-in
12335 */
12336 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12337 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12338 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12339 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12340 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12341 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342
cb53c626 12343 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12344 * mixer widget
f12ab1e0
TI
12345 * Note: PASD motherboards uses the Line In 2 as the input for
12346 * front panel mic (mic 2)
9c7f852e
TI
12347 */
12348 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12349 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12350 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12352 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12353 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12354 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12355 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12356
9c7f852e
TI
12357 /*
12358 * Set up output mixers (0x0c - 0x0e)
12359 */
12360 /* set vol=0 to output mixers */
12361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12362 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12364
12365 /* set up input amps for analog loopback */
12366 /* Amp Indices: DAC = 0, mixer = 1 */
12367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12369 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12370 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12371 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12372 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12373
ce875f07 12374 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12376 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12377
12378 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12379 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12380
12381 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12383
12384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12385 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12386 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12387 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12388 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12389
0e4835c1 12390 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12391 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12392 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12393 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12394 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12395 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12396
12397
12398 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12399 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12400 /* Input mixer1: only unmute Mic */
9c7f852e 12401 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12402 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12410 /* Input mixer2 */
12411 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12412 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12420 /* Input mixer3 */
12421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12427 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12428 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12429 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12430
ce875f07
TI
12431 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12432
9c7f852e
TI
12433 { }
12434};
12435
a9111321 12436static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12437 /*
12438 * Unmute ADC0-2 and set the default input to mic-in
12439 */
12440 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12441 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12442 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12443 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12444 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12446
cb53c626 12447 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12448 * mixer widget
12449 * Note: PASD motherboards uses the Line In 2 as the input for front
12450 * panel mic (mic 2)
12451 */
12452 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12461 /*
12462 * Set up output mixers (0x0c - 0x0e)
12463 */
12464 /* set vol=0 to output mixers */
12465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12468
12469 /* set up input amps for analog loopback */
12470 /* Amp Indices: DAC = 0, mixer = 1 */
12471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12472 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12474 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12475 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12476 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12477
12478
12479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12480 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12481 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12485 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12486
12487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12488 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12489
12490 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12491 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12492
12493 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12494 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12495 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12496 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12497 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12498 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12499
12500 /* FIXME: use matrix-type input source selection */
12501 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12502 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12503 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12504 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12505 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12508 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12510 /* Input mixer2 */
12511 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12512 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12516 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12518 /* Input mixer3 */
12519 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12520 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12522 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12524 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12526
ce875f07
TI
12527 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12528
cd7509a4
KY
12529 { }
12530};
12531
a9111321 12532static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12533
12534 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12535 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12537
12538 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12539 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12540 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12541 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12542
12543 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12545 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12546 {}
12547};
12548
18675e42
TI
12549/*
12550 * Pin config fixes
12551 */
12552enum {
12553 PINFIX_FSC_H270,
12554};
12555
12556static const struct alc_fixup alc262_fixups[] = {
12557 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12558 .type = ALC_FIXUP_PINS,
12559 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12560 { 0x14, 0x99130110 }, /* speaker */
12561 { 0x15, 0x0221142f }, /* front HP */
12562 { 0x1b, 0x0121141f }, /* rear HP */
12563 { }
12564 }
12565 },
18675e42
TI
12566};
12567
a9111321 12568static const struct snd_pci_quirk alc262_fixup_tbl[] = {
18675e42
TI
12569 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12570 {}
12571};
12572
9f99a638 12573
cb53c626
TI
12574#ifdef CONFIG_SND_HDA_POWER_SAVE
12575#define alc262_loopbacks alc880_loopbacks
12576#endif
12577
def319f9 12578/* pcm configuration: identical with ALC880 */
df694daa
KY
12579#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12580#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12581#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12582#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12583
12584/*
12585 * BIOS auto configuration
12586 */
12587static int alc262_parse_auto_config(struct hda_codec *codec)
12588{
12589 struct alc_spec *spec = codec->spec;
12590 int err;
4c6d72d1 12591 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12592
f12ab1e0
TI
12593 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12594 alc262_ignore);
12595 if (err < 0)
df694daa 12596 return err;
e64f14f4 12597 if (!spec->autocfg.line_outs) {
0852d7a6 12598 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12599 spec->multiout.max_channels = 2;
12600 spec->no_analog = 1;
12601 goto dig_only;
12602 }
df694daa 12603 return 0; /* can't find valid BIOS pin config */
e64f14f4 12604 }
f12ab1e0
TI
12605 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12606 if (err < 0)
12607 return err;
05f5f477 12608 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12609 if (err < 0)
df694daa
KY
12610 return err;
12611
12612 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12613
e64f14f4 12614 dig_only:
757899ac 12615 alc_auto_parse_digital(codec);
df694daa 12616
603c4019 12617 if (spec->kctls.list)
d88897ea 12618 add_mixer(spec, spec->kctls.list);
df694daa 12619
d88897ea 12620 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12621 spec->num_mux_defs = 1;
61b9b9b1 12622 spec->input_mux = &spec->private_imux[0];
df694daa 12623
776e184e
TI
12624 err = alc_auto_add_mic_boost(codec);
12625 if (err < 0)
12626 return err;
12627
6227cdce 12628 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12629
df694daa
KY
12630 return 1;
12631}
12632
12633#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12634#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12635#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12636#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12637
12638
12639/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12640static void alc262_auto_init(struct hda_codec *codec)
df694daa 12641{
f6c7e546 12642 struct alc_spec *spec = codec->spec;
df694daa
KY
12643 alc262_auto_init_multi_out(codec);
12644 alc262_auto_init_hp_out(codec);
12645 alc262_auto_init_analog_input(codec);
f511b01c 12646 alc262_auto_init_input_src(codec);
757899ac 12647 alc_auto_init_digital(codec);
f6c7e546 12648 if (spec->unsol_event)
7fb0d78f 12649 alc_inithook(codec);
df694daa
KY
12650}
12651
12652/*
12653 * configuration and preset
12654 */
ea734963 12655static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12656 [ALC262_BASIC] = "basic",
12657 [ALC262_HIPPO] = "hippo",
12658 [ALC262_HIPPO_1] = "hippo_1",
12659 [ALC262_FUJITSU] = "fujitsu",
12660 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12661 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12662 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12663 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12664 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12665 [ALC262_BENQ_T31] = "benq-t31",
12666 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12667 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12668 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12669 [ALC262_ULTRA] = "ultra",
0e31daf7 12670 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12671 [ALC262_NEC] = "nec",
ba340e82 12672 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12673 [ALC262_AUTO] = "auto",
12674};
12675
a9111321 12676static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12677 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12678 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12679 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12680 ALC262_HP_BPC),
12681 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12682 ALC262_HP_BPC),
5734a07c
TI
12683 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12684 ALC262_HP_BPC),
53eff7e1
TI
12685 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12686 ALC262_HP_BPC),
cd7509a4 12687 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12688 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12689 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12690 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12691 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12692 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12693 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12694 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12695 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12696 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12697 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12698 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12699 ALC262_HP_TC_T5735),
8c427226 12700 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12701 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12702 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12703 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12704 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12705 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12706 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12707 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12708#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12709 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12710 ALC262_SONY_ASSAMD),
c5b5165c 12711#endif
36ca6e13 12712 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12713 ALC262_TOSHIBA_RX1),
80ffe869 12714 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12715 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12716 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12717 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12718 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12719 ALC262_ULTRA),
3e420e78 12720 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12721 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12722 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12723 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12724 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12725 {}
12726};
12727
a9111321 12728static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12729 [ALC262_BASIC] = {
12730 .mixers = { alc262_base_mixer },
12731 .init_verbs = { alc262_init_verbs },
12732 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12733 .dac_nids = alc262_dac_nids,
12734 .hp_nid = 0x03,
12735 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12736 .channel_mode = alc262_modes,
a3bcba38 12737 .input_mux = &alc262_capture_source,
df694daa 12738 },
ccc656ce 12739 [ALC262_HIPPO] = {
42171c17 12740 .mixers = { alc262_hippo_mixer },
6732bd0d 12741 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12742 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12743 .dac_nids = alc262_dac_nids,
12744 .hp_nid = 0x03,
12745 .dig_out_nid = ALC262_DIGOUT_NID,
12746 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12747 .channel_mode = alc262_modes,
12748 .input_mux = &alc262_capture_source,
e9427969 12749 .unsol_event = alc_sku_unsol_event,
4f5d1706 12750 .setup = alc262_hippo_setup,
e9427969 12751 .init_hook = alc_inithook,
ccc656ce
KY
12752 },
12753 [ALC262_HIPPO_1] = {
12754 .mixers = { alc262_hippo1_mixer },
12755 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12756 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12757 .dac_nids = alc262_dac_nids,
12758 .hp_nid = 0x02,
12759 .dig_out_nid = ALC262_DIGOUT_NID,
12760 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12761 .channel_mode = alc262_modes,
12762 .input_mux = &alc262_capture_source,
e9427969 12763 .unsol_event = alc_sku_unsol_event,
4f5d1706 12764 .setup = alc262_hippo1_setup,
e9427969 12765 .init_hook = alc_inithook,
ccc656ce 12766 },
834be88d
TI
12767 [ALC262_FUJITSU] = {
12768 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12769 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12770 alc262_fujitsu_unsol_verbs },
834be88d
TI
12771 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12772 .dac_nids = alc262_dac_nids,
12773 .hp_nid = 0x03,
12774 .dig_out_nid = ALC262_DIGOUT_NID,
12775 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12776 .channel_mode = alc262_modes,
12777 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12778 .unsol_event = alc_sku_unsol_event,
12779 .setup = alc262_fujitsu_setup,
12780 .init_hook = alc_inithook,
834be88d 12781 },
9c7f852e
TI
12782 [ALC262_HP_BPC] = {
12783 .mixers = { alc262_HP_BPC_mixer },
12784 .init_verbs = { alc262_HP_BPC_init_verbs },
12785 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12786 .dac_nids = alc262_dac_nids,
12787 .hp_nid = 0x03,
12788 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12789 .channel_mode = alc262_modes,
12790 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12791 .unsol_event = alc_sku_unsol_event,
12792 .setup = alc262_hp_bpc_setup,
12793 .init_hook = alc_inithook,
f12ab1e0 12794 },
cd7509a4
KY
12795 [ALC262_HP_BPC_D7000_WF] = {
12796 .mixers = { alc262_HP_BPC_WildWest_mixer },
12797 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12798 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12799 .dac_nids = alc262_dac_nids,
12800 .hp_nid = 0x03,
12801 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12802 .channel_mode = alc262_modes,
accbe498 12803 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12804 .unsol_event = alc_sku_unsol_event,
12805 .setup = alc262_hp_wildwest_setup,
12806 .init_hook = alc_inithook,
f12ab1e0 12807 },
cd7509a4
KY
12808 [ALC262_HP_BPC_D7000_WL] = {
12809 .mixers = { alc262_HP_BPC_WildWest_mixer,
12810 alc262_HP_BPC_WildWest_option_mixer },
12811 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12812 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12813 .dac_nids = alc262_dac_nids,
12814 .hp_nid = 0x03,
12815 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12816 .channel_mode = alc262_modes,
accbe498 12817 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12818 .unsol_event = alc_sku_unsol_event,
12819 .setup = alc262_hp_wildwest_setup,
12820 .init_hook = alc_inithook,
f12ab1e0 12821 },
66d2a9d6
KY
12822 [ALC262_HP_TC_T5735] = {
12823 .mixers = { alc262_hp_t5735_mixer },
12824 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12825 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12826 .dac_nids = alc262_dac_nids,
12827 .hp_nid = 0x03,
12828 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12829 .channel_mode = alc262_modes,
12830 .input_mux = &alc262_capture_source,
dc99be47 12831 .unsol_event = alc_sku_unsol_event,
4f5d1706 12832 .setup = alc262_hp_t5735_setup,
dc99be47 12833 .init_hook = alc_inithook,
8c427226
KY
12834 },
12835 [ALC262_HP_RP5700] = {
12836 .mixers = { alc262_hp_rp5700_mixer },
12837 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12838 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12839 .dac_nids = alc262_dac_nids,
12840 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12841 .channel_mode = alc262_modes,
12842 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12843 },
304dcaac
TI
12844 [ALC262_BENQ_ED8] = {
12845 .mixers = { alc262_base_mixer },
12846 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12847 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12848 .dac_nids = alc262_dac_nids,
12849 .hp_nid = 0x03,
12850 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12851 .channel_mode = alc262_modes,
12852 .input_mux = &alc262_capture_source,
f12ab1e0 12853 },
272a527c
KY
12854 [ALC262_SONY_ASSAMD] = {
12855 .mixers = { alc262_sony_mixer },
12856 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12857 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12858 .dac_nids = alc262_dac_nids,
12859 .hp_nid = 0x02,
12860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12861 .channel_mode = alc262_modes,
12862 .input_mux = &alc262_capture_source,
e9427969 12863 .unsol_event = alc_sku_unsol_event,
4f5d1706 12864 .setup = alc262_hippo_setup,
e9427969 12865 .init_hook = alc_inithook,
83c34218
KY
12866 },
12867 [ALC262_BENQ_T31] = {
12868 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12869 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12870 alc_hp15_unsol_verbs },
83c34218
KY
12871 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12872 .dac_nids = alc262_dac_nids,
12873 .hp_nid = 0x03,
12874 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12875 .channel_mode = alc262_modes,
12876 .input_mux = &alc262_capture_source,
e9427969 12877 .unsol_event = alc_sku_unsol_event,
4f5d1706 12878 .setup = alc262_hippo_setup,
e9427969 12879 .init_hook = alc_inithook,
ea1fb29a 12880 },
f651b50b 12881 [ALC262_ULTRA] = {
f9e336f6
TI
12882 .mixers = { alc262_ultra_mixer },
12883 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12884 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12885 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12886 .dac_nids = alc262_dac_nids,
f651b50b
TD
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
12889 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12890 .adc_nids = alc262_adc_nids, /* ADC0 */
12891 .capsrc_nids = alc262_capsrc_nids,
12892 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12893 .unsol_event = alc262_ultra_unsol_event,
12894 .init_hook = alc262_ultra_automute,
12895 },
0e31daf7
J
12896 [ALC262_LENOVO_3000] = {
12897 .mixers = { alc262_lenovo_3000_mixer },
12898 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12899 alc262_lenovo_3000_unsol_verbs,
12900 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12901 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12902 .dac_nids = alc262_dac_nids,
12903 .hp_nid = 0x03,
12904 .dig_out_nid = ALC262_DIGOUT_NID,
12905 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12906 .channel_mode = alc262_modes,
12907 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12908 .unsol_event = alc_sku_unsol_event,
12909 .setup = alc262_lenovo_3000_setup,
12910 .init_hook = alc_inithook,
0e31daf7 12911 },
e8f9ae2a
PT
12912 [ALC262_NEC] = {
12913 .mixers = { alc262_nec_mixer },
12914 .init_verbs = { alc262_nec_verbs },
12915 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12916 .dac_nids = alc262_dac_nids,
12917 .hp_nid = 0x03,
12918 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12919 .channel_mode = alc262_modes,
12920 .input_mux = &alc262_capture_source,
12921 },
4e555fe5
KY
12922 [ALC262_TOSHIBA_S06] = {
12923 .mixers = { alc262_toshiba_s06_mixer },
12924 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12925 alc262_eapd_verbs },
12926 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12927 .capsrc_nids = alc262_dmic_capsrc_nids,
12928 .dac_nids = alc262_dac_nids,
12929 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12930 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12931 .dig_out_nid = ALC262_DIGOUT_NID,
12932 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12933 .channel_mode = alc262_modes,
4f5d1706
TI
12934 .unsol_event = alc_sku_unsol_event,
12935 .setup = alc262_toshiba_s06_setup,
12936 .init_hook = alc_inithook,
4e555fe5 12937 },
9f99a638
HM
12938 [ALC262_TOSHIBA_RX1] = {
12939 .mixers = { alc262_toshiba_rx1_mixer },
12940 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12941 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12942 .dac_nids = alc262_dac_nids,
12943 .hp_nid = 0x03,
12944 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12945 .channel_mode = alc262_modes,
12946 .input_mux = &alc262_capture_source,
e9427969 12947 .unsol_event = alc_sku_unsol_event,
4f5d1706 12948 .setup = alc262_hippo_setup,
e9427969 12949 .init_hook = alc_inithook,
9f99a638 12950 },
ba340e82
TV
12951 [ALC262_TYAN] = {
12952 .mixers = { alc262_tyan_mixer },
12953 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12954 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12955 .dac_nids = alc262_dac_nids,
12956 .hp_nid = 0x02,
12957 .dig_out_nid = ALC262_DIGOUT_NID,
12958 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12959 .channel_mode = alc262_modes,
12960 .input_mux = &alc262_capture_source,
d922b51d 12961 .unsol_event = alc_sku_unsol_event,
4f5d1706 12962 .setup = alc262_tyan_setup,
d922b51d 12963 .init_hook = alc_hp_automute,
ba340e82 12964 },
df694daa
KY
12965};
12966
12967static int patch_alc262(struct hda_codec *codec)
12968{
12969 struct alc_spec *spec;
12970 int board_config;
12971 int err;
12972
dc041e0b 12973 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12974 if (spec == NULL)
12975 return -ENOMEM;
12976
12977 codec->spec = spec;
12978#if 0
f12ab1e0
TI
12979 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12980 * under-run
12981 */
df694daa
KY
12982 {
12983 int tmp;
12984 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12985 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12986 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12987 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12988 }
12989#endif
da00c244 12990 alc_auto_parse_customize_define(codec);
df694daa 12991
2c3bf9ab
TI
12992 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12993
f5fcc13c
TI
12994 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12995 alc262_models,
12996 alc262_cfg_tbl);
cd7509a4 12997
f5fcc13c 12998 if (board_config < 0) {
9a11f1aa
TI
12999 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13000 codec->chip_name);
df694daa
KY
13001 board_config = ALC262_AUTO;
13002 }
13003
b5bfbc67
TI
13004 if (board_config == ALC262_AUTO) {
13005 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13006 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13007 }
18675e42 13008
df694daa
KY
13009 if (board_config == ALC262_AUTO) {
13010 /* automatic parse from the BIOS config */
13011 err = alc262_parse_auto_config(codec);
13012 if (err < 0) {
13013 alc_free(codec);
13014 return err;
f12ab1e0 13015 } else if (!err) {
9c7f852e
TI
13016 printk(KERN_INFO
13017 "hda_codec: Cannot set up configuration "
13018 "from BIOS. Using base mode...\n");
df694daa
KY
13019 board_config = ALC262_BASIC;
13020 }
13021 }
13022
dc1eae25 13023 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13024 err = snd_hda_attach_beep_device(codec, 0x1);
13025 if (err < 0) {
13026 alc_free(codec);
13027 return err;
13028 }
680cd536
KK
13029 }
13030
df694daa 13031 if (board_config != ALC262_AUTO)
e9c364c0 13032 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13033
df694daa
KY
13034 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13035 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13036
df694daa
KY
13037 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13038 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13039
f12ab1e0 13040 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13041 int i;
13042 /* check whether the digital-mic has to be supported */
13043 for (i = 0; i < spec->input_mux->num_items; i++) {
13044 if (spec->input_mux->items[i].index >= 9)
13045 break;
13046 }
13047 if (i < spec->input_mux->num_items) {
13048 /* use only ADC0 */
13049 spec->adc_nids = alc262_dmic_adc_nids;
13050 spec->num_adc_nids = 1;
13051 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13052 } else {
8c927b4a
TI
13053 /* all analog inputs */
13054 /* check whether NID 0x07 is valid */
13055 unsigned int wcap = get_wcaps(codec, 0x07);
13056
13057 /* get type */
a22d543a 13058 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13059 if (wcap != AC_WID_AUD_IN) {
13060 spec->adc_nids = alc262_adc_nids_alt;
13061 spec->num_adc_nids =
13062 ARRAY_SIZE(alc262_adc_nids_alt);
13063 spec->capsrc_nids = alc262_capsrc_nids_alt;
13064 } else {
13065 spec->adc_nids = alc262_adc_nids;
13066 spec->num_adc_nids =
13067 ARRAY_SIZE(alc262_adc_nids);
13068 spec->capsrc_nids = alc262_capsrc_nids;
13069 }
df694daa
KY
13070 }
13071 }
e64f14f4 13072 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13073 set_capture_mixer(codec);
dc1eae25 13074 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13075 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13076
b5bfbc67 13077 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13078
2134ea4f
TI
13079 spec->vmaster_nid = 0x0c;
13080
df694daa
KY
13081 codec->patch_ops = alc_patch_ops;
13082 if (board_config == ALC262_AUTO)
ae6b813a 13083 spec->init_hook = alc262_auto_init;
1c716153 13084 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13085
13086 alc_init_jacks(codec);
cb53c626
TI
13087#ifdef CONFIG_SND_HDA_POWER_SAVE
13088 if (!spec->loopback.amplist)
13089 spec->loopback.amplist = alc262_loopbacks;
13090#endif
ea1fb29a 13091
df694daa
KY
13092 return 0;
13093}
13094
a361d84b
KY
13095/*
13096 * ALC268 channel source setting (2 channel)
13097 */
13098#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13099#define alc268_modes alc260_modes
ea1fb29a 13100
4c6d72d1 13101static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13102 /* front, hp */
13103 0x02, 0x03
13104};
13105
4c6d72d1 13106static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13107 /* ADC0-1 */
13108 0x08, 0x07
13109};
13110
4c6d72d1 13111static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13112 /* ADC0 */
13113 0x08
13114};
13115
4c6d72d1 13116static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13117
a9111321 13118static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13119 /* output mixer control */
13120 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13121 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13122 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13123 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13124 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13125 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13126 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13127 { }
13128};
13129
a9111321 13130static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13131 /* output mixer control */
13132 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13133 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13134 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13135 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13136 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13137 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13138 { }
13139};
13140
aef9d318 13141/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13142static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13143 .ops = &snd_hda_bind_sw,
13144 .values = {
13145 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13146 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13147 0
13148 },
13149};
13150
a9111321 13151static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13152 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13153 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13154 { }
13155};
13156
a9111321 13157static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13158 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13159 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13160 { }
13161};
13162
d273809e 13163/* Toshiba specific */
a9111321 13164static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13165 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13166 { } /* end */
13167};
13168
13169/* Acer specific */
889c4395 13170/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13171static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13172 .ops = &snd_hda_bind_vol,
13173 .values = {
13174 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13175 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13176 0
13177 },
13178};
13179
0f0f391c 13180static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13181{
13182 struct alc_spec *spec = codec->spec;
889c4395 13183
0f0f391c
TI
13184 spec->autocfg.hp_pins[0] = 0x14;
13185 spec->autocfg.speaker_pins[0] = 0x15;
13186 spec->automute = 1;
13187 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13188}
13189
0f0f391c
TI
13190#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13191#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13192
a9111321 13193static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13194 /* output mixer control */
13195 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13196 {
13197 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13198 .name = "Master Playback Switch",
0f0f391c
TI
13199 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13200 .info = snd_ctl_boolean_mono_info,
13201 .get = alc268_acer_master_sw_get,
8ef355da 13202 .put = alc268_acer_master_sw_put,
8ef355da
KY
13203 },
13204 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13205 { }
13206};
13207
a9111321 13208static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13209 /* output mixer control */
13210 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13211 {
13212 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13213 .name = "Master Playback Switch",
0f0f391c
TI
13214 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13215 .info = snd_ctl_boolean_mono_info,
13216 .get = alc268_acer_master_sw_get,
d273809e 13217 .put = alc268_acer_master_sw_put,
d273809e 13218 },
5f99f86a
DH
13219 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13220 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13221 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13222 { }
13223};
13224
a9111321 13225static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13226 /* output mixer control */
13227 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13228 {
13229 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13230 .name = "Master Playback Switch",
0f0f391c
TI
13231 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13232 .info = snd_ctl_boolean_mono_info,
13233 .get = alc268_acer_master_sw_get,
c238b4f4 13234 .put = alc268_acer_master_sw_put,
c238b4f4 13235 },
5f99f86a
DH
13236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13237 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13238 { }
13239};
13240
a9111321 13241static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13242 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13243 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13244 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13245 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13246 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13247 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13248 { }
13249};
13250
a9111321 13251static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13252 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13253 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13256 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13257 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13258 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13259 { }
13260};
13261
13262/* unsolicited event for HP jack sensing */
4f5d1706 13263#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13264
4f5d1706
TI
13265static void alc268_acer_lc_setup(struct hda_codec *codec)
13266{
13267 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13268 spec->autocfg.hp_pins[0] = 0x15;
13269 spec->autocfg.speaker_pins[0] = 0x14;
13270 spec->automute_mixer_nid[0] = 0x0f;
13271 spec->automute = 1;
13272 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
13273 spec->ext_mic.pin = 0x18;
13274 spec->ext_mic.mux_idx = 0;
13275 spec->int_mic.pin = 0x12;
13276 spec->int_mic.mux_idx = 6;
13277 spec->auto_mic = 1;
8ef355da
KY
13278}
13279
a9111321 13280static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13281 /* output mixer control */
13282 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13283 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13287 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13288 { }
13289};
13290
a9111321 13291static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13292 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13294 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13295 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13296 { }
13297};
13298
13299/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13300static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13301{
a9fd4f3f 13302 struct alc_spec *spec = codec->spec;
3866f0b0 13303
a9fd4f3f
TI
13304 spec->autocfg.hp_pins[0] = 0x15;
13305 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13306 spec->ext_mic.pin = 0x18;
13307 spec->ext_mic.mux_idx = 0;
13308 spec->int_mic.pin = 0x19;
13309 spec->int_mic.mux_idx = 1;
13310 spec->auto_mic = 1;
d922b51d
TI
13311 spec->automute = 1;
13312 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13313}
13314
a9111321 13315static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13316 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13317 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13318 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13320 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13321 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13322 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13323 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13324 { }
13325};
13326
a9111321 13327static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13328 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13329 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13330 { }
13331};
13332
4f5d1706 13333static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13334{
a9fd4f3f 13335 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13336 spec->autocfg.hp_pins[0] = 0x15;
13337 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13338 spec->ext_mic.pin = 0x18;
13339 spec->ext_mic.mux_idx = 0;
13340 spec->int_mic.pin = 0x19;
13341 spec->int_mic.mux_idx = 1;
13342 spec->auto_mic = 1;
d922b51d
TI
13343 spec->automute = 1;
13344 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13345}
13346
a361d84b
KY
13347/*
13348 * generic initialization of ADC, input mixers and output mixers
13349 */
a9111321 13350static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13351 /* Unmute DAC0-1 and set vol = 0 */
13352 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13353 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13354
13355 /*
13356 * Set up output mixers (0x0c - 0x0e)
13357 */
13358 /* set vol=0 to output mixers */
13359 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13360 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13361
13362 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13363 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13364
13365 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13367 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13369 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13370 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13371 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13372 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13373
13374 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13375 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13376 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13377 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13378 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13379
13380 /* set PCBEEP vol = 0, mute connections */
13381 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13382 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13383 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13384
a9b3aa8a 13385 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13386
a9b3aa8a
JZ
13387 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13388 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13389 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13390 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13391
a361d84b
KY
13392 { }
13393};
13394
13395/*
13396 * generic initialization of ADC, input mixers and output mixers
13397 */
a9111321 13398static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13399 /* set output DAC */
4cfb91c6
TI
13400 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13401 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13402
13403 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13404 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13406 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13407 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13408
a361d84b 13409 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13410 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13411 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13412
13413 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13415
aef9d318
TI
13416 /* set PCBEEP vol = 0, mute connections */
13417 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13418 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13419 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13420
13421 { }
13422};
13423
a9111321 13424static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13425 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13427 { } /* end */
13428};
13429
a9111321 13430static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13431 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13432 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13433 _DEFINE_CAPSRC(1),
a361d84b
KY
13434 { } /* end */
13435};
13436
a9111321 13437static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13438 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13439 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13440 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13441 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13442 _DEFINE_CAPSRC(2),
a361d84b
KY
13443 { } /* end */
13444};
13445
a9111321 13446static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13447 .num_items = 4,
13448 .items = {
13449 { "Mic", 0x0 },
13450 { "Front Mic", 0x1 },
13451 { "Line", 0x2 },
13452 { "CD", 0x3 },
13453 },
13454};
13455
a9111321 13456static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13457 .num_items = 3,
13458 .items = {
13459 { "Mic", 0x0 },
13460 { "Internal Mic", 0x1 },
13461 { "Line", 0x2 },
13462 },
13463};
13464
a9111321 13465static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13466 .num_items = 3,
13467 .items = {
13468 { "Mic", 0x0 },
13469 { "Internal Mic", 0x6 },
13470 { "Line", 0x2 },
13471 },
13472};
13473
86c53bd2 13474#ifdef CONFIG_SND_DEBUG
a9111321 13475static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13476 /* Volume widgets */
13477 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13478 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13479 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13480 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13481 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13482 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13483 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13484 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13485 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13486 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13488 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13489 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13490 /* The below appears problematic on some hardwares */
13491 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13492 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13493 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13494 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13495 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13496
13497 /* Modes for retasking pin widgets */
13498 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13499 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13500 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13501 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13502
13503 /* Controls for GPIO pins, assuming they are configured as outputs */
13504 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13505 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13506 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13507 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13508
13509 /* Switches to allow the digital SPDIF output pin to be enabled.
13510 * The ALC268 does not have an SPDIF input.
13511 */
13512 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13513
13514 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13515 * this output to turn on an external amplifier.
13516 */
13517 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13518 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13519
13520 { } /* end */
13521};
13522#endif
13523
a361d84b
KY
13524/* create input playback/capture controls for the given pin */
13525static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13526 const char *ctlname, int idx)
13527{
3f3b7c1a 13528 hda_nid_t dac;
a361d84b
KY
13529 int err;
13530
3f3b7c1a
TI
13531 switch (nid) {
13532 case 0x14:
13533 case 0x16:
13534 dac = 0x02;
13535 break;
13536 case 0x15:
b08b1637
TI
13537 case 0x1a: /* ALC259/269 only */
13538 case 0x1b: /* ALC259/269 only */
531d8791 13539 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13540 dac = 0x03;
13541 break;
13542 default:
c7a9434d
TI
13543 snd_printd(KERN_WARNING "hda_codec: "
13544 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13545 return 0;
13546 }
13547 if (spec->multiout.dac_nids[0] != dac &&
13548 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13549 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13550 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13551 HDA_OUTPUT));
13552 if (err < 0)
13553 return err;
dda14410 13554 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13555 }
13556
3f3b7c1a 13557 if (nid != 0x16)
0afe5f89 13558 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13559 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13560 else /* mono */
0afe5f89 13561 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13562 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13563 if (err < 0)
13564 return err;
13565 return 0;
13566}
13567
13568/* add playback controls from the parsed DAC table */
13569static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13570 const struct auto_pin_cfg *cfg)
13571{
13572 hda_nid_t nid;
13573 int err;
13574
a361d84b 13575 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13576
13577 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13578 if (nid) {
13579 const char *name;
13580 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13581 name = "Speaker";
13582 else
13583 name = "Front";
13584 err = alc268_new_analog_output(spec, nid, name, 0);
13585 if (err < 0)
13586 return err;
13587 }
a361d84b
KY
13588
13589 nid = cfg->speaker_pins[0];
13590 if (nid == 0x1d) {
0afe5f89 13591 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13592 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13593 if (err < 0)
13594 return err;
7bfb9c03 13595 } else if (nid) {
3f3b7c1a
TI
13596 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13597 if (err < 0)
13598 return err;
a361d84b
KY
13599 }
13600 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13601 if (nid) {
13602 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13603 if (err < 0)
13604 return err;
13605 }
a361d84b
KY
13606
13607 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13608 if (nid == 0x16) {
0afe5f89 13609 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13610 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13611 if (err < 0)
13612 return err;
13613 }
ea1fb29a 13614 return 0;
a361d84b
KY
13615}
13616
13617/* create playback/capture controls for input pins */
05f5f477 13618static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13619 const struct auto_pin_cfg *cfg)
13620{
05f5f477 13621 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13622}
13623
e9af4f36
TI
13624static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13625 hda_nid_t nid, int pin_type)
13626{
13627 int idx;
13628
13629 alc_set_pin_output(codec, nid, pin_type);
13630 if (nid == 0x14 || nid == 0x16)
13631 idx = 0;
13632 else
13633 idx = 1;
13634 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13635}
13636
13637static void alc268_auto_init_multi_out(struct hda_codec *codec)
13638{
13639 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13640 int i;
13641
13642 for (i = 0; i < spec->autocfg.line_outs; i++) {
13643 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13644 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13645 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13646 }
13647}
13648
13649static void alc268_auto_init_hp_out(struct hda_codec *codec)
13650{
13651 struct alc_spec *spec = codec->spec;
13652 hda_nid_t pin;
e1ca7b4e 13653 int i;
e9af4f36 13654
e1ca7b4e
TI
13655 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13656 pin = spec->autocfg.hp_pins[i];
e9af4f36 13657 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13658 }
13659 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13660 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13661 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13662 }
13663 if (spec->autocfg.mono_out_pin)
13664 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13665 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13666}
13667
a361d84b
KY
13668static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13669{
13670 struct alc_spec *spec = codec->spec;
13671 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13672 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13673 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13674 unsigned int dac_vol1, dac_vol2;
13675
e9af4f36 13676 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13677 snd_hda_codec_write(codec, speaker_nid, 0,
13678 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13679 /* mute mixer inputs from 0x1d */
a361d84b
KY
13680 snd_hda_codec_write(codec, 0x0f, 0,
13681 AC_VERB_SET_AMP_GAIN_MUTE,
13682 AMP_IN_UNMUTE(1));
13683 snd_hda_codec_write(codec, 0x10, 0,
13684 AC_VERB_SET_AMP_GAIN_MUTE,
13685 AMP_IN_UNMUTE(1));
13686 } else {
e9af4f36 13687 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13688 snd_hda_codec_write(codec, 0x0f, 0,
13689 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13690 snd_hda_codec_write(codec, 0x10, 0,
13691 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13692 }
13693
13694 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13695 if (line_nid == 0x14)
a361d84b
KY
13696 dac_vol2 = AMP_OUT_ZERO;
13697 else if (line_nid == 0x15)
13698 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13699 if (hp_nid == 0x14)
a361d84b
KY
13700 dac_vol2 = AMP_OUT_ZERO;
13701 else if (hp_nid == 0x15)
13702 dac_vol1 = AMP_OUT_ZERO;
13703 if (line_nid != 0x16 || hp_nid != 0x16 ||
13704 spec->autocfg.line_out_pins[1] != 0x16 ||
13705 spec->autocfg.line_out_pins[2] != 0x16)
13706 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13707
13708 snd_hda_codec_write(codec, 0x02, 0,
13709 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13710 snd_hda_codec_write(codec, 0x03, 0,
13711 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13712}
13713
def319f9 13714/* pcm configuration: identical with ALC880 */
a361d84b
KY
13715#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13716#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13717#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13718#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13719
13720/*
13721 * BIOS auto configuration
13722 */
13723static int alc268_parse_auto_config(struct hda_codec *codec)
13724{
13725 struct alc_spec *spec = codec->spec;
13726 int err;
4c6d72d1 13727 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13728
13729 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13730 alc268_ignore);
13731 if (err < 0)
13732 return err;
7e0e44d4
TI
13733 if (!spec->autocfg.line_outs) {
13734 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13735 spec->multiout.max_channels = 2;
13736 spec->no_analog = 1;
13737 goto dig_only;
13738 }
a361d84b 13739 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13740 }
a361d84b
KY
13741 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13742 if (err < 0)
13743 return err;
05f5f477 13744 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13745 if (err < 0)
13746 return err;
13747
13748 spec->multiout.max_channels = 2;
13749
7e0e44d4 13750 dig_only:
a361d84b 13751 /* digital only support output */
757899ac 13752 alc_auto_parse_digital(codec);
603c4019 13753 if (spec->kctls.list)
d88897ea 13754 add_mixer(spec, spec->kctls.list);
a361d84b 13755
892981ff 13756 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13757 add_mixer(spec, alc268_beep_mixer);
aef9d318 13758
d88897ea 13759 add_verb(spec, alc268_volume_init_verbs);
5908589f 13760 spec->num_mux_defs = 2;
61b9b9b1 13761 spec->input_mux = &spec->private_imux[0];
a361d84b 13762
776e184e
TI
13763 err = alc_auto_add_mic_boost(codec);
13764 if (err < 0)
13765 return err;
13766
6227cdce 13767 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13768
a361d84b
KY
13769 return 1;
13770}
13771
a361d84b 13772#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13773#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13774
13775/* init callback for auto-configuration model -- overriding the default init */
13776static void alc268_auto_init(struct hda_codec *codec)
13777{
f6c7e546 13778 struct alc_spec *spec = codec->spec;
a361d84b
KY
13779 alc268_auto_init_multi_out(codec);
13780 alc268_auto_init_hp_out(codec);
13781 alc268_auto_init_mono_speaker_out(codec);
13782 alc268_auto_init_analog_input(codec);
ae0ebbf7 13783 alc268_auto_init_input_src(codec);
757899ac 13784 alc_auto_init_digital(codec);
f6c7e546 13785 if (spec->unsol_event)
7fb0d78f 13786 alc_inithook(codec);
a361d84b
KY
13787}
13788
13789/*
13790 * configuration and preset
13791 */
ea734963 13792static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13793 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13794 [ALC268_3ST] = "3stack",
983f8ae4 13795 [ALC268_TOSHIBA] = "toshiba",
d273809e 13796 [ALC268_ACER] = "acer",
c238b4f4 13797 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13798 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13799 [ALC268_DELL] = "dell",
f12462c5 13800 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13801#ifdef CONFIG_SND_DEBUG
13802 [ALC268_TEST] = "test",
13803#endif
a361d84b
KY
13804 [ALC268_AUTO] = "auto",
13805};
13806
a9111321 13807static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13808 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13809 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13810 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13811 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13812 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13813 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13814 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13815 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13816 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13817 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13818 /* almost compatible with toshiba but with optional digital outs;
13819 * auto-probing seems working fine
13820 */
8871e5b9 13821 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13822 ALC268_AUTO),
a361d84b 13823 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13824 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13825 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13826 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13827 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13828 {}
13829};
13830
3abf2f36 13831/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13832static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13833 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13834 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13835 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13836 ALC268_TOSHIBA),
13837 {}
13838};
13839
a9111321 13840static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13841 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13842 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13843 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13844 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13845 alc267_quanta_il1_verbs },
13846 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13847 .dac_nids = alc268_dac_nids,
13848 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13849 .adc_nids = alc268_adc_nids_alt,
13850 .hp_nid = 0x03,
13851 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13852 .channel_mode = alc268_modes,
4f5d1706
TI
13853 .unsol_event = alc_sku_unsol_event,
13854 .setup = alc267_quanta_il1_setup,
13855 .init_hook = alc_inithook,
eb5a6621 13856 },
a361d84b 13857 [ALC268_3ST] = {
aef9d318
TI
13858 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13859 alc268_beep_mixer },
a361d84b
KY
13860 .init_verbs = { alc268_base_init_verbs },
13861 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13862 .dac_nids = alc268_dac_nids,
13863 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13864 .adc_nids = alc268_adc_nids_alt,
e1406348 13865 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13866 .hp_nid = 0x03,
13867 .dig_out_nid = ALC268_DIGOUT_NID,
13868 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13869 .channel_mode = alc268_modes,
13870 .input_mux = &alc268_capture_source,
13871 },
d1a991a6 13872 [ALC268_TOSHIBA] = {
42171c17 13873 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13874 alc268_beep_mixer },
d273809e
TI
13875 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13876 alc268_toshiba_verbs },
d1a991a6
KY
13877 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13878 .dac_nids = alc268_dac_nids,
13879 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13880 .adc_nids = alc268_adc_nids_alt,
e1406348 13881 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13882 .hp_nid = 0x03,
13883 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13884 .channel_mode = alc268_modes,
13885 .input_mux = &alc268_capture_source,
e9427969 13886 .unsol_event = alc_sku_unsol_event,
4f5d1706 13887 .setup = alc268_toshiba_setup,
e9427969 13888 .init_hook = alc_inithook,
d273809e
TI
13889 },
13890 [ALC268_ACER] = {
432fd133 13891 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13892 alc268_beep_mixer },
d273809e
TI
13893 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13894 alc268_acer_verbs },
13895 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13896 .dac_nids = alc268_dac_nids,
13897 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13898 .adc_nids = alc268_adc_nids_alt,
e1406348 13899 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13900 .hp_nid = 0x02,
13901 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13902 .channel_mode = alc268_modes,
0ccb541c 13903 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13904 .unsol_event = alc_sku_unsol_event,
13905 .setup = alc268_acer_setup,
13906 .init_hook = alc_inithook,
d1a991a6 13907 },
c238b4f4
TI
13908 [ALC268_ACER_DMIC] = {
13909 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13910 alc268_beep_mixer },
13911 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13912 alc268_acer_verbs },
13913 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13914 .dac_nids = alc268_dac_nids,
13915 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13916 .adc_nids = alc268_adc_nids_alt,
13917 .capsrc_nids = alc268_capsrc_nids,
13918 .hp_nid = 0x02,
13919 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13920 .channel_mode = alc268_modes,
13921 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13922 .unsol_event = alc_sku_unsol_event,
13923 .setup = alc268_acer_setup,
13924 .init_hook = alc_inithook,
c238b4f4 13925 },
8ef355da
KY
13926 [ALC268_ACER_ASPIRE_ONE] = {
13927 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13928 alc268_beep_mixer,
fdbc6626 13929 alc268_capture_nosrc_mixer },
8ef355da
KY
13930 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13931 alc268_acer_aspire_one_verbs },
13932 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13933 .dac_nids = alc268_dac_nids,
13934 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13935 .adc_nids = alc268_adc_nids_alt,
13936 .capsrc_nids = alc268_capsrc_nids,
13937 .hp_nid = 0x03,
13938 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13939 .channel_mode = alc268_modes,
3b8510ce 13940 .unsol_event = alc_sku_unsol_event,
4f5d1706 13941 .setup = alc268_acer_lc_setup,
3b8510ce 13942 .init_hook = alc_inithook,
8ef355da 13943 },
3866f0b0 13944 [ALC268_DELL] = {
fdbc6626
TI
13945 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13946 alc268_capture_nosrc_mixer },
3866f0b0
TI
13947 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13948 alc268_dell_verbs },
13949 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13950 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13951 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13952 .adc_nids = alc268_adc_nids_alt,
13953 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13954 .hp_nid = 0x02,
13955 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13956 .channel_mode = alc268_modes,
a9fd4f3f 13957 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13958 .setup = alc268_dell_setup,
13959 .init_hook = alc_inithook,
3866f0b0 13960 },
f12462c5 13961 [ALC268_ZEPTO] = {
aef9d318
TI
13962 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13963 alc268_beep_mixer },
f12462c5
MT
13964 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13965 alc268_toshiba_verbs },
13966 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13967 .dac_nids = alc268_dac_nids,
13968 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13969 .adc_nids = alc268_adc_nids_alt,
e1406348 13970 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13971 .hp_nid = 0x03,
13972 .dig_out_nid = ALC268_DIGOUT_NID,
13973 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13974 .channel_mode = alc268_modes,
13975 .input_mux = &alc268_capture_source,
e9427969 13976 .unsol_event = alc_sku_unsol_event,
4f5d1706 13977 .setup = alc268_toshiba_setup,
e9427969 13978 .init_hook = alc_inithook,
f12462c5 13979 },
86c53bd2
JW
13980#ifdef CONFIG_SND_DEBUG
13981 [ALC268_TEST] = {
13982 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13983 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13984 alc268_volume_init_verbs },
13985 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13986 .dac_nids = alc268_dac_nids,
13987 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13988 .adc_nids = alc268_adc_nids_alt,
e1406348 13989 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13990 .hp_nid = 0x03,
13991 .dig_out_nid = ALC268_DIGOUT_NID,
13992 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13993 .channel_mode = alc268_modes,
13994 .input_mux = &alc268_capture_source,
13995 },
13996#endif
a361d84b
KY
13997};
13998
13999static int patch_alc268(struct hda_codec *codec)
14000{
14001 struct alc_spec *spec;
14002 int board_config;
22971e3a 14003 int i, has_beep, err;
a361d84b 14004
ef86f581 14005 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14006 if (spec == NULL)
14007 return -ENOMEM;
14008
14009 codec->spec = spec;
14010
14011 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14012 alc268_models,
14013 alc268_cfg_tbl);
14014
3abf2f36
TI
14015 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14016 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14017 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14018
a361d84b 14019 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14020 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14021 codec->chip_name);
a361d84b
KY
14022 board_config = ALC268_AUTO;
14023 }
14024
14025 if (board_config == ALC268_AUTO) {
14026 /* automatic parse from the BIOS config */
14027 err = alc268_parse_auto_config(codec);
14028 if (err < 0) {
14029 alc_free(codec);
14030 return err;
14031 } else if (!err) {
14032 printk(KERN_INFO
14033 "hda_codec: Cannot set up configuration "
14034 "from BIOS. Using base mode...\n");
14035 board_config = ALC268_3ST;
14036 }
14037 }
14038
14039 if (board_config != ALC268_AUTO)
e9c364c0 14040 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14041
a361d84b
KY
14042 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14043 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14044 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14045
a361d84b
KY
14046 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14047
22971e3a
TI
14048 has_beep = 0;
14049 for (i = 0; i < spec->num_mixers; i++) {
14050 if (spec->mixers[i] == alc268_beep_mixer) {
14051 has_beep = 1;
14052 break;
14053 }
14054 }
14055
14056 if (has_beep) {
14057 err = snd_hda_attach_beep_device(codec, 0x1);
14058 if (err < 0) {
14059 alc_free(codec);
14060 return err;
14061 }
14062 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14063 /* override the amp caps for beep generator */
14064 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14065 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14066 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14067 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14068 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14069 }
aef9d318 14070
7e0e44d4 14071 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14072 /* check whether NID 0x07 is valid */
14073 unsigned int wcap = get_wcaps(codec, 0x07);
14074
defb5ab2 14075 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14076 /* get type */
a22d543a 14077 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14078 if (spec->auto_mic ||
14079 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14080 spec->adc_nids = alc268_adc_nids_alt;
14081 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14082 if (spec->auto_mic)
14083 fixup_automic_adc(codec);
fdbc6626
TI
14084 if (spec->auto_mic || spec->input_mux->num_items == 1)
14085 add_mixer(spec, alc268_capture_nosrc_mixer);
14086 else
14087 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14088 } else {
14089 spec->adc_nids = alc268_adc_nids;
14090 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14091 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14092 }
14093 }
2134ea4f
TI
14094
14095 spec->vmaster_nid = 0x02;
14096
a361d84b
KY
14097 codec->patch_ops = alc_patch_ops;
14098 if (board_config == ALC268_AUTO)
14099 spec->init_hook = alc268_auto_init;
1c716153 14100 spec->shutup = alc_eapd_shutup;
ea1fb29a 14101
bf1b0225
KY
14102 alc_init_jacks(codec);
14103
a361d84b
KY
14104 return 0;
14105}
14106
f6a92248
KY
14107/*
14108 * ALC269 channel source setting (2 channel)
14109 */
14110#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14111
14112#define alc269_dac_nids alc260_dac_nids
14113
4c6d72d1 14114static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14115 /* ADC1 */
f53281e6
KY
14116 0x08,
14117};
14118
4c6d72d1 14119static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14120 0x23,
14121};
14122
4c6d72d1 14123static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14124 /* ADC1 */
14125 0x09,
14126};
14127
4c6d72d1 14128static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14129 0x22,
14130};
14131
4c6d72d1 14132static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14133 0x08, 0x09, 0x07, 0x11,
6694635d 14134};
e01bf509 14135
f6a92248
KY
14136#define alc269_modes alc260_modes
14137#define alc269_capture_source alc880_lg_lw_capture_source
14138
a9111321 14139static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14140 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14141 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14142 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14143 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14147 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14148 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14149 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14150 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14151 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14152 { } /* end */
14153};
14154
a9111321 14155static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14156 /* output mixer control */
14157 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14158 {
14159 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14160 .name = "Master Playback Switch",
5e26dfd0 14161 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14162 .info = snd_hda_mixer_amp_switch_info,
14163 .get = snd_hda_mixer_amp_switch_get,
14164 .put = alc268_acer_master_sw_put,
14165 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14166 },
14167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14170 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14171 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14172 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14173 { }
14174};
14175
a9111321 14176static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14177 /* output mixer control */
14178 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14179 {
14180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14181 .name = "Master Playback Switch",
5e26dfd0 14182 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14183 .info = snd_hda_mixer_amp_switch_info,
14184 .get = snd_hda_mixer_amp_switch_get,
14185 .put = alc268_acer_master_sw_put,
14186 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14187 },
14188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14190 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14191 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14192 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14193 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14194 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14195 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14196 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14197 { }
14198};
14199
a9111321 14200static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14201 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14202 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14203 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14204 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14205 { } /* end */
14206};
14207
a9111321 14208static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14209 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14213 { } /* end */
14214};
14215
a9111321 14216static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14217 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14218 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14219 { } /* end */
14220};
14221
f53281e6 14222/* capture mixer elements */
a9111321 14223static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14224 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14225 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14226 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14227 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14228 { } /* end */
14229};
14230
a9111321 14231static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14232 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14233 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14235 { } /* end */
14236};
14237
a9111321 14238static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14239 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14240 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14241 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14242 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14243 { } /* end */
14244};
14245
a9111321 14246static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14247 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14248 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14250 { } /* end */
14251};
14252
26f5df26 14253/* FSC amilo */
84898e87 14254#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14255
a9111321 14256static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14257 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14258 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14259 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14260 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14261 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14262 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14263 { }
14264};
f6a92248 14265
a9111321 14266static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14267 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14268 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14269 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14271 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14272 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14273 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14274 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14275 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14276 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14277 { }
14278};
14279
60db6b53
KY
14280/* toggle speaker-output according to the hp-jack state */
14281static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14282{
3b8510ce 14283 alc_hp_automute(codec);
f6a92248 14284
60db6b53
KY
14285 snd_hda_codec_write(codec, 0x20, 0,
14286 AC_VERB_SET_COEF_INDEX, 0x0c);
14287 snd_hda_codec_write(codec, 0x20, 0,
14288 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14289
60db6b53
KY
14290 snd_hda_codec_write(codec, 0x20, 0,
14291 AC_VERB_SET_COEF_INDEX, 0x0c);
14292 snd_hda_codec_write(codec, 0x20, 0,
14293 AC_VERB_SET_PROC_COEF, 0x480);
14294}
f6a92248 14295
3b8510ce
TI
14296#define alc269_lifebook_speaker_automute \
14297 alc269_quanta_fl1_speaker_automute
64154835 14298
64154835
TV
14299static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14300{
14301 unsigned int present_laptop;
14302 unsigned int present_dock;
14303
864f92be
WF
14304 present_laptop = snd_hda_jack_detect(codec, 0x18);
14305 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14306
14307 /* Laptop mic port overrides dock mic port, design decision */
14308 if (present_dock)
14309 snd_hda_codec_write(codec, 0x23, 0,
14310 AC_VERB_SET_CONNECT_SEL, 0x3);
14311 if (present_laptop)
14312 snd_hda_codec_write(codec, 0x23, 0,
14313 AC_VERB_SET_CONNECT_SEL, 0x0);
14314 if (!present_dock && !present_laptop)
14315 snd_hda_codec_write(codec, 0x23, 0,
14316 AC_VERB_SET_CONNECT_SEL, 0x1);
14317}
14318
60db6b53
KY
14319static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14320 unsigned int res)
14321{
4f5d1706
TI
14322 switch (res >> 26) {
14323 case ALC880_HP_EVENT:
60db6b53 14324 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14325 break;
14326 case ALC880_MIC_EVENT:
14327 alc_mic_automute(codec);
14328 break;
14329 }
60db6b53 14330}
f6a92248 14331
64154835
TV
14332static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14333 unsigned int res)
14334{
14335 if ((res >> 26) == ALC880_HP_EVENT)
14336 alc269_lifebook_speaker_automute(codec);
14337 if ((res >> 26) == ALC880_MIC_EVENT)
14338 alc269_lifebook_mic_autoswitch(codec);
14339}
14340
4f5d1706
TI
14341static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14342{
14343 struct alc_spec *spec = codec->spec;
20645d70
TI
14344 spec->autocfg.hp_pins[0] = 0x15;
14345 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14346 spec->automute_mixer_nid[0] = 0x0c;
14347 spec->automute = 1;
14348 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14349 spec->ext_mic.pin = 0x18;
14350 spec->ext_mic.mux_idx = 0;
14351 spec->int_mic.pin = 0x19;
14352 spec->int_mic.mux_idx = 1;
14353 spec->auto_mic = 1;
14354}
14355
60db6b53
KY
14356static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14357{
14358 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14359 alc_mic_automute(codec);
60db6b53 14360}
f6a92248 14361
3b8510ce
TI
14362static void alc269_lifebook_setup(struct hda_codec *codec)
14363{
14364 struct alc_spec *spec = codec->spec;
14365 spec->autocfg.hp_pins[0] = 0x15;
14366 spec->autocfg.hp_pins[1] = 0x1a;
14367 spec->autocfg.speaker_pins[0] = 0x14;
14368 spec->automute_mixer_nid[0] = 0x0c;
14369 spec->automute = 1;
14370 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14371}
14372
64154835
TV
14373static void alc269_lifebook_init_hook(struct hda_codec *codec)
14374{
14375 alc269_lifebook_speaker_automute(codec);
14376 alc269_lifebook_mic_autoswitch(codec);
14377}
14378
a9111321 14379static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14380 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14381 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14382 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14383 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14384 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14385 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14386 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14387 {}
14388};
14389
a9111321 14390static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14391 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14392 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14393 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14394 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14395 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14396 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14397 {}
14398};
14399
a9111321 14400static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14401 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14402 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14403 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14404 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14405 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14406 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14407 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14408 {}
14409};
14410
a9111321 14411static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14412 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14413 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14414 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14415 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14416 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14417 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14418 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14419 {}
14420};
14421
a9111321 14422static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14423 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14424 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14425 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14426 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14427 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14428 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14429 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14430 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14431 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14432 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14433 { }
14434};
14435
226b1ec8 14436static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14437{
4f5d1706 14438 struct alc_spec *spec = codec->spec;
20645d70
TI
14439 spec->autocfg.hp_pins[0] = 0x15;
14440 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14441 spec->automute_mixer_nid[0] = 0x0c;
14442 spec->automute = 1;
14443 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14444 spec->ext_mic.pin = 0x18;
14445 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14446 spec->int_mic.pin = 0x19;
14447 spec->int_mic.mux_idx = 1;
4f5d1706 14448 spec->auto_mic = 1;
f53281e6
KY
14449}
14450
226b1ec8 14451static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14452{
14453 struct alc_spec *spec = codec->spec;
20645d70
TI
14454 spec->autocfg.hp_pins[0] = 0x15;
14455 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14456 spec->automute_mixer_nid[0] = 0x0c;
14457 spec->automute = 1;
14458 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14459 spec->ext_mic.pin = 0x18;
14460 spec->ext_mic.mux_idx = 0;
14461 spec->int_mic.pin = 0x12;
226b1ec8 14462 spec->int_mic.mux_idx = 5;
84898e87
KY
14463 spec->auto_mic = 1;
14464}
14465
226b1ec8 14466static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14467{
4f5d1706 14468 struct alc_spec *spec = codec->spec;
226b1ec8 14469 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14470 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14471 spec->automute_mixer_nid[0] = 0x0c;
14472 spec->automute = 1;
14473 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14474 spec->ext_mic.pin = 0x18;
14475 spec->ext_mic.mux_idx = 0;
14476 spec->int_mic.pin = 0x19;
14477 spec->int_mic.mux_idx = 1;
14478 spec->auto_mic = 1;
f53281e6
KY
14479}
14480
226b1ec8
KY
14481static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14482{
14483 struct alc_spec *spec = codec->spec;
14484 spec->autocfg.hp_pins[0] = 0x21;
14485 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14486 spec->automute_mixer_nid[0] = 0x0c;
14487 spec->automute = 1;
14488 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14489 spec->ext_mic.pin = 0x18;
14490 spec->ext_mic.mux_idx = 0;
14491 spec->int_mic.pin = 0x12;
14492 spec->int_mic.mux_idx = 6;
14493 spec->auto_mic = 1;
14494}
14495
60db6b53
KY
14496/*
14497 * generic initialization of ADC, input mixers and output mixers
14498 */
a9111321 14499static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14500 /*
14501 * Unmute ADC0 and set the default input to mic-in
14502 */
84898e87 14503 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14504
14505 /*
84898e87 14506 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14507 */
14508 /* set vol=0 to output mixers */
14509 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14510 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14511
14512 /* set up input amps for analog loopback */
14513 /* Amp Indices: DAC = 0, mixer = 1 */
14514 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14516 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14517 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14519 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14520
14521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14522 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14523 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14525 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14526 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14527 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14528
14529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14530 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14531
84898e87
KY
14532 /* FIXME: use Mux-type input source selection */
14533 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14534 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14535 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14536
84898e87
KY
14537 /* set EAPD */
14538 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14539 { }
14540};
14541
a9111321 14542static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14543 /*
14544 * Unmute ADC0 and set the default input to mic-in
14545 */
14546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14547
14548 /*
14549 * Set up output mixers (0x02 - 0x03)
14550 */
14551 /* set vol=0 to output mixers */
14552 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14553 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14554
14555 /* set up input amps for analog loopback */
14556 /* Amp Indices: DAC = 0, mixer = 1 */
14557 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14558 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14559 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14560 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14561 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563
14564 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14565 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14566 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14567 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14568 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14569 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14570 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14571
14572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14573 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14574
14575 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14576 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14577 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14578 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14579
14580 /* set EAPD */
14581 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14582 { }
14583};
14584
9d0b71b1
TI
14585#define alc269_auto_create_multi_out_ctls \
14586 alc268_auto_create_multi_out_ctls
05f5f477
TI
14587#define alc269_auto_create_input_ctls \
14588 alc268_auto_create_input_ctls
f6a92248
KY
14589
14590#ifdef CONFIG_SND_HDA_POWER_SAVE
14591#define alc269_loopbacks alc880_loopbacks
14592#endif
14593
def319f9 14594/* pcm configuration: identical with ALC880 */
f6a92248
KY
14595#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14596#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14597#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14598#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14599
a9111321 14600static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14601 .substreams = 1,
14602 .channels_min = 2,
14603 .channels_max = 8,
14604 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14605 /* NID is set in alc_build_pcms */
14606 .ops = {
14607 .open = alc880_playback_pcm_open,
14608 .prepare = alc880_playback_pcm_prepare,
14609 .cleanup = alc880_playback_pcm_cleanup
14610 },
14611};
14612
a9111321 14613static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14614 .substreams = 1,
14615 .channels_min = 2,
14616 .channels_max = 2,
14617 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14618 /* NID is set in alc_build_pcms */
14619};
14620
ad35879a
TI
14621#ifdef CONFIG_SND_HDA_POWER_SAVE
14622static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14623{
14624 switch (codec->subsystem_id) {
14625 case 0x103c1586:
14626 return 1;
14627 }
14628 return 0;
14629}
14630
14631static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14632{
14633 /* update mute-LED according to the speaker mute state */
14634 if (nid == 0x01 || nid == 0x14) {
14635 int pinval;
14636 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14637 HDA_AMP_MUTE)
14638 pinval = 0x24;
14639 else
14640 pinval = 0x20;
14641 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14642 snd_hda_codec_update_cache(codec, 0x19, 0,
14643 AC_VERB_SET_PIN_WIDGET_CONTROL,
14644 pinval);
ad35879a
TI
14645 }
14646 return alc_check_power_status(codec, nid);
14647}
14648#endif /* CONFIG_SND_HDA_POWER_SAVE */
14649
840b64c0
TI
14650static int alc275_setup_dual_adc(struct hda_codec *codec)
14651{
14652 struct alc_spec *spec = codec->spec;
14653
14654 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14655 return 0;
14656 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14657 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14658 if (spec->ext_mic.pin <= 0x12) {
14659 spec->private_adc_nids[0] = 0x08;
14660 spec->private_adc_nids[1] = 0x11;
14661 spec->private_capsrc_nids[0] = 0x23;
14662 spec->private_capsrc_nids[1] = 0x22;
14663 } else {
14664 spec->private_adc_nids[0] = 0x11;
14665 spec->private_adc_nids[1] = 0x08;
14666 spec->private_capsrc_nids[0] = 0x22;
14667 spec->private_capsrc_nids[1] = 0x23;
14668 }
14669 spec->adc_nids = spec->private_adc_nids;
14670 spec->capsrc_nids = spec->private_capsrc_nids;
14671 spec->num_adc_nids = 2;
14672 spec->dual_adc_switch = 1;
14673 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14674 spec->adc_nids[0], spec->adc_nids[1]);
14675 return 1;
14676 }
14677 return 0;
14678}
14679
d433a678
TI
14680/* different alc269-variants */
14681enum {
14682 ALC269_TYPE_NORMAL,
48c88e82 14683 ALC269_TYPE_ALC258,
d433a678 14684 ALC269_TYPE_ALC259,
48c88e82
KY
14685 ALC269_TYPE_ALC269VB,
14686 ALC269_TYPE_ALC270,
d433a678
TI
14687 ALC269_TYPE_ALC271X,
14688};
14689
f6a92248
KY
14690/*
14691 * BIOS auto configuration
14692 */
14693static int alc269_parse_auto_config(struct hda_codec *codec)
14694{
14695 struct alc_spec *spec = codec->spec;
cfb9fb55 14696 int err;
4c6d72d1 14697 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14698
14699 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14700 alc269_ignore);
14701 if (err < 0)
14702 return err;
14703
14704 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14705 if (err < 0)
14706 return err;
f3550d1b
TI
14707 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14708 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14709 else
14710 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14711 0x22, 0);
f6a92248
KY
14712 if (err < 0)
14713 return err;
14714
14715 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14716
757899ac 14717 alc_auto_parse_digital(codec);
f6a92248 14718
603c4019 14719 if (spec->kctls.list)
d88897ea 14720 add_mixer(spec, spec->kctls.list);
f6a92248 14721
d433a678 14722 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14723 add_verb(spec, alc269vb_init_verbs);
6227cdce 14724 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14725 } else {
14726 add_verb(spec, alc269_init_verbs);
6227cdce 14727 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14728 }
14729
f6a92248 14730 spec->num_mux_defs = 1;
61b9b9b1 14731 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14732
14733 if (!alc275_setup_dual_adc(codec))
14734 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14735 sizeof(alc269_adc_candidates));
6694635d 14736
f6a92248
KY
14737 err = alc_auto_add_mic_boost(codec);
14738 if (err < 0)
14739 return err;
14740
7e0e44d4 14741 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14742 set_capture_mixer(codec);
f53281e6 14743
f6a92248
KY
14744 return 1;
14745}
14746
e9af4f36
TI
14747#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14748#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14749#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14750#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14751
14752
14753/* init callback for auto-configuration model -- overriding the default init */
14754static void alc269_auto_init(struct hda_codec *codec)
14755{
f6c7e546 14756 struct alc_spec *spec = codec->spec;
f6a92248
KY
14757 alc269_auto_init_multi_out(codec);
14758 alc269_auto_init_hp_out(codec);
14759 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14760 if (!spec->dual_adc_switch)
14761 alc269_auto_init_input_src(codec);
757899ac 14762 alc_auto_init_digital(codec);
f6c7e546 14763 if (spec->unsol_event)
7fb0d78f 14764 alc_inithook(codec);
f6a92248
KY
14765}
14766
0ec33d1f
TI
14767static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14768{
14769 int val = alc_read_coef_idx(codec, 0x04);
14770 if (power_up)
14771 val |= 1 << 11;
14772 else
14773 val &= ~(1 << 11);
14774 alc_write_coef_idx(codec, 0x04, val);
14775}
14776
5402e4cb 14777static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14778{
0ec33d1f
TI
14779 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14780 alc269_toggle_power_output(codec, 0);
977ddd6b 14781 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14782 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14783 msleep(150);
14784 }
977ddd6b 14785}
0ec33d1f 14786
5402e4cb 14787#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14788static int alc269_resume(struct hda_codec *codec)
14789{
977ddd6b 14790 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14791 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14792 msleep(150);
14793 }
14794
14795 codec->patch_ops.init(codec);
14796
14797 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14798 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14799 msleep(200);
14800 }
14801
0ec33d1f
TI
14802 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14803 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14804
14805 snd_hda_codec_resume_amp(codec);
14806 snd_hda_codec_resume_cache(codec);
9e5341b9 14807 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14808 return 0;
14809}
0ec33d1f 14810#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14811
1a99d4a4 14812static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14813 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14814{
14815 int coef;
14816
58701120 14817 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14818 return;
1a99d4a4
KY
14819 coef = alc_read_coef_idx(codec, 0x1e);
14820 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14821}
14822
6981d184
TI
14823static void alc271_fixup_dmic(struct hda_codec *codec,
14824 const struct alc_fixup *fix, int action)
14825{
a9111321 14826 static const struct hda_verb verbs[] = {
6981d184
TI
14827 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14828 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14829 {}
14830 };
14831 unsigned int cfg;
14832
14833 if (strcmp(codec->chip_name, "ALC271X"))
14834 return;
14835 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14836 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14837 snd_hda_sequence_write(codec, verbs);
14838}
14839
ff818c24
TI
14840enum {
14841 ALC269_FIXUP_SONY_VAIO,
74dc8909 14842 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14843 ALC269_FIXUP_DELL_M101Z,
022c92be 14844 ALC269_FIXUP_SKU_IGNORE,
ac612407 14845 ALC269_FIXUP_ASUS_G73JW,
357f915e 14846 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14847 ALC275_FIXUP_SONY_HWEQ,
6981d184 14848 ALC271_FIXUP_DMIC,
ff818c24
TI
14849};
14850
ff818c24
TI
14851static const struct alc_fixup alc269_fixups[] = {
14852 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14853 .type = ALC_FIXUP_VERBS,
14854 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14855 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14856 {}
14857 }
ff818c24 14858 },
74dc8909 14859 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14860 .type = ALC_FIXUP_VERBS,
14861 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14862 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14863 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14864 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14865 { }
b5bfbc67
TI
14866 },
14867 .chained = true,
14868 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14869 },
145a902b 14870 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14871 .type = ALC_FIXUP_VERBS,
14872 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14873 /* Enables internal speaker */
14874 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14875 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14876 {}
14877 }
14878 },
022c92be 14879 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14880 .type = ALC_FIXUP_SKU,
14881 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14882 },
ac612407 14883 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14884 .type = ALC_FIXUP_PINS,
14885 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14886 { 0x17, 0x99130111 }, /* subwoofer */
14887 { }
14888 }
14889 },
357f915e 14890 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14891 .type = ALC_FIXUP_VERBS,
14892 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14893 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14894 {}
14895 }
14896 },
1a99d4a4 14897 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14898 .type = ALC_FIXUP_FUNC,
14899 .v.func = alc269_fixup_hweq,
14900 .chained = true,
14901 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14902 },
14903 [ALC271_FIXUP_DMIC] = {
14904 .type = ALC_FIXUP_FUNC,
14905 .v.func = alc271_fixup_dmic,
14906 },
ff818c24
TI
14907};
14908
a9111321 14909static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14910 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14911 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14912 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14913 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14914 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14915 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14916 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14917 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14918 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14919 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14920 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14921 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14922 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14923 {}
14924};
14925
14926
f6a92248
KY
14927/*
14928 * configuration and preset
14929 */
ea734963 14930static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14931 [ALC269_BASIC] = "basic",
2922c9af 14932 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14933 [ALC269_AMIC] = "laptop-amic",
14934 [ALC269_DMIC] = "laptop-dmic",
64154835 14935 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14936 [ALC269_LIFEBOOK] = "lifebook",
14937 [ALC269_AUTO] = "auto",
f6a92248
KY
14938};
14939
a9111321 14940static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14941 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14942 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14943 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14944 ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14954 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14955 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14967 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14977 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14979 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14981 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14982 ALC269_DMIC),
60db6b53 14983 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14984 ALC269_DMIC),
14985 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14986 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14987 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14988 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14989 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14990 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14991 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14992 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14993 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14994 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14995 {}
14996};
14997
a9111321 14998static const struct alc_config_preset alc269_presets[] = {
f6a92248 14999 [ALC269_BASIC] = {
f9e336f6 15000 .mixers = { alc269_base_mixer },
f6a92248
KY
15001 .init_verbs = { alc269_init_verbs },
15002 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15003 .dac_nids = alc269_dac_nids,
15004 .hp_nid = 0x03,
15005 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15006 .channel_mode = alc269_modes,
15007 .input_mux = &alc269_capture_source,
15008 },
60db6b53
KY
15009 [ALC269_QUANTA_FL1] = {
15010 .mixers = { alc269_quanta_fl1_mixer },
15011 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15012 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15013 .dac_nids = alc269_dac_nids,
15014 .hp_nid = 0x03,
15015 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15016 .channel_mode = alc269_modes,
15017 .input_mux = &alc269_capture_source,
15018 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15019 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15020 .init_hook = alc269_quanta_fl1_init_hook,
15021 },
84898e87
KY
15022 [ALC269_AMIC] = {
15023 .mixers = { alc269_laptop_mixer },
15024 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15025 .init_verbs = { alc269_init_verbs,
84898e87 15026 alc269_laptop_amic_init_verbs },
f53281e6
KY
15027 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15028 .dac_nids = alc269_dac_nids,
15029 .hp_nid = 0x03,
15030 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15031 .channel_mode = alc269_modes,
3b8510ce 15032 .unsol_event = alc_sku_unsol_event,
84898e87 15033 .setup = alc269_laptop_amic_setup,
3b8510ce 15034 .init_hook = alc_inithook,
f53281e6 15035 },
84898e87
KY
15036 [ALC269_DMIC] = {
15037 .mixers = { alc269_laptop_mixer },
15038 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15039 .init_verbs = { alc269_init_verbs,
84898e87
KY
15040 alc269_laptop_dmic_init_verbs },
15041 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15042 .dac_nids = alc269_dac_nids,
15043 .hp_nid = 0x03,
15044 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15045 .channel_mode = alc269_modes,
3b8510ce 15046 .unsol_event = alc_sku_unsol_event,
84898e87 15047 .setup = alc269_laptop_dmic_setup,
3b8510ce 15048 .init_hook = alc_inithook,
84898e87
KY
15049 },
15050 [ALC269VB_AMIC] = {
15051 .mixers = { alc269vb_laptop_mixer },
15052 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15053 .init_verbs = { alc269vb_init_verbs,
15054 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15055 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15056 .dac_nids = alc269_dac_nids,
15057 .hp_nid = 0x03,
15058 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15059 .channel_mode = alc269_modes,
3b8510ce 15060 .unsol_event = alc_sku_unsol_event,
226b1ec8 15061 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15062 .init_hook = alc_inithook,
84898e87
KY
15063 },
15064 [ALC269VB_DMIC] = {
15065 .mixers = { alc269vb_laptop_mixer },
15066 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15067 .init_verbs = { alc269vb_init_verbs,
15068 alc269vb_laptop_dmic_init_verbs },
15069 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15070 .dac_nids = alc269_dac_nids,
15071 .hp_nid = 0x03,
15072 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15073 .channel_mode = alc269_modes,
3b8510ce 15074 .unsol_event = alc_sku_unsol_event,
84898e87 15075 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15076 .init_hook = alc_inithook,
f53281e6 15077 },
26f5df26 15078 [ALC269_FUJITSU] = {
45bdd1c1 15079 .mixers = { alc269_fujitsu_mixer },
84898e87 15080 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15081 .init_verbs = { alc269_init_verbs,
84898e87 15082 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15083 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15084 .dac_nids = alc269_dac_nids,
15085 .hp_nid = 0x03,
15086 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15087 .channel_mode = alc269_modes,
3b8510ce 15088 .unsol_event = alc_sku_unsol_event,
84898e87 15089 .setup = alc269_laptop_dmic_setup,
3b8510ce 15090 .init_hook = alc_inithook,
26f5df26 15091 },
64154835
TV
15092 [ALC269_LIFEBOOK] = {
15093 .mixers = { alc269_lifebook_mixer },
15094 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15095 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15096 .dac_nids = alc269_dac_nids,
15097 .hp_nid = 0x03,
15098 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15099 .channel_mode = alc269_modes,
15100 .input_mux = &alc269_capture_source,
15101 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15102 .setup = alc269_lifebook_setup,
64154835
TV
15103 .init_hook = alc269_lifebook_init_hook,
15104 },
fe3eb0a7
KY
15105 [ALC271_ACER] = {
15106 .mixers = { alc269_asus_mixer },
15107 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15108 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15109 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15110 .dac_nids = alc269_dac_nids,
15111 .adc_nids = alc262_dmic_adc_nids,
15112 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15113 .capsrc_nids = alc262_dmic_capsrc_nids,
15114 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15115 .channel_mode = alc269_modes,
15116 .input_mux = &alc269_capture_source,
15117 .dig_out_nid = ALC880_DIGOUT_NID,
15118 .unsol_event = alc_sku_unsol_event,
15119 .setup = alc269vb_laptop_dmic_setup,
15120 .init_hook = alc_inithook,
15121 },
f6a92248
KY
15122};
15123
977ddd6b
KY
15124static int alc269_fill_coef(struct hda_codec *codec)
15125{
15126 int val;
15127
15128 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15129 alc_write_coef_idx(codec, 0xf, 0x960b);
15130 alc_write_coef_idx(codec, 0xe, 0x8817);
15131 }
15132
15133 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15134 alc_write_coef_idx(codec, 0xf, 0x960b);
15135 alc_write_coef_idx(codec, 0xe, 0x8814);
15136 }
15137
15138 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15139 val = alc_read_coef_idx(codec, 0x04);
15140 /* Power up output pin */
15141 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15142 }
15143
15144 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15145 val = alc_read_coef_idx(codec, 0xd);
15146 if ((val & 0x0c00) >> 10 != 0x1) {
15147 /* Capless ramp up clock control */
15148 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15149 }
15150 val = alc_read_coef_idx(codec, 0x17);
15151 if ((val & 0x01c0) >> 6 != 0x4) {
15152 /* Class D power on reset */
15153 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15154 }
15155 }
15156 return 0;
15157}
15158
f6a92248
KY
15159static int patch_alc269(struct hda_codec *codec)
15160{
15161 struct alc_spec *spec;
48c88e82 15162 int board_config, coef;
f6a92248
KY
15163 int err;
15164
15165 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15166 if (spec == NULL)
15167 return -ENOMEM;
15168
15169 codec->spec = spec;
15170
da00c244
KY
15171 alc_auto_parse_customize_define(codec);
15172
c793bec5
KY
15173 if (codec->vendor_id == 0x10ec0269) {
15174 coef = alc_read_coef_idx(codec, 0);
15175 if ((coef & 0x00f0) == 0x0010) {
15176 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15177 spec->cdefine.platform_type == 1) {
15178 alc_codec_rename(codec, "ALC271X");
15179 spec->codec_variant = ALC269_TYPE_ALC271X;
15180 } else if ((coef & 0xf000) == 0x1000) {
15181 spec->codec_variant = ALC269_TYPE_ALC270;
15182 } else if ((coef & 0xf000) == 0x2000) {
15183 alc_codec_rename(codec, "ALC259");
15184 spec->codec_variant = ALC269_TYPE_ALC259;
15185 } else if ((coef & 0xf000) == 0x3000) {
15186 alc_codec_rename(codec, "ALC258");
15187 spec->codec_variant = ALC269_TYPE_ALC258;
15188 } else {
15189 alc_codec_rename(codec, "ALC269VB");
15190 spec->codec_variant = ALC269_TYPE_ALC269VB;
15191 }
15192 } else
15193 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15194 alc269_fill_coef(codec);
15195 }
977ddd6b 15196
f6a92248
KY
15197 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15198 alc269_models,
15199 alc269_cfg_tbl);
15200
15201 if (board_config < 0) {
9a11f1aa
TI
15202 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15203 codec->chip_name);
f6a92248
KY
15204 board_config = ALC269_AUTO;
15205 }
15206
b5bfbc67
TI
15207 if (board_config == ALC269_AUTO) {
15208 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15209 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15210 }
ff818c24 15211
f6a92248
KY
15212 if (board_config == ALC269_AUTO) {
15213 /* automatic parse from the BIOS config */
15214 err = alc269_parse_auto_config(codec);
15215 if (err < 0) {
15216 alc_free(codec);
15217 return err;
15218 } else if (!err) {
15219 printk(KERN_INFO
15220 "hda_codec: Cannot set up configuration "
15221 "from BIOS. Using base mode...\n");
15222 board_config = ALC269_BASIC;
15223 }
15224 }
15225
dc1eae25 15226 if (has_cdefine_beep(codec)) {
8af2591d
TI
15227 err = snd_hda_attach_beep_device(codec, 0x1);
15228 if (err < 0) {
15229 alc_free(codec);
15230 return err;
15231 }
680cd536
KK
15232 }
15233
f6a92248 15234 if (board_config != ALC269_AUTO)
e9c364c0 15235 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15236
84898e87 15237 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15238 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15239 * fix the sample rate of analog I/O to 44.1kHz
15240 */
15241 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15242 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15243 } else if (spec->dual_adc_switch) {
15244 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15245 /* switch ADC dynamically */
15246 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15247 } else {
15248 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15249 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15250 }
f6a92248
KY
15251 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15252 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15253
6694635d 15254 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15255 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15256 spec->adc_nids = alc269_adc_nids;
15257 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15258 spec->capsrc_nids = alc269_capsrc_nids;
15259 } else {
15260 spec->adc_nids = alc269vb_adc_nids;
15261 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15262 spec->capsrc_nids = alc269vb_capsrc_nids;
15263 }
84898e87
KY
15264 }
15265
f9e336f6 15266 if (!spec->cap_mixer)
b59bdf3b 15267 set_capture_mixer(codec);
dc1eae25 15268 if (has_cdefine_beep(codec))
da00c244 15269 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15270
b5bfbc67 15271 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15272
100d5eb3
TI
15273 spec->vmaster_nid = 0x02;
15274
f6a92248 15275 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15276#ifdef SND_HDA_NEEDS_RESUME
15277 codec->patch_ops.resume = alc269_resume;
15278#endif
f6a92248
KY
15279 if (board_config == ALC269_AUTO)
15280 spec->init_hook = alc269_auto_init;
5402e4cb 15281 spec->shutup = alc269_shutup;
bf1b0225
KY
15282
15283 alc_init_jacks(codec);
f6a92248
KY
15284#ifdef CONFIG_SND_HDA_POWER_SAVE
15285 if (!spec->loopback.amplist)
15286 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15287 if (alc269_mic2_for_mute_led(codec))
15288 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15289#endif
15290
15291 return 0;
15292}
15293
df694daa
KY
15294/*
15295 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15296 */
15297
15298/*
15299 * set the path ways for 2 channel output
15300 * need to set the codec line out and mic 1 pin widgets to inputs
15301 */
a9111321 15302static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15303 /* set pin widget 1Ah (line in) for input */
15304 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15305 /* set pin widget 18h (mic1/2) for input, for mic also enable
15306 * the vref
15307 */
df694daa
KY
15308 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15309
9c7f852e
TI
15310 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15311#if 0
15312 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15313 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15314#endif
df694daa
KY
15315 { } /* end */
15316};
15317/*
15318 * 6ch mode
15319 * need to set the codec line out and mic 1 pin widgets to outputs
15320 */
a9111321 15321static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15322 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15323 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15324 /* set pin widget 18h (mic1) for output (CLFE)*/
15325 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15326
15327 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15328 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15329
9c7f852e
TI
15330 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15331#if 0
15332 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15333 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15334#endif
df694daa
KY
15335 { } /* end */
15336};
15337
a9111321 15338static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15339 { 2, alc861_threestack_ch2_init },
15340 { 6, alc861_threestack_ch6_init },
15341};
22309c3e 15342/* Set mic1 as input and unmute the mixer */
a9111321 15343static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15344 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15345 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15346 { } /* end */
15347};
15348/* Set mic1 as output and mute mixer */
a9111321 15349static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15350 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15351 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15352 { } /* end */
15353};
15354
a9111321 15355static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15356 { 2, alc861_uniwill_m31_ch2_init },
15357 { 4, alc861_uniwill_m31_ch4_init },
15358};
df694daa 15359
7cdbff94 15360/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15361static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15362 /* set pin widget 1Ah (line in) for input */
15363 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15364 /* set pin widget 18h (mic1/2) for input, for mic also enable
15365 * the vref
15366 */
7cdbff94
MD
15367 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15368
15369 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15370#if 0
15371 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15372 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15373#endif
15374 { } /* end */
15375};
15376/* Set mic1 nad line-in as output and mute mixer */
a9111321 15377static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15378 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15379 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15380 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15381 /* set pin widget 18h (mic1) for output (CLFE)*/
15382 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15383 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15384 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15385 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15386
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15388#if 0
15389 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15390 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15391#endif
15392 { } /* end */
15393};
15394
a9111321 15395static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15396 { 2, alc861_asus_ch2_init },
15397 { 6, alc861_asus_ch6_init },
15398};
15399
df694daa
KY
15400/* patch-ALC861 */
15401
a9111321 15402static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15403 /* output mixer control */
15404 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15405 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15406 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15407 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15409
15410 /*Input mixer control */
15411 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15412 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15413 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15414 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15415 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15416 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15418 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15419 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15420 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15421
df694daa
KY
15422 { } /* end */
15423};
15424
a9111321 15425static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15426 /* output mixer control */
15427 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15428 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15429 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15430 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15431 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15432
15433 /* Input mixer control */
15434 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15435 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15436 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15437 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15438 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15439 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15441 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15443 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15444
df694daa
KY
15445 {
15446 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15447 .name = "Channel Mode",
15448 .info = alc_ch_mode_info,
15449 .get = alc_ch_mode_get,
15450 .put = alc_ch_mode_put,
15451 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15452 },
15453 { } /* end */
a53d1aec
TD
15454};
15455
a9111321 15456static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15460 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15461
a53d1aec 15462 { } /* end */
f12ab1e0 15463};
a53d1aec 15464
a9111321 15465static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15466 /* output mixer control */
15467 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15468 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15469 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15471 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15472
15473 /* Input mixer control */
15474 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15475 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15476 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15477 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15478 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15479 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15480 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15481 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15482 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15483 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15484
22309c3e
TI
15485 {
15486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15487 .name = "Channel Mode",
15488 .info = alc_ch_mode_info,
15489 .get = alc_ch_mode_get,
15490 .put = alc_ch_mode_put,
15491 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15492 },
15493 { } /* end */
f12ab1e0 15494};
7cdbff94 15495
a9111321 15496static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15497 /* output mixer control */
15498 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15499 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15500 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15503
15504 /* Input mixer control */
15505 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15506 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15507 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15508 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15509 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15510 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15512 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15513 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15514 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15515
7cdbff94
MD
15516 {
15517 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15518 .name = "Channel Mode",
15519 .info = alc_ch_mode_info,
15520 .get = alc_ch_mode_get,
15521 .put = alc_ch_mode_put,
15522 .private_value = ARRAY_SIZE(alc861_asus_modes),
15523 },
15524 { }
56bb0cab
TI
15525};
15526
15527/* additional mixer */
a9111321 15528static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15529 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15530 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15531 { }
15532};
7cdbff94 15533
df694daa
KY
15534/*
15535 * generic initialization of ADC, input mixers and output mixers
15536 */
a9111321 15537static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15538 /*
15539 * Unmute ADC0 and set the default input to mic-in
15540 */
15541 /* port-A for surround (rear panel) */
15542 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15543 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15544 /* port-B for mic-in (rear panel) with vref */
15545 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15546 /* port-C for line-in (rear panel) */
15547 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15548 /* port-D for Front */
15549 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15550 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15551 /* port-E for HP out (front panel) */
15552 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15553 /* route front PCM to HP */
9dece1d7 15554 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15555 /* port-F for mic-in (front panel) with vref */
15556 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15557 /* port-G for CLFE (rear panel) */
15558 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15559 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15560 /* port-H for side (rear panel) */
15561 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15562 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15563 /* CD-in */
15564 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15565 /* route front mic to ADC1*/
15566 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15567 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15568
df694daa
KY
15569 /* Unmute DAC0~3 & spdif out*/
15570 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15571 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15572 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15573 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15574 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15575
df694daa
KY
15576 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15577 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15578 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15581
df694daa
KY
15582 /* Unmute Stereo Mixer 15 */
15583 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15584 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15587
15588 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15589 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15590 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15592 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15594 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15596 /* hp used DAC 3 (Front) */
15597 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15598 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15599
15600 { }
15601};
15602
a9111321 15603static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15604 /*
15605 * Unmute ADC0 and set the default input to mic-in
15606 */
15607 /* port-A for surround (rear panel) */
15608 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15609 /* port-B for mic-in (rear panel) with vref */
15610 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15611 /* port-C for line-in (rear panel) */
15612 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15613 /* port-D for Front */
15614 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15615 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15616 /* port-E for HP out (front panel) */
15617 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15618 /* route front PCM to HP */
9dece1d7 15619 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15620 /* port-F for mic-in (front panel) with vref */
15621 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15622 /* port-G for CLFE (rear panel) */
15623 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15624 /* port-H for side (rear panel) */
15625 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15626 /* CD-in */
15627 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15628 /* route front mic to ADC1*/
15629 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15630 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15631 /* Unmute DAC0~3 & spdif out*/
15632 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15633 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15634 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15637
df694daa
KY
15638 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15639 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15640 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15641 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15643
df694daa
KY
15644 /* Unmute Stereo Mixer 15 */
15645 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15646 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15649
15650 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15651 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15652 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15654 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15655 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15656 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15658 /* hp used DAC 3 (Front) */
15659 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15661 { }
15662};
22309c3e 15663
a9111321 15664static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15665 /*
15666 * Unmute ADC0 and set the default input to mic-in
15667 */
15668 /* port-A for surround (rear panel) */
15669 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15670 /* port-B for mic-in (rear panel) with vref */
15671 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15672 /* port-C for line-in (rear panel) */
15673 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15674 /* port-D for Front */
15675 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15676 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15677 /* port-E for HP out (front panel) */
f12ab1e0
TI
15678 /* this has to be set to VREF80 */
15679 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15680 /* route front PCM to HP */
9dece1d7 15681 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15682 /* port-F for mic-in (front panel) with vref */
15683 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15684 /* port-G for CLFE (rear panel) */
15685 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15686 /* port-H for side (rear panel) */
15687 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15688 /* CD-in */
15689 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15690 /* route front mic to ADC1*/
15691 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15693 /* Unmute DAC0~3 & spdif out*/
15694 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15695 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15696 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15697 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15699
22309c3e
TI
15700 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15701 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15702 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15703 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15705
22309c3e
TI
15706 /* Unmute Stereo Mixer 15 */
15707 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15708 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15711
15712 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15713 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15714 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15716 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15718 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15720 /* hp used DAC 3 (Front) */
15721 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15722 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15723 { }
15724};
15725
a9111321 15726static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15727 /*
15728 * Unmute ADC0 and set the default input to mic-in
15729 */
f12ab1e0
TI
15730 /* port-A for surround (rear panel)
15731 * according to codec#0 this is the HP jack
15732 */
7cdbff94
MD
15733 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15734 /* route front PCM to HP */
15735 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15736 /* port-B for mic-in (rear panel) with vref */
15737 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15738 /* port-C for line-in (rear panel) */
15739 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15740 /* port-D for Front */
15741 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15742 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15743 /* port-E for HP out (front panel) */
f12ab1e0
TI
15744 /* this has to be set to VREF80 */
15745 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15746 /* route front PCM to HP */
9dece1d7 15747 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15748 /* port-F for mic-in (front panel) with vref */
15749 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15750 /* port-G for CLFE (rear panel) */
15751 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15752 /* port-H for side (rear panel) */
15753 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15754 /* CD-in */
15755 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15756 /* route front mic to ADC1*/
15757 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15758 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15759 /* Unmute DAC0~3 & spdif out*/
15760 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15761 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15762 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15763 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15764 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15765 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15766 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15770
7cdbff94
MD
15771 /* Unmute Stereo Mixer 15 */
15772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15776
15777 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15778 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15779 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15785 /* hp used DAC 3 (Front) */
15786 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15787 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15788 { }
15789};
15790
56bb0cab 15791/* additional init verbs for ASUS laptops */
a9111321 15792static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15793 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15794 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15795 { }
15796};
7cdbff94 15797
df694daa
KY
15798/*
15799 * generic initialization of ADC, input mixers and output mixers
15800 */
a9111321 15801static const struct hda_verb alc861_auto_init_verbs[] = {
df694daa
KY
15802 /*
15803 * Unmute ADC0 and set the default input to mic-in
15804 */
f12ab1e0 15805 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15806 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15807
df694daa
KY
15808 /* Unmute DAC0~3 & spdif out*/
15809 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15810 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15811 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15812 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15813 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15814
df694daa
KY
15815 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15816 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15817 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15818 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15819 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15820
df694daa
KY
15821 /* Unmute Stereo Mixer 15 */
15822 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15826
1c20930a
TI
15827 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15828 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15829 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15830 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15831 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15833 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15834 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15835
15836 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15837 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15840 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15841 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15842 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15843 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15844
f12ab1e0 15845 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15846
15847 { }
15848};
15849
a9111321 15850static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15851 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15852
a53d1aec
TD
15853 { }
15854};
15855
15856/* toggle speaker-output according to the hp-jack state */
15857static void alc861_toshiba_automute(struct hda_codec *codec)
15858{
864f92be 15859 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15860
47fd830a
TI
15861 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15862 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15863 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15864 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15865}
15866
15867static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15868 unsigned int res)
15869{
a53d1aec
TD
15870 if ((res >> 26) == ALC880_HP_EVENT)
15871 alc861_toshiba_automute(codec);
15872}
15873
def319f9 15874/* pcm configuration: identical with ALC880 */
df694daa
KY
15875#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15876#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15877#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15878#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15879
15880
15881#define ALC861_DIGOUT_NID 0x07
15882
a9111321 15883static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15884 { 8, NULL }
15885};
15886
4c6d72d1 15887static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15888 /* front, surround, clfe, side */
15889 0x03, 0x06, 0x05, 0x04
15890};
15891
4c6d72d1 15892static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15893 /* front, clfe, surround */
15894 0x03, 0x05, 0x06
15895};
15896
4c6d72d1 15897static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15898 /* ADC0-2 */
15899 0x08,
15900};
15901
a9111321 15902static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15903 .num_items = 5,
15904 .items = {
15905 { "Mic", 0x0 },
15906 { "Front Mic", 0x3 },
15907 { "Line", 0x1 },
15908 { "CD", 0x4 },
15909 { "Mixer", 0x5 },
15910 },
15911};
15912
1c20930a
TI
15913static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15914{
15915 struct alc_spec *spec = codec->spec;
15916 hda_nid_t mix, srcs[5];
15917 int i, j, num;
15918
15919 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15920 return 0;
15921 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15922 if (num < 0)
15923 return 0;
15924 for (i = 0; i < num; i++) {
15925 unsigned int type;
a22d543a 15926 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15927 if (type != AC_WID_AUD_OUT)
15928 continue;
15929 for (j = 0; j < spec->multiout.num_dacs; j++)
15930 if (spec->multiout.dac_nids[j] == srcs[i])
15931 break;
15932 if (j >= spec->multiout.num_dacs)
15933 return srcs[i];
15934 }
15935 return 0;
15936}
15937
df694daa 15938/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15939static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15940 const struct auto_pin_cfg *cfg)
df694daa 15941{
1c20930a 15942 struct alc_spec *spec = codec->spec;
df694daa 15943 int i;
1c20930a 15944 hda_nid_t nid, dac;
df694daa
KY
15945
15946 spec->multiout.dac_nids = spec->private_dac_nids;
15947 for (i = 0; i < cfg->line_outs; i++) {
15948 nid = cfg->line_out_pins[i];
1c20930a
TI
15949 dac = alc861_look_for_dac(codec, nid);
15950 if (!dac)
15951 continue;
dda14410 15952 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15953 }
df694daa
KY
15954 return 0;
15955}
15956
bcb2f0f5
TI
15957static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15958 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15959{
bcb2f0f5 15960 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15961 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15962}
15963
bcb2f0f5
TI
15964#define alc861_create_out_sw(codec, pfx, nid, chs) \
15965 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15966
df694daa 15967/* add playback controls from the parsed DAC table */
1c20930a 15968static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15969 const struct auto_pin_cfg *cfg)
15970{
1c20930a 15971 struct alc_spec *spec = codec->spec;
ea734963 15972 static const char * const chname[4] = {
f12ab1e0
TI
15973 "Front", "Surround", NULL /*CLFE*/, "Side"
15974 };
ce764ab2 15975 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 15976 hda_nid_t nid;
ce764ab2 15977 int i, err, noutputs;
1c20930a 15978
ce764ab2
TI
15979 noutputs = cfg->line_outs;
15980 if (spec->multi_ios > 0)
15981 noutputs += spec->multi_ios;
15982
15983 for (i = 0; i < noutputs; i++) {
df694daa 15984 nid = spec->multiout.dac_nids[i];
f12ab1e0 15985 if (!nid)
df694daa 15986 continue;
bcb2f0f5 15987 if (!pfx && i == 2) {
df694daa 15988 /* Center/LFE */
1c20930a 15989 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15990 if (err < 0)
df694daa 15991 return err;
1c20930a 15992 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15993 if (err < 0)
df694daa
KY
15994 return err;
15995 } else {
bcb2f0f5 15996 const char *name = pfx;
5a882646
DH
15997 int index = i;
15998 if (!name) {
bcb2f0f5 15999 name = chname[i];
5a882646
DH
16000 index = 0;
16001 }
16002 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16003 if (err < 0)
df694daa
KY
16004 return err;
16005 }
16006 }
16007 return 0;
16008}
16009
1c20930a 16010static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16011{
1c20930a 16012 struct alc_spec *spec = codec->spec;
df694daa
KY
16013 int err;
16014 hda_nid_t nid;
16015
f12ab1e0 16016 if (!pin)
df694daa
KY
16017 return 0;
16018
16019 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16020 nid = alc861_look_for_dac(codec, pin);
16021 if (nid) {
16022 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16023 if (err < 0)
16024 return err;
16025 spec->multiout.hp_nid = nid;
16026 }
df694daa
KY
16027 }
16028 return 0;
16029}
16030
16031/* create playback/capture controls for input pins */
05f5f477 16032static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16033 const struct auto_pin_cfg *cfg)
df694daa 16034{
05f5f477 16035 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16036}
16037
f12ab1e0
TI
16038static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16039 hda_nid_t nid,
1c20930a 16040 int pin_type, hda_nid_t dac)
df694daa 16041{
1c20930a
TI
16042 hda_nid_t mix, srcs[5];
16043 int i, num;
16044
564c5bea
JL
16045 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16046 pin_type);
1c20930a 16047 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16048 AMP_OUT_UNMUTE);
1c20930a
TI
16049 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16050 return;
16051 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16052 if (num < 0)
16053 return;
16054 for (i = 0; i < num; i++) {
16055 unsigned int mute;
16056 if (srcs[i] == dac || srcs[i] == 0x15)
16057 mute = AMP_IN_UNMUTE(i);
16058 else
16059 mute = AMP_IN_MUTE(i);
16060 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16061 mute);
16062 }
df694daa
KY
16063}
16064
16065static void alc861_auto_init_multi_out(struct hda_codec *codec)
16066{
16067 struct alc_spec *spec = codec->spec;
16068 int i;
16069
16070 for (i = 0; i < spec->autocfg.line_outs; i++) {
16071 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16072 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16073 if (nid)
baba8ee9 16074 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16075 spec->multiout.dac_nids[i]);
df694daa
KY
16076 }
16077}
16078
16079static void alc861_auto_init_hp_out(struct hda_codec *codec)
16080{
16081 struct alc_spec *spec = codec->spec;
df694daa 16082
15870f05
TI
16083 if (spec->autocfg.hp_outs)
16084 alc861_auto_set_output_and_unmute(codec,
16085 spec->autocfg.hp_pins[0],
16086 PIN_HP,
1c20930a 16087 spec->multiout.hp_nid);
15870f05
TI
16088 if (spec->autocfg.speaker_outs)
16089 alc861_auto_set_output_and_unmute(codec,
16090 spec->autocfg.speaker_pins[0],
16091 PIN_OUT,
1c20930a 16092 spec->multiout.dac_nids[0]);
df694daa
KY
16093}
16094
16095static void alc861_auto_init_analog_input(struct hda_codec *codec)
16096{
16097 struct alc_spec *spec = codec->spec;
66ceeb6b 16098 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16099 int i;
16100
66ceeb6b
TI
16101 for (i = 0; i < cfg->num_inputs; i++) {
16102 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16103 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16104 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16105 }
16106}
16107
16108/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16109/* return 1 if successful, 0 if the proper config is not found,
16110 * or a negative error code
16111 */
df694daa
KY
16112static int alc861_parse_auto_config(struct hda_codec *codec)
16113{
16114 struct alc_spec *spec = codec->spec;
16115 int err;
4c6d72d1 16116 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16117
f12ab1e0
TI
16118 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16119 alc861_ignore);
16120 if (err < 0)
df694daa 16121 return err;
f12ab1e0 16122 if (!spec->autocfg.line_outs)
df694daa
KY
16123 return 0; /* can't find valid BIOS pin config */
16124
1c20930a 16125 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16126 if (err < 0)
16127 return err;
16128 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16129 if (err < 0)
16130 return err;
1c20930a 16131 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16132 if (err < 0)
16133 return err;
1c20930a 16134 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16135 if (err < 0)
16136 return err;
05f5f477 16137 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16138 if (err < 0)
df694daa
KY
16139 return err;
16140
16141 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16142
757899ac 16143 alc_auto_parse_digital(codec);
df694daa 16144
603c4019 16145 if (spec->kctls.list)
d88897ea 16146 add_mixer(spec, spec->kctls.list);
df694daa 16147
d88897ea 16148 add_verb(spec, alc861_auto_init_verbs);
df694daa 16149
a1e8d2da 16150 spec->num_mux_defs = 1;
61b9b9b1 16151 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16152
16153 spec->adc_nids = alc861_adc_nids;
16154 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16155 set_capture_mixer(codec);
df694daa 16156
6227cdce 16157 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16158
df694daa
KY
16159 return 1;
16160}
16161
ae6b813a
TI
16162/* additional initialization for auto-configuration model */
16163static void alc861_auto_init(struct hda_codec *codec)
df694daa 16164{
f6c7e546 16165 struct alc_spec *spec = codec->spec;
df694daa
KY
16166 alc861_auto_init_multi_out(codec);
16167 alc861_auto_init_hp_out(codec);
16168 alc861_auto_init_analog_input(codec);
757899ac 16169 alc_auto_init_digital(codec);
f6c7e546 16170 if (spec->unsol_event)
7fb0d78f 16171 alc_inithook(codec);
df694daa
KY
16172}
16173
cb53c626 16174#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16175static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16176 { 0x15, HDA_INPUT, 0 },
16177 { 0x15, HDA_INPUT, 1 },
16178 { 0x15, HDA_INPUT, 2 },
16179 { 0x15, HDA_INPUT, 3 },
16180 { } /* end */
16181};
16182#endif
16183
df694daa
KY
16184
16185/*
16186 * configuration and preset
16187 */
ea734963 16188static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16189 [ALC861_3ST] = "3stack",
16190 [ALC660_3ST] = "3stack-660",
16191 [ALC861_3ST_DIG] = "3stack-dig",
16192 [ALC861_6ST_DIG] = "6stack-dig",
16193 [ALC861_UNIWILL_M31] = "uniwill-m31",
16194 [ALC861_TOSHIBA] = "toshiba",
16195 [ALC861_ASUS] = "asus",
16196 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16197 [ALC861_AUTO] = "auto",
16198};
16199
a9111321 16200static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16201 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16202 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16203 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16204 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16205 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16206 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16207 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16208 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16209 * Any other models that need this preset?
16210 */
16211 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16212 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16213 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16214 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16215 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16216 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16217 /* FIXME: the below seems conflict */
16218 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16219 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16220 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16221 {}
16222};
16223
a9111321 16224static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16225 [ALC861_3ST] = {
16226 .mixers = { alc861_3ST_mixer },
16227 .init_verbs = { alc861_threestack_init_verbs },
16228 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16229 .dac_nids = alc861_dac_nids,
16230 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16231 .channel_mode = alc861_threestack_modes,
4e195a7b 16232 .need_dac_fix = 1,
df694daa
KY
16233 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16234 .adc_nids = alc861_adc_nids,
16235 .input_mux = &alc861_capture_source,
16236 },
16237 [ALC861_3ST_DIG] = {
16238 .mixers = { alc861_base_mixer },
16239 .init_verbs = { alc861_threestack_init_verbs },
16240 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16241 .dac_nids = alc861_dac_nids,
16242 .dig_out_nid = ALC861_DIGOUT_NID,
16243 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16244 .channel_mode = alc861_threestack_modes,
4e195a7b 16245 .need_dac_fix = 1,
df694daa
KY
16246 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16247 .adc_nids = alc861_adc_nids,
16248 .input_mux = &alc861_capture_source,
16249 },
16250 [ALC861_6ST_DIG] = {
16251 .mixers = { alc861_base_mixer },
16252 .init_verbs = { alc861_base_init_verbs },
16253 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16254 .dac_nids = alc861_dac_nids,
16255 .dig_out_nid = ALC861_DIGOUT_NID,
16256 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16257 .channel_mode = alc861_8ch_modes,
16258 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16259 .adc_nids = alc861_adc_nids,
16260 .input_mux = &alc861_capture_source,
16261 },
9c7f852e
TI
16262 [ALC660_3ST] = {
16263 .mixers = { alc861_3ST_mixer },
16264 .init_verbs = { alc861_threestack_init_verbs },
16265 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16266 .dac_nids = alc660_dac_nids,
16267 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16268 .channel_mode = alc861_threestack_modes,
4e195a7b 16269 .need_dac_fix = 1,
9c7f852e
TI
16270 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16271 .adc_nids = alc861_adc_nids,
16272 .input_mux = &alc861_capture_source,
16273 },
22309c3e
TI
16274 [ALC861_UNIWILL_M31] = {
16275 .mixers = { alc861_uniwill_m31_mixer },
16276 .init_verbs = { alc861_uniwill_m31_init_verbs },
16277 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16278 .dac_nids = alc861_dac_nids,
16279 .dig_out_nid = ALC861_DIGOUT_NID,
16280 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16281 .channel_mode = alc861_uniwill_m31_modes,
16282 .need_dac_fix = 1,
16283 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16284 .adc_nids = alc861_adc_nids,
16285 .input_mux = &alc861_capture_source,
16286 },
a53d1aec
TD
16287 [ALC861_TOSHIBA] = {
16288 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16289 .init_verbs = { alc861_base_init_verbs,
16290 alc861_toshiba_init_verbs },
a53d1aec
TD
16291 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16292 .dac_nids = alc861_dac_nids,
16293 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16294 .channel_mode = alc883_3ST_2ch_modes,
16295 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16296 .adc_nids = alc861_adc_nids,
16297 .input_mux = &alc861_capture_source,
16298 .unsol_event = alc861_toshiba_unsol_event,
16299 .init_hook = alc861_toshiba_automute,
16300 },
7cdbff94
MD
16301 [ALC861_ASUS] = {
16302 .mixers = { alc861_asus_mixer },
16303 .init_verbs = { alc861_asus_init_verbs },
16304 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16305 .dac_nids = alc861_dac_nids,
16306 .dig_out_nid = ALC861_DIGOUT_NID,
16307 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16308 .channel_mode = alc861_asus_modes,
16309 .need_dac_fix = 1,
16310 .hp_nid = 0x06,
16311 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16312 .adc_nids = alc861_adc_nids,
16313 .input_mux = &alc861_capture_source,
16314 },
56bb0cab
TI
16315 [ALC861_ASUS_LAPTOP] = {
16316 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16317 .init_verbs = { alc861_asus_init_verbs,
16318 alc861_asus_laptop_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16320 .dac_nids = alc861_dac_nids,
16321 .dig_out_nid = ALC861_DIGOUT_NID,
16322 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16323 .channel_mode = alc883_3ST_2ch_modes,
16324 .need_dac_fix = 1,
16325 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16326 .adc_nids = alc861_adc_nids,
16327 .input_mux = &alc861_capture_source,
16328 },
16329};
df694daa 16330
cfc9b06f
TI
16331/* Pin config fixes */
16332enum {
16333 PINFIX_FSC_AMILO_PI1505,
16334};
16335
cfc9b06f
TI
16336static const struct alc_fixup alc861_fixups[] = {
16337 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16338 .type = ALC_FIXUP_PINS,
16339 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16340 { 0x0b, 0x0221101f }, /* HP */
16341 { 0x0f, 0x90170310 }, /* speaker */
16342 { }
16343 }
cfc9b06f
TI
16344 },
16345};
16346
a9111321 16347static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16348 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16349 {}
16350};
df694daa
KY
16351
16352static int patch_alc861(struct hda_codec *codec)
16353{
16354 struct alc_spec *spec;
16355 int board_config;
16356 int err;
16357
dc041e0b 16358 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16359 if (spec == NULL)
16360 return -ENOMEM;
16361
f12ab1e0 16362 codec->spec = spec;
df694daa 16363
f5fcc13c
TI
16364 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16365 alc861_models,
16366 alc861_cfg_tbl);
9c7f852e 16367
f5fcc13c 16368 if (board_config < 0) {
9a11f1aa
TI
16369 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16370 codec->chip_name);
df694daa
KY
16371 board_config = ALC861_AUTO;
16372 }
16373
b5bfbc67
TI
16374 if (board_config == ALC861_AUTO) {
16375 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16376 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16377 }
cfc9b06f 16378
df694daa
KY
16379 if (board_config == ALC861_AUTO) {
16380 /* automatic parse from the BIOS config */
16381 err = alc861_parse_auto_config(codec);
16382 if (err < 0) {
16383 alc_free(codec);
16384 return err;
f12ab1e0 16385 } else if (!err) {
9c7f852e
TI
16386 printk(KERN_INFO
16387 "hda_codec: Cannot set up configuration "
16388 "from BIOS. Using base mode...\n");
df694daa
KY
16389 board_config = ALC861_3ST_DIG;
16390 }
16391 }
16392
680cd536
KK
16393 err = snd_hda_attach_beep_device(codec, 0x23);
16394 if (err < 0) {
16395 alc_free(codec);
16396 return err;
16397 }
16398
df694daa 16399 if (board_config != ALC861_AUTO)
e9c364c0 16400 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16401
df694daa
KY
16402 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16403 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16404
df694daa
KY
16405 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16406 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16407
c7a8eb10
TI
16408 if (!spec->cap_mixer)
16409 set_capture_mixer(codec);
45bdd1c1
TI
16410 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16411
2134ea4f
TI
16412 spec->vmaster_nid = 0x03;
16413
b5bfbc67 16414 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16415
df694daa 16416 codec->patch_ops = alc_patch_ops;
c97259df 16417 if (board_config == ALC861_AUTO) {
ae6b813a 16418 spec->init_hook = alc861_auto_init;
c97259df
DC
16419#ifdef CONFIG_SND_HDA_POWER_SAVE
16420 spec->power_hook = alc_power_eapd;
16421#endif
16422 }
cb53c626
TI
16423#ifdef CONFIG_SND_HDA_POWER_SAVE
16424 if (!spec->loopback.amplist)
16425 spec->loopback.amplist = alc861_loopbacks;
16426#endif
ea1fb29a 16427
1da177e4
LT
16428 return 0;
16429}
16430
f32610ed
JS
16431/*
16432 * ALC861-VD support
16433 *
16434 * Based on ALC882
16435 *
16436 * In addition, an independent DAC
16437 */
16438#define ALC861VD_DIGOUT_NID 0x06
16439
4c6d72d1 16440static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16441 /* front, surr, clfe, side surr */
16442 0x02, 0x03, 0x04, 0x05
16443};
16444
16445/* dac_nids for ALC660vd are in a different order - according to
16446 * Realtek's driver.
def319f9 16447 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16448 * of ALC660vd codecs, but for now there is only 3stack mixer
16449 * - and it is the same as in 861vd.
16450 * adc_nids in ALC660vd are (is) the same as in 861vd
16451 */
4c6d72d1 16452static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16453 /* front, rear, clfe, rear_surr */
16454 0x02, 0x04, 0x03
16455};
16456
4c6d72d1 16457static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16458 /* ADC0 */
16459 0x09,
16460};
16461
4c6d72d1 16462static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16463
f32610ed
JS
16464/* input MUX */
16465/* FIXME: should be a matrix-type input source selection */
a9111321 16466static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16467 .num_items = 4,
16468 .items = {
16469 { "Mic", 0x0 },
16470 { "Front Mic", 0x1 },
16471 { "Line", 0x2 },
16472 { "CD", 0x4 },
16473 },
16474};
16475
a9111321 16476static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16477 .num_items = 2,
272a527c 16478 .items = {
8607f7c4 16479 { "Mic", 0x0 },
28c4edb7 16480 { "Internal Mic", 0x1 },
272a527c
KY
16481 },
16482};
16483
a9111321 16484static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16485 .num_items = 2,
16486 .items = {
16487 { "Front Mic", 0x0 },
16488 { "ATAPI Mic", 0x1 },
16489 },
16490};
16491
f32610ed
JS
16492/*
16493 * 2ch mode
16494 */
a9111321 16495static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16496 { 2, NULL }
16497};
16498
16499/*
16500 * 6ch mode
16501 */
a9111321 16502static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16503 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16504 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16505 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16506 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16507 { } /* end */
16508};
16509
16510/*
16511 * 8ch mode
16512 */
a9111321 16513static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16514 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16515 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16516 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16517 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16518 { } /* end */
16519};
16520
a9111321 16521static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16522 { 6, alc861vd_6stack_ch6_init },
16523 { 8, alc861vd_6stack_ch8_init },
16524};
16525
a9111321 16526static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16527 {
16528 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16529 .name = "Channel Mode",
16530 .info = alc_ch_mode_info,
16531 .get = alc_ch_mode_get,
16532 .put = alc_ch_mode_put,
16533 },
16534 { } /* end */
16535};
16536
f32610ed
JS
16537/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16538 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16539 */
a9111321 16540static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16541 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16543
16544 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16545 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16546
16547 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16548 HDA_OUTPUT),
16549 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16550 HDA_OUTPUT),
16551 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16552 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16553
16554 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16555 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16556
16557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16558
5f99f86a 16559 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16560 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16561 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16562
5f99f86a 16563 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16564 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16565 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16566
16567 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16568 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16569
16570 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16571 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16572
f32610ed
JS
16573 { } /* end */
16574};
16575
a9111321 16576static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16577 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16578 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16579
16580 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16581
5f99f86a 16582 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16583 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16584 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16585
5f99f86a 16586 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16589
16590 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16591 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16592
16593 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16594 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16595
f32610ed
JS
16596 { } /* end */
16597};
16598
a9111321 16599static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16600 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16601 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16602 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16603
16604 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16605
5f99f86a 16606 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16607 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16609
5f99f86a 16610 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16611 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16612 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16613
16614 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16615 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16616
16617 { } /* end */
16618};
16619
b419f346 16620/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16621 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16622 */
a9111321 16623static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16624 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16625 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16626 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16627 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16628 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16629 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16630 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16631 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16632 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16633 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16634 { } /* end */
16635};
16636
d1a991a6
KY
16637/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16638 * Front Mic=0x18, ATAPI Mic = 0x19,
16639 */
a9111321 16640static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16641 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16642 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16643 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16644 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16645 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16646 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16647 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16648 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16649
d1a991a6
KY
16650 { } /* end */
16651};
16652
f32610ed
JS
16653/*
16654 * generic initialization of ADC, input mixers and output mixers
16655 */
a9111321 16656static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16657 /*
16658 * Unmute ADC0 and set the default input to mic-in
16659 */
16660 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16661 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16662
16663 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16664 * the analog-loopback mixer widget
16665 */
16666 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16667 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16668 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16669 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16672
16673 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16678
16679 /*
16680 * Set up output mixers (0x02 - 0x05)
16681 */
16682 /* set vol=0 to output mixers */
16683 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16684 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16685 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16686 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16687
16688 /* set up input amps for analog loopback */
16689 /* Amp Indices: DAC = 0, mixer = 1 */
16690 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16691 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16692 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16693 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16694 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16695 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16696 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16697 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16698
16699 { }
16700};
16701
16702/*
16703 * 3-stack pin configuration:
16704 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16705 */
a9111321 16706static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16707 /*
16708 * Set pin mode and muting
16709 */
16710 /* set front pin widgets 0x14 for output */
16711 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16712 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16713 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16714
16715 /* Mic (rear) pin: input vref at 80% */
16716 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16717 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16718 /* Front Mic pin: input vref at 80% */
16719 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16721 /* Line In pin: input */
16722 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16723 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16724 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16725 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16726 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16727 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16728 /* CD pin widget for input */
16729 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16730
16731 { }
16732};
16733
16734/*
16735 * 6-stack pin configuration:
16736 */
a9111321 16737static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16738 /*
16739 * Set pin mode and muting
16740 */
16741 /* set front pin widgets 0x14 for output */
16742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16744 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16745
16746 /* Rear Pin: output 1 (0x0d) */
16747 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16748 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16749 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16750 /* CLFE Pin: output 2 (0x0e) */
16751 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16752 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16753 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16754 /* Side Pin: output 3 (0x0f) */
16755 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16756 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16757 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16758
16759 /* Mic (rear) pin: input vref at 80% */
16760 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16761 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16762 /* Front Mic pin: input vref at 80% */
16763 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16764 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16765 /* Line In pin: input */
16766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16767 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16768 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16769 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16770 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16771 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16772 /* CD pin widget for input */
16773 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16774
16775 { }
16776};
16777
a9111321 16778static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16779 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16780 { }
16781};
16782
a9111321 16783static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16784 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16785 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16786 { }
16787};
16788
a9111321 16789static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16792 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16793 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16794 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16795 {}
16796};
16797
4f5d1706 16798static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16799{
a9fd4f3f 16800 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16801 spec->autocfg.hp_pins[0] = 0x1b;
16802 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16803 spec->automute = 1;
16804 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16805}
16806
16807static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16808{
d922b51d 16809 alc_hp_automute(codec);
eeb43387 16810 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16811}
16812
16813static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16814 unsigned int res)
16815{
16816 switch (res >> 26) {
bdd148a3 16817 case ALC880_MIC_EVENT:
eeb43387 16818 alc88x_simple_mic_automute(codec);
bdd148a3 16819 break;
a9fd4f3f 16820 default:
d922b51d 16821 alc_sku_unsol_event(codec, res);
a9fd4f3f 16822 break;
bdd148a3
KY
16823 }
16824}
16825
a9111321 16826static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16827 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16828 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16829 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16830 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16831
16832 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16833 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16834 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16835 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16836 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16837 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16838 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16839 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16840
272a527c
KY
16841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16843 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16844 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16845 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16846 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16847 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16848 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16849
16850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16852 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16853 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16855 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16856 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16857 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16858
16859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16860 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16863
16864 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16865 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16866 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16867
16868 { } /* end */
16869};
16870
16871/* toggle speaker-output according to the hp-jack state */
4f5d1706 16872static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16873{
a9fd4f3f 16874 struct alc_spec *spec = codec->spec;
272a527c 16875
a9fd4f3f
TI
16876 spec->autocfg.hp_pins[0] = 0x15;
16877 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16878 spec->automute = 1;
16879 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16880}
16881
cb53c626
TI
16882#ifdef CONFIG_SND_HDA_POWER_SAVE
16883#define alc861vd_loopbacks alc880_loopbacks
16884#endif
16885
def319f9 16886/* pcm configuration: identical with ALC880 */
f32610ed
JS
16887#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16888#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16889#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16890#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16891
16892/*
16893 * configuration and preset
16894 */
ea734963 16895static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16896 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16897 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16898 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16899 [ALC861VD_3ST] = "3stack",
16900 [ALC861VD_3ST_DIG] = "3stack-digout",
16901 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16902 [ALC861VD_LENOVO] = "lenovo",
272a527c 16903 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16904 [ALC861VD_HP] = "hp",
f32610ed
JS
16905 [ALC861VD_AUTO] = "auto",
16906};
16907
a9111321 16908static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16909 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16910 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16911 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16912 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16913 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16914 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16915 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16916 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16917 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16918 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16919 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16920 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16921 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16922 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16923 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16924 {}
16925};
16926
a9111321 16927static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16928 [ALC660VD_3ST] = {
16929 .mixers = { alc861vd_3st_mixer },
16930 .init_verbs = { alc861vd_volume_init_verbs,
16931 alc861vd_3stack_init_verbs },
16932 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16933 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16934 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16935 .channel_mode = alc861vd_3stack_2ch_modes,
16936 .input_mux = &alc861vd_capture_source,
16937 },
6963f84c
MC
16938 [ALC660VD_3ST_DIG] = {
16939 .mixers = { alc861vd_3st_mixer },
16940 .init_verbs = { alc861vd_volume_init_verbs,
16941 alc861vd_3stack_init_verbs },
16942 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16943 .dac_nids = alc660vd_dac_nids,
16944 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16945 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16946 .channel_mode = alc861vd_3stack_2ch_modes,
16947 .input_mux = &alc861vd_capture_source,
16948 },
f32610ed
JS
16949 [ALC861VD_3ST] = {
16950 .mixers = { alc861vd_3st_mixer },
16951 .init_verbs = { alc861vd_volume_init_verbs,
16952 alc861vd_3stack_init_verbs },
16953 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16954 .dac_nids = alc861vd_dac_nids,
16955 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16956 .channel_mode = alc861vd_3stack_2ch_modes,
16957 .input_mux = &alc861vd_capture_source,
16958 },
16959 [ALC861VD_3ST_DIG] = {
16960 .mixers = { alc861vd_3st_mixer },
16961 .init_verbs = { alc861vd_volume_init_verbs,
16962 alc861vd_3stack_init_verbs },
16963 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16964 .dac_nids = alc861vd_dac_nids,
16965 .dig_out_nid = ALC861VD_DIGOUT_NID,
16966 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16967 .channel_mode = alc861vd_3stack_2ch_modes,
16968 .input_mux = &alc861vd_capture_source,
16969 },
16970 [ALC861VD_6ST_DIG] = {
16971 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16972 .init_verbs = { alc861vd_volume_init_verbs,
16973 alc861vd_6stack_init_verbs },
16974 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16975 .dac_nids = alc861vd_dac_nids,
16976 .dig_out_nid = ALC861VD_DIGOUT_NID,
16977 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16978 .channel_mode = alc861vd_6stack_modes,
16979 .input_mux = &alc861vd_capture_source,
16980 },
bdd148a3
KY
16981 [ALC861VD_LENOVO] = {
16982 .mixers = { alc861vd_lenovo_mixer },
16983 .init_verbs = { alc861vd_volume_init_verbs,
16984 alc861vd_3stack_init_verbs,
16985 alc861vd_eapd_verbs,
16986 alc861vd_lenovo_unsol_verbs },
16987 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16988 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16989 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16990 .channel_mode = alc861vd_3stack_2ch_modes,
16991 .input_mux = &alc861vd_capture_source,
16992 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16993 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16994 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16995 },
272a527c
KY
16996 [ALC861VD_DALLAS] = {
16997 .mixers = { alc861vd_dallas_mixer },
16998 .init_verbs = { alc861vd_dallas_verbs },
16999 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17000 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17001 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17002 .channel_mode = alc861vd_3stack_2ch_modes,
17003 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 17004 .unsol_event = alc_sku_unsol_event,
4f5d1706 17005 .setup = alc861vd_dallas_setup,
d922b51d 17006 .init_hook = alc_hp_automute,
d1a991a6
KY
17007 },
17008 [ALC861VD_HP] = {
17009 .mixers = { alc861vd_hp_mixer },
17010 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17011 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17012 .dac_nids = alc861vd_dac_nids,
d1a991a6 17013 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17014 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17015 .channel_mode = alc861vd_3stack_2ch_modes,
17016 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17017 .unsol_event = alc_sku_unsol_event,
4f5d1706 17018 .setup = alc861vd_dallas_setup,
d922b51d 17019 .init_hook = alc_hp_automute,
ea1fb29a 17020 },
13c94744
TI
17021 [ALC660VD_ASUS_V1S] = {
17022 .mixers = { alc861vd_lenovo_mixer },
17023 .init_verbs = { alc861vd_volume_init_verbs,
17024 alc861vd_3stack_init_verbs,
17025 alc861vd_eapd_verbs,
17026 alc861vd_lenovo_unsol_verbs },
17027 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17028 .dac_nids = alc660vd_dac_nids,
17029 .dig_out_nid = ALC861VD_DIGOUT_NID,
17030 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17031 .channel_mode = alc861vd_3stack_2ch_modes,
17032 .input_mux = &alc861vd_capture_source,
17033 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17034 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17035 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17036 },
f32610ed
JS
17037};
17038
17039/*
17040 * BIOS auto configuration
17041 */
05f5f477
TI
17042static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17043 const struct auto_pin_cfg *cfg)
17044{
7167594a 17045 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17046}
17047
17048
f32610ed
JS
17049static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17050 hda_nid_t nid, int pin_type, int dac_idx)
17051{
f6c7e546 17052 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17053}
17054
17055static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17056{
17057 struct alc_spec *spec = codec->spec;
17058 int i;
17059
17060 for (i = 0; i <= HDA_SIDE; i++) {
17061 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17062 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17063 if (nid)
17064 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17065 pin_type, i);
f32610ed
JS
17066 }
17067}
17068
17069
17070static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17071{
17072 struct alc_spec *spec = codec->spec;
17073 hda_nid_t pin;
17074
17075 pin = spec->autocfg.hp_pins[0];
def319f9 17076 if (pin) /* connect to front and use dac 0 */
f32610ed 17077 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17078 pin = spec->autocfg.speaker_pins[0];
17079 if (pin)
17080 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17081}
17082
f32610ed
JS
17083#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17084
17085static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17086{
17087 struct alc_spec *spec = codec->spec;
66ceeb6b 17088 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17089 int i;
17090
66ceeb6b
TI
17091 for (i = 0; i < cfg->num_inputs; i++) {
17092 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17093 if (alc_is_input_pin(codec, nid)) {
30ea098f 17094 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17095 if (nid != ALC861VD_PIN_CD_NID &&
17096 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17097 snd_hda_codec_write(codec, nid, 0,
17098 AC_VERB_SET_AMP_GAIN_MUTE,
17099 AMP_OUT_MUTE);
17100 }
17101 }
17102}
17103
f511b01c
TI
17104#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17105
f32610ed
JS
17106#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17107#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17108
17109/* add playback controls from the parsed DAC table */
569ed348 17110/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17111 * different NIDs for mute/unmute switch and volume control */
17112static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17113 const struct auto_pin_cfg *cfg)
17114{
ea734963
TI
17115 static const char * const chname[4] = {
17116 "Front", "Surround", "CLFE", "Side"
17117 };
ce764ab2 17118 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17119 hda_nid_t nid_v, nid_s;
ce764ab2 17120 int i, err, noutputs;
f32610ed 17121
ce764ab2
TI
17122 noutputs = cfg->line_outs;
17123 if (spec->multi_ios > 0)
17124 noutputs += spec->multi_ios;
17125
17126 for (i = 0; i < noutputs; i++) {
f12ab1e0 17127 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17128 continue;
17129 nid_v = alc861vd_idx_to_mixer_vol(
17130 alc880_dac_to_idx(
17131 spec->multiout.dac_nids[i]));
17132 nid_s = alc861vd_idx_to_mixer_switch(
17133 alc880_dac_to_idx(
17134 spec->multiout.dac_nids[i]));
17135
bcb2f0f5 17136 if (!pfx && i == 2) {
f32610ed 17137 /* Center/LFE */
0afe5f89
TI
17138 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17139 "Center",
f12ab1e0
TI
17140 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17141 HDA_OUTPUT));
17142 if (err < 0)
f32610ed 17143 return err;
0afe5f89
TI
17144 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17145 "LFE",
f12ab1e0
TI
17146 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17147 HDA_OUTPUT));
17148 if (err < 0)
f32610ed 17149 return err;
0afe5f89
TI
17150 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17151 "Center",
f12ab1e0
TI
17152 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17153 HDA_INPUT));
17154 if (err < 0)
f32610ed 17155 return err;
0afe5f89
TI
17156 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17157 "LFE",
f12ab1e0
TI
17158 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17159 HDA_INPUT));
17160 if (err < 0)
f32610ed
JS
17161 return err;
17162 } else {
bcb2f0f5 17163 const char *name = pfx;
5a882646
DH
17164 int index = i;
17165 if (!name) {
bcb2f0f5 17166 name = chname[i];
5a882646
DH
17167 index = 0;
17168 }
bcb2f0f5 17169 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17170 name, index,
f12ab1e0
TI
17171 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17172 HDA_OUTPUT));
17173 if (err < 0)
f32610ed 17174 return err;
bcb2f0f5 17175 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17176 name, index,
bdd148a3 17177 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17178 HDA_INPUT));
17179 if (err < 0)
f32610ed
JS
17180 return err;
17181 }
17182 }
17183 return 0;
17184}
17185
17186/* add playback controls for speaker and HP outputs */
17187/* Based on ALC880 version. But ALC861VD has separate,
17188 * different NIDs for mute/unmute switch and volume control */
17189static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17190 hda_nid_t pin, const char *pfx)
17191{
17192 hda_nid_t nid_v, nid_s;
17193 int err;
f32610ed 17194
f12ab1e0 17195 if (!pin)
f32610ed
JS
17196 return 0;
17197
17198 if (alc880_is_fixed_pin(pin)) {
17199 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17200 /* specify the DAC as the extra output */
f12ab1e0 17201 if (!spec->multiout.hp_nid)
f32610ed
JS
17202 spec->multiout.hp_nid = nid_v;
17203 else
17204 spec->multiout.extra_out_nid[0] = nid_v;
17205 /* control HP volume/switch on the output mixer amp */
17206 nid_v = alc861vd_idx_to_mixer_vol(
17207 alc880_fixed_pin_idx(pin));
17208 nid_s = alc861vd_idx_to_mixer_switch(
17209 alc880_fixed_pin_idx(pin));
17210
0afe5f89 17211 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17212 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17213 if (err < 0)
f32610ed 17214 return err;
0afe5f89 17215 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17216 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17217 if (err < 0)
f32610ed
JS
17218 return err;
17219 } else if (alc880_is_multi_pin(pin)) {
17220 /* set manual connection */
17221 /* we have only a switch on HP-out PIN */
0afe5f89 17222 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17223 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17224 if (err < 0)
f32610ed
JS
17225 return err;
17226 }
17227 return 0;
17228}
17229
17230/* parse the BIOS configuration and set up the alc_spec
17231 * return 1 if successful, 0 if the proper config is not found,
17232 * or a negative error code
17233 * Based on ALC880 version - had to change it to override
17234 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17235static int alc861vd_parse_auto_config(struct hda_codec *codec)
17236{
17237 struct alc_spec *spec = codec->spec;
17238 int err;
4c6d72d1 17239 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17240
f12ab1e0
TI
17241 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17242 alc861vd_ignore);
17243 if (err < 0)
f32610ed 17244 return err;
f12ab1e0 17245 if (!spec->autocfg.line_outs)
f32610ed
JS
17246 return 0; /* can't find valid BIOS pin config */
17247
f12ab1e0 17248 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17249 if (err < 0)
17250 return err;
17251 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17252 if (err < 0)
17253 return err;
17254 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17255 if (err < 0)
17256 return err;
17257 err = alc861vd_auto_create_extra_out(spec,
17258 spec->autocfg.speaker_pins[0],
17259 "Speaker");
17260 if (err < 0)
17261 return err;
17262 err = alc861vd_auto_create_extra_out(spec,
17263 spec->autocfg.hp_pins[0],
17264 "Headphone");
17265 if (err < 0)
17266 return err;
05f5f477 17267 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17268 if (err < 0)
f32610ed
JS
17269 return err;
17270
17271 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17272
757899ac 17273 alc_auto_parse_digital(codec);
f32610ed 17274
603c4019 17275 if (spec->kctls.list)
d88897ea 17276 add_mixer(spec, spec->kctls.list);
f32610ed 17277
d88897ea 17278 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17279
17280 spec->num_mux_defs = 1;
61b9b9b1 17281 spec->input_mux = &spec->private_imux[0];
f32610ed 17282
776e184e
TI
17283 err = alc_auto_add_mic_boost(codec);
17284 if (err < 0)
17285 return err;
17286
6227cdce 17287 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17288
f32610ed
JS
17289 return 1;
17290}
17291
17292/* additional initialization for auto-configuration model */
17293static void alc861vd_auto_init(struct hda_codec *codec)
17294{
f6c7e546 17295 struct alc_spec *spec = codec->spec;
f32610ed
JS
17296 alc861vd_auto_init_multi_out(codec);
17297 alc861vd_auto_init_hp_out(codec);
17298 alc861vd_auto_init_analog_input(codec);
f511b01c 17299 alc861vd_auto_init_input_src(codec);
757899ac 17300 alc_auto_init_digital(codec);
f6c7e546 17301 if (spec->unsol_event)
7fb0d78f 17302 alc_inithook(codec);
f32610ed
JS
17303}
17304
f8f25ba3
TI
17305enum {
17306 ALC660VD_FIX_ASUS_GPIO1
17307};
17308
17309/* reset GPIO1 */
f8f25ba3
TI
17310static const struct alc_fixup alc861vd_fixups[] = {
17311 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17312 .type = ALC_FIXUP_VERBS,
17313 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17314 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17315 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17316 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17317 { }
17318 }
f8f25ba3
TI
17319 },
17320};
17321
a9111321 17322static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17323 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17324 {}
17325};
17326
f32610ed
JS
17327static int patch_alc861vd(struct hda_codec *codec)
17328{
17329 struct alc_spec *spec;
17330 int err, board_config;
17331
17332 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17333 if (spec == NULL)
17334 return -ENOMEM;
17335
17336 codec->spec = spec;
17337
17338 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17339 alc861vd_models,
17340 alc861vd_cfg_tbl);
17341
17342 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17343 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17344 codec->chip_name);
f32610ed
JS
17345 board_config = ALC861VD_AUTO;
17346 }
17347
b5bfbc67
TI
17348 if (board_config == ALC861VD_AUTO) {
17349 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17350 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17351 }
f8f25ba3 17352
f32610ed
JS
17353 if (board_config == ALC861VD_AUTO) {
17354 /* automatic parse from the BIOS config */
17355 err = alc861vd_parse_auto_config(codec);
17356 if (err < 0) {
17357 alc_free(codec);
17358 return err;
f12ab1e0 17359 } else if (!err) {
f32610ed
JS
17360 printk(KERN_INFO
17361 "hda_codec: Cannot set up configuration "
17362 "from BIOS. Using base mode...\n");
17363 board_config = ALC861VD_3ST;
17364 }
17365 }
17366
680cd536
KK
17367 err = snd_hda_attach_beep_device(codec, 0x23);
17368 if (err < 0) {
17369 alc_free(codec);
17370 return err;
17371 }
17372
f32610ed 17373 if (board_config != ALC861VD_AUTO)
e9c364c0 17374 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17375
2f893286 17376 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17377 /* always turn on EAPD */
d88897ea 17378 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17379 }
17380
f32610ed
JS
17381 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17382 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17383
f32610ed
JS
17384 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17385 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17386
dd704698
TI
17387 if (!spec->adc_nids) {
17388 spec->adc_nids = alc861vd_adc_nids;
17389 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17390 }
17391 if (!spec->capsrc_nids)
17392 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17393
b59bdf3b 17394 set_capture_mixer(codec);
45bdd1c1 17395 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17396
2134ea4f
TI
17397 spec->vmaster_nid = 0x02;
17398
b5bfbc67 17399 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17400
f32610ed
JS
17401 codec->patch_ops = alc_patch_ops;
17402
17403 if (board_config == ALC861VD_AUTO)
17404 spec->init_hook = alc861vd_auto_init;
1c716153 17405 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17406#ifdef CONFIG_SND_HDA_POWER_SAVE
17407 if (!spec->loopback.amplist)
17408 spec->loopback.amplist = alc861vd_loopbacks;
17409#endif
f32610ed
JS
17410
17411 return 0;
17412}
17413
bc9f98a9
KY
17414/*
17415 * ALC662 support
17416 *
17417 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17418 * configuration. Each pin widget can choose any input DACs and a mixer.
17419 * Each ADC is connected from a mixer of all inputs. This makes possible
17420 * 6-channel independent captures.
17421 *
17422 * In addition, an independent DAC for the multi-playback (not used in this
17423 * driver yet).
17424 */
17425#define ALC662_DIGOUT_NID 0x06
17426#define ALC662_DIGIN_NID 0x0a
17427
4c6d72d1 17428static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17429 /* front, rear, clfe */
bc9f98a9
KY
17430 0x02, 0x03, 0x04
17431};
17432
4c6d72d1 17433static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17434 0x02, 0x03
17435};
17436
4c6d72d1 17437static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17438 /* ADC1-2 */
b59bdf3b 17439 0x09, 0x08
bc9f98a9 17440};
e1406348 17441
4c6d72d1 17442static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17443 /* ADC1-2 */
17444 0x08,
17445};
17446
4c6d72d1
TI
17447static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17448static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17449
e1406348 17450
bc9f98a9
KY
17451/* input MUX */
17452/* FIXME: should be a matrix-type input source selection */
a9111321 17453static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17454 .num_items = 4,
17455 .items = {
17456 { "Mic", 0x0 },
17457 { "Front Mic", 0x1 },
17458 { "Line", 0x2 },
17459 { "CD", 0x4 },
17460 },
17461};
17462
a9111321 17463static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17464 .num_items = 2,
17465 .items = {
17466 { "Mic", 0x1 },
17467 { "Line", 0x2 },
17468 },
17469};
291702f0 17470
a9111321 17471static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17472 .num_items = 3,
17473 .items = {
17474 { "Mic", 0x0 },
17475 { "Front Mic", 0x1 },
17476 { "Line", 0x2 },
17477 },
17478};
17479
4f5d1706 17480#if 0 /* set to 1 for testing other input sources below */
a9111321 17481static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17482 .num_items = 16,
17483 .items = {
17484 { "Autoselect Mic", 0x0 },
17485 { "Internal Mic", 0x1 },
17486 { "In-0x02", 0x2 },
17487 { "In-0x03", 0x3 },
17488 { "In-0x04", 0x4 },
17489 { "In-0x05", 0x5 },
17490 { "In-0x06", 0x6 },
17491 { "In-0x07", 0x7 },
17492 { "In-0x08", 0x8 },
17493 { "In-0x09", 0x9 },
17494 { "In-0x0a", 0x0a },
17495 { "In-0x0b", 0x0b },
17496 { "In-0x0c", 0x0c },
17497 { "In-0x0d", 0x0d },
17498 { "In-0x0e", 0x0e },
17499 { "In-0x0f", 0x0f },
17500 },
17501};
17502#endif
17503
bc9f98a9
KY
17504/*
17505 * 2ch mode
17506 */
a9111321 17507static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17508 { 2, NULL }
17509};
17510
17511/*
17512 * 2ch mode
17513 */
a9111321 17514static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17515 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17516 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17517 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17518 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17519 { } /* end */
17520};
17521
17522/*
17523 * 6ch mode
17524 */
a9111321 17525static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17526 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17527 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17528 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17529 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17530 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17531 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17532 { } /* end */
17533};
17534
a9111321 17535static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17536 { 2, alc662_3ST_ch2_init },
17537 { 6, alc662_3ST_ch6_init },
17538};
17539
17540/*
17541 * 2ch mode
17542 */
a9111321 17543static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17544 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17545 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17546 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17547 { } /* end */
17548};
17549
17550/*
17551 * 6ch mode
17552 */
a9111321 17553static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17554 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17555 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17556 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17557 { } /* end */
17558};
17559
a9111321 17560static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17561 { 2, alc662_sixstack_ch6_init },
17562 { 6, alc662_sixstack_ch8_init },
17563};
17564
17565/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17566 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17567 */
17568
a9111321 17569static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17570 /* output mixer control */
17571 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17572 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17573 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17574 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17575 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17576 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17577 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17578 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17580
17581 /*Input mixer control */
17582 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17583 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17584 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17585 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17586 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17587 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17590 { } /* end */
17591};
17592
a9111321 17593static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17594 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17595 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17597 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17598 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17599 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17600 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17601 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17602 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17604 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17605 { } /* end */
17606};
17607
a9111321 17608static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17609 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17610 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17611 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17612 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17613 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17614 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17615 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17616 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17617 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17618 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17619 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17620 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17621 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17622 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17623 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17624 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17625 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17626 { } /* end */
17627};
17628
a9111321 17629static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17630 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17631 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17632 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17633 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17635 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17636 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17639 { } /* end */
17640};
17641
a9111321 17642static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17643 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17644 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17645
5f99f86a 17646 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17649
5f99f86a 17650 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17651 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17652 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17653 { } /* end */
17654};
17655
a9111321 17656static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17657 ALC262_HIPPO_MASTER_SWITCH,
17658 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17659 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17660 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17661 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17662 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17663 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17664 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17665 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17666 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17667 { } /* end */
17668};
17669
a9111321 17670static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17671 .ops = &snd_hda_bind_vol,
17672 .values = {
17673 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17674 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17675 0
17676 },
17677};
17678
a9111321 17679static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17680 .ops = &snd_hda_bind_sw,
17681 .values = {
17682 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17683 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17684 0
17685 },
17686};
17687
a9111321 17688static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17689 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17690 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17693 { } /* end */
17694};
17695
a9111321 17696static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17697 .ops = &snd_hda_bind_sw,
17698 .values = {
17699 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17700 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17701 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17702 0
17703 },
17704};
17705
a9111321 17706static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17707 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17708 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17711 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17712 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17713
17714 { } /* end */
17715};
17716
a9111321 17717static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17718 .ops = &snd_hda_bind_sw,
17719 .values = {
17720 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17721 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17722 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17723 0
17724 },
17725};
17726
a9111321 17727static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17728 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17729 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17731 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17732 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17733 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17734 { } /* end */
17735};
17736
a9111321 17737static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17738 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17739 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17740 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17741 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17742 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17743 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17744 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17745 { } /* end */
17746};
17747
a9111321 17748static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17749 .ops = &snd_hda_bind_vol,
17750 .values = {
17751 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17752 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17753 0
17754 },
17755};
17756
a9111321 17757static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17758 .ops = &snd_hda_bind_sw,
17759 .values = {
17760 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17761 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17762 0
17763 },
17764};
17765
a9111321 17766static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17767 HDA_BIND_VOL("Master Playback Volume",
17768 &alc663_asus_two_bind_master_vol),
17769 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17770 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17771 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17772 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17773 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17774 { } /* end */
17775};
17776
a9111321 17777static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17778 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17779 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17780 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17781 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17782 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17783 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17784 { } /* end */
17785};
17786
a9111321 17787static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17788 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17789 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17790 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17791 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17792 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17793
17794 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17796 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17797 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17798 { } /* end */
17799};
17800
a9111321 17801static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17802 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17803 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17804 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17805
17806 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17807 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17808 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17809 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17810 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17811 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17812 { } /* end */
17813};
17814
a9111321 17815static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17816 .ops = &snd_hda_bind_sw,
17817 .values = {
17818 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17819 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17820 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17821 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17822 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17823 0
17824 },
17825};
17826
a9111321 17827static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17828 .ops = &snd_hda_bind_sw,
17829 .values = {
17830 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17831 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17832 0
17833 },
17834};
17835
a9111321 17836static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17837 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17838 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17839 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17840 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17841 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17842 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17843 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17844 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17845 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17846 { } /* end */
17847};
17848
a9111321 17849static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17850 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17851 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17852 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17853 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17854 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17857 { } /* end */
17858};
17859
17860
a9111321 17861static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17862 {
17863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17864 .name = "Channel Mode",
17865 .info = alc_ch_mode_info,
17866 .get = alc_ch_mode_get,
17867 .put = alc_ch_mode_put,
17868 },
17869 { } /* end */
17870};
17871
a9111321 17872static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17873 /* ADC: mute amp left and right */
17874 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17875 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17876
b60dd394
KY
17877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17878 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17883
17884 /* Front Pin: output 0 (0x0c) */
17885 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17887
17888 /* Rear Pin: output 1 (0x0d) */
17889 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17890 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17891
17892 /* CLFE Pin: output 2 (0x0e) */
17893 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17894 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17895
17896 /* Mic (rear) pin: input vref at 80% */
17897 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17898 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17899 /* Front Mic pin: input vref at 80% */
17900 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17901 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17902 /* Line In pin: input */
17903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17904 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17905 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17906 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17907 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17908 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17909 /* CD pin widget for input */
17910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17911
17912 /* FIXME: use matrix-type input source selection */
17913 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17914 /* Input mixer */
17915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17916 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17917
a7f2371f
TI
17918 { }
17919};
17920
a9111321 17921static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17922 /* always trun on EAPD */
17923 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17924 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17925 { }
17926};
17927
a9111321 17928static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17931 {}
17932};
17933
a9111321 17934static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17935 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17936 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17937 {}
bc9f98a9
KY
17938};
17939
8c427226 17940/* Set Unsolicited Event*/
a9111321 17941static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17942 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17943 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17944 {}
17945};
17946
a9111321 17947static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17949 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17950 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17951 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17952 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17953 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17954 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17955 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17956 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17957 {}
17958};
17959
a9111321 17960static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17961 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17962 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17963 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17964 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17965 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17966 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17967 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17968 {}
17969};
17970
a9111321 17971static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17972 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17973 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17974 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17975 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17978 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17979 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17980 {}
17981};
6dda9f4a 17982
a9111321 17983static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17984 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17985 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17986 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17987 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17988 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
17992};
6dda9f4a 17993
a9111321 17994static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17996 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17997 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17998 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17999 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18000 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18001 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18002 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18003 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18004 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18005 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18006 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18007 {}
18008};
18009
a9111321 18010static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
18011 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18012 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18013 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18014 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18015 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18023 {}
18024};
18025
a9111321 18026static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
18027 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18029 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18030
18031 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18032 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18033 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18034
18035 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18036 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18037 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18038 {}
18039};
18040
a9111321 18041static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
18042 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18043 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18044 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18045
18046 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18047 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18048 {}
18049};
18050
a9111321 18051static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
18052 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18053 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18054 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18055 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18056 {}
18057};
18058
a9111321 18059static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
18060 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18061 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18062 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18063 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18064 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18065 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18066 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18069 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18070 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18071 {}
18072};
18073
a9111321 18074static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
18075 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18076 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18077 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18078 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18079 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18080 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18081 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18082 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18083 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18084 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18085 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18086 {}
18087};
18088
a9111321 18089static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
18090 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18091 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18092 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18093 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18094 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18095 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18097 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18098 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18099 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18100 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18102 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18103 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18104 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18105 {}
18106};
18107
a9111321 18108static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
18109 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18113 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18114 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18115 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18116 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18118 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18119 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18120 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18122 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126};
18127
a9111321 18128static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
18129 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18130 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18131 { } /* end */
18132};
18133
a9111321 18134static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
18135 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18136 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18137 { } /* end */
18138};
18139
e6a5e1b7 18140static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18141{
e6a5e1b7 18142 struct alc_spec *spec = codec->spec;
bc9f98a9 18143
e6a5e1b7
TI
18144 spec->autocfg.hp_pins[0] = 0x1b;
18145 spec->autocfg.line_out_pins[0] = 0x14;
18146 spec->autocfg.speaker_pins[0] = 0x15;
18147 spec->automute = 1;
18148 spec->detect_line = 1;
18149 spec->automute_lines = 1;
18150 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18151}
18152
4f5d1706
TI
18153static void alc662_eeepc_setup(struct hda_codec *codec)
18154{
18155 struct alc_spec *spec = codec->spec;
18156
18157 alc262_hippo1_setup(codec);
18158 spec->ext_mic.pin = 0x18;
18159 spec->ext_mic.mux_idx = 0;
18160 spec->int_mic.pin = 0x19;
18161 spec->int_mic.mux_idx = 1;
18162 spec->auto_mic = 1;
18163}
18164
4f5d1706 18165static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18166{
42171c17
TI
18167 struct alc_spec *spec = codec->spec;
18168
18169 spec->autocfg.hp_pins[0] = 0x14;
18170 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18171 spec->automute = 1;
18172 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18173}
18174
4f5d1706
TI
18175static void alc663_m51va_setup(struct hda_codec *codec)
18176{
18177 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18178 spec->autocfg.hp_pins[0] = 0x21;
18179 spec->autocfg.speaker_pins[0] = 0x14;
18180 spec->automute_mixer_nid[0] = 0x0c;
18181 spec->automute = 1;
18182 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18183 spec->ext_mic.pin = 0x18;
18184 spec->ext_mic.mux_idx = 0;
18185 spec->int_mic.pin = 0x12;
ebb83eeb 18186 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18187 spec->auto_mic = 1;
18188}
18189
f1d4e28b 18190/* ***************** Mode1 ******************************/
ebb83eeb
KY
18191static void alc663_mode1_setup(struct hda_codec *codec)
18192{
18193 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18194 spec->autocfg.hp_pins[0] = 0x21;
18195 spec->autocfg.speaker_pins[0] = 0x14;
18196 spec->automute_mixer_nid[0] = 0x0c;
18197 spec->automute = 1;
18198 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18199 spec->ext_mic.pin = 0x18;
18200 spec->ext_mic.mux_idx = 0;
18201 spec->int_mic.pin = 0x19;
18202 spec->int_mic.mux_idx = 1;
18203 spec->auto_mic = 1;
18204}
18205
f1d4e28b 18206/* ***************** Mode2 ******************************/
3b8510ce 18207static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18208{
3b8510ce
TI
18209 struct alc_spec *spec = codec->spec;
18210 spec->autocfg.hp_pins[0] = 0x1b;
18211 spec->autocfg.speaker_pins[0] = 0x14;
18212 spec->automute = 1;
18213 spec->automute_mode = ALC_AUTOMUTE_PIN;
18214 spec->ext_mic.pin = 0x18;
18215 spec->ext_mic.mux_idx = 0;
18216 spec->int_mic.pin = 0x19;
18217 spec->int_mic.mux_idx = 1;
18218 spec->auto_mic = 1;
f1d4e28b
KY
18219}
18220
f1d4e28b 18221/* ***************** Mode3 ******************************/
3b8510ce 18222static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18223{
3b8510ce
TI
18224 struct alc_spec *spec = codec->spec;
18225 spec->autocfg.hp_pins[0] = 0x21;
18226 spec->autocfg.hp_pins[0] = 0x15;
18227 spec->autocfg.speaker_pins[0] = 0x14;
18228 spec->automute = 1;
18229 spec->automute_mode = ALC_AUTOMUTE_PIN;
18230 spec->ext_mic.pin = 0x18;
18231 spec->ext_mic.mux_idx = 0;
18232 spec->int_mic.pin = 0x19;
18233 spec->int_mic.mux_idx = 1;
18234 spec->auto_mic = 1;
f1d4e28b
KY
18235}
18236
f1d4e28b 18237/* ***************** Mode4 ******************************/
3b8510ce 18238static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18239{
3b8510ce
TI
18240 struct alc_spec *spec = codec->spec;
18241 spec->autocfg.hp_pins[0] = 0x21;
18242 spec->autocfg.speaker_pins[0] = 0x14;
18243 spec->autocfg.speaker_pins[1] = 0x16;
18244 spec->automute_mixer_nid[0] = 0x0c;
18245 spec->automute_mixer_nid[1] = 0x0e;
18246 spec->automute = 1;
18247 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18248 spec->ext_mic.pin = 0x18;
18249 spec->ext_mic.mux_idx = 0;
18250 spec->int_mic.pin = 0x19;
18251 spec->int_mic.mux_idx = 1;
18252 spec->auto_mic = 1;
f1d4e28b
KY
18253}
18254
f1d4e28b 18255/* ***************** Mode5 ******************************/
3b8510ce 18256static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18257{
3b8510ce
TI
18258 struct alc_spec *spec = codec->spec;
18259 spec->autocfg.hp_pins[0] = 0x15;
18260 spec->autocfg.speaker_pins[0] = 0x14;
18261 spec->autocfg.speaker_pins[1] = 0x16;
18262 spec->automute_mixer_nid[0] = 0x0c;
18263 spec->automute_mixer_nid[1] = 0x0e;
18264 spec->automute = 1;
18265 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18266 spec->ext_mic.pin = 0x18;
18267 spec->ext_mic.mux_idx = 0;
18268 spec->int_mic.pin = 0x19;
18269 spec->int_mic.mux_idx = 1;
18270 spec->auto_mic = 1;
f1d4e28b
KY
18271}
18272
f1d4e28b 18273/* ***************** Mode6 ******************************/
3b8510ce 18274static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18275{
3b8510ce
TI
18276 struct alc_spec *spec = codec->spec;
18277 spec->autocfg.hp_pins[0] = 0x1b;
18278 spec->autocfg.hp_pins[0] = 0x15;
18279 spec->autocfg.speaker_pins[0] = 0x14;
18280 spec->automute_mixer_nid[0] = 0x0c;
18281 spec->automute = 1;
18282 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18283 spec->ext_mic.pin = 0x18;
18284 spec->ext_mic.mux_idx = 0;
18285 spec->int_mic.pin = 0x19;
18286 spec->int_mic.mux_idx = 1;
18287 spec->auto_mic = 1;
f1d4e28b
KY
18288}
18289
ebb83eeb 18290/* ***************** Mode7 ******************************/
3b8510ce 18291static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18292{
3b8510ce
TI
18293 struct alc_spec *spec = codec->spec;
18294 spec->autocfg.hp_pins[0] = 0x1b;
18295 spec->autocfg.hp_pins[0] = 0x21;
18296 spec->autocfg.speaker_pins[0] = 0x14;
18297 spec->autocfg.speaker_pins[0] = 0x17;
18298 spec->automute = 1;
18299 spec->automute_mode = ALC_AUTOMUTE_PIN;
18300 spec->ext_mic.pin = 0x18;
18301 spec->ext_mic.mux_idx = 0;
18302 spec->int_mic.pin = 0x19;
18303 spec->int_mic.mux_idx = 1;
18304 spec->auto_mic = 1;
ebb83eeb
KY
18305}
18306
18307/* ***************** Mode8 ******************************/
3b8510ce 18308static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18309{
3b8510ce
TI
18310 struct alc_spec *spec = codec->spec;
18311 spec->autocfg.hp_pins[0] = 0x21;
18312 spec->autocfg.hp_pins[1] = 0x15;
18313 spec->autocfg.speaker_pins[0] = 0x14;
18314 spec->autocfg.speaker_pins[0] = 0x17;
18315 spec->automute = 1;
18316 spec->automute_mode = ALC_AUTOMUTE_PIN;
18317 spec->ext_mic.pin = 0x18;
18318 spec->ext_mic.mux_idx = 0;
18319 spec->int_mic.pin = 0x12;
18320 spec->int_mic.mux_idx = 9;
18321 spec->auto_mic = 1;
ebb83eeb
KY
18322}
18323
e6a5e1b7 18324static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18325{
e6a5e1b7
TI
18326 struct alc_spec *spec = codec->spec;
18327 spec->autocfg.hp_pins[0] = 0x21;
18328 spec->autocfg.line_out_pins[0] = 0x15;
18329 spec->autocfg.speaker_pins[0] = 0x14;
18330 spec->automute = 1;
18331 spec->automute_mode = ALC_AUTOMUTE_AMP;
18332 spec->detect_line = 1;
18333 spec->automute_lines = 1;
18334 spec->ext_mic.pin = 0x18;
18335 spec->ext_mic.mux_idx = 0;
18336 spec->int_mic.pin = 0x12;
18337 spec->int_mic.mux_idx = 9;
18338 spec->auto_mic = 1;
6dda9f4a
KY
18339}
18340
4f5d1706
TI
18341#define alc663_g50v_setup alc663_m51va_setup
18342
a9111321 18343static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18344 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18345 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18346
5f99f86a 18347 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18348 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18349 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18350
5f99f86a 18351 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18352 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18353 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18354 { } /* end */
18355};
18356
a9111321 18357static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18358 /* Master Playback automatically created from Speaker and Headphone */
18359 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18360 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18361 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18362 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18363
8607f7c4
DH
18364 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18366 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18367
28c4edb7
DH
18368 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18369 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18370 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18371 { } /* end */
18372};
18373
cb53c626
TI
18374#ifdef CONFIG_SND_HDA_POWER_SAVE
18375#define alc662_loopbacks alc880_loopbacks
18376#endif
18377
bc9f98a9 18378
def319f9 18379/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18380#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18381#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18382#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18383#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18384
18385/*
18386 * configuration and preset
18387 */
ea734963 18388static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18389 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18390 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18391 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18392 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18393 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18394 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18395 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18396 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18397 [ALC663_ASUS_M51VA] = "m51va",
18398 [ALC663_ASUS_G71V] = "g71v",
18399 [ALC663_ASUS_H13] = "h13",
18400 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18401 [ALC663_ASUS_MODE1] = "asus-mode1",
18402 [ALC662_ASUS_MODE2] = "asus-mode2",
18403 [ALC663_ASUS_MODE3] = "asus-mode3",
18404 [ALC663_ASUS_MODE4] = "asus-mode4",
18405 [ALC663_ASUS_MODE5] = "asus-mode5",
18406 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18407 [ALC663_ASUS_MODE7] = "asus-mode7",
18408 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18409 [ALC272_DELL] = "dell",
18410 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18411 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18412 [ALC662_AUTO] = "auto",
18413};
18414
a9111321 18415static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18416 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18417 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18418 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18419 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18420 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18421 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18422 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18423 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18424 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18425 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18426 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18427 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18428 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18429 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18430 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18431 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18432 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18433 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18434 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18435 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18436 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18437 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18438 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18439 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18440 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18441 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18442 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18443 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18444 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18445 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18446 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18447 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18448 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18449 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18450 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18451 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18452 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18453 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18454 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18455 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18456 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18457 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18458 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18459 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18460 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18461 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18462 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18463 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18464 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18465 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18466 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18467 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18468 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18469 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18470 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18471 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18472 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18473 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18474 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18475 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18476 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18477 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18478 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18479 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18480 ALC662_3ST_6ch_DIG),
4dee8baa 18481 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18482 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18483 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18484 ALC662_3ST_6ch_DIG),
6227cdce 18485 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18486 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18487 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18488 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18489 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18490 ALC662_3ST_6ch_DIG),
dea0a509
TI
18491 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18492 ALC663_ASUS_H13),
965b76d2 18493 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18494 {}
18495};
18496
a9111321 18497static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18498 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18499 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18500 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18501 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18502 .dac_nids = alc662_dac_nids,
18503 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18504 .dig_in_nid = ALC662_DIGIN_NID,
18505 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18506 .channel_mode = alc662_3ST_2ch_modes,
18507 .input_mux = &alc662_capture_source,
18508 },
18509 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18510 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18511 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18512 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18513 .dac_nids = alc662_dac_nids,
18514 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18515 .dig_in_nid = ALC662_DIGIN_NID,
18516 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18517 .channel_mode = alc662_3ST_6ch_modes,
18518 .need_dac_fix = 1,
18519 .input_mux = &alc662_capture_source,
f12ab1e0 18520 },
bc9f98a9 18521 [ALC662_3ST_6ch] = {
f9e336f6 18522 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18523 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18524 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18525 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18526 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18527 .channel_mode = alc662_3ST_6ch_modes,
18528 .need_dac_fix = 1,
18529 .input_mux = &alc662_capture_source,
f12ab1e0 18530 },
bc9f98a9 18531 [ALC662_5ST_DIG] = {
f9e336f6 18532 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18533 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18534 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18535 .dac_nids = alc662_dac_nids,
18536 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18537 .dig_in_nid = ALC662_DIGIN_NID,
18538 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18539 .channel_mode = alc662_5stack_modes,
18540 .input_mux = &alc662_capture_source,
18541 },
18542 [ALC662_LENOVO_101E] = {
f9e336f6 18543 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18544 .init_verbs = { alc662_init_verbs,
18545 alc662_eapd_init_verbs,
18546 alc662_sue_init_verbs },
bc9f98a9
KY
18547 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18548 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18549 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18550 .channel_mode = alc662_3ST_2ch_modes,
18551 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18552 .unsol_event = alc_sku_unsol_event,
18553 .setup = alc662_lenovo_101e_setup,
18554 .init_hook = alc_inithook,
bc9f98a9 18555 },
291702f0 18556 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18557 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18558 .init_verbs = { alc662_init_verbs,
a7f2371f 18559 alc662_eapd_init_verbs,
291702f0
KY
18560 alc662_eeepc_sue_init_verbs },
18561 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18562 .dac_nids = alc662_dac_nids,
291702f0
KY
18563 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18564 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18565 .unsol_event = alc_sku_unsol_event,
4f5d1706 18566 .setup = alc662_eeepc_setup,
e9427969 18567 .init_hook = alc_inithook,
291702f0 18568 },
8c427226 18569 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18570 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18571 alc662_chmode_mixer },
18572 .init_verbs = { alc662_init_verbs,
a7f2371f 18573 alc662_eapd_init_verbs,
8c427226
KY
18574 alc662_eeepc_ep20_sue_init_verbs },
18575 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18576 .dac_nids = alc662_dac_nids,
8c427226
KY
18577 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18578 .channel_mode = alc662_3ST_6ch_modes,
18579 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18580 .unsol_event = alc_sku_unsol_event,
4f5d1706 18581 .setup = alc662_eeepc_ep20_setup,
e9427969 18582 .init_hook = alc_inithook,
8c427226 18583 },
f1d4e28b 18584 [ALC662_ECS] = {
f9e336f6 18585 .mixers = { alc662_ecs_mixer },
f1d4e28b 18586 .init_verbs = { alc662_init_verbs,
a7f2371f 18587 alc662_eapd_init_verbs,
f1d4e28b
KY
18588 alc662_ecs_init_verbs },
18589 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18590 .dac_nids = alc662_dac_nids,
18591 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18592 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18593 .unsol_event = alc_sku_unsol_event,
4f5d1706 18594 .setup = alc662_eeepc_setup,
e9427969 18595 .init_hook = alc_inithook,
f1d4e28b 18596 },
6dda9f4a 18597 [ALC663_ASUS_M51VA] = {
f9e336f6 18598 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18599 .init_verbs = { alc662_init_verbs,
18600 alc662_eapd_init_verbs,
18601 alc663_m51va_init_verbs },
6dda9f4a
KY
18602 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18603 .dac_nids = alc662_dac_nids,
18604 .dig_out_nid = ALC662_DIGOUT_NID,
18605 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18606 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18607 .unsol_event = alc_sku_unsol_event,
4f5d1706 18608 .setup = alc663_m51va_setup,
3b8510ce 18609 .init_hook = alc_inithook,
6dda9f4a
KY
18610 },
18611 [ALC663_ASUS_G71V] = {
f9e336f6 18612 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18613 .init_verbs = { alc662_init_verbs,
18614 alc662_eapd_init_verbs,
18615 alc663_g71v_init_verbs },
6dda9f4a
KY
18616 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18617 .dac_nids = alc662_dac_nids,
18618 .dig_out_nid = ALC662_DIGOUT_NID,
18619 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18620 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18621 .unsol_event = alc_sku_unsol_event,
4f5d1706 18622 .setup = alc663_g71v_setup,
e6a5e1b7 18623 .init_hook = alc_inithook,
6dda9f4a
KY
18624 },
18625 [ALC663_ASUS_H13] = {
f9e336f6 18626 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18627 .init_verbs = { alc662_init_verbs,
18628 alc662_eapd_init_verbs,
18629 alc663_m51va_init_verbs },
6dda9f4a
KY
18630 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18631 .dac_nids = alc662_dac_nids,
18632 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18633 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18634 .setup = alc663_m51va_setup,
18635 .unsol_event = alc_sku_unsol_event,
18636 .init_hook = alc_inithook,
6dda9f4a
KY
18637 },
18638 [ALC663_ASUS_G50V] = {
f9e336f6 18639 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18640 .init_verbs = { alc662_init_verbs,
18641 alc662_eapd_init_verbs,
18642 alc663_g50v_init_verbs },
6dda9f4a
KY
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .dac_nids = alc662_dac_nids,
18645 .dig_out_nid = ALC662_DIGOUT_NID,
18646 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18647 .channel_mode = alc662_3ST_6ch_modes,
18648 .input_mux = &alc663_capture_source,
3b8510ce 18649 .unsol_event = alc_sku_unsol_event,
4f5d1706 18650 .setup = alc663_g50v_setup,
3b8510ce 18651 .init_hook = alc_inithook,
6dda9f4a 18652 },
f1d4e28b 18653 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18654 .mixers = { alc663_m51va_mixer },
18655 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18656 .init_verbs = { alc662_init_verbs,
a7f2371f 18657 alc662_eapd_init_verbs,
f1d4e28b
KY
18658 alc663_21jd_amic_init_verbs },
18659 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18660 .hp_nid = 0x03,
18661 .dac_nids = alc662_dac_nids,
18662 .dig_out_nid = ALC662_DIGOUT_NID,
18663 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18664 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18665 .unsol_event = alc_sku_unsol_event,
4f5d1706 18666 .setup = alc663_mode1_setup,
3b8510ce 18667 .init_hook = alc_inithook,
f1d4e28b
KY
18668 },
18669 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18670 .mixers = { alc662_1bjd_mixer },
18671 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18672 .init_verbs = { alc662_init_verbs,
a7f2371f 18673 alc662_eapd_init_verbs,
f1d4e28b
KY
18674 alc662_1bjd_amic_init_verbs },
18675 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18676 .dac_nids = alc662_dac_nids,
18677 .dig_out_nid = ALC662_DIGOUT_NID,
18678 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18679 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18680 .unsol_event = alc_sku_unsol_event,
4f5d1706 18681 .setup = alc662_mode2_setup,
3b8510ce 18682 .init_hook = alc_inithook,
f1d4e28b
KY
18683 },
18684 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18685 .mixers = { alc663_two_hp_m1_mixer },
18686 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18687 .init_verbs = { alc662_init_verbs,
a7f2371f 18688 alc662_eapd_init_verbs,
f1d4e28b
KY
18689 alc663_two_hp_amic_m1_init_verbs },
18690 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18691 .hp_nid = 0x03,
18692 .dac_nids = alc662_dac_nids,
18693 .dig_out_nid = ALC662_DIGOUT_NID,
18694 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18695 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18696 .unsol_event = alc_sku_unsol_event,
4f5d1706 18697 .setup = alc663_mode3_setup,
3b8510ce 18698 .init_hook = alc_inithook,
f1d4e28b
KY
18699 },
18700 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18701 .mixers = { alc663_asus_21jd_clfe_mixer },
18702 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18703 .init_verbs = { alc662_init_verbs,
a7f2371f 18704 alc662_eapd_init_verbs,
f1d4e28b
KY
18705 alc663_21jd_amic_init_verbs},
18706 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18707 .hp_nid = 0x03,
18708 .dac_nids = alc662_dac_nids,
18709 .dig_out_nid = ALC662_DIGOUT_NID,
18710 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18711 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18712 .unsol_event = alc_sku_unsol_event,
4f5d1706 18713 .setup = alc663_mode4_setup,
3b8510ce 18714 .init_hook = alc_inithook,
f1d4e28b
KY
18715 },
18716 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18717 .mixers = { alc663_asus_15jd_clfe_mixer },
18718 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18719 .init_verbs = { alc662_init_verbs,
a7f2371f 18720 alc662_eapd_init_verbs,
f1d4e28b
KY
18721 alc663_15jd_amic_init_verbs },
18722 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18723 .hp_nid = 0x03,
18724 .dac_nids = alc662_dac_nids,
18725 .dig_out_nid = ALC662_DIGOUT_NID,
18726 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18727 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18728 .unsol_event = alc_sku_unsol_event,
4f5d1706 18729 .setup = alc663_mode5_setup,
3b8510ce 18730 .init_hook = alc_inithook,
f1d4e28b
KY
18731 },
18732 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18733 .mixers = { alc663_two_hp_m2_mixer },
18734 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18735 .init_verbs = { alc662_init_verbs,
a7f2371f 18736 alc662_eapd_init_verbs,
f1d4e28b
KY
18737 alc663_two_hp_amic_m2_init_verbs },
18738 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18739 .hp_nid = 0x03,
18740 .dac_nids = alc662_dac_nids,
18741 .dig_out_nid = ALC662_DIGOUT_NID,
18742 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18743 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18744 .unsol_event = alc_sku_unsol_event,
4f5d1706 18745 .setup = alc663_mode6_setup,
3b8510ce 18746 .init_hook = alc_inithook,
f1d4e28b 18747 },
ebb83eeb
KY
18748 [ALC663_ASUS_MODE7] = {
18749 .mixers = { alc663_mode7_mixer },
18750 .cap_mixer = alc662_auto_capture_mixer,
18751 .init_verbs = { alc662_init_verbs,
a7f2371f 18752 alc662_eapd_init_verbs,
ebb83eeb
KY
18753 alc663_mode7_init_verbs },
18754 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18755 .hp_nid = 0x03,
18756 .dac_nids = alc662_dac_nids,
18757 .dig_out_nid = ALC662_DIGOUT_NID,
18758 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18759 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18760 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18761 .setup = alc663_mode7_setup,
3b8510ce 18762 .init_hook = alc_inithook,
ebb83eeb
KY
18763 },
18764 [ALC663_ASUS_MODE8] = {
18765 .mixers = { alc663_mode8_mixer },
18766 .cap_mixer = alc662_auto_capture_mixer,
18767 .init_verbs = { alc662_init_verbs,
a7f2371f 18768 alc662_eapd_init_verbs,
ebb83eeb
KY
18769 alc663_mode8_init_verbs },
18770 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18771 .hp_nid = 0x03,
18772 .dac_nids = alc662_dac_nids,
18773 .dig_out_nid = ALC662_DIGOUT_NID,
18774 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18775 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18776 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18777 .setup = alc663_mode8_setup,
3b8510ce 18778 .init_hook = alc_inithook,
ebb83eeb 18779 },
622e84cd
KY
18780 [ALC272_DELL] = {
18781 .mixers = { alc663_m51va_mixer },
18782 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18783 .init_verbs = { alc662_init_verbs,
18784 alc662_eapd_init_verbs,
18785 alc272_dell_init_verbs },
622e84cd 18786 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18787 .dac_nids = alc272_dac_nids,
622e84cd
KY
18788 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18789 .adc_nids = alc272_adc_nids,
18790 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18791 .capsrc_nids = alc272_capsrc_nids,
18792 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18793 .unsol_event = alc_sku_unsol_event,
4f5d1706 18794 .setup = alc663_m51va_setup,
3b8510ce 18795 .init_hook = alc_inithook,
622e84cd
KY
18796 },
18797 [ALC272_DELL_ZM1] = {
18798 .mixers = { alc663_m51va_mixer },
18799 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18800 .init_verbs = { alc662_init_verbs,
18801 alc662_eapd_init_verbs,
18802 alc272_dell_zm1_init_verbs },
622e84cd 18803 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18804 .dac_nids = alc272_dac_nids,
622e84cd
KY
18805 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18806 .adc_nids = alc662_adc_nids,
b59bdf3b 18807 .num_adc_nids = 1,
622e84cd
KY
18808 .capsrc_nids = alc662_capsrc_nids,
18809 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18810 .unsol_event = alc_sku_unsol_event,
4f5d1706 18811 .setup = alc663_m51va_setup,
3b8510ce 18812 .init_hook = alc_inithook,
622e84cd 18813 },
9541ba1d
CP
18814 [ALC272_SAMSUNG_NC10] = {
18815 .mixers = { alc272_nc10_mixer },
18816 .init_verbs = { alc662_init_verbs,
a7f2371f 18817 alc662_eapd_init_verbs,
9541ba1d
CP
18818 alc663_21jd_amic_init_verbs },
18819 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18820 .dac_nids = alc272_dac_nids,
18821 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18822 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18823 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18824 .unsol_event = alc_sku_unsol_event,
4f5d1706 18825 .setup = alc663_mode4_setup,
3b8510ce 18826 .init_hook = alc_inithook,
9541ba1d 18827 },
bc9f98a9
KY
18828};
18829
18830
18831/*
18832 * BIOS auto configuration
18833 */
18834
7085ec12 18835/* convert from MIX nid to DAC */
604401a9 18836static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18837{
604401a9 18838 hda_nid_t list[5];
1304ac89
TI
18839 int i, num;
18840
18841 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18842 for (i = 0; i < num; i++) {
18843 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18844 return list[i];
18845 }
18846 return 0;
7085ec12
TI
18847}
18848
604401a9
TI
18849/* go down to the selector widget before the mixer */
18850static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18851{
18852 hda_nid_t srcs[5];
18853 int num = snd_hda_get_connections(codec, pin, srcs,
18854 ARRAY_SIZE(srcs));
18855 if (num != 1 ||
18856 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18857 return pin;
18858 return srcs[0];
18859}
18860
7085ec12 18861/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18862static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18863 hda_nid_t dac)
18864{
cc1c452e 18865 hda_nid_t mix[5];
7085ec12
TI
18866 int i, num;
18867
604401a9 18868 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18869 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18870 for (i = 0; i < num; i++) {
604401a9 18871 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18872 return mix[i];
18873 }
18874 return 0;
18875}
18876
ce764ab2
TI
18877/* select the connection from pin to DAC if needed */
18878static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18879 hda_nid_t dac)
18880{
18881 hda_nid_t mix[5];
18882 int i, num;
18883
18884 pin = alc_go_down_to_selector(codec, pin);
18885 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18886 if (num < 2)
18887 return 0;
18888 for (i = 0; i < num; i++) {
18889 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18890 snd_hda_codec_update_cache(codec, pin, 0,
18891 AC_VERB_SET_CONNECT_SEL, i);
18892 return 0;
18893 }
18894 }
18895 return 0;
18896}
18897
7085ec12 18898/* look for an empty DAC slot */
604401a9 18899static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18900{
18901 struct alc_spec *spec = codec->spec;
18902 hda_nid_t srcs[5];
18903 int i, j, num;
18904
604401a9 18905 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18906 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18907 for (i = 0; i < num; i++) {
604401a9 18908 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18909 if (!nid)
18910 continue;
18911 for (j = 0; j < spec->multiout.num_dacs; j++)
18912 if (spec->multiout.dac_nids[j] == nid)
18913 break;
18914 if (j >= spec->multiout.num_dacs)
18915 return nid;
18916 }
18917 return 0;
18918}
18919
18920/* fill in the dac_nids table from the parsed pin configuration */
18921static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18922 const struct auto_pin_cfg *cfg)
18923{
18924 struct alc_spec *spec = codec->spec;
18925 int i;
18926 hda_nid_t dac;
18927
18928 spec->multiout.dac_nids = spec->private_dac_nids;
18929 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18930 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18931 if (!dac)
18932 continue;
dda14410 18933 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
7085ec12
TI
18934 }
18935 return 0;
18936}
18937
bcb2f0f5
TI
18938static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18939 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18940{
bcb2f0f5 18941 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18942 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18943}
18944
bcb2f0f5
TI
18945static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18946 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18947{
bcb2f0f5 18948 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
18949 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18950}
18951
bcb2f0f5
TI
18952#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18953 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18954#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18955 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
18956#define alc662_add_stereo_vol(spec, pfx, nid) \
18957 alc662_add_vol_ctl(spec, pfx, nid, 3)
18958#define alc662_add_stereo_sw(spec, pfx, nid) \
18959 alc662_add_sw_ctl(spec, pfx, nid, 3)
18960
bc9f98a9 18961/* add playback controls from the parsed DAC table */
7085ec12 18962static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18963 const struct auto_pin_cfg *cfg)
18964{
7085ec12 18965 struct alc_spec *spec = codec->spec;
ea734963 18966 static const char * const chname[4] = {
bc9f98a9
KY
18967 "Front", "Surround", NULL /*CLFE*/, "Side"
18968 };
ce764ab2
TI
18969 const char *pfx = alc_get_line_out_pfx(spec, true);
18970 hda_nid_t nid, mix, pin;
18971 int i, err, noutputs;
bc9f98a9 18972
ce764ab2
TI
18973 noutputs = cfg->line_outs;
18974 if (spec->multi_ios > 0)
18975 noutputs += spec->multi_ios;
18976
18977 for (i = 0; i < noutputs; i++) {
7085ec12
TI
18978 nid = spec->multiout.dac_nids[i];
18979 if (!nid)
18980 continue;
ce764ab2
TI
18981 if (i >= cfg->line_outs)
18982 pin = spec->multi_io[i - 1].pin;
18983 else
18984 pin = cfg->line_out_pins[i];
18985 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18986 if (!mix)
bc9f98a9 18987 continue;
bcb2f0f5 18988 if (!pfx && i == 2) {
bc9f98a9 18989 /* Center/LFE */
7085ec12 18990 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18991 if (err < 0)
18992 return err;
7085ec12 18993 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18994 if (err < 0)
18995 return err;
7085ec12 18996 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18997 if (err < 0)
18998 return err;
7085ec12 18999 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19000 if (err < 0)
19001 return err;
19002 } else {
bcb2f0f5 19003 const char *name = pfx;
5a882646
DH
19004 int index = i;
19005 if (!name) {
bcb2f0f5 19006 name = chname[i];
5a882646
DH
19007 index = 0;
19008 }
19009 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19010 if (err < 0)
19011 return err;
5a882646 19012 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19013 if (err < 0)
19014 return err;
19015 }
19016 }
19017 return 0;
19018}
19019
19020/* add playback controls for speaker and HP outputs */
7085ec12
TI
19021/* return DAC nid if any new DAC is assigned */
19022static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19023 const char *pfx)
19024{
7085ec12
TI
19025 struct alc_spec *spec = codec->spec;
19026 hda_nid_t nid, mix;
bc9f98a9 19027 int err;
bc9f98a9
KY
19028
19029 if (!pin)
19030 return 0;
604401a9 19031 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19032 if (!nid) {
7085ec12
TI
19033 /* the corresponding DAC is already occupied */
19034 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19035 return 0; /* no way */
19036 /* create a switch only */
0afe5f89 19037 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19038 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19039 }
19040
604401a9 19041 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19042 if (!mix)
19043 return 0;
19044 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19045 if (err < 0)
19046 return err;
19047 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19048 if (err < 0)
19049 return err;
19050 return nid;
bc9f98a9
KY
19051}
19052
19053/* create playback/capture controls for input pins */
05f5f477 19054#define alc662_auto_create_input_ctls \
4b7348a1 19055 alc882_auto_create_input_ctls
bc9f98a9
KY
19056
19057static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19058 hda_nid_t nid, int pin_type,
7085ec12 19059 hda_nid_t dac)
bc9f98a9 19060{
7085ec12 19061 int i, num;
ce503f38 19062 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19063
f6c7e546 19064 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19065 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19066 for (i = 0; i < num; i++) {
604401a9 19067 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19068 continue;
0e53f344
TI
19069 /* need the manual connection? */
19070 if (num > 1)
19071 snd_hda_codec_write(codec, nid, 0,
19072 AC_VERB_SET_CONNECT_SEL, i);
19073 /* unmute mixer widget inputs */
19074 snd_hda_codec_write(codec, srcs[i], 0,
19075 AC_VERB_SET_AMP_GAIN_MUTE,
19076 AMP_IN_UNMUTE(0));
19077 snd_hda_codec_write(codec, srcs[i], 0,
19078 AC_VERB_SET_AMP_GAIN_MUTE,
19079 AMP_IN_UNMUTE(1));
7085ec12 19080 return;
bc9f98a9
KY
19081 }
19082}
19083
19084static void alc662_auto_init_multi_out(struct hda_codec *codec)
19085{
19086 struct alc_spec *spec = codec->spec;
7085ec12 19087 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19088 int i;
19089
19090 for (i = 0; i <= HDA_SIDE; i++) {
19091 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19092 if (nid)
baba8ee9 19093 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19094 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19095 }
19096}
19097
19098static void alc662_auto_init_hp_out(struct hda_codec *codec)
19099{
19100 struct alc_spec *spec = codec->spec;
19101 hda_nid_t pin;
19102
19103 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19104 if (pin)
19105 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19106 spec->multiout.hp_nid);
f6c7e546
TI
19107 pin = spec->autocfg.speaker_pins[0];
19108 if (pin)
7085ec12
TI
19109 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19110 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19111}
19112
bc9f98a9
KY
19113#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19114
19115static void alc662_auto_init_analog_input(struct hda_codec *codec)
19116{
19117 struct alc_spec *spec = codec->spec;
66ceeb6b 19118 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19119 int i;
19120
66ceeb6b
TI
19121 for (i = 0; i < cfg->num_inputs; i++) {
19122 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19123 if (alc_is_input_pin(codec, nid)) {
30ea098f 19124 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19125 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19126 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19127 snd_hda_codec_write(codec, nid, 0,
19128 AC_VERB_SET_AMP_GAIN_MUTE,
19129 AMP_OUT_MUTE);
19130 }
19131 }
19132}
19133
f511b01c
TI
19134#define alc662_auto_init_input_src alc882_auto_init_input_src
19135
ce764ab2
TI
19136/*
19137 * multi-io helper
19138 */
19139static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19140 unsigned int location)
19141{
19142 struct alc_spec *spec = codec->spec;
19143 struct auto_pin_cfg *cfg = &spec->autocfg;
19144 int type, i, num_pins = 0;
19145
19146 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19147 for (i = 0; i < cfg->num_inputs; i++) {
19148 hda_nid_t nid = cfg->inputs[i].pin;
19149 hda_nid_t dac;
19150 unsigned int defcfg, caps;
19151 if (cfg->inputs[i].type != type)
19152 continue;
19153 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19154 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19155 continue;
19156 if (location && get_defcfg_location(defcfg) != location)
19157 continue;
19158 caps = snd_hda_query_pin_caps(codec, nid);
19159 if (!(caps & AC_PINCAP_OUT))
19160 continue;
19161 dac = alc_auto_look_for_dac(codec, nid);
19162 if (!dac)
19163 continue;
19164 spec->multi_io[num_pins].pin = nid;
19165 spec->multi_io[num_pins].dac = dac;
19166 num_pins++;
dda14410 19167 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19168 }
19169 }
19170 spec->multiout.num_dacs = 1;
19171 if (num_pins < 2)
19172 return 0;
19173 return num_pins;
19174}
19175
19176static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19177 struct snd_ctl_elem_info *uinfo)
19178{
19179 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19180 struct alc_spec *spec = codec->spec;
19181
19182 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19183 uinfo->count = 1;
19184 uinfo->value.enumerated.items = spec->multi_ios + 1;
19185 if (uinfo->value.enumerated.item > spec->multi_ios)
19186 uinfo->value.enumerated.item = spec->multi_ios;
19187 sprintf(uinfo->value.enumerated.name, "%dch",
19188 (uinfo->value.enumerated.item + 1) * 2);
19189 return 0;
19190}
19191
19192static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19193 struct snd_ctl_elem_value *ucontrol)
19194{
19195 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19196 struct alc_spec *spec = codec->spec;
19197 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19198 return 0;
19199}
19200
19201static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19202{
19203 struct alc_spec *spec = codec->spec;
19204 hda_nid_t nid = spec->multi_io[idx].pin;
19205
19206 if (!spec->multi_io[idx].ctl_in)
19207 spec->multi_io[idx].ctl_in =
19208 snd_hda_codec_read(codec, nid, 0,
19209 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19210 if (output) {
19211 snd_hda_codec_update_cache(codec, nid, 0,
19212 AC_VERB_SET_PIN_WIDGET_CONTROL,
19213 PIN_OUT);
19214 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19215 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19216 HDA_AMP_MUTE, 0);
19217 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19218 } else {
19219 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19220 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19221 HDA_AMP_MUTE, HDA_AMP_MUTE);
19222 snd_hda_codec_update_cache(codec, nid, 0,
19223 AC_VERB_SET_PIN_WIDGET_CONTROL,
19224 spec->multi_io[idx].ctl_in);
19225 }
19226 return 0;
19227}
19228
19229static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19230 struct snd_ctl_elem_value *ucontrol)
19231{
19232 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19233 struct alc_spec *spec = codec->spec;
19234 int i, ch;
19235
19236 ch = ucontrol->value.enumerated.item[0];
19237 if (ch < 0 || ch > spec->multi_ios)
19238 return -EINVAL;
19239 if (ch == (spec->ext_channel_count - 1) / 2)
19240 return 0;
19241 spec->ext_channel_count = (ch + 1) * 2;
19242 for (i = 0; i < spec->multi_ios; i++)
19243 alc_set_multi_io(codec, i, i < ch);
19244 spec->multiout.max_channels = spec->ext_channel_count;
19245 return 1;
19246}
19247
a9111321 19248static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19249 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19250 .name = "Channel Mode",
19251 .info = alc_auto_ch_mode_info,
19252 .get = alc_auto_ch_mode_get,
19253 .put = alc_auto_ch_mode_put,
19254};
19255
19256static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19257{
19258 struct alc_spec *spec = codec->spec;
19259 struct auto_pin_cfg *cfg = &spec->autocfg;
19260 unsigned int location, defcfg;
19261 int num_pins;
19262
19263 if (cfg->line_outs != 1 ||
19264 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19265 return 0;
19266
19267 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19268 location = get_defcfg_location(defcfg);
19269
19270 num_pins = alc_auto_fill_multi_ios(codec, location);
19271 if (num_pins > 0) {
19272 struct snd_kcontrol_new *knew;
19273
19274 knew = alc_kcontrol_new(spec);
19275 if (!knew)
19276 return -ENOMEM;
19277 *knew = alc_auto_channel_mode_enum;
19278 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19279 if (!knew->name)
19280 return -ENOMEM;
19281
19282 spec->multi_ios = num_pins;
19283 spec->ext_channel_count = 2;
19284 spec->multiout.num_dacs = num_pins + 1;
19285 }
19286 return 0;
19287}
19288
bc9f98a9
KY
19289static int alc662_parse_auto_config(struct hda_codec *codec)
19290{
19291 struct alc_spec *spec = codec->spec;
19292 int err;
4c6d72d1 19293 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19294
19295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19296 alc662_ignore);
19297 if (err < 0)
19298 return err;
19299 if (!spec->autocfg.line_outs)
19300 return 0; /* can't find valid BIOS pin config */
19301
7085ec12 19302 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19303 if (err < 0)
19304 return err;
19305 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19306 if (err < 0)
19307 return err;
7085ec12 19308 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19309 if (err < 0)
19310 return err;
7085ec12 19311 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19312 spec->autocfg.speaker_pins[0],
19313 "Speaker");
19314 if (err < 0)
19315 return err;
7085ec12
TI
19316 if (err)
19317 spec->multiout.extra_out_nid[0] = err;
19318 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19319 "Headphone");
19320 if (err < 0)
19321 return err;
7085ec12
TI
19322 if (err)
19323 spec->multiout.hp_nid = err;
05f5f477 19324 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19325 if (err < 0)
bc9f98a9
KY
19326 return err;
19327
19328 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19329
757899ac 19330 alc_auto_parse_digital(codec);
bc9f98a9 19331
603c4019 19332 if (spec->kctls.list)
d88897ea 19333 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19334
19335 spec->num_mux_defs = 1;
61b9b9b1 19336 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19337
ee979a14
TI
19338 err = alc_auto_add_mic_boost(codec);
19339 if (err < 0)
19340 return err;
19341
6227cdce
KY
19342 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19343 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19344 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19345 else
19346 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19347
8c87286f 19348 return 1;
bc9f98a9
KY
19349}
19350
19351/* additional initialization for auto-configuration model */
19352static void alc662_auto_init(struct hda_codec *codec)
19353{
f6c7e546 19354 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19355 alc662_auto_init_multi_out(codec);
19356 alc662_auto_init_hp_out(codec);
19357 alc662_auto_init_analog_input(codec);
f511b01c 19358 alc662_auto_init_input_src(codec);
757899ac 19359 alc_auto_init_digital(codec);
f6c7e546 19360 if (spec->unsol_event)
7fb0d78f 19361 alc_inithook(codec);
bc9f98a9
KY
19362}
19363
6be7948f 19364static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19365 const struct alc_fixup *fix, int action)
6fc398cb 19366{
b5bfbc67 19367 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19368 return;
6be7948f
TB
19369 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19370 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19371 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19372 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19373 (0 << AC_AMPCAP_MUTE_SHIFT)))
19374 printk(KERN_WARNING
19375 "hda_codec: failed to override amp caps for NID 0x2\n");
19376}
19377
6cb3b707 19378enum {
2df03514 19379 ALC662_FIXUP_ASPIRE,
6cb3b707 19380 ALC662_FIXUP_IDEAPAD,
6be7948f 19381 ALC272_FIXUP_MARIO,
d2ebd479 19382 ALC662_FIXUP_CZC_P10T,
94024cd1 19383 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19384};
19385
19386static const struct alc_fixup alc662_fixups[] = {
2df03514 19387 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19388 .type = ALC_FIXUP_PINS,
19389 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19390 { 0x15, 0x99130112 }, /* subwoofer */
19391 { }
19392 }
19393 },
6cb3b707 19394 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19395 .type = ALC_FIXUP_PINS,
19396 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19397 { 0x17, 0x99130112 }, /* subwoofer */
19398 { }
19399 }
19400 },
6be7948f 19401 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19402 .type = ALC_FIXUP_FUNC,
19403 .v.func = alc272_fixup_mario,
d2ebd479
AA
19404 },
19405 [ALC662_FIXUP_CZC_P10T] = {
19406 .type = ALC_FIXUP_VERBS,
19407 .v.verbs = (const struct hda_verb[]) {
19408 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19409 {}
19410 }
19411 },
94024cd1
DH
19412 [ALC662_FIXUP_SKU_IGNORE] = {
19413 .type = ALC_FIXUP_SKU,
19414 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19415 },
6cb3b707
DH
19416};
19417
a9111321 19418static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19419 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19420 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19421 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19422 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19423 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19424 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19425 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19426 {}
19427};
19428
6be7948f
TB
19429static const struct alc_model_fixup alc662_fixup_models[] = {
19430 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19431 {}
19432};
6cb3b707
DH
19433
19434
bc9f98a9
KY
19435static int patch_alc662(struct hda_codec *codec)
19436{
19437 struct alc_spec *spec;
19438 int err, board_config;
693194f3 19439 int coef;
bc9f98a9
KY
19440
19441 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19442 if (!spec)
19443 return -ENOMEM;
19444
19445 codec->spec = spec;
19446
da00c244
KY
19447 alc_auto_parse_customize_define(codec);
19448
2c3bf9ab
TI
19449 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19450
693194f3
KY
19451 coef = alc_read_coef_idx(codec, 0);
19452 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19453 alc_codec_rename(codec, "ALC661");
693194f3
KY
19454 else if (coef & (1 << 14) &&
19455 codec->bus->pci->subsystem_vendor == 0x1025 &&
19456 spec->cdefine.platform_type == 1)
c027ddcd 19457 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19458 else if (coef == 0x4011)
19459 alc_codec_rename(codec, "ALC656");
274693f3 19460
bc9f98a9
KY
19461 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19462 alc662_models,
19463 alc662_cfg_tbl);
19464 if (board_config < 0) {
9a11f1aa
TI
19465 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19466 codec->chip_name);
bc9f98a9
KY
19467 board_config = ALC662_AUTO;
19468 }
19469
19470 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19471 alc_pick_fixup(codec, alc662_fixup_models,
19472 alc662_fixup_tbl, alc662_fixups);
19473 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19474 /* automatic parse from the BIOS config */
19475 err = alc662_parse_auto_config(codec);
19476 if (err < 0) {
19477 alc_free(codec);
19478 return err;
8c87286f 19479 } else if (!err) {
bc9f98a9
KY
19480 printk(KERN_INFO
19481 "hda_codec: Cannot set up configuration "
19482 "from BIOS. Using base mode...\n");
19483 board_config = ALC662_3ST_2ch_DIG;
19484 }
19485 }
19486
dc1eae25 19487 if (has_cdefine_beep(codec)) {
8af2591d
TI
19488 err = snd_hda_attach_beep_device(codec, 0x1);
19489 if (err < 0) {
19490 alc_free(codec);
19491 return err;
19492 }
680cd536
KK
19493 }
19494
bc9f98a9 19495 if (board_config != ALC662_AUTO)
e9c364c0 19496 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19497
bc9f98a9
KY
19498 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19499 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19500
bc9f98a9
KY
19501 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19502 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19503
dd704698
TI
19504 if (!spec->adc_nids) {
19505 spec->adc_nids = alc662_adc_nids;
19506 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19507 }
19508 if (!spec->capsrc_nids)
19509 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19510
f9e336f6 19511 if (!spec->cap_mixer)
b59bdf3b 19512 set_capture_mixer(codec);
cec27c89 19513
dc1eae25 19514 if (has_cdefine_beep(codec)) {
da00c244
KY
19515 switch (codec->vendor_id) {
19516 case 0x10ec0662:
19517 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19518 break;
19519 case 0x10ec0272:
19520 case 0x10ec0663:
19521 case 0x10ec0665:
19522 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19523 break;
19524 case 0x10ec0273:
19525 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19526 break;
19527 }
cec27c89 19528 }
2134ea4f
TI
19529 spec->vmaster_nid = 0x02;
19530
b5bfbc67
TI
19531 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19532
bc9f98a9 19533 codec->patch_ops = alc_patch_ops;
b5bfbc67 19534 if (board_config == ALC662_AUTO)
bc9f98a9 19535 spec->init_hook = alc662_auto_init;
1c716153 19536 spec->shutup = alc_eapd_shutup;
6cb3b707 19537
bf1b0225
KY
19538 alc_init_jacks(codec);
19539
cb53c626
TI
19540#ifdef CONFIG_SND_HDA_POWER_SAVE
19541 if (!spec->loopback.amplist)
19542 spec->loopback.amplist = alc662_loopbacks;
19543#endif
bc9f98a9
KY
19544
19545 return 0;
19546}
19547
274693f3
KY
19548static int patch_alc888(struct hda_codec *codec)
19549{
19550 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19551 kfree(codec->chip_name);
01e0f137
KY
19552 if (codec->vendor_id == 0x10ec0887)
19553 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19554 else
19555 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19556 if (!codec->chip_name) {
19557 alc_free(codec);
274693f3 19558 return -ENOMEM;
ac2c92e0
TI
19559 }
19560 return patch_alc662(codec);
274693f3 19561 }
ac2c92e0 19562 return patch_alc882(codec);
274693f3
KY
19563}
19564
d1eb57f4
KY
19565/*
19566 * ALC680 support
19567 */
c69aefab 19568#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19569#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19570#define alc680_modes alc260_modes
19571
4c6d72d1 19572static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19573 /* Lout1, Lout2, hp */
19574 0x02, 0x03, 0x04
19575};
19576
4c6d72d1 19577static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19578 /* ADC0-2 */
19579 /* DMIC, MIC, Line-in*/
19580 0x07, 0x08, 0x09
19581};
19582
c69aefab
KY
19583/*
19584 * Analog capture ADC cgange
19585 */
66ceeb6b
TI
19586static void alc680_rec_autoswitch(struct hda_codec *codec)
19587{
19588 struct alc_spec *spec = codec->spec;
19589 struct auto_pin_cfg *cfg = &spec->autocfg;
19590 int pin_found = 0;
19591 int type_found = AUTO_PIN_LAST;
19592 hda_nid_t nid;
19593 int i;
19594
19595 for (i = 0; i < cfg->num_inputs; i++) {
19596 nid = cfg->inputs[i].pin;
06dec228 19597 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19598 continue;
19599 if (snd_hda_jack_detect(codec, nid)) {
19600 if (cfg->inputs[i].type < type_found) {
19601 type_found = cfg->inputs[i].type;
19602 pin_found = nid;
19603 }
19604 }
19605 }
19606
19607 nid = 0x07;
19608 if (pin_found)
19609 snd_hda_get_connections(codec, pin_found, &nid, 1);
19610
19611 if (nid != spec->cur_adc)
19612 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19613 spec->cur_adc = nid;
19614 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19615 spec->cur_adc_format);
19616}
19617
c69aefab
KY
19618static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19619 struct hda_codec *codec,
19620 unsigned int stream_tag,
19621 unsigned int format,
19622 struct snd_pcm_substream *substream)
19623{
19624 struct alc_spec *spec = codec->spec;
c69aefab 19625
66ceeb6b 19626 spec->cur_adc = 0x07;
c69aefab
KY
19627 spec->cur_adc_stream_tag = stream_tag;
19628 spec->cur_adc_format = format;
19629
66ceeb6b 19630 alc680_rec_autoswitch(codec);
c69aefab
KY
19631 return 0;
19632}
19633
19634static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19635 struct hda_codec *codec,
19636 struct snd_pcm_substream *substream)
19637{
19638 snd_hda_codec_cleanup_stream(codec, 0x07);
19639 snd_hda_codec_cleanup_stream(codec, 0x08);
19640 snd_hda_codec_cleanup_stream(codec, 0x09);
19641 return 0;
19642}
19643
a9111321 19644static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19645 .substreams = 1, /* can be overridden */
19646 .channels_min = 2,
19647 .channels_max = 2,
19648 /* NID is set in alc_build_pcms */
19649 .ops = {
19650 .prepare = alc680_capture_pcm_prepare,
19651 .cleanup = alc680_capture_pcm_cleanup
19652 },
19653};
19654
a9111321 19655static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19656 /* output mixer control */
19657 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19658 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19659 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19660 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19662 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19663 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19664 { }
19665};
19666
a9111321 19667static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19668 .ops = &snd_hda_bind_vol,
19669 .values = {
19670 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19671 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19672 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19673 0
19674 },
19675};
19676
a9111321 19677static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19678 .ops = &snd_hda_bind_sw,
19679 .values = {
19680 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19681 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19682 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19683 0
19684 },
19685};
19686
a9111321 19687static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19688 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19689 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19690 { } /* end */
19691};
19692
19693/*
19694 * generic initialization of ADC, input mixers and output mixers
19695 */
a9111321 19696static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19697 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19698 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19699 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19700
c69aefab
KY
19701 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19702 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19703 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19704 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19706 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19707
19708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19710 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19711 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19712 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19713
19714 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19715 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19716 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19717
d1eb57f4
KY
19718 { }
19719};
19720
c69aefab
KY
19721/* toggle speaker-output according to the hp-jack state */
19722static void alc680_base_setup(struct hda_codec *codec)
19723{
19724 struct alc_spec *spec = codec->spec;
19725
19726 spec->autocfg.hp_pins[0] = 0x16;
19727 spec->autocfg.speaker_pins[0] = 0x14;
19728 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19729 spec->autocfg.num_inputs = 2;
19730 spec->autocfg.inputs[0].pin = 0x18;
19731 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19732 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19733 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19734 spec->automute = 1;
19735 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19736}
19737
19738static void alc680_unsol_event(struct hda_codec *codec,
19739 unsigned int res)
19740{
19741 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19742 alc_hp_automute(codec);
c69aefab
KY
19743 if ((res >> 26) == ALC880_MIC_EVENT)
19744 alc680_rec_autoswitch(codec);
19745}
19746
19747static void alc680_inithook(struct hda_codec *codec)
19748{
d922b51d 19749 alc_hp_automute(codec);
c69aefab
KY
19750 alc680_rec_autoswitch(codec);
19751}
19752
d1eb57f4
KY
19753/* create input playback/capture controls for the given pin */
19754static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19755 const char *ctlname, int idx)
19756{
19757 hda_nid_t dac;
19758 int err;
19759
19760 switch (nid) {
19761 case 0x14:
19762 dac = 0x02;
19763 break;
19764 case 0x15:
19765 dac = 0x03;
19766 break;
19767 case 0x16:
19768 dac = 0x04;
19769 break;
19770 default:
19771 return 0;
19772 }
19773 if (spec->multiout.dac_nids[0] != dac &&
19774 spec->multiout.dac_nids[1] != dac) {
19775 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19776 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19777 HDA_OUTPUT));
19778 if (err < 0)
19779 return err;
19780
19781 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19782 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19783
19784 if (err < 0)
19785 return err;
dda14410 19786 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19787 }
19788
19789 return 0;
19790}
19791
19792/* add playback controls from the parsed DAC table */
19793static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19794 const struct auto_pin_cfg *cfg)
19795{
19796 hda_nid_t nid;
19797 int err;
19798
19799 spec->multiout.dac_nids = spec->private_dac_nids;
19800
19801 nid = cfg->line_out_pins[0];
19802 if (nid) {
19803 const char *name;
19804 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19805 name = "Speaker";
19806 else
19807 name = "Front";
19808 err = alc680_new_analog_output(spec, nid, name, 0);
19809 if (err < 0)
19810 return err;
19811 }
19812
19813 nid = cfg->speaker_pins[0];
19814 if (nid) {
19815 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19816 if (err < 0)
19817 return err;
19818 }
19819 nid = cfg->hp_pins[0];
19820 if (nid) {
19821 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19822 if (err < 0)
19823 return err;
19824 }
19825
19826 return 0;
19827}
19828
19829static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19830 hda_nid_t nid, int pin_type)
19831{
19832 alc_set_pin_output(codec, nid, pin_type);
19833}
19834
19835static void alc680_auto_init_multi_out(struct hda_codec *codec)
19836{
19837 struct alc_spec *spec = codec->spec;
19838 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19839 if (nid) {
19840 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19841 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19842 }
19843}
19844
19845static void alc680_auto_init_hp_out(struct hda_codec *codec)
19846{
19847 struct alc_spec *spec = codec->spec;
19848 hda_nid_t pin;
19849
19850 pin = spec->autocfg.hp_pins[0];
19851 if (pin)
19852 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19853 pin = spec->autocfg.speaker_pins[0];
19854 if (pin)
19855 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19856}
19857
19858/* pcm configuration: identical with ALC880 */
19859#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19860#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19861#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19862#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19863#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19864
19865/*
19866 * BIOS auto configuration
19867 */
19868static int alc680_parse_auto_config(struct hda_codec *codec)
19869{
19870 struct alc_spec *spec = codec->spec;
19871 int err;
4c6d72d1 19872 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19873
19874 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19875 alc680_ignore);
19876 if (err < 0)
19877 return err;
c69aefab 19878
d1eb57f4
KY
19879 if (!spec->autocfg.line_outs) {
19880 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19881 spec->multiout.max_channels = 2;
19882 spec->no_analog = 1;
19883 goto dig_only;
19884 }
19885 return 0; /* can't find valid BIOS pin config */
19886 }
19887 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19888 if (err < 0)
19889 return err;
19890
19891 spec->multiout.max_channels = 2;
19892
19893 dig_only:
19894 /* digital only support output */
757899ac 19895 alc_auto_parse_digital(codec);
d1eb57f4
KY
19896 if (spec->kctls.list)
19897 add_mixer(spec, spec->kctls.list);
19898
19899 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19900
19901 err = alc_auto_add_mic_boost(codec);
19902 if (err < 0)
19903 return err;
19904
19905 return 1;
19906}
19907
19908#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19909
19910/* init callback for auto-configuration model -- overriding the default init */
19911static void alc680_auto_init(struct hda_codec *codec)
19912{
19913 struct alc_spec *spec = codec->spec;
19914 alc680_auto_init_multi_out(codec);
19915 alc680_auto_init_hp_out(codec);
19916 alc680_auto_init_analog_input(codec);
757899ac 19917 alc_auto_init_digital(codec);
d1eb57f4
KY
19918 if (spec->unsol_event)
19919 alc_inithook(codec);
19920}
19921
19922/*
19923 * configuration and preset
19924 */
ea734963 19925static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19926 [ALC680_BASE] = "base",
19927 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19928};
19929
a9111321 19930static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19931 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19932 {}
19933};
19934
a9111321 19935static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19936 [ALC680_BASE] = {
19937 .mixers = { alc680_base_mixer },
c69aefab 19938 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19939 .init_verbs = { alc680_init_verbs },
19940 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19941 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19942 .dig_out_nid = ALC680_DIGOUT_NID,
19943 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19944 .channel_mode = alc680_modes,
c69aefab
KY
19945 .unsol_event = alc680_unsol_event,
19946 .setup = alc680_base_setup,
19947 .init_hook = alc680_inithook,
19948
d1eb57f4
KY
19949 },
19950};
19951
19952static int patch_alc680(struct hda_codec *codec)
19953{
19954 struct alc_spec *spec;
19955 int board_config;
19956 int err;
19957
19958 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19959 if (spec == NULL)
19960 return -ENOMEM;
19961
19962 codec->spec = spec;
19963
19964 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19965 alc680_models,
19966 alc680_cfg_tbl);
19967
19968 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19969 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19970 codec->chip_name);
19971 board_config = ALC680_AUTO;
19972 }
19973
19974 if (board_config == ALC680_AUTO) {
19975 /* automatic parse from the BIOS config */
19976 err = alc680_parse_auto_config(codec);
19977 if (err < 0) {
19978 alc_free(codec);
19979 return err;
19980 } else if (!err) {
19981 printk(KERN_INFO
19982 "hda_codec: Cannot set up configuration "
19983 "from BIOS. Using base mode...\n");
19984 board_config = ALC680_BASE;
19985 }
19986 }
19987
19988 if (board_config != ALC680_AUTO)
19989 setup_preset(codec, &alc680_presets[board_config]);
19990
19991 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19992 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19993 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19994 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19995
19996 if (!spec->adc_nids) {
19997 spec->adc_nids = alc680_adc_nids;
19998 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19999 }
20000
20001 if (!spec->cap_mixer)
20002 set_capture_mixer(codec);
20003
20004 spec->vmaster_nid = 0x02;
20005
20006 codec->patch_ops = alc_patch_ops;
20007 if (board_config == ALC680_AUTO)
20008 spec->init_hook = alc680_auto_init;
20009
20010 return 0;
20011}
20012
1da177e4
LT
20013/*
20014 * patch entries
20015 */
a9111321 20016static const struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20017 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20018 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20019 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20020 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20021 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20022 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20023 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20024 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20025 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20026 .patch = patch_alc861 },
f32610ed
JS
20027 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20028 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20029 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20030 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20031 .patch = patch_alc882 },
bc9f98a9
KY
20032 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20033 .patch = patch_alc662 },
6dda9f4a 20034 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20035 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20036 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20037 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20038 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20039 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20040 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20041 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20042 .patch = patch_alc882 },
cb308f97 20043 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20044 .patch = patch_alc882 },
df694daa 20045 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20046 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20047 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20048 .patch = patch_alc882 },
274693f3 20049 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20050 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20051 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20052 {} /* terminator */
20053};
1289e9e8
TI
20054
20055MODULE_ALIAS("snd-hda-codec-id:10ec*");
20056
20057MODULE_LICENSE("GPL");
20058MODULE_DESCRIPTION("Realtek HD-audio codec");
20059
20060static struct hda_codec_preset_list realtek_list = {
20061 .preset = snd_hda_preset_realtek,
20062 .owner = THIS_MODULE,
20063};
20064
20065static int __init patch_realtek_init(void)
20066{
20067 return snd_hda_add_codec_preset(&realtek_list);
20068}
20069
20070static void __exit patch_realtek_exit(void)
20071{
20072 snd_hda_delete_codec_preset(&realtek_list);
20073}
20074
20075module_init(patch_realtek_init)
20076module_exit(patch_realtek_exit)