]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
Linux 3.0-rc2
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 351
840b64c0
TI
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
1da177e4 358 /* capture source */
a1e8d2da 359 unsigned int num_mux_defs;
1da177e4
LT
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
6c819492 362 struct alc_mic_route ext_mic;
8ed99d97 363 struct alc_mic_route dock_mic;
6c819492 364 struct alc_mic_route int_mic;
1da177e4
LT
365
366 /* channel model */
d2a6d7dc 367 const struct hda_channel_mode *channel_mode;
1da177e4 368 int num_channel_mode;
4e195a7b 369 int need_dac_fix;
3b315d70
HM
370 int const_channel_count;
371 int ext_channel_count;
1da177e4
LT
372
373 /* PCM information */
4c5186ed 374 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 375
e9edcee0
TI
376 /* dynamic controls, init_verbs and input_mux */
377 struct auto_pin_cfg autocfg;
da00c244 378 struct alc_customize_define cdefine;
603c4019 379 struct snd_array kctls;
61b9b9b1 380 struct hda_input_mux private_imux[3];
41923e44 381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 384
ae6b813a
TI
385 /* hooks */
386 void (*init_hook)(struct hda_codec *codec);
387 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 388#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 389 void (*power_hook)(struct hda_codec *codec);
f5de24b0 390#endif
1c716153 391 void (*shutup)(struct hda_codec *codec);
ae6b813a 392
834be88d 393 /* for pin sensing */
834be88d 394 unsigned int jack_present: 1;
e6a5e1b7 395 unsigned int line_jack_present:1;
e9427969 396 unsigned int master_mute:1;
6c819492 397 unsigned int auto_mic:1;
d922b51d 398 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
399 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 401 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 402
e64f14f4
TI
403 /* other flags */
404 unsigned int no_analog :1; /* digital I/O only */
840b64c0 405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 406 unsigned int single_input_src:1;
d922b51d
TI
407
408 /* auto-mute control */
409 int automute_mode;
3b8510ce 410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 411
4a79ba34 412 int init_amp;
d433a678 413 int codec_variant; /* flag for other variants */
e64f14f4 414
2134ea4f
TI
415 /* for virtual master */
416 hda_nid_t vmaster_nid;
cb53c626
TI
417#ifdef CONFIG_SND_HDA_POWER_SAVE
418 struct hda_loopback_check loopback;
419#endif
2c3bf9ab
TI
420
421 /* for PLL fix */
422 hda_nid_t pll_nid;
423 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
424
425 /* fix-up list */
426 int fixup_id;
427 const struct alc_fixup *fixup_list;
428 const char *fixup_name;
ce764ab2
TI
429
430 /* multi-io */
431 int multi_ios;
432 struct alc_multi_io multi_io[4];
df694daa
KY
433};
434
435/*
436 * configuration template - to be copied to the spec instance
437 */
438struct alc_config_preset {
a9111321 439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
440 * with spec
441 */
a9111321 442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
443 const struct hda_verb *init_verbs[5];
444 unsigned int num_dacs;
4c6d72d1 445 const hda_nid_t *dac_nids;
df694daa
KY
446 hda_nid_t dig_out_nid; /* optional */
447 hda_nid_t hp_nid; /* optional */
4c6d72d1 448 const hda_nid_t *slave_dig_outs;
df694daa 449 unsigned int num_adc_nids;
4c6d72d1
TI
450 const hda_nid_t *adc_nids;
451 const hda_nid_t *capsrc_nids;
df694daa
KY
452 hda_nid_t dig_in_nid;
453 unsigned int num_channel_mode;
454 const struct hda_channel_mode *channel_mode;
4e195a7b 455 int need_dac_fix;
3b315d70 456 int const_channel_count;
a1e8d2da 457 unsigned int num_mux_defs;
df694daa 458 const struct hda_input_mux *input_mux;
ae6b813a 459 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 460 void (*setup)(struct hda_codec *);
ae6b813a 461 void (*init_hook)(struct hda_codec *);
cb53c626 462#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 463 const struct hda_amp_list *loopbacks;
c97259df 464 void (*power_hook)(struct hda_codec *codec);
cb53c626 465#endif
1da177e4
LT
466};
467
1da177e4
LT
468
469/*
470 * input MUX handling
471 */
9c7f852e
TI
472static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
474{
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
477 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
478 if (mux_idx >= spec->num_mux_defs)
479 mux_idx = 0;
5311114d
TI
480 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
481 mux_idx = 0;
a1e8d2da 482 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
483}
484
9c7f852e
TI
485static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
487{
488 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489 struct alc_spec *spec = codec->spec;
490 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
491
492 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
493 return 0;
494}
495
9c7f852e
TI
496static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
498{
499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500 struct alc_spec *spec = codec->spec;
cd896c33 501 const struct hda_input_mux *imux;
1da177e4 502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 503 unsigned int mux_idx;
e1406348
TI
504 hda_nid_t nid = spec->capsrc_nids ?
505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 506 unsigned int type;
1da177e4 507
cd896c33
TI
508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509 imux = &spec->input_mux[mux_idx];
5311114d
TI
510 if (!imux->num_items && mux_idx > 0)
511 imux = &spec->input_mux[0];
cd896c33 512
a22d543a 513 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 514 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
515 /* Matrix-mixer style (e.g. ALC882) */
516 unsigned int *cur_val = &spec->cur_mux[adc_idx];
517 unsigned int i, idx;
518
519 idx = ucontrol->value.enumerated.item[0];
520 if (idx >= imux->num_items)
521 idx = imux->num_items - 1;
522 if (*cur_val == idx)
523 return 0;
524 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index,
528 HDA_AMP_MUTE, v);
529 }
530 *cur_val = idx;
531 return 1;
532 } else {
533 /* MUX style (e.g. ALC880) */
cd896c33 534 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
535 &spec->cur_mux[adc_idx]);
536 }
537}
e9edcee0 538
1da177e4
LT
539/*
540 * channel mode setting
541 */
9c7f852e
TI
542static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
544{
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
547 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548 spec->num_channel_mode);
1da177e4
LT
549}
550
9c7f852e
TI
551static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
553{
554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555 struct alc_spec *spec = codec->spec;
d2a6d7dc 556 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 557 spec->num_channel_mode,
3b315d70 558 spec->ext_channel_count);
1da177e4
LT
559}
560
9c7f852e
TI
561static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
563{
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 struct alc_spec *spec = codec->spec;
4e195a7b
TI
566 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567 spec->num_channel_mode,
3b315d70
HM
568 &spec->ext_channel_count);
569 if (err >= 0 && !spec->const_channel_count) {
570 spec->multiout.max_channels = spec->ext_channel_count;
571 if (spec->need_dac_fix)
572 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
573 }
4e195a7b 574 return err;
1da177e4
LT
575}
576
a9430dd8 577/*
4c5186ed 578 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 579 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
580 * being part of a format specifier. Maximum allowed length of a value is
581 * 63 characters plus NULL terminator.
7cf51e48
JW
582 *
583 * Note: some retasking pin complexes seem to ignore requests for input
584 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
585 * are requested. Therefore order this list so that this behaviour will not
586 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588 * March 2006.
4c5186ed 589 */
a9111321 590static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
591 "Mic 50pc bias", "Mic 80pc bias",
592 "Line in", "Line out", "Headphone out",
4c5186ed 593};
a9111321 594static const unsigned char alc_pin_mode_values[] = {
7cf51e48 595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
596};
597/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
598 * in the pin being assumed to be exclusively an input or an output pin. In
599 * addition, "input" pins may or may not process the mic bias option
600 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
601 * accept requests for bias as of chip versions up to March 2006) and/or
602 * wiring in the computer.
a9430dd8 603 */
a1e8d2da
JW
604#define ALC_PIN_DIR_IN 0x00
605#define ALC_PIN_DIR_OUT 0x01
606#define ALC_PIN_DIR_INOUT 0x02
607#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
608#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 609
ea1fb29a 610/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
611 * For each direction the minimum and maximum values are given.
612 */
a9111321 613static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
614 { 0, 2 }, /* ALC_PIN_DIR_IN */
615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
617 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
618 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
619};
620#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
621#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
622#define alc_pin_mode_n_items(_dir) \
623 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
624
9c7f852e
TI
625static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_info *uinfo)
a9430dd8 627{
4c5186ed
JW
628 unsigned int item_num = uinfo->value.enumerated.item;
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630
631 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 632 uinfo->count = 1;
4c5186ed
JW
633 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
634
635 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
636 item_num = alc_pin_mode_min(dir);
637 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
638 return 0;
639}
640
9c7f852e
TI
641static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
a9430dd8 643{
4c5186ed 644 unsigned int i;
a9430dd8
JW
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 647 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 648 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
649 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_PIN_WIDGET_CONTROL,
651 0x00);
a9430dd8 652
4c5186ed
JW
653 /* Find enumerated value for current pinctl setting */
654 i = alc_pin_mode_min(dir);
4b35d2ca 655 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 656 i++;
9c7f852e 657 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
658 return 0;
659}
660
9c7f852e
TI
661static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662 struct snd_ctl_elem_value *ucontrol)
a9430dd8 663{
4c5186ed 664 signed int change;
a9430dd8
JW
665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
667 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668 long val = *ucontrol->value.integer.value;
9c7f852e
TI
669 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_PIN_WIDGET_CONTROL,
671 0x00);
a9430dd8 672
f12ab1e0 673 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
674 val = alc_pin_mode_min(dir);
675
676 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
677 if (change) {
678 /* Set pin mode to that requested */
82beb8fd
TI
679 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL,
681 alc_pin_mode_values[val]);
cdcd9268 682
ea1fb29a 683 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
684 * for the requested pin mode. Enum values of 2 or less are
685 * input modes.
686 *
687 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
688 * reduces noise slightly (particularly on input) so we'll
689 * do it. However, having both input and output buffers
690 * enabled simultaneously doesn't seem to be problematic if
691 * this turns out to be necessary in the future.
cdcd9268
JW
692 */
693 if (val <= 2) {
47fd830a
TI
694 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
695 HDA_AMP_MUTE, HDA_AMP_MUTE);
696 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
697 HDA_AMP_MUTE, 0);
cdcd9268 698 } else {
47fd830a
TI
699 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700 HDA_AMP_MUTE, HDA_AMP_MUTE);
701 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
702 HDA_AMP_MUTE, 0);
cdcd9268
JW
703 }
704 }
a9430dd8
JW
705 return change;
706}
707
4c5186ed 708#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
711 .info = alc_pin_mode_info, \
712 .get = alc_pin_mode_get, \
713 .put = alc_pin_mode_put, \
714 .private_value = nid | (dir<<16) }
df694daa 715
5c8f858d
JW
716/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
717 * together using a mask with more than one bit set. This control is
718 * currently used only by the ALC260 test model. At this stage they are not
719 * needed for any "production" models.
720 */
721#ifdef CONFIG_SND_DEBUG
a5ce8890 722#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 723
9c7f852e
TI
724static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
726{
727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
728 hda_nid_t nid = kcontrol->private_value & 0xffff;
729 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
730 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
731 unsigned int val = snd_hda_codec_read(codec, nid, 0,
732 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
733
734 *valp = (val & mask) != 0;
735 return 0;
736}
9c7f852e
TI
737static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
739{
740 signed int change;
741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
742 hda_nid_t nid = kcontrol->private_value & 0xffff;
743 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
744 long val = *ucontrol->value.integer.value;
9c7f852e
TI
745 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746 AC_VERB_GET_GPIO_DATA,
747 0x00);
5c8f858d
JW
748
749 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
750 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751 if (val == 0)
5c8f858d
JW
752 gpio_data &= ~mask;
753 else
754 gpio_data |= mask;
82beb8fd
TI
755 snd_hda_codec_write_cache(codec, nid, 0,
756 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
757
758 return change;
759}
760#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
761 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 762 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
763 .info = alc_gpio_data_info, \
764 .get = alc_gpio_data_get, \
765 .put = alc_gpio_data_put, \
766 .private_value = nid | (mask<<16) }
767#endif /* CONFIG_SND_DEBUG */
768
92621f13
JW
769/* A switch control to allow the enabling of the digital IO pins on the
770 * ALC260. This is incredibly simplistic; the intention of this control is
771 * to provide something in the test model allowing digital outputs to be
772 * identified if present. If models are found which can utilise these
773 * outputs a more complete mixer control can be devised for those models if
774 * necessary.
775 */
776#ifdef CONFIG_SND_DEBUG
a5ce8890 777#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 778
9c7f852e
TI
779static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
781{
782 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783 hda_nid_t nid = kcontrol->private_value & 0xffff;
784 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785 long *valp = ucontrol->value.integer.value;
9c7f852e 786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 787 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
788
789 *valp = (val & mask) != 0;
790 return 0;
791}
9c7f852e
TI
792static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
794{
795 signed int change;
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long val = *ucontrol->value.integer.value;
9c7f852e 800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 801 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 802 0x00);
92621f13
JW
803
804 /* Set/unset the masked control bit(s) as needed */
9c7f852e 805 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
806 if (val==0)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
82beb8fd
TI
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811 ctrl_data);
92621f13
JW
812
813 return change;
814}
815#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
816 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
818 .info = alc_spdif_ctrl_info, \
819 .get = alc_spdif_ctrl_get, \
820 .put = alc_spdif_ctrl_put, \
821 .private_value = nid | (mask<<16) }
822#endif /* CONFIG_SND_DEBUG */
823
f8225f6d
JW
824/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
825 * Again, this is only used in the ALC26x test models to help identify when
826 * the EAPD line must be asserted for features to work.
827 */
828#ifdef CONFIG_SND_DEBUG
829#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
830
831static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
832 struct snd_ctl_elem_value *ucontrol)
833{
834 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
835 hda_nid_t nid = kcontrol->private_value & 0xffff;
836 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
837 long *valp = ucontrol->value.integer.value;
838 unsigned int val = snd_hda_codec_read(codec, nid, 0,
839 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
840
841 *valp = (val & mask) != 0;
842 return 0;
843}
844
845static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol)
847{
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff;
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
852 long val = *ucontrol->value.integer.value;
853 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_EAPD_BTLENABLE,
855 0x00);
856
857 /* Set/unset the masked control bit(s) as needed */
858 change = (!val ? 0 : mask) != (ctrl_data & mask);
859 if (!val)
860 ctrl_data &= ~mask;
861 else
862 ctrl_data |= mask;
863 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864 ctrl_data);
865
866 return change;
867}
868
869#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 871 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
872 .info = alc_eapd_ctrl_info, \
873 .get = alc_eapd_ctrl_get, \
874 .put = alc_eapd_ctrl_put, \
875 .private_value = nid | (mask<<16) }
876#endif /* CONFIG_SND_DEBUG */
877
23f0c048
TI
878/*
879 * set up the input pin config (depending on the given auto-pin type)
880 */
881static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
882 int auto_pin_type)
883{
884 unsigned int val = PIN_IN;
885
86e2959a 886 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 887 unsigned int pincap;
954a29c8
TI
888 unsigned int oldval;
889 oldval = snd_hda_codec_read(codec, nid, 0,
890 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 891 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 892 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
893 /* if the default pin setup is vref50, we give it priority */
894 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 895 val = PIN_VREF80;
461c6c3a
TI
896 else if (pincap & AC_PINCAP_VREF_50)
897 val = PIN_VREF50;
898 else if (pincap & AC_PINCAP_VREF_100)
899 val = PIN_VREF100;
900 else if (pincap & AC_PINCAP_VREF_GRD)
901 val = PIN_VREFGRD;
23f0c048
TI
902 }
903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904}
905
f6837bbd
TI
906static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907{
908 struct alc_spec *spec = codec->spec;
909 struct auto_pin_cfg *cfg = &spec->autocfg;
910
911 if (!cfg->line_outs) {
912 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913 cfg->line_out_pins[cfg->line_outs])
914 cfg->line_outs++;
915 }
916 if (!cfg->speaker_outs) {
917 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918 cfg->speaker_pins[cfg->speaker_outs])
919 cfg->speaker_outs++;
920 }
921 if (!cfg->hp_outs) {
922 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923 cfg->hp_pins[cfg->hp_outs])
924 cfg->hp_outs++;
925 }
926}
927
d88897ea
TI
928/*
929 */
a9111321 930static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
931{
932 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
933 return;
934 spec->mixers[spec->num_mixers++] = mix;
935}
936
937static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
938{
939 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
940 return;
941 spec->init_verbs[spec->num_init_verbs++] = verb;
942}
943
df694daa
KY
944/*
945 * set up from the preset table
946 */
e9c364c0 947static void setup_preset(struct hda_codec *codec,
9c7f852e 948 const struct alc_config_preset *preset)
df694daa 949{
e9c364c0 950 struct alc_spec *spec = codec->spec;
df694daa
KY
951 int i;
952
953 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 954 add_mixer(spec, preset->mixers[i]);
f9e336f6 955 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
956 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957 i++)
d88897ea 958 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 959
df694daa
KY
960 spec->channel_mode = preset->channel_mode;
961 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 962 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 963 spec->const_channel_count = preset->const_channel_count;
df694daa 964
3b315d70
HM
965 if (preset->const_channel_count)
966 spec->multiout.max_channels = preset->const_channel_count;
967 else
968 spec->multiout.max_channels = spec->channel_mode[0].channels;
969 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
970
971 spec->multiout.num_dacs = preset->num_dacs;
972 spec->multiout.dac_nids = preset->dac_nids;
973 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 974 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 975 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 976
a1e8d2da 977 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 978 if (!spec->num_mux_defs)
a1e8d2da 979 spec->num_mux_defs = 1;
df694daa
KY
980 spec->input_mux = preset->input_mux;
981
982 spec->num_adc_nids = preset->num_adc_nids;
983 spec->adc_nids = preset->adc_nids;
e1406348 984 spec->capsrc_nids = preset->capsrc_nids;
df694daa 985 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
986
987 spec->unsol_event = preset->unsol_event;
988 spec->init_hook = preset->init_hook;
cb53c626 989#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 990 spec->power_hook = preset->power_hook;
cb53c626
TI
991 spec->loopback.amplist = preset->loopbacks;
992#endif
e9c364c0
TI
993
994 if (preset->setup)
995 preset->setup(codec);
f6837bbd
TI
996
997 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
998}
999
bc9f98a9 1000/* Enable GPIO mask and set output */
a9111321 1001static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1003 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1005 { }
1006};
1007
a9111321 1008static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1009 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1012 { }
1013};
1014
a9111321 1015static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1016 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1017 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1019 { }
1020};
1021
2c3bf9ab
TI
1022/*
1023 * Fix hardware PLL issue
1024 * On some codecs, the analog PLL gating control must be off while
1025 * the default value is 1.
1026 */
1027static void alc_fix_pll(struct hda_codec *codec)
1028{
1029 struct alc_spec *spec = codec->spec;
1030 unsigned int val;
1031
1032 if (!spec->pll_nid)
1033 return;
1034 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1035 spec->pll_coef_idx);
1036 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1037 AC_VERB_GET_PROC_COEF, 0);
1038 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1039 spec->pll_coef_idx);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1041 val & ~(1 << spec->pll_coef_bit));
1042}
1043
1044static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1045 unsigned int coef_idx, unsigned int coef_bit)
1046{
1047 struct alc_spec *spec = codec->spec;
1048 spec->pll_nid = nid;
1049 spec->pll_coef_idx = coef_idx;
1050 spec->pll_coef_bit = coef_bit;
1051 alc_fix_pll(codec);
1052}
1053
9ad0e496
KY
1054static int alc_init_jacks(struct hda_codec *codec)
1055{
cd372fb3 1056#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1057 struct alc_spec *spec = codec->spec;
1058 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin;
8ed99d97 1061 unsigned int dock_nid = spec->dock_mic.pin;
9ad0e496 1062
265a0247 1063 if (hp_nid) {
cd372fb3
TI
1064 err = snd_hda_input_jack_add(codec, hp_nid,
1065 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1066 if (err < 0)
1067 return err;
cd372fb3 1068 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1069 }
9ad0e496 1070
265a0247 1071 if (mic_nid) {
cd372fb3
TI
1072 err = snd_hda_input_jack_add(codec, mic_nid,
1073 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1074 if (err < 0)
1075 return err;
cd372fb3 1076 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1077 }
8ed99d97
TI
1078 if (dock_nid) {
1079 err = snd_hda_input_jack_add(codec, dock_nid,
1080 SND_JACK_MICROPHONE, NULL);
1081 if (err < 0)
1082 return err;
1083 snd_hda_input_jack_report(codec, dock_nid);
1084 }
cd372fb3 1085#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1086 return 0;
1087}
9ad0e496 1088
e6a5e1b7 1089static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1090{
e6a5e1b7 1091 int i, present = 0;
c9b58006 1092
e6a5e1b7
TI
1093 for (i = 0; i < num_pins; i++) {
1094 hda_nid_t nid = pins[i];
bb35febd
TI
1095 if (!nid)
1096 break;
cd372fb3 1097 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1098 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1099 }
e6a5e1b7
TI
1100 return present;
1101}
bb35febd 1102
e6a5e1b7 1103static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1104 bool mute, bool hp_out)
e6a5e1b7
TI
1105{
1106 struct alc_spec *spec = codec->spec;
1107 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1108 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1109 int i;
1110
1111 for (i = 0; i < num_pins; i++) {
1112 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1113 if (!nid)
1114 break;
3b8510ce
TI
1115 switch (spec->automute_mode) {
1116 case ALC_AUTOMUTE_PIN:
bb35febd 1117 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1118 AC_VERB_SET_PIN_WIDGET_CONTROL,
1119 pin_bits);
3b8510ce
TI
1120 break;
1121 case ALC_AUTOMUTE_AMP:
bb35febd 1122 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1123 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1124 break;
1125 case ALC_AUTOMUTE_MIXER:
1126 nid = spec->automute_mixer_nid[i];
1127 if (!nid)
1128 break;
1129 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1130 HDA_AMP_MUTE, mute_bits);
3b8510ce 1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1132 HDA_AMP_MUTE, mute_bits);
3b8510ce 1133 break;
bb35febd 1134 }
a9fd4f3f 1135 }
c9b58006
KY
1136}
1137
e6a5e1b7
TI
1138/* Toggle internal speakers muting */
1139static void update_speakers(struct hda_codec *codec)
1140{
1141 struct alc_spec *spec = codec->spec;
1a1455de 1142 int on;
e6a5e1b7 1143
1a1455de
TI
1144 if (!spec->automute)
1145 on = 0;
1146 else
1147 on = spec->jack_present | spec->line_jack_present;
1148 on |= spec->master_mute;
e6a5e1b7 1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1150 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1151
1152 /* toggle line-out mutes if needed, too */
1a1455de
TI
1153 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1154 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1155 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1156 return;
1a1455de
TI
1157 if (!spec->automute_lines || !spec->automute)
1158 on = 0;
1159 else
1160 on = spec->jack_present;
1161 on |= spec->master_mute;
e6a5e1b7 1162 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1163 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1164}
1165
1166static void alc_hp_automute(struct hda_codec *codec)
1167{
1168 struct alc_spec *spec = codec->spec;
1169
1170 if (!spec->automute)
1171 return;
1172 spec->jack_present =
1173 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1174 spec->autocfg.hp_pins);
1175 update_speakers(codec);
1176}
1177
1178static void alc_line_automute(struct hda_codec *codec)
1179{
1180 struct alc_spec *spec = codec->spec;
1181
1182 if (!spec->automute || !spec->detect_line)
1183 return;
1184 spec->line_jack_present =
1185 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1186 spec->autocfg.line_out_pins);
1187 update_speakers(codec);
1188}
1189
6c819492
TI
1190static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1191 hda_nid_t nid)
1192{
1193 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1194 int i, nums;
1195
1196 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1197 for (i = 0; i < nums; i++)
1198 if (conn[i] == nid)
1199 return i;
1200 return -1;
1201}
1202
840b64c0
TI
1203/* switch the current ADC according to the jack state */
1204static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1205{
1206 struct alc_spec *spec = codec->spec;
1207 unsigned int present;
1208 hda_nid_t new_adc;
1209
1210 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1211 if (present)
1212 spec->cur_adc_idx = 1;
1213 else
1214 spec->cur_adc_idx = 0;
1215 new_adc = spec->adc_nids[spec->cur_adc_idx];
1216 if (spec->cur_adc && spec->cur_adc != new_adc) {
1217 /* stream is running, let's swap the current ADC */
f0cea797 1218 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1219 spec->cur_adc = new_adc;
1220 snd_hda_codec_setup_stream(codec, new_adc,
1221 spec->cur_adc_stream_tag, 0,
1222 spec->cur_adc_format);
1223 }
1224}
1225
7fb0d78f
KY
1226static void alc_mic_automute(struct hda_codec *codec)
1227{
1228 struct alc_spec *spec = codec->spec;
8ed99d97 1229 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1230 unsigned int present, type;
1231 hda_nid_t cap_nid;
1232
b59bdf3b
TI
1233 if (!spec->auto_mic)
1234 return;
6c819492
TI
1235 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1236 return;
1237 if (snd_BUG_ON(!spec->adc_nids))
1238 return;
1239
840b64c0
TI
1240 if (spec->dual_adc_switch) {
1241 alc_dual_mic_adc_auto_switch(codec);
1242 return;
1243 }
1244
6c819492
TI
1245 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1246
8ed99d97
TI
1247 alive = &spec->int_mic;
1248 dead1 = &spec->ext_mic;
1249 dead2 = &spec->dock_mic;
1250
864f92be 1251 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1252 if (present) {
1253 alive = &spec->ext_mic;
8ed99d97
TI
1254 dead1 = &spec->int_mic;
1255 dead2 = &spec->dock_mic;
1256 }
1257 if (!present && spec->dock_mic.pin > 0) {
1258 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1259 if (present) {
1260 alive = &spec->dock_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->ext_mic;
1263 }
1264 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
6c819492
TI
1265 }
1266
6c819492
TI
1267 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1268 if (type == AC_WID_AUD_MIX) {
1269 /* Matrix-mixer style (e.g. ALC882) */
1270 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1271 alive->mux_idx,
1272 HDA_AMP_MUTE, 0);
8ed99d97
TI
1273 if (dead1->pin > 0)
1274 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1275 dead1->mux_idx,
1276 HDA_AMP_MUTE, HDA_AMP_MUTE);
1277 if (dead2->pin > 0)
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 dead2->mux_idx,
1280 HDA_AMP_MUTE, HDA_AMP_MUTE);
6c819492
TI
1281 } else {
1282 /* MUX style (e.g. ALC880) */
1283 snd_hda_codec_write_cache(codec, cap_nid, 0,
1284 AC_VERB_SET_CONNECT_SEL,
1285 alive->mux_idx);
1286 }
cd372fb3 1287 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1288
1289 /* FIXME: analog mixer */
7fb0d78f
KY
1290}
1291
c9b58006
KY
1292/* unsolicited event for HP jack sensing */
1293static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1294{
1295 if (codec->vendor_id == 0x10ec0880)
1296 res >>= 28;
1297 else
1298 res >>= 26;
a9fd4f3f
TI
1299 switch (res) {
1300 case ALC880_HP_EVENT:
d922b51d 1301 alc_hp_automute(codec);
a9fd4f3f 1302 break;
e6a5e1b7
TI
1303 case ALC880_FRONT_EVENT:
1304 alc_line_automute(codec);
1305 break;
a9fd4f3f 1306 case ALC880_MIC_EVENT:
7fb0d78f 1307 alc_mic_automute(codec);
a9fd4f3f
TI
1308 break;
1309 }
7fb0d78f
KY
1310}
1311
1312static void alc_inithook(struct hda_codec *codec)
1313{
d922b51d 1314 alc_hp_automute(codec);
e6a5e1b7 1315 alc_line_automute(codec);
7fb0d78f 1316 alc_mic_automute(codec);
c9b58006
KY
1317}
1318
f9423e7a
KY
1319/* additional initialization for ALC888 variants */
1320static void alc888_coef_init(struct hda_codec *codec)
1321{
1322 unsigned int tmp;
1323
1324 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1325 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1326 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1327 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1328 /* alc888S-VC */
1329 snd_hda_codec_read(codec, 0x20, 0,
1330 AC_VERB_SET_PROC_COEF, 0x830);
1331 else
1332 /* alc888-VB */
1333 snd_hda_codec_read(codec, 0x20, 0,
1334 AC_VERB_SET_PROC_COEF, 0x3030);
1335}
1336
87a8c370
JK
1337static void alc889_coef_init(struct hda_codec *codec)
1338{
1339 unsigned int tmp;
1340
1341 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1342 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1343 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1344 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1345}
1346
3fb4a508
TI
1347/* turn on/off EAPD control (only if available) */
1348static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1349{
1350 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1351 return;
1352 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1353 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1354 on ? 2 : 0);
1355}
1356
691f1fcc
TI
1357/* turn on/off EAPD controls of the codec */
1358static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1359{
1360 /* We currently only handle front, HP */
1361 switch (codec->vendor_id) {
1362 case 0x10ec0260:
1363 set_eapd(codec, 0x0f, on);
1364 set_eapd(codec, 0x10, on);
1365 break;
1366 case 0x10ec0262:
1367 case 0x10ec0267:
1368 case 0x10ec0268:
1369 case 0x10ec0269:
1370 case 0x10ec0270:
1371 case 0x10ec0272:
1372 case 0x10ec0660:
1373 case 0x10ec0662:
1374 case 0x10ec0663:
1375 case 0x10ec0665:
1376 case 0x10ec0862:
1377 case 0x10ec0889:
1378 case 0x10ec0892:
1379 set_eapd(codec, 0x14, on);
1380 set_eapd(codec, 0x15, on);
1381 break;
1382 }
1383}
1384
1c716153
TI
1385/* generic shutup callback;
1386 * just turning off EPAD and a little pause for avoiding pop-noise
1387 */
1388static void alc_eapd_shutup(struct hda_codec *codec)
1389{
1390 alc_auto_setup_eapd(codec, false);
1391 msleep(200);
1392}
1393
4a79ba34 1394static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1395{
4a79ba34 1396 unsigned int tmp;
bc9f98a9 1397
4a79ba34
TI
1398 switch (type) {
1399 case ALC_INIT_GPIO1:
bc9f98a9
KY
1400 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1401 break;
4a79ba34 1402 case ALC_INIT_GPIO2:
bc9f98a9
KY
1403 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1404 break;
4a79ba34 1405 case ALC_INIT_GPIO3:
bdd148a3
KY
1406 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1407 break;
4a79ba34 1408 case ALC_INIT_DEFAULT:
691f1fcc 1409 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1410 switch (codec->vendor_id) {
1411 case 0x10ec0260:
1412 snd_hda_codec_write(codec, 0x1a, 0,
1413 AC_VERB_SET_COEF_INDEX, 7);
1414 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1415 AC_VERB_GET_PROC_COEF, 0);
1416 snd_hda_codec_write(codec, 0x1a, 0,
1417 AC_VERB_SET_COEF_INDEX, 7);
1418 snd_hda_codec_write(codec, 0x1a, 0,
1419 AC_VERB_SET_PROC_COEF,
1420 tmp | 0x2010);
1421 break;
1422 case 0x10ec0262:
1423 case 0x10ec0880:
1424 case 0x10ec0882:
1425 case 0x10ec0883:
1426 case 0x10ec0885:
4a5a4c56 1427 case 0x10ec0887:
20b67ddd 1428 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1429 alc889_coef_init(codec);
c9b58006 1430 break;
f9423e7a 1431 case 0x10ec0888:
4a79ba34 1432 alc888_coef_init(codec);
f9423e7a 1433 break;
0aea778e 1434#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1435 case 0x10ec0267:
1436 case 0x10ec0268:
1437 snd_hda_codec_write(codec, 0x20, 0,
1438 AC_VERB_SET_COEF_INDEX, 7);
1439 tmp = snd_hda_codec_read(codec, 0x20, 0,
1440 AC_VERB_GET_PROC_COEF, 0);
1441 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1442 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1443 snd_hda_codec_write(codec, 0x20, 0,
1444 AC_VERB_SET_PROC_COEF,
1445 tmp | 0x3000);
1446 break;
0aea778e 1447#endif /* XXX */
bc9f98a9 1448 }
4a79ba34
TI
1449 break;
1450 }
1451}
1452
1a1455de
TI
1453static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1454 struct snd_ctl_elem_info *uinfo)
1455{
ae8a60a5
TI
1456 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1457 struct alc_spec *spec = codec->spec;
1458 static const char * const texts2[] = {
1459 "Disabled", "Enabled"
1460 };
1461 static const char * const texts3[] = {
1a1455de
TI
1462 "Disabled", "Speaker Only", "Line-Out+Speaker"
1463 };
ae8a60a5 1464 const char * const *texts;
1a1455de
TI
1465
1466 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1467 uinfo->count = 1;
ae8a60a5
TI
1468 if (spec->automute_hp_lo) {
1469 uinfo->value.enumerated.items = 3;
1470 texts = texts3;
1471 } else {
1472 uinfo->value.enumerated.items = 2;
1473 texts = texts2;
1474 }
1475 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1476 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1477 strcpy(uinfo->value.enumerated.name,
1478 texts[uinfo->value.enumerated.item]);
1479 return 0;
1480}
1481
1482static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1483 struct snd_ctl_elem_value *ucontrol)
1484{
1485 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1486 struct alc_spec *spec = codec->spec;
1487 unsigned int val;
1488 if (!spec->automute)
1489 val = 0;
1490 else if (!spec->automute_lines)
1491 val = 1;
1492 else
1493 val = 2;
1494 ucontrol->value.enumerated.item[0] = val;
1495 return 0;
1496}
1497
1498static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1499 struct snd_ctl_elem_value *ucontrol)
1500{
1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1502 struct alc_spec *spec = codec->spec;
1503
1504 switch (ucontrol->value.enumerated.item[0]) {
1505 case 0:
1506 if (!spec->automute)
1507 return 0;
1508 spec->automute = 0;
1509 break;
1510 case 1:
1511 if (spec->automute && !spec->automute_lines)
1512 return 0;
1513 spec->automute = 1;
1514 spec->automute_lines = 0;
1515 break;
1516 case 2:
ae8a60a5
TI
1517 if (!spec->automute_hp_lo)
1518 return -EINVAL;
1a1455de
TI
1519 if (spec->automute && spec->automute_lines)
1520 return 0;
1521 spec->automute = 1;
1522 spec->automute_lines = 1;
1523 break;
1524 default:
1525 return -EINVAL;
1526 }
1527 update_speakers(codec);
1528 return 1;
1529}
1530
a9111321 1531static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1533 .name = "Auto-Mute Mode",
1534 .info = alc_automute_mode_info,
1535 .get = alc_automute_mode_get,
1536 .put = alc_automute_mode_put,
1537};
1538
1539static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1540
1541static int alc_add_automute_mode_enum(struct hda_codec *codec)
1542{
1543 struct alc_spec *spec = codec->spec;
1544 struct snd_kcontrol_new *knew;
1545
1546 knew = alc_kcontrol_new(spec);
1547 if (!knew)
1548 return -ENOMEM;
1549 *knew = alc_automute_mode_enum;
1550 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1551 if (!knew->name)
1552 return -ENOMEM;
1553 return 0;
1554}
1555
4a79ba34
TI
1556static void alc_init_auto_hp(struct hda_codec *codec)
1557{
1558 struct alc_spec *spec = codec->spec;
bb35febd 1559 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1560 int present = 0;
bb35febd 1561 int i;
4a79ba34 1562
1daf5f46
TI
1563 if (cfg->hp_pins[0])
1564 present++;
1565 if (cfg->line_out_pins[0])
1566 present++;
1567 if (cfg->speaker_pins[0])
1568 present++;
1569 if (present < 2) /* need two different output types */
1570 return;
ae8a60a5
TI
1571 if (present == 3)
1572 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1573
bb35febd 1574 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1575 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1576 sizeof(cfg->speaker_pins));
1577 cfg->speaker_outs = cfg->line_outs;
1578 }
1579
1580 if (!cfg->hp_pins[0]) {
1581 memcpy(cfg->hp_pins, cfg->line_out_pins,
1582 sizeof(cfg->hp_pins));
1583 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1584 }
1585
bb35febd 1586 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1587 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1588 if (!is_jack_detectable(codec, nid))
1a1455de 1589 continue;
bb35febd 1590 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1591 nid);
1592 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1593 AC_VERB_SET_UNSOLICITED_ENABLE,
1594 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1595 spec->automute = 1;
1596 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1597 }
1a1455de
TI
1598 if (spec->automute && cfg->line_out_pins[0] &&
1599 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1600 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1601 for (i = 0; i < cfg->line_outs; i++) {
1602 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1603 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1604 continue;
1605 snd_printdd("realtek: Enable Line-Out auto-muting "
1606 "on NID 0x%x\n", nid);
1607 snd_hda_codec_write_cache(codec, nid, 0,
1608 AC_VERB_SET_UNSOLICITED_ENABLE,
1609 AC_USRSP_EN | ALC880_FRONT_EVENT);
1610 spec->detect_line = 1;
1611 }
52d3cb88 1612 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1613 }
1614
1615 if (spec->automute) {
1a1455de
TI
1616 /* create a control for automute mode */
1617 alc_add_automute_mode_enum(codec);
ae8a60a5 1618 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1619 }
4a79ba34
TI
1620}
1621
6c819492
TI
1622static void alc_init_auto_mic(struct hda_codec *codec)
1623{
1624 struct alc_spec *spec = codec->spec;
1625 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1626 hda_nid_t fixed, ext, dock;
6c819492
TI
1627 int i;
1628
8ed99d97 1629 fixed = ext = dock = 0;
66ceeb6b
TI
1630 for (i = 0; i < cfg->num_inputs; i++) {
1631 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1632 unsigned int defcfg;
6c819492 1633 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1634 switch (snd_hda_get_input_pin_attr(defcfg)) {
1635 case INPUT_PIN_ATTR_INT:
6c819492
TI
1636 if (fixed)
1637 return; /* already occupied */
8ed99d97
TI
1638 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1639 return; /* invalid type */
6c819492
TI
1640 fixed = nid;
1641 break;
99ae28be
TI
1642 case INPUT_PIN_ATTR_UNUSED:
1643 return; /* invalid entry */
8ed99d97
TI
1644 case INPUT_PIN_ATTR_DOCK:
1645 if (dock)
1646 return; /* already occupied */
1647 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1648 return; /* invalid type */
1649 dock = nid;
1650 break;
99ae28be 1651 default:
6c819492
TI
1652 if (ext)
1653 return; /* already occupied */
8ed99d97
TI
1654 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1655 return; /* invalid type */
6c819492
TI
1656 ext = nid;
1657 break;
6c819492
TI
1658 }
1659 }
8ed99d97
TI
1660 if (!ext && dock) {
1661 ext = dock;
1662 dock = 0;
1663 }
eaa9b3a7
TI
1664 if (!ext || !fixed)
1665 return;
e35d9d6a 1666 if (!is_jack_detectable(codec, ext))
6c819492 1667 return; /* no unsol support */
8ed99d97
TI
1668 if (dock && !is_jack_detectable(codec, dock))
1669 return; /* no unsol support */
1670 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1671 ext, fixed, dock);
6c819492 1672 spec->ext_mic.pin = ext;
8ed99d97 1673 spec->dock_mic.pin = dock;
6c819492
TI
1674 spec->int_mic.pin = fixed;
1675 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1676 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1677 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1678 spec->auto_mic = 1;
1679 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1680 AC_VERB_SET_UNSOLICITED_ENABLE,
1681 AC_USRSP_EN | ALC880_MIC_EVENT);
1682 spec->unsol_event = alc_sku_unsol_event;
1683}
1684
90622917
DH
1685/* Could be any non-zero and even value. When used as fixup, tells
1686 * the driver to ignore any present sku defines.
1687 */
1688#define ALC_FIXUP_SKU_IGNORE (2)
1689
da00c244
KY
1690static int alc_auto_parse_customize_define(struct hda_codec *codec)
1691{
1692 unsigned int ass, tmp, i;
7fb56223 1693 unsigned nid = 0;
da00c244
KY
1694 struct alc_spec *spec = codec->spec;
1695
b6cbe517
TI
1696 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1697
90622917
DH
1698 if (spec->cdefine.fixup) {
1699 ass = spec->cdefine.sku_cfg;
1700 if (ass == ALC_FIXUP_SKU_IGNORE)
1701 return -1;
1702 goto do_sku;
1703 }
1704
da00c244 1705 ass = codec->subsystem_id & 0xffff;
b6cbe517 1706 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1707 goto do_sku;
1708
1709 nid = 0x1d;
1710 if (codec->vendor_id == 0x10ec0260)
1711 nid = 0x17;
1712 ass = snd_hda_codec_get_pincfg(codec, nid);
1713
1714 if (!(ass & 1)) {
1715 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1716 codec->chip_name, ass);
1717 return -1;
1718 }
1719
1720 /* check sum */
1721 tmp = 0;
1722 for (i = 1; i < 16; i++) {
1723 if ((ass >> i) & 1)
1724 tmp++;
1725 }
1726 if (((ass >> 16) & 0xf) != tmp)
1727 return -1;
1728
1729 spec->cdefine.port_connectivity = ass >> 30;
1730 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1731 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1732 spec->cdefine.customization = ass >> 8;
1733do_sku:
1734 spec->cdefine.sku_cfg = ass;
1735 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1736 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1737 spec->cdefine.swap = (ass & 0x2) >> 1;
1738 spec->cdefine.override = ass & 0x1;
1739
1740 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1741 nid, spec->cdefine.sku_cfg);
1742 snd_printd("SKU: port_connectivity=0x%x\n",
1743 spec->cdefine.port_connectivity);
1744 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1745 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1746 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1747 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1748 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1749 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1750 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1751
1752 return 0;
1753}
1754
4a79ba34
TI
1755/* check subsystem ID and set up device-specific initialization;
1756 * return 1 if initialized, 0 if invalid SSID
1757 */
1758/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1759 * 31 ~ 16 : Manufacture ID
1760 * 15 ~ 8 : SKU ID
1761 * 7 ~ 0 : Assembly ID
1762 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1763 */
1764static int alc_subsystem_id(struct hda_codec *codec,
1765 hda_nid_t porta, hda_nid_t porte,
6227cdce 1766 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1767{
1768 unsigned int ass, tmp, i;
1769 unsigned nid;
1770 struct alc_spec *spec = codec->spec;
1771
90622917
DH
1772 if (spec->cdefine.fixup) {
1773 ass = spec->cdefine.sku_cfg;
1774 if (ass == ALC_FIXUP_SKU_IGNORE)
1775 return 0;
1776 goto do_sku;
1777 }
1778
4a79ba34
TI
1779 ass = codec->subsystem_id & 0xffff;
1780 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1781 goto do_sku;
1782
1783 /* invalid SSID, check the special NID pin defcfg instead */
1784 /*
def319f9 1785 * 31~30 : port connectivity
4a79ba34
TI
1786 * 29~21 : reserve
1787 * 20 : PCBEEP input
1788 * 19~16 : Check sum (15:1)
1789 * 15~1 : Custom
1790 * 0 : override
1791 */
1792 nid = 0x1d;
1793 if (codec->vendor_id == 0x10ec0260)
1794 nid = 0x17;
1795 ass = snd_hda_codec_get_pincfg(codec, nid);
1796 snd_printd("realtek: No valid SSID, "
1797 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1798 ass, nid);
6227cdce 1799 if (!(ass & 1))
4a79ba34
TI
1800 return 0;
1801 if ((ass >> 30) != 1) /* no physical connection */
1802 return 0;
1803
1804 /* check sum */
1805 tmp = 0;
1806 for (i = 1; i < 16; i++) {
1807 if ((ass >> i) & 1)
1808 tmp++;
1809 }
1810 if (((ass >> 16) & 0xf) != tmp)
1811 return 0;
1812do_sku:
1813 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1814 ass & 0xffff, codec->vendor_id);
1815 /*
1816 * 0 : override
1817 * 1 : Swap Jack
1818 * 2 : 0 --> Desktop, 1 --> Laptop
1819 * 3~5 : External Amplifier control
1820 * 7~6 : Reserved
1821 */
1822 tmp = (ass & 0x38) >> 3; /* external Amp control */
1823 switch (tmp) {
1824 case 1:
1825 spec->init_amp = ALC_INIT_GPIO1;
1826 break;
1827 case 3:
1828 spec->init_amp = ALC_INIT_GPIO2;
1829 break;
1830 case 7:
1831 spec->init_amp = ALC_INIT_GPIO3;
1832 break;
1833 case 5:
5a8cfb4e 1834 default:
4a79ba34 1835 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1836 break;
1837 }
ea1fb29a 1838
8c427226 1839 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1840 * when the external headphone out jack is plugged"
1841 */
8c427226 1842 if (!(ass & 0x8000))
4a79ba34 1843 return 1;
c9b58006
KY
1844 /*
1845 * 10~8 : Jack location
1846 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1847 * 14~13: Resvered
1848 * 15 : 1 --> enable the function "Mute internal speaker
1849 * when the external headphone out jack is plugged"
1850 */
c9b58006 1851 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1852 hda_nid_t nid;
c9b58006
KY
1853 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1854 if (tmp == 0)
01d4825d 1855 nid = porta;
c9b58006 1856 else if (tmp == 1)
01d4825d 1857 nid = porte;
c9b58006 1858 else if (tmp == 2)
01d4825d 1859 nid = portd;
6227cdce
KY
1860 else if (tmp == 3)
1861 nid = porti;
c9b58006 1862 else
4a79ba34 1863 return 1;
01d4825d
TI
1864 for (i = 0; i < spec->autocfg.line_outs; i++)
1865 if (spec->autocfg.line_out_pins[i] == nid)
1866 return 1;
1867 spec->autocfg.hp_pins[0] = nid;
c9b58006 1868 }
4a79ba34
TI
1869 return 1;
1870}
ea1fb29a 1871
4a79ba34 1872static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1873 hda_nid_t porta, hda_nid_t porte,
1874 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1875{
6227cdce 1876 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1877 struct alc_spec *spec = codec->spec;
1878 snd_printd("realtek: "
1879 "Enable default setup for auto mode as fallback\n");
1880 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1881 }
1a1455de
TI
1882
1883 alc_init_auto_hp(codec);
1884 alc_init_auto_mic(codec);
bc9f98a9
KY
1885}
1886
f95474ec 1887/*
f8f25ba3 1888 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1889 */
1890
1891struct alc_pincfg {
1892 hda_nid_t nid;
1893 u32 val;
1894};
1895
e1eb5f10
TB
1896struct alc_model_fixup {
1897 const int id;
1898 const char *name;
1899};
1900
f8f25ba3 1901struct alc_fixup {
b5bfbc67 1902 int type;
361fe6e9
TI
1903 bool chained;
1904 int chain_id;
b5bfbc67
TI
1905 union {
1906 unsigned int sku;
1907 const struct alc_pincfg *pins;
1908 const struct hda_verb *verbs;
1909 void (*func)(struct hda_codec *codec,
1910 const struct alc_fixup *fix,
1911 int action);
1912 } v;
f8f25ba3
TI
1913};
1914
b5bfbc67
TI
1915enum {
1916 ALC_FIXUP_INVALID,
1917 ALC_FIXUP_SKU,
1918 ALC_FIXUP_PINS,
1919 ALC_FIXUP_VERBS,
1920 ALC_FIXUP_FUNC,
1921};
1922
1923enum {
1924 ALC_FIXUP_ACT_PRE_PROBE,
1925 ALC_FIXUP_ACT_PROBE,
58701120 1926 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1927};
1928
1929static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1930{
b5bfbc67
TI
1931 struct alc_spec *spec = codec->spec;
1932 int id = spec->fixup_id;
aa1d0c52 1933#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1934 const char *modelname = spec->fixup_name;
aa1d0c52 1935#endif
b5bfbc67 1936 int depth = 0;
f95474ec 1937
b5bfbc67
TI
1938 if (!spec->fixup_list)
1939 return;
1940
1941 while (id >= 0) {
1942 const struct alc_fixup *fix = spec->fixup_list + id;
1943 const struct alc_pincfg *cfg;
1944
1945 switch (fix->type) {
1946 case ALC_FIXUP_SKU:
1947 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1948 break;;
1949 snd_printdd(KERN_INFO "hda_codec: %s: "
1950 "Apply sku override for %s\n",
1951 codec->chip_name, modelname);
1952 spec->cdefine.sku_cfg = fix->v.sku;
1953 spec->cdefine.fixup = 1;
1954 break;
1955 case ALC_FIXUP_PINS:
1956 cfg = fix->v.pins;
1957 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1958 break;
1959 snd_printdd(KERN_INFO "hda_codec: %s: "
1960 "Apply pincfg for %s\n",
1961 codec->chip_name, modelname);
1962 for (; cfg->nid; cfg++)
1963 snd_hda_codec_set_pincfg(codec, cfg->nid,
1964 cfg->val);
1965 break;
1966 case ALC_FIXUP_VERBS:
1967 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1968 break;
1969 snd_printdd(KERN_INFO "hda_codec: %s: "
1970 "Apply fix-verbs for %s\n",
1971 codec->chip_name, modelname);
1972 add_verb(codec->spec, fix->v.verbs);
1973 break;
1974 case ALC_FIXUP_FUNC:
1975 if (!fix->v.func)
1976 break;
1977 snd_printdd(KERN_INFO "hda_codec: %s: "
1978 "Apply fix-func for %s\n",
1979 codec->chip_name, modelname);
1980 fix->v.func(codec, fix, action);
1981 break;
1982 default:
1983 snd_printk(KERN_ERR "hda_codec: %s: "
1984 "Invalid fixup type %d\n",
1985 codec->chip_name, fix->type);
1986 break;
1987 }
24af2b1c 1988 if (!fix->chained)
b5bfbc67
TI
1989 break;
1990 if (++depth > 10)
1991 break;
24af2b1c 1992 id = fix->chain_id;
9d57883f 1993 }
f95474ec
TI
1994}
1995
e1eb5f10 1996static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1997 const struct alc_model_fixup *models,
1998 const struct snd_pci_quirk *quirk,
1999 const struct alc_fixup *fixlist)
e1eb5f10 2000{
b5bfbc67
TI
2001 struct alc_spec *spec = codec->spec;
2002 int id = -1;
2003 const char *name = NULL;
e1eb5f10 2004
e1eb5f10
TB
2005 if (codec->modelname && models) {
2006 while (models->name) {
2007 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2008 id = models->id;
2009 name = models->name;
e1eb5f10
TB
2010 break;
2011 }
2012 models++;
2013 }
b5bfbc67
TI
2014 }
2015 if (id < 0) {
2016 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2017 if (quirk) {
2018 id = quirk->value;
2019#ifdef CONFIG_SND_DEBUG_VERBOSE
2020 name = quirk->name;
2021#endif
2022 }
2023 }
2024
2025 spec->fixup_id = id;
2026 if (id >= 0) {
2027 spec->fixup_list = fixlist;
2028 spec->fixup_name = name;
e1eb5f10 2029 }
f95474ec
TI
2030}
2031
274693f3
KY
2032static int alc_read_coef_idx(struct hda_codec *codec,
2033 unsigned int coef_idx)
2034{
2035 unsigned int val;
2036 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2037 coef_idx);
2038 val = snd_hda_codec_read(codec, 0x20, 0,
2039 AC_VERB_GET_PROC_COEF, 0);
2040 return val;
2041}
2042
977ddd6b
KY
2043static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2044 unsigned int coef_val)
2045{
2046 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2047 coef_idx);
2048 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2049 coef_val);
2050}
2051
757899ac
TI
2052/* set right pin controls for digital I/O */
2053static void alc_auto_init_digital(struct hda_codec *codec)
2054{
2055 struct alc_spec *spec = codec->spec;
2056 int i;
2057 hda_nid_t pin;
2058
2059 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2060 pin = spec->autocfg.dig_out_pins[i];
2061 if (pin) {
2062 snd_hda_codec_write(codec, pin, 0,
2063 AC_VERB_SET_PIN_WIDGET_CONTROL,
2064 PIN_OUT);
2065 }
2066 }
2067 pin = spec->autocfg.dig_in_pin;
2068 if (pin)
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2071 PIN_IN);
2072}
2073
2074/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2075static void alc_auto_parse_digital(struct hda_codec *codec)
2076{
2077 struct alc_spec *spec = codec->spec;
2078 int i, err;
2079 hda_nid_t dig_nid;
2080
2081 /* support multiple SPDIFs; the secondary is set up as a slave */
2082 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2083 err = snd_hda_get_connections(codec,
2084 spec->autocfg.dig_out_pins[i],
2085 &dig_nid, 1);
2086 if (err < 0)
2087 continue;
2088 if (!i) {
2089 spec->multiout.dig_out_nid = dig_nid;
2090 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2091 } else {
2092 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2093 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2094 break;
2095 spec->slave_dig_outs[i - 1] = dig_nid;
2096 }
2097 }
2098
2099 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2100 dig_nid = codec->start_nid;
2101 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2102 unsigned int wcaps = get_wcaps(codec, dig_nid);
2103 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2104 continue;
2105 if (!(wcaps & AC_WCAP_DIGITAL))
2106 continue;
2107 if (!(wcaps & AC_WCAP_CONN_LIST))
2108 continue;
2109 err = get_connection_index(codec, dig_nid,
2110 spec->autocfg.dig_in_pin);
2111 if (err >= 0) {
2112 spec->dig_in_nid = dig_nid;
2113 break;
2114 }
2115 }
757899ac
TI
2116 }
2117}
2118
ef8ef5fb
VP
2119/*
2120 * ALC888
2121 */
2122
2123/*
2124 * 2ch mode
2125 */
a9111321 2126static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2127/* Mic-in jack as mic in */
2128 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2129 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2130/* Line-in jack as Line in */
2131 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2132 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2133/* Line-Out as Front */
2134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2135 { } /* end */
2136};
2137
2138/*
2139 * 4ch mode
2140 */
a9111321 2141static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2142/* Mic-in jack as mic in */
2143 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2144 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2145/* Line-in jack as Surround */
2146 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2147 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2148/* Line-Out as Front */
2149 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2150 { } /* end */
2151};
2152
2153/*
2154 * 6ch mode
2155 */
a9111321 2156static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2157/* Mic-in jack as CLFE */
2158 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2159 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2160/* Line-in jack as Surround */
2161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2163/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2164 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2165 { } /* end */
2166};
2167
2168/*
2169 * 8ch mode
2170 */
a9111321 2171static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2172/* Mic-in jack as CLFE */
2173 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2174 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2175/* Line-in jack as Surround */
2176 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2177 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2178/* Line-Out as Side */
2179 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2180 { } /* end */
2181};
2182
a9111321 2183static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2184 { 2, alc888_4ST_ch2_intel_init },
2185 { 4, alc888_4ST_ch4_intel_init },
2186 { 6, alc888_4ST_ch6_intel_init },
2187 { 8, alc888_4ST_ch8_intel_init },
2188};
2189
2190/*
2191 * ALC888 Fujitsu Siemens Amillo xa3530
2192 */
2193
a9111321 2194static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2195/* Front Mic: set to PIN_IN (empty by default) */
2196 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2197/* Connect Internal HP to Front */
2198 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2199 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2200 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2201/* Connect Bass HP to Front */
2202 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2203 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2204 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2205/* Connect Line-Out side jack (SPDIF) to Side */
2206 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2207 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2208 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2209/* Connect Mic jack to CLFE */
2210 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2211 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2212 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2213/* Connect Line-in jack to Surround */
2214 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2215 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2216 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2217/* Connect HP out jack to Front */
2218 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2219 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2220 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2221/* Enable unsolicited event for HP jack and Line-out jack */
2222 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2223 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2224 {}
2225};
2226
4f5d1706 2227static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2228{
2229 struct alc_spec *spec = codec->spec;
2230
2231 spec->autocfg.hp_pins[0] = 0x15;
2232 spec->autocfg.speaker_pins[0] = 0x14;
2233 spec->autocfg.speaker_pins[1] = 0x16;
2234 spec->autocfg.speaker_pins[2] = 0x17;
2235 spec->autocfg.speaker_pins[3] = 0x19;
2236 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2237 spec->automute = 1;
2238 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2239}
2240
2241static void alc889_intel_init_hook(struct hda_codec *codec)
2242{
2243 alc889_coef_init(codec);
d922b51d 2244 alc_hp_automute(codec);
6732bd0d
WF
2245}
2246
4f5d1706 2247static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2248{
2249 struct alc_spec *spec = codec->spec;
2250
2251 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2252 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2253 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2254 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2255 spec->automute = 1;
2256 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2257}
ef8ef5fb 2258
5b2d1eca
VP
2259/*
2260 * ALC888 Acer Aspire 4930G model
2261 */
2262
a9111321 2263static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2264/* Front Mic: set to PIN_IN (empty by default) */
2265 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2266/* Unselect Front Mic by default in input mixer 3 */
2267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2268/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2270/* Connect Internal HP to front */
2271 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2272 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2273 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2274/* Connect HP out to front */
2275 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2276 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2277 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2278 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2279 { }
2280};
2281
d2fd4b09
TV
2282/*
2283 * ALC888 Acer Aspire 6530G model
2284 */
2285
a9111321 2286static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2287/* Route to built-in subwoofer as well as speakers */
2288 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2289 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2290 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2291 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2292/* Bias voltage on for external mic port */
2293 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2294/* Front Mic: set to PIN_IN (empty by default) */
2295 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2296/* Unselect Front Mic by default in input mixer 3 */
2297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2298/* Enable unsolicited event for HP jack */
2299 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2300/* Enable speaker output */
2301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2302 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2303 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2304/* Enable headphone output */
2305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2306 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2307 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2308 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2309 { }
2310};
2311
d9477207
DK
2312/*
2313 *ALC888 Acer Aspire 7730G model
2314 */
2315
a9111321 2316static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2317/* Bias voltage on for external mic port */
2318 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2319/* Front Mic: set to PIN_IN (empty by default) */
2320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2321/* Unselect Front Mic by default in input mixer 3 */
2322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2323/* Enable unsolicited event for HP jack */
2324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2325/* Enable speaker output */
2326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2328 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329/* Enable headphone output */
2330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2333 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2334/*Enable internal subwoofer */
2335 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2338 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2339 { }
2340};
2341
3b315d70 2342/*
018df418 2343 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2344 */
2345
a9111321 2346static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2347/* Front Mic: set to PIN_IN (empty by default) */
2348 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2349/* Unselect Front Mic by default in input mixer 3 */
2350 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2351/* Enable unsolicited event for HP jack */
2352 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2353/* Connect Internal Front to Front */
2354 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2355 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2356 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2357/* Connect Internal Rear to Rear */
2358 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2359 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2360 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2361/* Connect Internal CLFE to CLFE */
2362 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2363 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2364 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2365/* Connect HP out to Front */
018df418 2366 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2367 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2368 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2369/* Enable all DACs */
2370/* DAC DISABLE/MUTE 1? */
2371/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2372 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2373 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2374/* DAC DISABLE/MUTE 2? */
2375/* some bit here disables the other DACs. Init=0x4900 */
2376 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2377 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2378/* DMIC fix
2379 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2380 * which makes the stereo useless. However, either the mic or the ALC889
2381 * makes the signal become a difference/sum signal instead of standard
2382 * stereo, which is annoying. So instead we flip this bit which makes the
2383 * codec replicate the sum signal to both channels, turning it into a
2384 * normal mono mic.
2385 */
2386/* DMIC_CONTROL? Init value = 0x0001 */
2387 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2388 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2389 { }
2390};
2391
a9111321 2392static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2393 /* Front mic only available on one ADC */
2394 {
2395 .num_items = 4,
2396 .items = {
2397 { "Mic", 0x0 },
2398 { "Line", 0x2 },
2399 { "CD", 0x4 },
2400 { "Front Mic", 0xb },
2401 },
2402 },
2403 {
2404 .num_items = 3,
2405 .items = {
2406 { "Mic", 0x0 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 },
2410 }
2411};
2412
a9111321 2413static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2414 /* Interal mic only available on one ADC */
2415 {
684a8842 2416 .num_items = 5,
d2fd4b09 2417 .items = {
8607f7c4 2418 { "Mic", 0x0 },
684a8842 2419 { "Line In", 0x2 },
d2fd4b09 2420 { "CD", 0x4 },
684a8842 2421 { "Input Mix", 0xa },
28c4edb7 2422 { "Internal Mic", 0xb },
d2fd4b09
TV
2423 },
2424 },
2425 {
684a8842 2426 .num_items = 4,
d2fd4b09 2427 .items = {
8607f7c4 2428 { "Mic", 0x0 },
684a8842 2429 { "Line In", 0x2 },
d2fd4b09 2430 { "CD", 0x4 },
684a8842 2431 { "Input Mix", 0xa },
d2fd4b09
TV
2432 },
2433 }
2434};
2435
a9111321 2436static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2437 /* Digital mic only available on first "ADC" */
2438 {
2439 .num_items = 5,
2440 .items = {
2441 { "Mic", 0x0 },
2442 { "Line", 0x2 },
2443 { "CD", 0x4 },
2444 { "Front Mic", 0xb },
2445 { "Input Mix", 0xa },
2446 },
2447 },
2448 {
2449 .num_items = 4,
2450 .items = {
2451 { "Mic", 0x0 },
2452 { "Line", 0x2 },
2453 { "CD", 0x4 },
2454 { "Input Mix", 0xa },
2455 },
2456 },
2457 {
2458 .num_items = 4,
2459 .items = {
2460 { "Mic", 0x0 },
2461 { "Line", 0x2 },
2462 { "CD", 0x4 },
2463 { "Input Mix", 0xa },
2464 },
2465 }
2466};
2467
a9111321 2468static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2469 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2470 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2471 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2472 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2473 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2474 HDA_OUTPUT),
2475 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2476 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2477 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2481 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2484 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2485 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2486 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2487 { } /* end */
2488};
2489
a9111321 2490static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2491 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2492 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2494 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2495 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2496 HDA_OUTPUT),
786c51f9
ŁW
2497 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2498 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2502 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2503 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2505 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2507 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2508 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2509 { } /* end */
2510};
2511
a9111321 2512static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2513 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2514 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2516 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2518 HDA_OUTPUT),
2519 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2521 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2523 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2525 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2526 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2527 { } /* end */
2528};
2529
2530
4f5d1706 2531static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2532{
a9fd4f3f 2533 struct alc_spec *spec = codec->spec;
5b2d1eca 2534
a9fd4f3f
TI
2535 spec->autocfg.hp_pins[0] = 0x15;
2536 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2537 spec->autocfg.speaker_pins[1] = 0x16;
2538 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2539 spec->automute = 1;
2540 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2541}
2542
4f5d1706 2543static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2544{
2545 struct alc_spec *spec = codec->spec;
2546
2547 spec->autocfg.hp_pins[0] = 0x15;
2548 spec->autocfg.speaker_pins[0] = 0x14;
2549 spec->autocfg.speaker_pins[1] = 0x16;
2550 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2551 spec->automute = 1;
2552 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2553}
2554
d9477207
DK
2555static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2556{
2557 struct alc_spec *spec = codec->spec;
2558
2559 spec->autocfg.hp_pins[0] = 0x15;
2560 spec->autocfg.speaker_pins[0] = 0x14;
2561 spec->autocfg.speaker_pins[1] = 0x16;
2562 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2563 spec->automute = 1;
2564 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2565}
2566
4f5d1706 2567static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2568{
2569 struct alc_spec *spec = codec->spec;
2570
2571 spec->autocfg.hp_pins[0] = 0x15;
2572 spec->autocfg.speaker_pins[0] = 0x14;
2573 spec->autocfg.speaker_pins[1] = 0x16;
2574 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2575 spec->automute = 1;
2576 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2577}
2578
1da177e4 2579/*
e9edcee0
TI
2580 * ALC880 3-stack model
2581 *
2582 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2583 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2584 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2585 */
2586
4c6d72d1 2587static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2588 /* front, rear, clfe, rear_surr */
2589 0x02, 0x05, 0x04, 0x03
2590};
2591
4c6d72d1 2592static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2593 /* ADC0-2 */
2594 0x07, 0x08, 0x09,
2595};
2596
2597/* The datasheet says the node 0x07 is connected from inputs,
2598 * but it shows zero connection in the real implementation on some devices.
df694daa 2599 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2600 */
4c6d72d1 2601static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2602 /* ADC1-2 */
2603 0x08, 0x09,
2604};
2605
2606#define ALC880_DIGOUT_NID 0x06
2607#define ALC880_DIGIN_NID 0x0a
2608
a9111321 2609static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2610 .num_items = 4,
2611 .items = {
2612 { "Mic", 0x0 },
2613 { "Front Mic", 0x3 },
2614 { "Line", 0x2 },
2615 { "CD", 0x4 },
2616 },
2617};
2618
2619/* channel source setting (2/6 channel selection for 3-stack) */
2620/* 2ch mode */
a9111321 2621static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2622 /* set line-in to input, mute it */
2623 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2624 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2625 /* set mic-in to input vref 80%, mute it */
2626 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2627 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2628 { } /* end */
2629};
2630
2631/* 6ch mode */
a9111321 2632static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2633 /* set line-in to output, unmute it */
2634 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2635 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2636 /* set mic-in to output, unmute it */
2637 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2638 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2639 { } /* end */
2640};
2641
a9111321 2642static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2643 { 2, alc880_threestack_ch2_init },
2644 { 6, alc880_threestack_ch6_init },
2645};
2646
a9111321 2647static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2648 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2649 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2650 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2651 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2652 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2653 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2654 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2655 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2656 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2657 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2658 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2659 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2660 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2661 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2662 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2663 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2664 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2665 {
2666 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2667 .name = "Channel Mode",
df694daa
KY
2668 .info = alc_ch_mode_info,
2669 .get = alc_ch_mode_get,
2670 .put = alc_ch_mode_put,
e9edcee0
TI
2671 },
2672 { } /* end */
2673};
2674
2675/* capture mixer elements */
f9e336f6
TI
2676static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2677 struct snd_ctl_elem_info *uinfo)
2678{
2679 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2680 struct alc_spec *spec = codec->spec;
2681 int err;
1da177e4 2682
5a9e02e9 2683 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2684 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2685 HDA_INPUT);
2686 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2687 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2688 return err;
2689}
2690
2691static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2692 unsigned int size, unsigned int __user *tlv)
2693{
2694 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2695 struct alc_spec *spec = codec->spec;
2696 int err;
1da177e4 2697
5a9e02e9 2698 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2699 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2700 HDA_INPUT);
2701 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2702 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2703 return err;
2704}
2705
2706typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2707 struct snd_ctl_elem_value *ucontrol);
2708
2709static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2710 struct snd_ctl_elem_value *ucontrol,
2711 getput_call_t func)
2712{
2713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2714 struct alc_spec *spec = codec->spec;
2715 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2716 int err;
2717
5a9e02e9 2718 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2719 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2720 3, 0, HDA_INPUT);
2721 err = func(kcontrol, ucontrol);
5a9e02e9 2722 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2723 return err;
2724}
2725
2726static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_value *ucontrol)
2728{
2729 return alc_cap_getput_caller(kcontrol, ucontrol,
2730 snd_hda_mixer_amp_volume_get);
2731}
2732
2733static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2734 struct snd_ctl_elem_value *ucontrol)
2735{
2736 return alc_cap_getput_caller(kcontrol, ucontrol,
2737 snd_hda_mixer_amp_volume_put);
2738}
2739
2740/* capture mixer elements */
2741#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2742
2743static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2744 struct snd_ctl_elem_value *ucontrol)
2745{
2746 return alc_cap_getput_caller(kcontrol, ucontrol,
2747 snd_hda_mixer_amp_switch_get);
2748}
2749
2750static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2751 struct snd_ctl_elem_value *ucontrol)
2752{
2753 return alc_cap_getput_caller(kcontrol, ucontrol,
2754 snd_hda_mixer_amp_switch_put);
2755}
2756
a23b688f 2757#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2758 { \
2759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2760 .name = "Capture Switch", \
2761 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2762 .count = num, \
2763 .info = alc_cap_sw_info, \
2764 .get = alc_cap_sw_get, \
2765 .put = alc_cap_sw_put, \
2766 }, \
2767 { \
2768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2769 .name = "Capture Volume", \
2770 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2771 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2772 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2773 .count = num, \
2774 .info = alc_cap_vol_info, \
2775 .get = alc_cap_vol_get, \
2776 .put = alc_cap_vol_put, \
2777 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2778 }
2779
2780#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2781 { \
2782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2783 /* .name = "Capture Source", */ \
2784 .name = "Input Source", \
2785 .count = num, \
2786 .info = alc_mux_enum_info, \
2787 .get = alc_mux_enum_get, \
2788 .put = alc_mux_enum_put, \
a23b688f
TI
2789 }
2790
2791#define DEFINE_CAPMIX(num) \
a9111321 2792static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2793 _DEFINE_CAPMIX(num), \
2794 _DEFINE_CAPSRC(num), \
2795 { } /* end */ \
2796}
2797
2798#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2799static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2800 _DEFINE_CAPMIX(num), \
2801 { } /* end */ \
f9e336f6
TI
2802}
2803
2804/* up to three ADCs */
2805DEFINE_CAPMIX(1);
2806DEFINE_CAPMIX(2);
2807DEFINE_CAPMIX(3);
a23b688f
TI
2808DEFINE_CAPMIX_NOSRC(1);
2809DEFINE_CAPMIX_NOSRC(2);
2810DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2811
2812/*
2813 * ALC880 5-stack model
2814 *
9c7f852e
TI
2815 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2816 * Side = 0x02 (0xd)
e9edcee0
TI
2817 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2818 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2819 */
2820
2821/* additional mixers to alc880_three_stack_mixer */
a9111321 2822static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2823 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2824 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2825 { } /* end */
2826};
2827
e9edcee0
TI
2828/* channel source setting (6/8 channel selection for 5-stack) */
2829/* 6ch mode */
a9111321 2830static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2831 /* set line-in to input, mute it */
2832 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2833 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2834 { } /* end */
2835};
2836
e9edcee0 2837/* 8ch mode */
a9111321 2838static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2839 /* set line-in to output, unmute it */
2840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2842 { } /* end */
2843};
2844
a9111321 2845static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2846 { 6, alc880_fivestack_ch6_init },
2847 { 8, alc880_fivestack_ch8_init },
2848};
2849
2850
2851/*
2852 * ALC880 6-stack model
2853 *
9c7f852e
TI
2854 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2855 * Side = 0x05 (0x0f)
e9edcee0
TI
2856 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2857 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2858 */
2859
4c6d72d1 2860static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2861 /* front, rear, clfe, rear_surr */
2862 0x02, 0x03, 0x04, 0x05
f12ab1e0 2863};
e9edcee0 2864
a9111321 2865static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2866 .num_items = 4,
2867 .items = {
2868 { "Mic", 0x0 },
2869 { "Front Mic", 0x1 },
2870 { "Line", 0x2 },
2871 { "CD", 0x4 },
2872 },
2873};
2874
2875/* fixed 8-channels */
a9111321 2876static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2877 { 8, NULL },
2878};
2879
a9111321 2880static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2881 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2882 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2883 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2884 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2885 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2886 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2887 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2888 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2889 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2890 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2891 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2892 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2893 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2894 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2895 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2896 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2897 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2898 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2899 {
2900 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2901 .name = "Channel Mode",
df694daa
KY
2902 .info = alc_ch_mode_info,
2903 .get = alc_ch_mode_get,
2904 .put = alc_ch_mode_put,
16ded525
TI
2905 },
2906 { } /* end */
2907};
2908
e9edcee0
TI
2909
2910/*
2911 * ALC880 W810 model
2912 *
2913 * W810 has rear IO for:
2914 * Front (DAC 02)
2915 * Surround (DAC 03)
2916 * Center/LFE (DAC 04)
2917 * Digital out (06)
2918 *
2919 * The system also has a pair of internal speakers, and a headphone jack.
2920 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2921 *
e9edcee0
TI
2922 * There is a variable resistor to control the speaker or headphone
2923 * volume. This is a hardware-only device without a software API.
2924 *
2925 * Plugging headphones in will disable the internal speakers. This is
2926 * implemented in hardware, not via the driver using jack sense. In
2927 * a similar fashion, plugging into the rear socket marked "front" will
2928 * disable both the speakers and headphones.
2929 *
2930 * For input, there's a microphone jack, and an "audio in" jack.
2931 * These may not do anything useful with this driver yet, because I
2932 * haven't setup any initialization verbs for these yet...
2933 */
2934
4c6d72d1 2935static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2936 /* front, rear/surround, clfe */
2937 0x02, 0x03, 0x04
16ded525
TI
2938};
2939
e9edcee0 2940/* fixed 6 channels */
a9111321 2941static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2942 { 6, NULL }
2943};
2944
2945/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2946static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2947 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2948 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2949 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2950 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2951 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2952 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2953 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2954 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2955 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2956 { } /* end */
2957};
2958
2959
2960/*
2961 * Z710V model
2962 *
2963 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2964 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2965 * Line = 0x1a
e9edcee0
TI
2966 */
2967
4c6d72d1 2968static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2969 0x02
2970};
2971#define ALC880_Z71V_HP_DAC 0x03
2972
2973/* fixed 2 channels */
a9111321 2974static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2975 { 2, NULL }
2976};
2977
a9111321 2978static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2979 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2980 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2981 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2982 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2983 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2984 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2985 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2987 { } /* end */
2988};
2989
e9edcee0 2990
e9edcee0
TI
2991/*
2992 * ALC880 F1734 model
2993 *
2994 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2995 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2996 */
2997
4c6d72d1 2998static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
2999 0x03
3000};
3001#define ALC880_F1734_HP_DAC 0x02
3002
a9111321 3003static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3004 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3005 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3006 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3007 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3012 { } /* end */
3013};
3014
a9111321 3015static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3016 .num_items = 2,
3017 .items = {
3018 { "Mic", 0x1 },
3019 { "CD", 0x4 },
3020 },
3021};
3022
e9edcee0 3023
e9edcee0
TI
3024/*
3025 * ALC880 ASUS model
3026 *
3027 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3028 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3029 * Mic = 0x18, Line = 0x1a
3030 */
3031
3032#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3033#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3034
a9111321 3035static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3036 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3037 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3038 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3039 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3040 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3041 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3042 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3043 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3044 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3045 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3046 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3047 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3048 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3049 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3050 {
3051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3052 .name = "Channel Mode",
df694daa
KY
3053 .info = alc_ch_mode_info,
3054 .get = alc_ch_mode_get,
3055 .put = alc_ch_mode_put,
16ded525
TI
3056 },
3057 { } /* end */
3058};
e9edcee0 3059
e9edcee0
TI
3060/*
3061 * ALC880 ASUS W1V model
3062 *
3063 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3064 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3065 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3066 */
3067
3068/* additional mixers to alc880_asus_mixer */
a9111321 3069static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3070 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3071 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3072 { } /* end */
3073};
3074
df694daa 3075/* TCL S700 */
a9111321 3076static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3077 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3078 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3079 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3080 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3081 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3082 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3083 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3084 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3085 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3086 { } /* end */
3087};
3088
ccc656ce 3089/* Uniwill */
a9111321 3090static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3092 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3094 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3099 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3100 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3101 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3102 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3103 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3104 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3106 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3107 {
3108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3109 .name = "Channel Mode",
3110 .info = alc_ch_mode_info,
3111 .get = alc_ch_mode_get,
3112 .put = alc_ch_mode_put,
3113 },
3114 { } /* end */
3115};
3116
a9111321 3117static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3118 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3119 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3121 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3126 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3128 { } /* end */
3129};
3130
a9111321 3131static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3132 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3133 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3134 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3135 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3138 { } /* end */
3139};
3140
2134ea4f
TI
3141/*
3142 * virtual master controls
3143 */
3144
3145/*
3146 * slave controls for virtual master
3147 */
ea734963 3148static const char * const alc_slave_vols[] = {
2134ea4f
TI
3149 "Front Playback Volume",
3150 "Surround Playback Volume",
3151 "Center Playback Volume",
3152 "LFE Playback Volume",
3153 "Side Playback Volume",
3154 "Headphone Playback Volume",
3155 "Speaker Playback Volume",
3156 "Mono Playback Volume",
2134ea4f
TI
3157 "Line-Out Playback Volume",
3158 NULL,
3159};
3160
ea734963 3161static const char * const alc_slave_sws[] = {
2134ea4f
TI
3162 "Front Playback Switch",
3163 "Surround Playback Switch",
3164 "Center Playback Switch",
3165 "LFE Playback Switch",
3166 "Side Playback Switch",
3167 "Headphone Playback Switch",
3168 "Speaker Playback Switch",
3169 "Mono Playback Switch",
edb54a55 3170 "IEC958 Playback Switch",
23033b2b 3171 "Line-Out Playback Switch",
2134ea4f
TI
3172 NULL,
3173};
3174
1da177e4 3175/*
e9edcee0 3176 * build control elements
1da177e4 3177 */
603c4019 3178
5b0cb1d8
JK
3179#define NID_MAPPING (-1)
3180
3181#define SUBDEV_SPEAKER_ (0 << 6)
3182#define SUBDEV_HP_ (1 << 6)
3183#define SUBDEV_LINE_ (2 << 6)
3184#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3185#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3186#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3187
603c4019
TI
3188static void alc_free_kctls(struct hda_codec *codec);
3189
67d634c0 3190#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3191/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3192static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3193 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3194 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3195 { } /* end */
3196};
67d634c0 3197#endif
45bdd1c1 3198
1da177e4
LT
3199static int alc_build_controls(struct hda_codec *codec)
3200{
3201 struct alc_spec *spec = codec->spec;
2f44f847 3202 struct snd_kcontrol *kctl = NULL;
a9111321 3203 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3204 int i, j, err;
3205 unsigned int u;
3206 hda_nid_t nid;
1da177e4
LT
3207
3208 for (i = 0; i < spec->num_mixers; i++) {
3209 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3210 if (err < 0)
3211 return err;
3212 }
f9e336f6
TI
3213 if (spec->cap_mixer) {
3214 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3215 if (err < 0)
3216 return err;
3217 }
1da177e4 3218 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3219 err = snd_hda_create_spdif_out_ctls(codec,
3220 spec->multiout.dig_out_nid);
1da177e4
LT
3221 if (err < 0)
3222 return err;
e64f14f4
TI
3223 if (!spec->no_analog) {
3224 err = snd_hda_create_spdif_share_sw(codec,
3225 &spec->multiout);
3226 if (err < 0)
3227 return err;
3228 spec->multiout.share_spdif = 1;
3229 }
1da177e4
LT
3230 }
3231 if (spec->dig_in_nid) {
3232 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3233 if (err < 0)
3234 return err;
3235 }
2134ea4f 3236
67d634c0 3237#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3238 /* create beep controls if needed */
3239 if (spec->beep_amp) {
a9111321 3240 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3241 for (knew = alc_beep_mixer; knew->name; knew++) {
3242 struct snd_kcontrol *kctl;
3243 kctl = snd_ctl_new1(knew, codec);
3244 if (!kctl)
3245 return -ENOMEM;
3246 kctl->private_value = spec->beep_amp;
5e26dfd0 3247 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3248 if (err < 0)
3249 return err;
3250 }
3251 }
67d634c0 3252#endif
45bdd1c1 3253
2134ea4f 3254 /* if we have no master control, let's create it */
e64f14f4
TI
3255 if (!spec->no_analog &&
3256 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3257 unsigned int vmaster_tlv[4];
2134ea4f 3258 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3259 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3260 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3261 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3262 if (err < 0)
3263 return err;
3264 }
e64f14f4
TI
3265 if (!spec->no_analog &&
3266 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3267 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3268 NULL, alc_slave_sws);
3269 if (err < 0)
3270 return err;
3271 }
3272
5b0cb1d8 3273 /* assign Capture Source enums to NID */
fbe618f2
TI
3274 if (spec->capsrc_nids || spec->adc_nids) {
3275 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3276 if (!kctl)
3277 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3278 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3279 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3280 if (!nids)
3281 nids = spec->adc_nids;
3282 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3283 if (err < 0)
3284 return err;
3285 }
5b0cb1d8
JK
3286 }
3287 if (spec->cap_mixer) {
3288 const char *kname = kctl ? kctl->id.name : NULL;
3289 for (knew = spec->cap_mixer; knew->name; knew++) {
3290 if (kname && strcmp(knew->name, kname) == 0)
3291 continue;
3292 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3293 for (i = 0; kctl && i < kctl->count; i++) {
3294 err = snd_hda_add_nid(codec, kctl, i,
3295 spec->adc_nids[i]);
3296 if (err < 0)
3297 return err;
3298 }
3299 }
3300 }
3301
3302 /* other nid->control mapping */
3303 for (i = 0; i < spec->num_mixers; i++) {
3304 for (knew = spec->mixers[i]; knew->name; knew++) {
3305 if (knew->iface != NID_MAPPING)
3306 continue;
3307 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3308 if (kctl == NULL)
3309 continue;
3310 u = knew->subdevice;
3311 for (j = 0; j < 4; j++, u >>= 8) {
3312 nid = u & 0x3f;
3313 if (nid == 0)
3314 continue;
3315 switch (u & 0xc0) {
3316 case SUBDEV_SPEAKER_:
3317 nid = spec->autocfg.speaker_pins[nid];
3318 break;
3319 case SUBDEV_LINE_:
3320 nid = spec->autocfg.line_out_pins[nid];
3321 break;
3322 case SUBDEV_HP_:
3323 nid = spec->autocfg.hp_pins[nid];
3324 break;
3325 default:
3326 continue;
3327 }
3328 err = snd_hda_add_nid(codec, kctl, 0, nid);
3329 if (err < 0)
3330 return err;
3331 }
3332 u = knew->private_value;
3333 for (j = 0; j < 4; j++, u >>= 8) {
3334 nid = u & 0xff;
3335 if (nid == 0)
3336 continue;
3337 err = snd_hda_add_nid(codec, kctl, 0, nid);
3338 if (err < 0)
3339 return err;
3340 }
3341 }
3342 }
bae84e70
TI
3343
3344 alc_free_kctls(codec); /* no longer needed */
3345
1da177e4
LT
3346 return 0;
3347}
3348
e9edcee0 3349
1da177e4
LT
3350/*
3351 * initialize the codec volumes, etc
3352 */
3353
e9edcee0
TI
3354/*
3355 * generic initialization of ADC, input mixers and output mixers
3356 */
a9111321 3357static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3358 /*
3359 * Unmute ADC0-2 and set the default input to mic-in
3360 */
71fe7b82 3361 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3362 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3363 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3365 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3366 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3367
e9edcee0
TI
3368 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3369 * mixer widget
9c7f852e
TI
3370 * Note: PASD motherboards uses the Line In 2 as the input for front
3371 * panel mic (mic 2)
1da177e4 3372 */
e9edcee0 3373 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3381
e9edcee0
TI
3382 /*
3383 * Set up output mixers (0x0c - 0x0f)
1da177e4 3384 */
e9edcee0
TI
3385 /* set vol=0 to output mixers */
3386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3387 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3389 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3390 /* set up input amps for analog loopback */
3391 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3392 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3395 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3396 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3397 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3398 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3400
3401 { }
3402};
3403
e9edcee0
TI
3404/*
3405 * 3-stack pin configuration:
3406 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3407 */
a9111321 3408static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3409 /*
3410 * preset connection lists of input pins
3411 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3412 */
3413 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3414 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3415 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3416
3417 /*
3418 * Set pin mode and muting
3419 */
3420 /* set front pin widgets 0x14 for output */
05acb863 3421 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3422 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3423 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3424 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3425 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3426 /* Mic2 (as headphone out) for HP output */
3427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3428 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3429 /* Line In pin widget for input */
05acb863 3430 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3431 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3432 /* Line2 (as front mic) pin widget for input and vref at 80% */
3433 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3434 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3435 /* CD pin widget for input */
05acb863 3436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3437
e9edcee0
TI
3438 { }
3439};
1da177e4 3440
e9edcee0
TI
3441/*
3442 * 5-stack pin configuration:
3443 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3444 * line-in/side = 0x1a, f-mic = 0x1b
3445 */
a9111321 3446static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3447 /*
3448 * preset connection lists of input pins
3449 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3450 */
e9edcee0
TI
3451 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3452 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3453
e9edcee0
TI
3454 /*
3455 * Set pin mode and muting
1da177e4 3456 */
e9edcee0
TI
3457 /* set pin widgets 0x14-0x17 for output */
3458 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3459 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3461 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3462 /* unmute pins for output (no gain on this amp) */
3463 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3464 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3465 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3466 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3467
3468 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3469 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3470 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3471 /* Mic2 (as headphone out) for HP output */
3472 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3473 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 /* Line In pin widget for input */
3475 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3476 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3477 /* Line2 (as front mic) pin widget for input and vref at 80% */
3478 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3479 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3480 /* CD pin widget for input */
3481 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3482
3483 { }
3484};
3485
e9edcee0
TI
3486/*
3487 * W810 pin configuration:
3488 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3489 */
a9111321 3490static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3491 /* hphone/speaker input selector: front DAC */
3492 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3493
05acb863 3494 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3495 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3496 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3497 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3498 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3499 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3500
e9edcee0 3501 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3502 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3503
1da177e4
LT
3504 { }
3505};
3506
e9edcee0
TI
3507/*
3508 * Z71V pin configuration:
3509 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3510 */
a9111321 3511static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3512 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3513 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3515 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3516
16ded525 3517 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3518 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3519 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3520 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3521
3522 { }
3523};
3524
e9edcee0
TI
3525/*
3526 * 6-stack pin configuration:
9c7f852e
TI
3527 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3528 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3529 */
a9111321 3530static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3531 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3532
16ded525 3533 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3534 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3535 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3538 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3539 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3540 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541
16ded525 3542 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3543 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3544 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3545 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3546 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3547 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3548 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3549 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3550 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3551
e9edcee0
TI
3552 { }
3553};
3554
ccc656ce
KY
3555/*
3556 * Uniwill pin configuration:
3557 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3558 * line = 0x1a
3559 */
a9111321 3560static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3561 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3562
3563 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3564 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3567 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3568 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3569 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3570 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3571 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3573 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3577
3578 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3580 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3582 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3583 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3584 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3585 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3587
3588 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3589 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3590
3591 { }
3592};
3593
3594/*
3595* Uniwill P53
ea1fb29a 3596* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3597 */
a9111321 3598static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3599 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3600
3601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3602 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3603 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3604 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3605 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3606 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3607 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3609 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3610 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3611 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3612 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3613
3614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3615 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3616 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3617 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3618 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3619 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3620
3621 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3622 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3623
3624 { }
3625};
3626
a9111321 3627static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3628 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3629 { }
3630};
3631
458a4fab 3632/* auto-toggle front mic */
eeb43387 3633static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3634{
3635 unsigned int present;
3636 unsigned char bits;
ccc656ce 3637
864f92be 3638 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3639 bits = present ? HDA_AMP_MUTE : 0;
3640 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3641}
3642
4f5d1706 3643static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3644{
a9fd4f3f
TI
3645 struct alc_spec *spec = codec->spec;
3646
3647 spec->autocfg.hp_pins[0] = 0x14;
3648 spec->autocfg.speaker_pins[0] = 0x15;
3649 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3650 spec->automute = 1;
3651 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3652}
3653
3654static void alc880_uniwill_init_hook(struct hda_codec *codec)
3655{
d922b51d 3656 alc_hp_automute(codec);
eeb43387 3657 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3658}
3659
3660static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3661 unsigned int res)
3662{
3663 /* Looks like the unsol event is incompatible with the standard
3664 * definition. 4bit tag is placed at 28 bit!
3665 */
458a4fab 3666 switch (res >> 28) {
458a4fab 3667 case ALC880_MIC_EVENT:
eeb43387 3668 alc88x_simple_mic_automute(codec);
458a4fab 3669 break;
a9fd4f3f 3670 default:
d922b51d 3671 alc_sku_unsol_event(codec, res);
a9fd4f3f 3672 break;
458a4fab 3673 }
ccc656ce
KY
3674}
3675
4f5d1706 3676static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3677{
a9fd4f3f 3678 struct alc_spec *spec = codec->spec;
ccc656ce 3679
a9fd4f3f
TI
3680 spec->autocfg.hp_pins[0] = 0x14;
3681 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3682 spec->automute = 1;
3683 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3684}
3685
3686static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3687{
3688 unsigned int present;
ea1fb29a 3689
ccc656ce 3690 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3691 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3692 present &= HDA_AMP_VOLMASK;
3693 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3694 HDA_AMP_VOLMASK, present);
3695 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3696 HDA_AMP_VOLMASK, present);
ccc656ce 3697}
47fd830a 3698
ccc656ce
KY
3699static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3700 unsigned int res)
3701{
3702 /* Looks like the unsol event is incompatible with the standard
3703 * definition. 4bit tag is placed at 28 bit!
3704 */
f12ab1e0 3705 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3706 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3707 else
d922b51d 3708 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3709}
3710
e9edcee0
TI
3711/*
3712 * F1734 pin configuration:
3713 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3714 */
a9111321 3715static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3716 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3717 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3718 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3719 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3720 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3721
e9edcee0 3722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3726
e9edcee0
TI
3727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3728 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3730 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3732 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3734 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3736
937b4160
TI
3737 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3738 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3739
dfc0ff62
TI
3740 { }
3741};
3742
e9edcee0
TI
3743/*
3744 * ASUS pin configuration:
3745 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3746 */
a9111321 3747static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3748 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3749 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3750 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3751 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3752
3753 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3756 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3757 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3759 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3761
3762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3764 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3766 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3768 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3770 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3771
e9edcee0
TI
3772 { }
3773};
16ded525 3774
e9edcee0 3775/* Enable GPIO mask and set output */
bc9f98a9
KY
3776#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3777#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3778#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3779
3780/* Clevo m520g init */
a9111321 3781static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3782 /* headphone output */
3783 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3784 /* line-out */
3785 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3786 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3787 /* Line-in */
3788 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3790 /* CD */
3791 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3792 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3793 /* Mic1 (rear panel) */
3794 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3795 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3796 /* Mic2 (front panel) */
3797 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3798 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3799 /* headphone */
3800 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3801 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3802 /* change to EAPD mode */
3803 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3804 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3805
3806 { }
16ded525
TI
3807};
3808
a9111321 3809static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3810 /* change to EAPD mode */
3811 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3812 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3813
df694daa
KY
3814 /* Headphone output */
3815 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3816 /* Front output*/
3817 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3818 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3819
3820 /* Line In pin widget for input */
3821 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3822 /* CD pin widget for input */
3823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3824 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3826
3827 /* change to EAPD mode */
3828 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3829 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3830
3831 { }
3832};
16ded525 3833
e9edcee0 3834/*
ae6b813a
TI
3835 * LG m1 express dual
3836 *
3837 * Pin assignment:
3838 * Rear Line-In/Out (blue): 0x14
3839 * Build-in Mic-In: 0x15
3840 * Speaker-out: 0x17
3841 * HP-Out (green): 0x1b
3842 * Mic-In/Out (red): 0x19
3843 * SPDIF-Out: 0x1e
3844 */
3845
3846/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3847static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3848 0x05, 0x02, 0x03
3849};
3850
3851/* seems analog CD is not working */
a9111321 3852static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3853 .num_items = 3,
3854 .items = {
3855 { "Mic", 0x1 },
3856 { "Line", 0x5 },
3857 { "Internal Mic", 0x6 },
3858 },
3859};
3860
3861/* 2,4,6 channel modes */
a9111321 3862static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3863 /* set line-in and mic-in to input */
3864 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3866 { }
3867};
3868
a9111321 3869static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3870 /* set line-in to out and mic-in to input */
3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3873 { }
3874};
3875
a9111321 3876static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3877 /* set line-in and mic-in to output */
3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3880 { }
3881};
3882
a9111321 3883static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3884 { 2, alc880_lg_ch2_init },
3885 { 4, alc880_lg_ch4_init },
3886 { 6, alc880_lg_ch6_init },
3887};
3888
a9111321 3889static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3891 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3893 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3902 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3903 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3904 {
3905 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3906 .name = "Channel Mode",
3907 .info = alc_ch_mode_info,
3908 .get = alc_ch_mode_get,
3909 .put = alc_ch_mode_put,
3910 },
3911 { } /* end */
3912};
3913
a9111321 3914static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3915 /* set capture source to mic-in */
3916 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3917 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3919 /* mute all amp mixer inputs */
3920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3923 /* line-in to input */
3924 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3925 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3926 /* built-in mic */
3927 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3928 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3929 /* speaker-out */
3930 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3931 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3932 /* mic-in to input */
3933 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3934 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3935 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* HP-out */
3937 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3938 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3939 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3940 /* jack sense */
a9fd4f3f 3941 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3942 { }
3943};
3944
3945/* toggle speaker-output according to the hp-jack state */
4f5d1706 3946static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3947{
a9fd4f3f 3948 struct alc_spec *spec = codec->spec;
ae6b813a 3949
a9fd4f3f
TI
3950 spec->autocfg.hp_pins[0] = 0x1b;
3951 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3952 spec->automute = 1;
3953 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3954}
3955
d681518a
TI
3956/*
3957 * LG LW20
3958 *
3959 * Pin assignment:
3960 * Speaker-out: 0x14
3961 * Mic-In: 0x18
e4f41da9
CM
3962 * Built-in Mic-In: 0x19
3963 * Line-In: 0x1b
3964 * HP-Out: 0x1a
d681518a
TI
3965 * SPDIF-Out: 0x1e
3966 */
3967
a9111321 3968static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3969 .num_items = 3,
d681518a
TI
3970 .items = {
3971 { "Mic", 0x0 },
3972 { "Internal Mic", 0x1 },
e4f41da9 3973 { "Line In", 0x2 },
d681518a
TI
3974 },
3975};
3976
0a8c5da3
CM
3977#define alc880_lg_lw_modes alc880_threestack_modes
3978
a9111321 3979static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3980 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3981 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3982 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3983 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3984 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3985 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3986 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3987 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3988 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3989 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3993 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3994 {
3995 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3996 .name = "Channel Mode",
3997 .info = alc_ch_mode_info,
3998 .get = alc_ch_mode_get,
3999 .put = alc_ch_mode_put,
4000 },
d681518a
TI
4001 { } /* end */
4002};
4003
a9111321 4004static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4005 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4006 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4007 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4008
d681518a
TI
4009 /* set capture source to mic-in */
4010 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4011 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4012 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4013 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4014 /* speaker-out */
4015 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* HP-out */
d681518a
TI
4018 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4019 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4020 /* mic-in to input */
4021 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4022 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4023 /* built-in mic */
4024 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4025 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4026 /* jack sense */
a9fd4f3f 4027 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4028 { }
4029};
4030
4031/* toggle speaker-output according to the hp-jack state */
4f5d1706 4032static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4033{
a9fd4f3f 4034 struct alc_spec *spec = codec->spec;
d681518a 4035
a9fd4f3f
TI
4036 spec->autocfg.hp_pins[0] = 0x1b;
4037 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4038 spec->automute = 1;
4039 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4040}
4041
a9111321 4042static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4043 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4044 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4047 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4048 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4049 { } /* end */
4050};
4051
a9111321 4052static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4053 .num_items = 2,
4054 .items = {
4055 { "Mic", 0x0 },
4056 { "Internal Mic", 0x1 },
4057 },
4058};
4059
a9111321 4060static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4061 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4062
4063 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4064 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4065
4066 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4067 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4068 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4069 /* Mic2 (as headphone out) for HP output */
4070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4071 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4072 /* Internal Speaker */
4073 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4074 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4075
4076 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4077 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4078
4079 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4080 { }
4081};
4082
4083/* toggle speaker-output according to the hp-jack state */
4084static void alc880_medion_rim_automute(struct hda_codec *codec)
4085{
a9fd4f3f 4086 struct alc_spec *spec = codec->spec;
d922b51d 4087 alc_hp_automute(codec);
a9fd4f3f
TI
4088 /* toggle EAPD */
4089 if (spec->jack_present)
df99cd33
TI
4090 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4091 else
4092 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4093}
4094
4095static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4096 unsigned int res)
4097{
4098 /* Looks like the unsol event is incompatible with the standard
4099 * definition. 4bit tag is placed at 28 bit!
4100 */
4101 if ((res >> 28) == ALC880_HP_EVENT)
4102 alc880_medion_rim_automute(codec);
4103}
4104
4f5d1706 4105static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4106{
4107 struct alc_spec *spec = codec->spec;
4108
4109 spec->autocfg.hp_pins[0] = 0x14;
4110 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4111 spec->automute = 1;
4112 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4113}
4114
cb53c626 4115#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4116static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4117 { 0x0b, HDA_INPUT, 0 },
4118 { 0x0b, HDA_INPUT, 1 },
4119 { 0x0b, HDA_INPUT, 2 },
4120 { 0x0b, HDA_INPUT, 3 },
4121 { 0x0b, HDA_INPUT, 4 },
4122 { } /* end */
4123};
4124
a9111321 4125static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4126 { 0x0b, HDA_INPUT, 1 },
4127 { 0x0b, HDA_INPUT, 6 },
4128 { 0x0b, HDA_INPUT, 7 },
4129 { } /* end */
4130};
4131#endif
4132
ae6b813a
TI
4133/*
4134 * Common callbacks
e9edcee0
TI
4135 */
4136
584c0c4c
TI
4137static void alc_init_special_input_src(struct hda_codec *codec);
4138
1da177e4
LT
4139static int alc_init(struct hda_codec *codec)
4140{
4141 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4142 unsigned int i;
4143
2c3bf9ab 4144 alc_fix_pll(codec);
4a79ba34 4145 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4146
e9edcee0
TI
4147 for (i = 0; i < spec->num_init_verbs; i++)
4148 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4149 alc_init_special_input_src(codec);
ae6b813a
TI
4150
4151 if (spec->init_hook)
4152 spec->init_hook(codec);
4153
58701120
TI
4154 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4155
9e5341b9 4156 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4157 return 0;
4158}
4159
ae6b813a
TI
4160static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4161{
4162 struct alc_spec *spec = codec->spec;
4163
4164 if (spec->unsol_event)
4165 spec->unsol_event(codec, res);
4166}
4167
cb53c626
TI
4168#ifdef CONFIG_SND_HDA_POWER_SAVE
4169static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4170{
4171 struct alc_spec *spec = codec->spec;
4172 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4173}
4174#endif
4175
1da177e4
LT
4176/*
4177 * Analog playback callbacks
4178 */
4179static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4180 struct hda_codec *codec,
c8b6bf9b 4181 struct snd_pcm_substream *substream)
1da177e4
LT
4182{
4183 struct alc_spec *spec = codec->spec;
9a08160b
TI
4184 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4185 hinfo);
1da177e4
LT
4186}
4187
4188static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4189 struct hda_codec *codec,
4190 unsigned int stream_tag,
4191 unsigned int format,
c8b6bf9b 4192 struct snd_pcm_substream *substream)
1da177e4
LT
4193{
4194 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4195 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4196 stream_tag, format, substream);
1da177e4
LT
4197}
4198
4199static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4200 struct hda_codec *codec,
c8b6bf9b 4201 struct snd_pcm_substream *substream)
1da177e4
LT
4202{
4203 struct alc_spec *spec = codec->spec;
4204 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4205}
4206
4207/*
4208 * Digital out
4209 */
4210static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4211 struct hda_codec *codec,
c8b6bf9b 4212 struct snd_pcm_substream *substream)
1da177e4
LT
4213{
4214 struct alc_spec *spec = codec->spec;
4215 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4216}
4217
6b97eb45
TI
4218static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4219 struct hda_codec *codec,
4220 unsigned int stream_tag,
4221 unsigned int format,
4222 struct snd_pcm_substream *substream)
4223{
4224 struct alc_spec *spec = codec->spec;
4225 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4226 stream_tag, format, substream);
4227}
4228
9b5f12e5
TI
4229static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4230 struct hda_codec *codec,
4231 struct snd_pcm_substream *substream)
4232{
4233 struct alc_spec *spec = codec->spec;
4234 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4235}
4236
1da177e4
LT
4237static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4238 struct hda_codec *codec,
c8b6bf9b 4239 struct snd_pcm_substream *substream)
1da177e4
LT
4240{
4241 struct alc_spec *spec = codec->spec;
4242 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4243}
4244
4245/*
4246 * Analog capture
4247 */
6330079f 4248static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4249 struct hda_codec *codec,
4250 unsigned int stream_tag,
4251 unsigned int format,
c8b6bf9b 4252 struct snd_pcm_substream *substream)
1da177e4
LT
4253{
4254 struct alc_spec *spec = codec->spec;
4255
6330079f 4256 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4257 stream_tag, 0, format);
4258 return 0;
4259}
4260
6330079f 4261static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4262 struct hda_codec *codec,
c8b6bf9b 4263 struct snd_pcm_substream *substream)
1da177e4
LT
4264{
4265 struct alc_spec *spec = codec->spec;
4266
888afa15
TI
4267 snd_hda_codec_cleanup_stream(codec,
4268 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4269 return 0;
4270}
4271
840b64c0
TI
4272/* analog capture with dynamic dual-adc changes */
4273static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4274 struct hda_codec *codec,
4275 unsigned int stream_tag,
4276 unsigned int format,
4277 struct snd_pcm_substream *substream)
4278{
4279 struct alc_spec *spec = codec->spec;
4280 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4281 spec->cur_adc_stream_tag = stream_tag;
4282 spec->cur_adc_format = format;
4283 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4284 return 0;
4285}
4286
4287static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4288 struct hda_codec *codec,
4289 struct snd_pcm_substream *substream)
4290{
4291 struct alc_spec *spec = codec->spec;
4292 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4293 spec->cur_adc = 0;
4294 return 0;
4295}
4296
a9111321 4297static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4298 .substreams = 1,
4299 .channels_min = 2,
4300 .channels_max = 2,
4301 .nid = 0, /* fill later */
4302 .ops = {
4303 .prepare = dualmic_capture_pcm_prepare,
4304 .cleanup = dualmic_capture_pcm_cleanup
4305 },
4306};
1da177e4
LT
4307
4308/*
4309 */
a9111321 4310static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4311 .substreams = 1,
4312 .channels_min = 2,
4313 .channels_max = 8,
e9edcee0 4314 /* NID is set in alc_build_pcms */
1da177e4
LT
4315 .ops = {
4316 .open = alc880_playback_pcm_open,
4317 .prepare = alc880_playback_pcm_prepare,
4318 .cleanup = alc880_playback_pcm_cleanup
4319 },
4320};
4321
a9111321 4322static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4323 .substreams = 1,
4324 .channels_min = 2,
4325 .channels_max = 2,
4326 /* NID is set in alc_build_pcms */
4327};
4328
a9111321 4329static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4330 .substreams = 1,
4331 .channels_min = 2,
4332 .channels_max = 2,
4333 /* NID is set in alc_build_pcms */
4334};
4335
a9111321 4336static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4337 .substreams = 2, /* can be overridden */
1da177e4
LT
4338 .channels_min = 2,
4339 .channels_max = 2,
e9edcee0 4340 /* NID is set in alc_build_pcms */
1da177e4 4341 .ops = {
6330079f
TI
4342 .prepare = alc880_alt_capture_pcm_prepare,
4343 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4344 },
4345};
4346
a9111321 4347static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4348 .substreams = 1,
4349 .channels_min = 2,
4350 .channels_max = 2,
4351 /* NID is set in alc_build_pcms */
4352 .ops = {
4353 .open = alc880_dig_playback_pcm_open,
6b97eb45 4354 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4355 .prepare = alc880_dig_playback_pcm_prepare,
4356 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4357 },
4358};
4359
a9111321 4360static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4361 .substreams = 1,
4362 .channels_min = 2,
4363 .channels_max = 2,
4364 /* NID is set in alc_build_pcms */
4365};
4366
4c5186ed 4367/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4368static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4369 .substreams = 0,
4370 .channels_min = 0,
4371 .channels_max = 0,
4372};
4373
1da177e4
LT
4374static int alc_build_pcms(struct hda_codec *codec)
4375{
4376 struct alc_spec *spec = codec->spec;
4377 struct hda_pcm *info = spec->pcm_rec;
4378 int i;
4379
4380 codec->num_pcms = 1;
4381 codec->pcm_info = info;
4382
e64f14f4
TI
4383 if (spec->no_analog)
4384 goto skip_analog;
4385
812a2cca
TI
4386 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4387 "%s Analog", codec->chip_name);
1da177e4 4388 info->name = spec->stream_name_analog;
274693f3 4389
4a471b7d 4390 if (spec->stream_analog_playback) {
da3cec35
TI
4391 if (snd_BUG_ON(!spec->multiout.dac_nids))
4392 return -EINVAL;
4a471b7d
TI
4393 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4394 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4395 }
4396 if (spec->stream_analog_capture) {
da3cec35
TI
4397 if (snd_BUG_ON(!spec->adc_nids))
4398 return -EINVAL;
4a471b7d
TI
4399 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4400 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4401 }
4402
4403 if (spec->channel_mode) {
4404 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4405 for (i = 0; i < spec->num_channel_mode; i++) {
4406 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4407 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4408 }
1da177e4
LT
4409 }
4410 }
4411
e64f14f4 4412 skip_analog:
e08a007d 4413 /* SPDIF for stream index #1 */
1da177e4 4414 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4415 snprintf(spec->stream_name_digital,
4416 sizeof(spec->stream_name_digital),
4417 "%s Digital", codec->chip_name);
e08a007d 4418 codec->num_pcms = 2;
b25c9da1 4419 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4420 info = spec->pcm_rec + 1;
1da177e4 4421 info->name = spec->stream_name_digital;
8c441982
TI
4422 if (spec->dig_out_type)
4423 info->pcm_type = spec->dig_out_type;
4424 else
4425 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4426 if (spec->multiout.dig_out_nid &&
4427 spec->stream_digital_playback) {
1da177e4
LT
4428 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4429 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4430 }
4a471b7d
TI
4431 if (spec->dig_in_nid &&
4432 spec->stream_digital_capture) {
1da177e4
LT
4433 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4434 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4435 }
963f803f
TI
4436 /* FIXME: do we need this for all Realtek codec models? */
4437 codec->spdif_status_reset = 1;
1da177e4
LT
4438 }
4439
e64f14f4
TI
4440 if (spec->no_analog)
4441 return 0;
4442
e08a007d
TI
4443 /* If the use of more than one ADC is requested for the current
4444 * model, configure a second analog capture-only PCM.
4445 */
4446 /* Additional Analaog capture for index #2 */
6330079f
TI
4447 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4448 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4449 codec->num_pcms = 3;
c06134d7 4450 info = spec->pcm_rec + 2;
e08a007d 4451 info->name = spec->stream_name_analog;
6330079f
TI
4452 if (spec->alt_dac_nid) {
4453 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4454 *spec->stream_analog_alt_playback;
4455 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4456 spec->alt_dac_nid;
4457 } else {
4458 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4459 alc_pcm_null_stream;
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4461 }
ce85c9ac 4462 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4463 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4464 *spec->stream_analog_alt_capture;
4465 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4466 spec->adc_nids[1];
4467 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4468 spec->num_adc_nids - 1;
4469 } else {
4470 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4471 alc_pcm_null_stream;
4472 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4473 }
4474 }
4475
1da177e4
LT
4476 return 0;
4477}
4478
a4e09aa3
TI
4479static inline void alc_shutup(struct hda_codec *codec)
4480{
1c716153
TI
4481 struct alc_spec *spec = codec->spec;
4482
4483 if (spec && spec->shutup)
4484 spec->shutup(codec);
a4e09aa3
TI
4485 snd_hda_shutup_pins(codec);
4486}
4487
603c4019
TI
4488static void alc_free_kctls(struct hda_codec *codec)
4489{
4490 struct alc_spec *spec = codec->spec;
4491
4492 if (spec->kctls.list) {
4493 struct snd_kcontrol_new *kctl = spec->kctls.list;
4494 int i;
4495 for (i = 0; i < spec->kctls.used; i++)
4496 kfree(kctl[i].name);
4497 }
4498 snd_array_free(&spec->kctls);
4499}
4500
1da177e4
LT
4501static void alc_free(struct hda_codec *codec)
4502{
e9edcee0 4503 struct alc_spec *spec = codec->spec;
e9edcee0 4504
f12ab1e0 4505 if (!spec)
e9edcee0
TI
4506 return;
4507
a4e09aa3 4508 alc_shutup(codec);
cd372fb3 4509 snd_hda_input_jack_free(codec);
603c4019 4510 alc_free_kctls(codec);
e9edcee0 4511 kfree(spec);
680cd536 4512 snd_hda_detach_beep_device(codec);
1da177e4
LT
4513}
4514
f5de24b0 4515#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4516static void alc_power_eapd(struct hda_codec *codec)
4517{
691f1fcc 4518 alc_auto_setup_eapd(codec, false);
c97259df
DC
4519}
4520
f5de24b0
HM
4521static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4522{
4523 struct alc_spec *spec = codec->spec;
a4e09aa3 4524 alc_shutup(codec);
f5de24b0 4525 if (spec && spec->power_hook)
c97259df 4526 spec->power_hook(codec);
f5de24b0
HM
4527 return 0;
4528}
4529#endif
4530
e044c39a 4531#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4532static int alc_resume(struct hda_codec *codec)
4533{
1c716153 4534 msleep(150); /* to avoid pop noise */
e044c39a
TI
4535 codec->patch_ops.init(codec);
4536 snd_hda_codec_resume_amp(codec);
4537 snd_hda_codec_resume_cache(codec);
9e5341b9 4538 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4539 return 0;
4540}
e044c39a
TI
4541#endif
4542
1da177e4
LT
4543/*
4544 */
a9111321 4545static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4546 .build_controls = alc_build_controls,
4547 .build_pcms = alc_build_pcms,
4548 .init = alc_init,
4549 .free = alc_free,
ae6b813a 4550 .unsol_event = alc_unsol_event,
e044c39a
TI
4551#ifdef SND_HDA_NEEDS_RESUME
4552 .resume = alc_resume,
4553#endif
cb53c626 4554#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4555 .suspend = alc_suspend,
cb53c626
TI
4556 .check_power_status = alc_check_power_status,
4557#endif
c97259df 4558 .reboot_notify = alc_shutup,
1da177e4
LT
4559};
4560
c027ddcd
KY
4561/* replace the codec chip_name with the given string */
4562static int alc_codec_rename(struct hda_codec *codec, const char *name)
4563{
4564 kfree(codec->chip_name);
4565 codec->chip_name = kstrdup(name, GFP_KERNEL);
4566 if (!codec->chip_name) {
4567 alc_free(codec);
4568 return -ENOMEM;
4569 }
4570 return 0;
4571}
4572
2fa522be
TI
4573/*
4574 * Test configuration for debugging
4575 *
4576 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4577 * enum controls.
4578 */
4579#ifdef CONFIG_SND_DEBUG
4c6d72d1 4580static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4581 0x02, 0x03, 0x04, 0x05
4582};
4583
a9111321 4584static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4585 .num_items = 7,
2fa522be
TI
4586 .items = {
4587 { "In-1", 0x0 },
4588 { "In-2", 0x1 },
4589 { "In-3", 0x2 },
4590 { "In-4", 0x3 },
4591 { "CD", 0x4 },
ae6b813a
TI
4592 { "Front", 0x5 },
4593 { "Surround", 0x6 },
2fa522be
TI
4594 },
4595};
4596
a9111321 4597static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4598 { 2, NULL },
fd2c326d 4599 { 4, NULL },
2fa522be 4600 { 6, NULL },
fd2c326d 4601 { 8, NULL },
2fa522be
TI
4602};
4603
9c7f852e
TI
4604static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4605 struct snd_ctl_elem_info *uinfo)
2fa522be 4606{
4c6d72d1 4607 static const char * const texts[] = {
2fa522be
TI
4608 "N/A", "Line Out", "HP Out",
4609 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4610 };
4611 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4612 uinfo->count = 1;
4613 uinfo->value.enumerated.items = 8;
4614 if (uinfo->value.enumerated.item >= 8)
4615 uinfo->value.enumerated.item = 7;
4616 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4617 return 0;
4618}
4619
9c7f852e
TI
4620static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4621 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4622{
4623 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4624 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4625 unsigned int pin_ctl, item = 0;
4626
4627 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4628 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4629 if (pin_ctl & AC_PINCTL_OUT_EN) {
4630 if (pin_ctl & AC_PINCTL_HP_EN)
4631 item = 2;
4632 else
4633 item = 1;
4634 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4635 switch (pin_ctl & AC_PINCTL_VREFEN) {
4636 case AC_PINCTL_VREF_HIZ: item = 3; break;
4637 case AC_PINCTL_VREF_50: item = 4; break;
4638 case AC_PINCTL_VREF_GRD: item = 5; break;
4639 case AC_PINCTL_VREF_80: item = 6; break;
4640 case AC_PINCTL_VREF_100: item = 7; break;
4641 }
4642 }
4643 ucontrol->value.enumerated.item[0] = item;
4644 return 0;
4645}
4646
9c7f852e
TI
4647static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4648 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4649{
4650 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4651 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4652 static const unsigned int ctls[] = {
2fa522be
TI
4653 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4654 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4655 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4656 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4657 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4658 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4659 };
4660 unsigned int old_ctl, new_ctl;
4661
4662 old_ctl = snd_hda_codec_read(codec, nid, 0,
4663 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4664 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4665 if (old_ctl != new_ctl) {
82beb8fd
TI
4666 int val;
4667 snd_hda_codec_write_cache(codec, nid, 0,
4668 AC_VERB_SET_PIN_WIDGET_CONTROL,
4669 new_ctl);
47fd830a
TI
4670 val = ucontrol->value.enumerated.item[0] >= 3 ?
4671 HDA_AMP_MUTE : 0;
4672 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4673 HDA_AMP_MUTE, val);
2fa522be
TI
4674 return 1;
4675 }
4676 return 0;
4677}
4678
9c7f852e
TI
4679static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4680 struct snd_ctl_elem_info *uinfo)
2fa522be 4681{
4c6d72d1 4682 static const char * const texts[] = {
2fa522be
TI
4683 "Front", "Surround", "CLFE", "Side"
4684 };
4685 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4686 uinfo->count = 1;
4687 uinfo->value.enumerated.items = 4;
4688 if (uinfo->value.enumerated.item >= 4)
4689 uinfo->value.enumerated.item = 3;
4690 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4691 return 0;
4692}
4693
9c7f852e
TI
4694static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4695 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4696{
4697 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4698 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4699 unsigned int sel;
4700
4701 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4702 ucontrol->value.enumerated.item[0] = sel & 3;
4703 return 0;
4704}
4705
9c7f852e
TI
4706static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4707 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4708{
4709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4710 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4711 unsigned int sel;
4712
4713 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4714 if (ucontrol->value.enumerated.item[0] != sel) {
4715 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4716 snd_hda_codec_write_cache(codec, nid, 0,
4717 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4718 return 1;
4719 }
4720 return 0;
4721}
4722
4723#define PIN_CTL_TEST(xname,nid) { \
4724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4725 .name = xname, \
5b0cb1d8 4726 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4727 .info = alc_test_pin_ctl_info, \
4728 .get = alc_test_pin_ctl_get, \
4729 .put = alc_test_pin_ctl_put, \
4730 .private_value = nid \
4731 }
4732
4733#define PIN_SRC_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4735 .name = xname, \
5b0cb1d8 4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4737 .info = alc_test_pin_src_info, \
4738 .get = alc_test_pin_src_get, \
4739 .put = alc_test_pin_src_put, \
4740 .private_value = nid \
4741 }
4742
a9111321 4743static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4744 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4745 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4746 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4747 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4748 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4749 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4750 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4751 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4752 PIN_CTL_TEST("Front Pin Mode", 0x14),
4753 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4754 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4755 PIN_CTL_TEST("Side Pin Mode", 0x17),
4756 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4757 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4758 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4759 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4760 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4761 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4762 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4763 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4764 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4765 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4766 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4767 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4768 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4769 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4770 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4771 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4772 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4773 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4774 {
4775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4776 .name = "Channel Mode",
df694daa
KY
4777 .info = alc_ch_mode_info,
4778 .get = alc_ch_mode_get,
4779 .put = alc_ch_mode_put,
2fa522be
TI
4780 },
4781 { } /* end */
4782};
4783
a9111321 4784static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4785 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4786 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4787 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4788 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4789 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4790 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4791 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4792 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4793 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4794 /* Vol output for 0x0c-0x0f */
05acb863
TI
4795 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4798 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4799 /* Set output pins 0x14-0x17 */
05acb863
TI
4800 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4803 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4804 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4805 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4806 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4807 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4808 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4809 /* Set input pins 0x18-0x1c */
16ded525
TI
4810 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4811 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4812 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4813 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4814 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4815 /* Mute input pins 0x18-0x1b */
05acb863
TI
4816 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4817 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4818 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4819 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4820 /* ADC set up */
05acb863 4821 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4822 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4824 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4826 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4827 /* Analog input/passthru */
4828 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4830 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4831 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4832 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4833 { }
4834};
4835#endif
4836
1da177e4
LT
4837/*
4838 */
4839
ea734963 4840static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4841 [ALC880_3ST] = "3stack",
4842 [ALC880_TCL_S700] = "tcl",
4843 [ALC880_3ST_DIG] = "3stack-digout",
4844 [ALC880_CLEVO] = "clevo",
4845 [ALC880_5ST] = "5stack",
4846 [ALC880_5ST_DIG] = "5stack-digout",
4847 [ALC880_W810] = "w810",
4848 [ALC880_Z71V] = "z71v",
4849 [ALC880_6ST] = "6stack",
4850 [ALC880_6ST_DIG] = "6stack-digout",
4851 [ALC880_ASUS] = "asus",
4852 [ALC880_ASUS_W1V] = "asus-w1v",
4853 [ALC880_ASUS_DIG] = "asus-dig",
4854 [ALC880_ASUS_DIG2] = "asus-dig2",
4855 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4856 [ALC880_UNIWILL_P53] = "uniwill-p53",
4857 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4858 [ALC880_F1734] = "F1734",
4859 [ALC880_LG] = "lg",
4860 [ALC880_LG_LW] = "lg-lw",
df99cd33 4861 [ALC880_MEDION_RIM] = "medion",
2fa522be 4862#ifdef CONFIG_SND_DEBUG
f5fcc13c 4863 [ALC880_TEST] = "test",
2fa522be 4864#endif
f5fcc13c
TI
4865 [ALC880_AUTO] = "auto",
4866};
4867
a9111321 4868static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4869 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4870 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4871 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4872 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4873 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4874 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4875 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4876 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4877 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4878 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4879 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4880 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4881 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4882 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4883 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4884 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4885 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4886 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4887 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4888 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4890 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4891 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4893 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4894 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4895 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4896 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4897 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4898 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4899 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4900 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4901 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4902 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4903 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4904 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4905 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4906 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4907 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4908 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4909 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4910 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4911 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4912 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4913 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4914 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4915 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4916 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4917 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4918 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4919 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4920 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4921 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4922 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4923 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4924 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4925 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4926 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4927 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4928 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4929 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4930 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4931 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4932 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4933 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4934 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4935 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4936 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4938 /* default Intel */
4939 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4940 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4941 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4942 {}
4943};
4944
16ded525 4945/*
df694daa 4946 * ALC880 codec presets
16ded525 4947 */
a9111321 4948static const struct alc_config_preset alc880_presets[] = {
16ded525 4949 [ALC880_3ST] = {
e9edcee0 4950 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4951 .init_verbs = { alc880_volume_init_verbs,
4952 alc880_pin_3stack_init_verbs },
16ded525 4953 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4954 .dac_nids = alc880_dac_nids,
16ded525
TI
4955 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4956 .channel_mode = alc880_threestack_modes,
4e195a7b 4957 .need_dac_fix = 1,
16ded525
TI
4958 .input_mux = &alc880_capture_source,
4959 },
4960 [ALC880_3ST_DIG] = {
e9edcee0 4961 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4962 .init_verbs = { alc880_volume_init_verbs,
4963 alc880_pin_3stack_init_verbs },
16ded525 4964 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4965 .dac_nids = alc880_dac_nids,
4966 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4967 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4968 .channel_mode = alc880_threestack_modes,
4e195a7b 4969 .need_dac_fix = 1,
16ded525
TI
4970 .input_mux = &alc880_capture_source,
4971 },
df694daa
KY
4972 [ALC880_TCL_S700] = {
4973 .mixers = { alc880_tcl_s700_mixer },
4974 .init_verbs = { alc880_volume_init_verbs,
4975 alc880_pin_tcl_S700_init_verbs,
4976 alc880_gpio2_init_verbs },
4977 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4978 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4979 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4980 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4981 .hp_nid = 0x03,
4982 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4983 .channel_mode = alc880_2_jack_modes,
4984 .input_mux = &alc880_capture_source,
4985 },
16ded525 4986 [ALC880_5ST] = {
f12ab1e0
TI
4987 .mixers = { alc880_three_stack_mixer,
4988 alc880_five_stack_mixer},
4989 .init_verbs = { alc880_volume_init_verbs,
4990 alc880_pin_5stack_init_verbs },
16ded525
TI
4991 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4992 .dac_nids = alc880_dac_nids,
16ded525
TI
4993 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4994 .channel_mode = alc880_fivestack_modes,
4995 .input_mux = &alc880_capture_source,
4996 },
4997 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4998 .mixers = { alc880_three_stack_mixer,
4999 alc880_five_stack_mixer },
5000 .init_verbs = { alc880_volume_init_verbs,
5001 alc880_pin_5stack_init_verbs },
16ded525
TI
5002 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5003 .dac_nids = alc880_dac_nids,
5004 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5005 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5006 .channel_mode = alc880_fivestack_modes,
5007 .input_mux = &alc880_capture_source,
5008 },
b6482d48
TI
5009 [ALC880_6ST] = {
5010 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5011 .init_verbs = { alc880_volume_init_verbs,
5012 alc880_pin_6stack_init_verbs },
b6482d48
TI
5013 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5014 .dac_nids = alc880_6st_dac_nids,
5015 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5016 .channel_mode = alc880_sixstack_modes,
5017 .input_mux = &alc880_6stack_capture_source,
5018 },
16ded525 5019 [ALC880_6ST_DIG] = {
e9edcee0 5020 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5021 .init_verbs = { alc880_volume_init_verbs,
5022 alc880_pin_6stack_init_verbs },
16ded525
TI
5023 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5024 .dac_nids = alc880_6st_dac_nids,
5025 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5026 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5027 .channel_mode = alc880_sixstack_modes,
5028 .input_mux = &alc880_6stack_capture_source,
5029 },
5030 [ALC880_W810] = {
e9edcee0 5031 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5032 .init_verbs = { alc880_volume_init_verbs,
5033 alc880_pin_w810_init_verbs,
b0af0de5 5034 alc880_gpio2_init_verbs },
16ded525
TI
5035 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5036 .dac_nids = alc880_w810_dac_nids,
5037 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5038 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5039 .channel_mode = alc880_w810_modes,
5040 .input_mux = &alc880_capture_source,
5041 },
5042 [ALC880_Z71V] = {
e9edcee0 5043 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5044 .init_verbs = { alc880_volume_init_verbs,
5045 alc880_pin_z71v_init_verbs },
16ded525
TI
5046 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5047 .dac_nids = alc880_z71v_dac_nids,
5048 .dig_out_nid = ALC880_DIGOUT_NID,
5049 .hp_nid = 0x03,
e9edcee0
TI
5050 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5051 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5052 .input_mux = &alc880_capture_source,
5053 },
5054 [ALC880_F1734] = {
e9edcee0 5055 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5056 .init_verbs = { alc880_volume_init_verbs,
5057 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5058 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5059 .dac_nids = alc880_f1734_dac_nids,
5060 .hp_nid = 0x02,
5061 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5062 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5063 .input_mux = &alc880_f1734_capture_source,
5064 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5065 .setup = alc880_uniwill_p53_setup,
d922b51d 5066 .init_hook = alc_hp_automute,
16ded525
TI
5067 },
5068 [ALC880_ASUS] = {
e9edcee0 5069 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5070 .init_verbs = { alc880_volume_init_verbs,
5071 alc880_pin_asus_init_verbs,
e9edcee0
TI
5072 alc880_gpio1_init_verbs },
5073 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5074 .dac_nids = alc880_asus_dac_nids,
5075 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5076 .channel_mode = alc880_asus_modes,
4e195a7b 5077 .need_dac_fix = 1,
16ded525
TI
5078 .input_mux = &alc880_capture_source,
5079 },
5080 [ALC880_ASUS_DIG] = {
e9edcee0 5081 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5082 .init_verbs = { alc880_volume_init_verbs,
5083 alc880_pin_asus_init_verbs,
e9edcee0
TI
5084 alc880_gpio1_init_verbs },
5085 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5086 .dac_nids = alc880_asus_dac_nids,
16ded525 5087 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5088 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5089 .channel_mode = alc880_asus_modes,
4e195a7b 5090 .need_dac_fix = 1,
16ded525
TI
5091 .input_mux = &alc880_capture_source,
5092 },
df694daa
KY
5093 [ALC880_ASUS_DIG2] = {
5094 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5095 .init_verbs = { alc880_volume_init_verbs,
5096 alc880_pin_asus_init_verbs,
df694daa
KY
5097 alc880_gpio2_init_verbs }, /* use GPIO2 */
5098 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5099 .dac_nids = alc880_asus_dac_nids,
5100 .dig_out_nid = ALC880_DIGOUT_NID,
5101 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5102 .channel_mode = alc880_asus_modes,
4e195a7b 5103 .need_dac_fix = 1,
df694daa
KY
5104 .input_mux = &alc880_capture_source,
5105 },
16ded525 5106 [ALC880_ASUS_W1V] = {
e9edcee0 5107 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5108 .init_verbs = { alc880_volume_init_verbs,
5109 alc880_pin_asus_init_verbs,
e9edcee0
TI
5110 alc880_gpio1_init_verbs },
5111 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5112 .dac_nids = alc880_asus_dac_nids,
16ded525 5113 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5114 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5115 .channel_mode = alc880_asus_modes,
4e195a7b 5116 .need_dac_fix = 1,
16ded525
TI
5117 .input_mux = &alc880_capture_source,
5118 },
5119 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5120 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5121 .init_verbs = { alc880_volume_init_verbs,
5122 alc880_pin_asus_init_verbs },
e9edcee0
TI
5123 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5124 .dac_nids = alc880_asus_dac_nids,
16ded525 5125 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5126 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5127 .channel_mode = alc880_asus_modes,
4e195a7b 5128 .need_dac_fix = 1,
16ded525
TI
5129 .input_mux = &alc880_capture_source,
5130 },
ccc656ce
KY
5131 [ALC880_UNIWILL] = {
5132 .mixers = { alc880_uniwill_mixer },
5133 .init_verbs = { alc880_volume_init_verbs,
5134 alc880_uniwill_init_verbs },
5135 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5136 .dac_nids = alc880_asus_dac_nids,
5137 .dig_out_nid = ALC880_DIGOUT_NID,
5138 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5139 .channel_mode = alc880_threestack_modes,
5140 .need_dac_fix = 1,
5141 .input_mux = &alc880_capture_source,
5142 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5143 .setup = alc880_uniwill_setup,
a9fd4f3f 5144 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5145 },
5146 [ALC880_UNIWILL_P53] = {
5147 .mixers = { alc880_uniwill_p53_mixer },
5148 .init_verbs = { alc880_volume_init_verbs,
5149 alc880_uniwill_p53_init_verbs },
5150 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5151 .dac_nids = alc880_asus_dac_nids,
5152 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5153 .channel_mode = alc880_threestack_modes,
5154 .input_mux = &alc880_capture_source,
5155 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5156 .setup = alc880_uniwill_p53_setup,
d922b51d 5157 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5158 },
5159 [ALC880_FUJITSU] = {
45bdd1c1 5160 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5161 .init_verbs = { alc880_volume_init_verbs,
5162 alc880_uniwill_p53_init_verbs,
5163 alc880_beep_init_verbs },
5164 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5165 .dac_nids = alc880_dac_nids,
d53d7d9e 5166 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5167 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5168 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5169 .input_mux = &alc880_capture_source,
5170 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5171 .setup = alc880_uniwill_p53_setup,
d922b51d 5172 .init_hook = alc_hp_automute,
ccc656ce 5173 },
df694daa
KY
5174 [ALC880_CLEVO] = {
5175 .mixers = { alc880_three_stack_mixer },
5176 .init_verbs = { alc880_volume_init_verbs,
5177 alc880_pin_clevo_init_verbs },
5178 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5179 .dac_nids = alc880_dac_nids,
5180 .hp_nid = 0x03,
5181 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5182 .channel_mode = alc880_threestack_modes,
4e195a7b 5183 .need_dac_fix = 1,
df694daa
KY
5184 .input_mux = &alc880_capture_source,
5185 },
ae6b813a
TI
5186 [ALC880_LG] = {
5187 .mixers = { alc880_lg_mixer },
5188 .init_verbs = { alc880_volume_init_verbs,
5189 alc880_lg_init_verbs },
5190 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5191 .dac_nids = alc880_lg_dac_nids,
5192 .dig_out_nid = ALC880_DIGOUT_NID,
5193 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5194 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5195 .need_dac_fix = 1,
ae6b813a 5196 .input_mux = &alc880_lg_capture_source,
d922b51d 5197 .unsol_event = alc_sku_unsol_event,
4f5d1706 5198 .setup = alc880_lg_setup,
d922b51d 5199 .init_hook = alc_hp_automute,
cb53c626
TI
5200#ifdef CONFIG_SND_HDA_POWER_SAVE
5201 .loopbacks = alc880_lg_loopbacks,
5202#endif
ae6b813a 5203 },
d681518a
TI
5204 [ALC880_LG_LW] = {
5205 .mixers = { alc880_lg_lw_mixer },
5206 .init_verbs = { alc880_volume_init_verbs,
5207 alc880_lg_lw_init_verbs },
0a8c5da3 5208 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5209 .dac_nids = alc880_dac_nids,
5210 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5211 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5212 .channel_mode = alc880_lg_lw_modes,
d681518a 5213 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5214 .unsol_event = alc_sku_unsol_event,
4f5d1706 5215 .setup = alc880_lg_lw_setup,
d922b51d 5216 .init_hook = alc_hp_automute,
d681518a 5217 },
df99cd33
TI
5218 [ALC880_MEDION_RIM] = {
5219 .mixers = { alc880_medion_rim_mixer },
5220 .init_verbs = { alc880_volume_init_verbs,
5221 alc880_medion_rim_init_verbs,
5222 alc_gpio2_init_verbs },
5223 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5224 .dac_nids = alc880_dac_nids,
5225 .dig_out_nid = ALC880_DIGOUT_NID,
5226 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5227 .channel_mode = alc880_2_jack_modes,
5228 .input_mux = &alc880_medion_rim_capture_source,
5229 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5230 .setup = alc880_medion_rim_setup,
5231 .init_hook = alc880_medion_rim_automute,
df99cd33 5232 },
16ded525
TI
5233#ifdef CONFIG_SND_DEBUG
5234 [ALC880_TEST] = {
e9edcee0
TI
5235 .mixers = { alc880_test_mixer },
5236 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5237 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5238 .dac_nids = alc880_test_dac_nids,
5239 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5240 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5241 .channel_mode = alc880_test_modes,
5242 .input_mux = &alc880_test_capture_source,
5243 },
5244#endif
5245};
5246
e9edcee0
TI
5247/*
5248 * Automatic parse of I/O pins from the BIOS configuration
5249 */
5250
e9edcee0
TI
5251enum {
5252 ALC_CTL_WIDGET_VOL,
5253 ALC_CTL_WIDGET_MUTE,
5254 ALC_CTL_BIND_MUTE,
5255};
a9111321 5256static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5257 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5258 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5259 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5260};
5261
ce764ab2
TI
5262static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5263{
5264 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5265 return snd_array_new(&spec->kctls);
5266}
5267
e9edcee0 5268/* add dynamic controls */
f12ab1e0 5269static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5270 int cidx, unsigned long val)
e9edcee0 5271{
c8b6bf9b 5272 struct snd_kcontrol_new *knew;
e9edcee0 5273
ce764ab2 5274 knew = alc_kcontrol_new(spec);
603c4019
TI
5275 if (!knew)
5276 return -ENOMEM;
e9edcee0 5277 *knew = alc880_control_templates[type];
543537bd 5278 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5279 if (!knew->name)
e9edcee0 5280 return -ENOMEM;
66ceeb6b 5281 knew->index = cidx;
4d02d1b6 5282 if (get_amp_nid_(val))
5e26dfd0 5283 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5284 knew->private_value = val;
e9edcee0
TI
5285 return 0;
5286}
5287
0afe5f89
TI
5288static int add_control_with_pfx(struct alc_spec *spec, int type,
5289 const char *pfx, const char *dir,
66ceeb6b 5290 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5291{
5292 char name[32];
5293 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5294 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5295}
5296
66ceeb6b
TI
5297#define add_pb_vol_ctrl(spec, type, pfx, val) \
5298 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5299#define add_pb_sw_ctrl(spec, type, pfx, val) \
5300 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5301#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5302 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5303#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5304 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5305
e9edcee0
TI
5306#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5307#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5308#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5309#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5310#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5311#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5312#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5313#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5314#define ALC880_PIN_CD_NID 0x1c
5315
5316/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5317static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5318 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5319{
5320 hda_nid_t nid;
5321 int assigned[4];
5322 int i, j;
5323
5324 memset(assigned, 0, sizeof(assigned));
b0af0de5 5325 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5326
5327 /* check the pins hardwired to audio widget */
5328 for (i = 0; i < cfg->line_outs; i++) {
5329 nid = cfg->line_out_pins[i];
5330 if (alc880_is_fixed_pin(nid)) {
5331 int idx = alc880_fixed_pin_idx(nid);
dda14410 5332 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5333 assigned[idx] = 1;
5334 }
5335 }
5336 /* left pins can be connect to any audio widget */
5337 for (i = 0; i < cfg->line_outs; i++) {
5338 nid = cfg->line_out_pins[i];
5339 if (alc880_is_fixed_pin(nid))
5340 continue;
5341 /* search for an empty channel */
5342 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5343 if (!assigned[j]) {
dda14410 5344 spec->private_dac_nids[i] =
f12ab1e0 5345 alc880_idx_to_dac(j);
e9edcee0
TI
5346 assigned[j] = 1;
5347 break;
5348 }
5349 }
5350 }
5351 spec->multiout.num_dacs = cfg->line_outs;
5352 return 0;
5353}
5354
ce764ab2 5355static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5356 bool can_be_master)
5357{
ce764ab2
TI
5358 struct auto_pin_cfg *cfg = &spec->autocfg;
5359
5360 if (cfg->line_outs == 1 && !spec->multi_ios &&
5361 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5362 return "Master";
5363
5364 switch (cfg->line_out_type) {
5365 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5366 if (cfg->line_outs == 1)
5367 return "Speaker";
5368 break;
bcb2f0f5
TI
5369 case AUTO_PIN_HP_OUT:
5370 return "Headphone";
5371 default:
ce764ab2 5372 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5373 return "PCM";
5374 break;
5375 }
5376 return NULL;
5377}
5378
e9edcee0 5379/* add playback controls from the parsed DAC table */
df694daa
KY
5380static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5381 const struct auto_pin_cfg *cfg)
e9edcee0 5382{
ea734963 5383 static const char * const chname[4] = {
f12ab1e0
TI
5384 "Front", "Surround", NULL /*CLFE*/, "Side"
5385 };
ce764ab2 5386 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5387 hda_nid_t nid;
ce764ab2 5388 int i, err, noutputs;
e9edcee0 5389
ce764ab2
TI
5390 noutputs = cfg->line_outs;
5391 if (spec->multi_ios > 0)
5392 noutputs += spec->multi_ios;
5393
5394 for (i = 0; i < noutputs; i++) {
f12ab1e0 5395 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5396 continue;
5397 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5398 if (!pfx && i == 2) {
e9edcee0 5399 /* Center/LFE */
0afe5f89
TI
5400 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5401 "Center",
f12ab1e0
TI
5402 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5403 HDA_OUTPUT));
5404 if (err < 0)
e9edcee0 5405 return err;
0afe5f89
TI
5406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5407 "LFE",
f12ab1e0
TI
5408 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5409 HDA_OUTPUT));
5410 if (err < 0)
e9edcee0 5411 return err;
0afe5f89
TI
5412 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5413 "Center",
f12ab1e0
TI
5414 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5415 HDA_INPUT));
5416 if (err < 0)
e9edcee0 5417 return err;
0afe5f89
TI
5418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5419 "LFE",
f12ab1e0
TI
5420 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5421 HDA_INPUT));
5422 if (err < 0)
e9edcee0
TI
5423 return err;
5424 } else {
bcb2f0f5 5425 const char *name = pfx;
7e59e097
DH
5426 int index = i;
5427 if (!name) {
bcb2f0f5 5428 name = chname[i];
7e59e097
DH
5429 index = 0;
5430 }
bcb2f0f5 5431 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5432 name, index,
f12ab1e0
TI
5433 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5434 HDA_OUTPUT));
5435 if (err < 0)
e9edcee0 5436 return err;
bcb2f0f5 5437 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5438 name, index,
f12ab1e0
TI
5439 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5440 HDA_INPUT));
5441 if (err < 0)
e9edcee0
TI
5442 return err;
5443 }
5444 }
e9edcee0
TI
5445 return 0;
5446}
5447
8d88bc3d
TI
5448/* add playback controls for speaker and HP outputs */
5449static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5450 const char *pfx)
e9edcee0
TI
5451{
5452 hda_nid_t nid;
5453 int err;
5454
f12ab1e0 5455 if (!pin)
e9edcee0
TI
5456 return 0;
5457
5458 if (alc880_is_fixed_pin(pin)) {
5459 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5460 /* specify the DAC as the extra output */
f12ab1e0 5461 if (!spec->multiout.hp_nid)
e9edcee0 5462 spec->multiout.hp_nid = nid;
82bc955f
TI
5463 else
5464 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5465 /* control HP volume/switch on the output mixer amp */
5466 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5467 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5468 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5469 if (err < 0)
e9edcee0 5470 return err;
0afe5f89 5471 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5472 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5473 if (err < 0)
e9edcee0
TI
5474 return err;
5475 } else if (alc880_is_multi_pin(pin)) {
5476 /* set manual connection */
e9edcee0 5477 /* we have only a switch on HP-out PIN */
0afe5f89 5478 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5479 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5480 if (err < 0)
e9edcee0
TI
5481 return err;
5482 }
5483 return 0;
5484}
5485
5486/* create input playback/capture controls for the given pin */
f12ab1e0 5487static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5488 const char *ctlname, int ctlidx,
df694daa 5489 int idx, hda_nid_t mix_nid)
e9edcee0 5490{
df694daa 5491 int err;
e9edcee0 5492
66ceeb6b 5493 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5494 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5495 if (err < 0)
e9edcee0 5496 return err;
66ceeb6b 5497 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5498 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5499 if (err < 0)
e9edcee0
TI
5500 return err;
5501 return 0;
5502}
5503
05f5f477
TI
5504static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5505{
5506 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5507 return (pincap & AC_PINCAP_IN) != 0;
5508}
5509
e9edcee0 5510/* create playback/capture controls for input pins */
05f5f477
TI
5511static int alc_auto_create_input_ctls(struct hda_codec *codec,
5512 const struct auto_pin_cfg *cfg,
5513 hda_nid_t mixer,
5514 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5515{
05f5f477 5516 struct alc_spec *spec = codec->spec;
61b9b9b1 5517 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5518 int i, err, idx, type_idx = 0;
5519 const char *prev_label = NULL;
e9edcee0 5520
66ceeb6b 5521 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5522 hda_nid_t pin;
10a20af7 5523 const char *label;
05f5f477 5524
66ceeb6b 5525 pin = cfg->inputs[i].pin;
05f5f477
TI
5526 if (!alc_is_input_pin(codec, pin))
5527 continue;
5528
5322bf27
DH
5529 label = hda_get_autocfg_input_label(codec, cfg, i);
5530 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5531 type_idx++;
5532 else
5533 type_idx = 0;
5322bf27
DH
5534 prev_label = label;
5535
05f5f477
TI
5536 if (mixer) {
5537 idx = get_connection_index(codec, mixer, pin);
5538 if (idx >= 0) {
5539 err = new_analog_input(spec, pin,
10a20af7
TI
5540 label, type_idx,
5541 idx, mixer);
05f5f477
TI
5542 if (err < 0)
5543 return err;
5544 }
5545 }
5546
5547 if (!cap1)
5548 continue;
5549 idx = get_connection_index(codec, cap1, pin);
5550 if (idx < 0 && cap2)
5551 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5552 if (idx >= 0)
5553 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5554 }
5555 return 0;
5556}
5557
05f5f477
TI
5558static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5559 const struct auto_pin_cfg *cfg)
5560{
5561 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5562}
5563
f6c7e546
TI
5564static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5565 unsigned int pin_type)
5566{
5567 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5568 pin_type);
5569 /* unmute pin */
d260cdf6
TI
5570 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5571 AMP_OUT_UNMUTE);
f6c7e546
TI
5572}
5573
df694daa
KY
5574static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5575 hda_nid_t nid, int pin_type,
e9edcee0
TI
5576 int dac_idx)
5577{
f6c7e546 5578 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5579 /* need the manual connection? */
5580 if (alc880_is_multi_pin(nid)) {
5581 struct alc_spec *spec = codec->spec;
5582 int idx = alc880_multi_pin_idx(nid);
5583 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5584 AC_VERB_SET_CONNECT_SEL,
5585 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5586 }
5587}
5588
baba8ee9
TI
5589static int get_pin_type(int line_out_type)
5590{
5591 if (line_out_type == AUTO_PIN_HP_OUT)
5592 return PIN_HP;
5593 else
5594 return PIN_OUT;
5595}
5596
e9edcee0
TI
5597static void alc880_auto_init_multi_out(struct hda_codec *codec)
5598{
5599 struct alc_spec *spec = codec->spec;
5600 int i;
ea1fb29a 5601
e9edcee0
TI
5602 for (i = 0; i < spec->autocfg.line_outs; i++) {
5603 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5604 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5605 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5606 }
5607}
5608
8d88bc3d 5609static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5610{
5611 struct alc_spec *spec = codec->spec;
5612 hda_nid_t pin;
5613
82bc955f 5614 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5615 if (pin) /* connect to front */
5616 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5617 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5618 if (pin) /* connect to front */
5619 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5620}
5621
5622static void alc880_auto_init_analog_input(struct hda_codec *codec)
5623{
5624 struct alc_spec *spec = codec->spec;
66ceeb6b 5625 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5626 int i;
5627
66ceeb6b
TI
5628 for (i = 0; i < cfg->num_inputs; i++) {
5629 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5630 if (alc_is_input_pin(codec, nid)) {
30ea098f 5631 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5632 if (nid != ALC880_PIN_CD_NID &&
5633 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5634 snd_hda_codec_write(codec, nid, 0,
5635 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5636 AMP_OUT_MUTE);
5637 }
5638 }
5639}
5640
7f311a46
TI
5641static void alc880_auto_init_input_src(struct hda_codec *codec)
5642{
5643 struct alc_spec *spec = codec->spec;
5644 int c;
5645
5646 for (c = 0; c < spec->num_adc_nids; c++) {
5647 unsigned int mux_idx;
5648 const struct hda_input_mux *imux;
5649 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5650 imux = &spec->input_mux[mux_idx];
5651 if (!imux->num_items && mux_idx > 0)
5652 imux = &spec->input_mux[0];
5653 if (imux)
5654 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5655 AC_VERB_SET_CONNECT_SEL,
5656 imux->items[0].index);
5657 }
5658}
5659
ce764ab2
TI
5660static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5661
e9edcee0 5662/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5663/* return 1 if successful, 0 if the proper config is not found,
5664 * or a negative error code
5665 */
e9edcee0
TI
5666static int alc880_parse_auto_config(struct hda_codec *codec)
5667{
5668 struct alc_spec *spec = codec->spec;
757899ac 5669 int err;
4c6d72d1 5670 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5671
f12ab1e0
TI
5672 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5673 alc880_ignore);
5674 if (err < 0)
e9edcee0 5675 return err;
f12ab1e0 5676 if (!spec->autocfg.line_outs)
e9edcee0 5677 return 0; /* can't find valid BIOS pin config */
df694daa 5678
f12ab1e0 5679 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5680 if (err < 0)
5681 return err;
5682 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5683 if (err < 0)
5684 return err;
5685 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5686 if (err < 0)
5687 return err;
5688 err = alc880_auto_create_extra_out(spec,
5689 spec->autocfg.speaker_pins[0],
5690 "Speaker");
5691 if (err < 0)
5692 return err;
5693 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5694 "Headphone");
5695 if (err < 0)
5696 return err;
05f5f477 5697 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5698 if (err < 0)
e9edcee0
TI
5699 return err;
5700
5701 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5702
757899ac 5703 alc_auto_parse_digital(codec);
e9edcee0 5704
603c4019 5705 if (spec->kctls.list)
d88897ea 5706 add_mixer(spec, spec->kctls.list);
e9edcee0 5707
d88897ea 5708 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5709
a1e8d2da 5710 spec->num_mux_defs = 1;
61b9b9b1 5711 spec->input_mux = &spec->private_imux[0];
e9edcee0 5712
6227cdce 5713 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5714
e9edcee0
TI
5715 return 1;
5716}
5717
ae6b813a
TI
5718/* additional initialization for auto-configuration model */
5719static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5720{
f6c7e546 5721 struct alc_spec *spec = codec->spec;
e9edcee0 5722 alc880_auto_init_multi_out(codec);
8d88bc3d 5723 alc880_auto_init_extra_out(codec);
e9edcee0 5724 alc880_auto_init_analog_input(codec);
7f311a46 5725 alc880_auto_init_input_src(codec);
757899ac 5726 alc_auto_init_digital(codec);
f6c7e546 5727 if (spec->unsol_event)
7fb0d78f 5728 alc_inithook(codec);
e9edcee0
TI
5729}
5730
b59bdf3b
TI
5731/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5732 * one of two digital mic pins, e.g. on ALC272
5733 */
5734static void fixup_automic_adc(struct hda_codec *codec)
5735{
5736 struct alc_spec *spec = codec->spec;
5737 int i;
5738
5739 for (i = 0; i < spec->num_adc_nids; i++) {
5740 hda_nid_t cap = spec->capsrc_nids ?
5741 spec->capsrc_nids[i] : spec->adc_nids[i];
5742 int iidx, eidx;
5743
5744 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5745 if (iidx < 0)
5746 continue;
5747 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5748 if (eidx < 0)
5749 continue;
5750 spec->int_mic.mux_idx = iidx;
5751 spec->ext_mic.mux_idx = eidx;
5752 if (spec->capsrc_nids)
5753 spec->capsrc_nids += i;
5754 spec->adc_nids += i;
5755 spec->num_adc_nids = 1;
8ed99d97
TI
5756 /* optional dock-mic */
5757 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5758 if (eidx < 0)
5759 spec->dock_mic.pin = 0;
5760 else
5761 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5762 return;
5763 }
5764 snd_printd(KERN_INFO "hda_codec: %s: "
5765 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5766 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5767 spec->auto_mic = 0; /* disable auto-mic to be sure */
5768}
5769
748cce43
TI
5770/* select or unmute the given capsrc route */
5771static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5772 int idx)
5773{
5774 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5775 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5776 HDA_AMP_MUTE, 0);
5777 } else {
5778 snd_hda_codec_write_cache(codec, cap, 0,
5779 AC_VERB_SET_CONNECT_SEL, idx);
5780 }
5781}
5782
840b64c0
TI
5783/* set the default connection to that pin */
5784static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5785{
5786 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5787 int i;
5788
8ed99d97
TI
5789 if (!pin)
5790 return 0;
eaa9b3a7
TI
5791 for (i = 0; i < spec->num_adc_nids; i++) {
5792 hda_nid_t cap = spec->capsrc_nids ?
5793 spec->capsrc_nids[i] : spec->adc_nids[i];
5794 int idx;
5795
5796 idx = get_connection_index(codec, cap, pin);
5797 if (idx < 0)
5798 continue;
748cce43 5799 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5800 return i; /* return the found index */
5801 }
5802 return -1; /* not found */
5803}
5804
5805/* choose the ADC/MUX containing the input pin and initialize the setup */
5806static void fixup_single_adc(struct hda_codec *codec)
5807{
5808 struct alc_spec *spec = codec->spec;
66ceeb6b 5809 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5810 int i;
5811
5812 /* search for the input pin; there must be only one */
66ceeb6b 5813 if (cfg->num_inputs != 1)
eaa9b3a7 5814 return;
66ceeb6b 5815 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5816 if (i >= 0) {
5817 /* use only this ADC */
5818 if (spec->capsrc_nids)
5819 spec->capsrc_nids += i;
5820 spec->adc_nids += i;
5821 spec->num_adc_nids = 1;
584c0c4c 5822 spec->single_input_src = 1;
eaa9b3a7
TI
5823 }
5824}
5825
840b64c0
TI
5826/* initialize dual adcs */
5827static void fixup_dual_adc_switch(struct hda_codec *codec)
5828{
5829 struct alc_spec *spec = codec->spec;
5830 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5831 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5832 init_capsrc_for_pin(codec, spec->int_mic.pin);
5833}
5834
584c0c4c
TI
5835/* initialize some special cases for input sources */
5836static void alc_init_special_input_src(struct hda_codec *codec)
5837{
5838 struct alc_spec *spec = codec->spec;
5839 if (spec->dual_adc_switch)
5840 fixup_dual_adc_switch(codec);
5841 else if (spec->single_input_src)
5842 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5843}
5844
b59bdf3b 5845static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5846{
b59bdf3b 5847 struct alc_spec *spec = codec->spec;
a9111321 5848 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5849 { alc_capture_mixer_nosrc1,
5850 alc_capture_mixer_nosrc2,
5851 alc_capture_mixer_nosrc3 },
5852 { alc_capture_mixer1,
5853 alc_capture_mixer2,
5854 alc_capture_mixer3 },
f9e336f6 5855 };
a23b688f 5856 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5857 int mux = 0;
840b64c0
TI
5858 int num_adcs = spec->num_adc_nids;
5859 if (spec->dual_adc_switch)
584c0c4c 5860 num_adcs = 1;
840b64c0 5861 else if (spec->auto_mic)
b59bdf3b 5862 fixup_automic_adc(codec);
eaa9b3a7
TI
5863 else if (spec->input_mux) {
5864 if (spec->input_mux->num_items > 1)
5865 mux = 1;
5866 else if (spec->input_mux->num_items == 1)
5867 fixup_single_adc(codec);
5868 }
840b64c0 5869 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5870 }
f9e336f6
TI
5871}
5872
6694635d 5873/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5874static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5875 int num_nids)
5876{
5877 struct alc_spec *spec = codec->spec;
66ceeb6b 5878 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5879 int n;
5880 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5881
5882 for (n = 0; n < num_nids; n++) {
5883 hda_nid_t adc, cap;
5884 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5885 int nconns, i, j;
5886
5887 adc = nids[n];
5888 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5889 continue;
5890 cap = adc;
5891 nconns = snd_hda_get_connections(codec, cap, conn,
5892 ARRAY_SIZE(conn));
5893 if (nconns == 1) {
5894 cap = conn[0];
5895 nconns = snd_hda_get_connections(codec, cap, conn,
5896 ARRAY_SIZE(conn));
5897 }
5898 if (nconns <= 0)
5899 continue;
5900 if (!fallback_adc) {
5901 fallback_adc = adc;
5902 fallback_cap = cap;
5903 }
66ceeb6b
TI
5904 for (i = 0; i < cfg->num_inputs; i++) {
5905 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5906 for (j = 0; j < nconns; j++) {
5907 if (conn[j] == nid)
5908 break;
5909 }
5910 if (j >= nconns)
5911 break;
5912 }
66ceeb6b 5913 if (i >= cfg->num_inputs) {
6694635d
TI
5914 int num_adcs = spec->num_adc_nids;
5915 spec->private_adc_nids[num_adcs] = adc;
5916 spec->private_capsrc_nids[num_adcs] = cap;
5917 spec->num_adc_nids++;
5918 spec->adc_nids = spec->private_adc_nids;
5919 if (adc != cap)
5920 spec->capsrc_nids = spec->private_capsrc_nids;
5921 }
5922 }
5923 if (!spec->num_adc_nids) {
5924 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5925 " using fallback 0x%x\n",
5926 codec->chip_name, fallback_adc);
6694635d
TI
5927 spec->private_adc_nids[0] = fallback_adc;
5928 spec->adc_nids = spec->private_adc_nids;
5929 if (fallback_adc != fallback_cap) {
5930 spec->private_capsrc_nids[0] = fallback_cap;
5931 spec->capsrc_nids = spec->private_adc_nids;
5932 }
5933 }
5934}
5935
67d634c0 5936#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5937#define set_beep_amp(spec, nid, idx, dir) \
5938 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5939
a9111321 5940static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5941 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5942 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5943 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5944 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5945 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5946 {}
5947};
5948
5949static inline int has_cdefine_beep(struct hda_codec *codec)
5950{
5951 struct alc_spec *spec = codec->spec;
5952 const struct snd_pci_quirk *q;
5953 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5954 if (q)
5955 return q->value;
5956 return spec->cdefine.enable_pcbeep;
5957}
67d634c0
TI
5958#else
5959#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5960#define has_cdefine_beep(codec) 0
67d634c0 5961#endif
45bdd1c1
TI
5962
5963/*
5964 * OK, here we have finally the patch for ALC880
5965 */
5966
1da177e4
LT
5967static int patch_alc880(struct hda_codec *codec)
5968{
5969 struct alc_spec *spec;
5970 int board_config;
df694daa 5971 int err;
1da177e4 5972
e560d8d8 5973 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5974 if (spec == NULL)
5975 return -ENOMEM;
5976
5977 codec->spec = spec;
5978
f5fcc13c
TI
5979 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5980 alc880_models,
5981 alc880_cfg_tbl);
5982 if (board_config < 0) {
9a11f1aa
TI
5983 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5984 codec->chip_name);
e9edcee0 5985 board_config = ALC880_AUTO;
1da177e4 5986 }
1da177e4 5987
e9edcee0
TI
5988 if (board_config == ALC880_AUTO) {
5989 /* automatic parse from the BIOS config */
5990 err = alc880_parse_auto_config(codec);
5991 if (err < 0) {
5992 alc_free(codec);
5993 return err;
f12ab1e0 5994 } else if (!err) {
9c7f852e
TI
5995 printk(KERN_INFO
5996 "hda_codec: Cannot set up configuration "
5997 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5998 board_config = ALC880_3ST;
5999 }
1da177e4
LT
6000 }
6001
680cd536
KK
6002 err = snd_hda_attach_beep_device(codec, 0x1);
6003 if (err < 0) {
6004 alc_free(codec);
6005 return err;
6006 }
6007
df694daa 6008 if (board_config != ALC880_AUTO)
e9c364c0 6009 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 6010
1da177e4
LT
6011 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6012 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 6013 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6014
1da177e4
LT
6015 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6016 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6017
f12ab1e0 6018 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 6019 /* check whether NID 0x07 is valid */
54d17403 6020 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 6021 /* get type */
a22d543a 6022 wcap = get_wcaps_type(wcap);
e9edcee0
TI
6023 if (wcap != AC_WID_AUD_IN) {
6024 spec->adc_nids = alc880_adc_nids_alt;
6025 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
6026 } else {
6027 spec->adc_nids = alc880_adc_nids;
6028 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
6029 }
6030 }
b59bdf3b 6031 set_capture_mixer(codec);
45bdd1c1 6032 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 6033
2134ea4f
TI
6034 spec->vmaster_nid = 0x0c;
6035
1da177e4 6036 codec->patch_ops = alc_patch_ops;
e9edcee0 6037 if (board_config == ALC880_AUTO)
ae6b813a 6038 spec->init_hook = alc880_auto_init;
cb53c626
TI
6039#ifdef CONFIG_SND_HDA_POWER_SAVE
6040 if (!spec->loopback.amplist)
6041 spec->loopback.amplist = alc880_loopbacks;
6042#endif
1da177e4
LT
6043
6044 return 0;
6045}
6046
e9edcee0 6047
1da177e4
LT
6048/*
6049 * ALC260 support
6050 */
6051
4c6d72d1 6052static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6053 /* front */
6054 0x02,
6055};
6056
4c6d72d1 6057static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6058 /* ADC0 */
6059 0x04,
6060};
6061
4c6d72d1 6062static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6063 /* ADC1 */
6064 0x05,
6065};
6066
d57fdac0
JW
6067/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6068 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6069 */
4c6d72d1 6070static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6071 /* ADC0, ADC1 */
6072 0x04, 0x05
6073};
6074
e9edcee0
TI
6075#define ALC260_DIGOUT_NID 0x03
6076#define ALC260_DIGIN_NID 0x06
6077
a9111321 6078static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6079 .num_items = 4,
6080 .items = {
6081 { "Mic", 0x0 },
6082 { "Front Mic", 0x1 },
6083 { "Line", 0x2 },
6084 { "CD", 0x4 },
6085 },
6086};
6087
17e7aec6 6088/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6089 * headphone jack and the internal CD lines since these are the only pins at
6090 * which audio can appear. For flexibility, also allow the option of
6091 * recording the mixer output on the second ADC (ADC0 doesn't have a
6092 * connection to the mixer output).
a9430dd8 6093 */
a9111321 6094static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6095 {
6096 .num_items = 3,
6097 .items = {
6098 { "Mic/Line", 0x0 },
6099 { "CD", 0x4 },
6100 { "Headphone", 0x2 },
6101 },
a9430dd8 6102 },
a1e8d2da
JW
6103 {
6104 .num_items = 4,
6105 .items = {
6106 { "Mic/Line", 0x0 },
6107 { "CD", 0x4 },
6108 { "Headphone", 0x2 },
6109 { "Mixer", 0x5 },
6110 },
6111 },
6112
a9430dd8
JW
6113};
6114
a1e8d2da
JW
6115/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6116 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6117 */
a9111321 6118static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6119 {
6120 .num_items = 4,
6121 .items = {
6122 { "Mic", 0x0 },
6123 { "Line", 0x2 },
6124 { "CD", 0x4 },
6125 { "Headphone", 0x5 },
6126 },
6127 },
6128 {
6129 .num_items = 5,
6130 .items = {
6131 { "Mic", 0x0 },
6132 { "Line", 0x2 },
6133 { "CD", 0x4 },
6134 { "Headphone", 0x6 },
6135 { "Mixer", 0x5 },
6136 },
0bfc90e9
JW
6137 },
6138};
cc959489
MS
6139
6140/* Maxdata Favorit 100XS */
a9111321 6141static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6142 {
6143 .num_items = 2,
6144 .items = {
6145 { "Line/Mic", 0x0 },
6146 { "CD", 0x4 },
6147 },
6148 },
6149 {
6150 .num_items = 3,
6151 .items = {
6152 { "Line/Mic", 0x0 },
6153 { "CD", 0x4 },
6154 { "Mixer", 0x5 },
6155 },
6156 },
6157};
6158
1da177e4
LT
6159/*
6160 * This is just place-holder, so there's something for alc_build_pcms to look
6161 * at when it calculates the maximum number of channels. ALC260 has no mixer
6162 * element which allows changing the channel mode, so the verb list is
6163 * never used.
6164 */
a9111321 6165static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6166 { 2, NULL },
6167};
6168
df694daa
KY
6169
6170/* Mixer combinations
6171 *
6172 * basic: base_output + input + pc_beep + capture
6173 * HP: base_output + input + capture_alt
6174 * HP_3013: hp_3013 + input + capture
6175 * fujitsu: fujitsu + capture
0bfc90e9 6176 * acer: acer + capture
df694daa
KY
6177 */
6178
a9111321 6179static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6180 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6181 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6182 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6183 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6184 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6185 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6186 { } /* end */
f12ab1e0 6187};
1da177e4 6188
a9111321 6189static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6190 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6191 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6192 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6193 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6194 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6195 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6196 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6198 { } /* end */
6199};
6200
bec15c3a 6201/* update HP, line and mono out pins according to the master switch */
e9427969 6202static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a
TI
6203{
6204 struct alc_spec *spec = codec->spec;
e9427969
TI
6205
6206 /* change HP pins */
6207 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
6208 spec->autocfg.hp_pins, spec->master_mute, true);
6209 update_speakers(codec);
bec15c3a
TI
6210}
6211
6212static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6213 struct snd_ctl_elem_value *ucontrol)
6214{
6215 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6216 struct alc_spec *spec = codec->spec;
e9427969 6217 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6218 return 0;
6219}
6220
6221static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6222 struct snd_ctl_elem_value *ucontrol)
6223{
6224 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6225 struct alc_spec *spec = codec->spec;
e9427969 6226 int val = !*ucontrol->value.integer.value;
bec15c3a 6227
e9427969 6228 if (val == spec->master_mute)
bec15c3a 6229 return 0;
e9427969
TI
6230 spec->master_mute = val;
6231 alc260_hp_master_update(codec);
bec15c3a
TI
6232 return 1;
6233}
6234
a9111321 6235static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6236 {
6237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6238 .name = "Master Playback Switch",
5b0cb1d8 6239 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6240 .info = snd_ctl_boolean_mono_info,
6241 .get = alc260_hp_master_sw_get,
6242 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6243 },
6244 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6245 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6246 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6247 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6248 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6249 HDA_OUTPUT),
6250 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6251 { } /* end */
6252};
6253
a9111321 6254static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6255 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6256 {},
6257};
6258
e9427969 6259static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6260{
6261 struct alc_spec *spec = codec->spec;
bec15c3a 6262
e9427969
TI
6263 spec->autocfg.hp_pins[0] = 0x0f;
6264 spec->autocfg.speaker_pins[0] = 0x10;
6265 spec->autocfg.speaker_pins[1] = 0x11;
6266 spec->automute = 1;
6267 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6268}
6269
a9111321 6270static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6271 {
6272 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6273 .name = "Master Playback Switch",
5b0cb1d8 6274 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6275 .info = snd_ctl_boolean_mono_info,
6276 .get = alc260_hp_master_sw_get,
6277 .put = alc260_hp_master_sw_put,
bec15c3a 6278 },
df694daa
KY
6279 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6280 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6282 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6285 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6286 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6287 { } /* end */
6288};
6289
e9427969
TI
6290static void alc260_hp_3013_setup(struct hda_codec *codec)
6291{
6292 struct alc_spec *spec = codec->spec;
6293
6294 spec->autocfg.hp_pins[0] = 0x15;
6295 spec->autocfg.speaker_pins[0] = 0x10;
6296 spec->autocfg.speaker_pins[1] = 0x11;
6297 spec->automute = 1;
6298 spec->automute_mode = ALC_AUTOMUTE_PIN;
6299}
6300
a9111321 6301static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6302 .ops = &snd_hda_bind_vol,
6303 .values = {
6304 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6305 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6306 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6307 0
6308 },
6309};
6310
a9111321 6311static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6312 .ops = &snd_hda_bind_sw,
6313 .values = {
6314 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6315 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6316 0
6317 },
6318};
6319
a9111321 6320static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6321 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6322 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6323 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6324 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6325 { } /* end */
6326};
6327
a9111321 6328static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6329 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6330 {},
6331};
6332
e9427969 6333static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6334{
6335 struct alc_spec *spec = codec->spec;
bec15c3a 6336
e9427969
TI
6337 spec->autocfg.hp_pins[0] = 0x10;
6338 spec->autocfg.speaker_pins[0] = 0x0f;
6339 spec->autocfg.speaker_pins[1] = 0x11;
6340 spec->autocfg.speaker_pins[2] = 0x15;
6341 spec->automute = 1;
6342 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6343}
6344
6345/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6346 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6347 */
a9111321 6348static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6349 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6350 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6351 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6352 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6353 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6354 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6355 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6356 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6357 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6358 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6359 { } /* end */
6360};
6361
a1e8d2da
JW
6362/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6363 * versions of the ALC260 don't act on requests to enable mic bias from NID
6364 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6365 * datasheet doesn't mention this restriction. At this stage it's not clear
6366 * whether this behaviour is intentional or is a hardware bug in chip
6367 * revisions available in early 2006. Therefore for now allow the
6368 * "Headphone Jack Mode" control to span all choices, but if it turns out
6369 * that the lack of mic bias for this NID is intentional we could change the
6370 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6371 *
6372 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6373 * don't appear to make the mic bias available from the "line" jack, even
6374 * though the NID used for this jack (0x14) can supply it. The theory is
6375 * that perhaps Acer have included blocking capacitors between the ALC260
6376 * and the output jack. If this turns out to be the case for all such
6377 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6378 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6379 *
6380 * The C20x Tablet series have a mono internal speaker which is controlled
6381 * via the chip's Mono sum widget and pin complex, so include the necessary
6382 * controls for such models. On models without a "mono speaker" the control
6383 * won't do anything.
a1e8d2da 6384 */
a9111321 6385static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6386 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6387 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6388 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6389 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6390 HDA_OUTPUT),
31bffaa9 6391 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6392 HDA_INPUT),
0bfc90e9
JW
6393 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6394 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6395 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6396 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6397 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6398 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6399 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6400 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6401 { } /* end */
6402};
6403
cc959489
MS
6404/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6405 */
a9111321 6406static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6407 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6409 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6410 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6411 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6412 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6413 { } /* end */
6414};
6415
bc9f98a9
KY
6416/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6417 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6418 */
a9111321 6419static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6420 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6421 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6423 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6424 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6425 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6426 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6427 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6428 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6429 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6430 { } /* end */
6431};
6432
6433/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6434 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6435 */
a9111321 6436static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6437 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6438 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6440 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6441 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6442 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6443 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6444 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6445 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6446 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6447 { } /* end */
6448};
6449
df694daa
KY
6450/*
6451 * initialization verbs
6452 */
a9111321 6453static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6454 /* Line In pin widget for input */
05acb863 6455 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6456 /* CD pin widget for input */
05acb863 6457 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6458 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6459 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6460 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6461 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6462 /* LINE-2 is used for line-out in rear */
05acb863 6463 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6464 /* select line-out */
fd56f2db 6465 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6466 /* LINE-OUT pin */
05acb863 6467 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6468 /* enable HP */
05acb863 6469 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6470 /* enable Mono */
05acb863
TI
6471 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6472 /* mute capture amp left and right */
16ded525 6473 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6474 /* set connection select to line in (default select for this ADC) */
6475 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6476 /* mute capture amp left and right */
6477 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6478 /* set connection select to line in (default select for this ADC) */
6479 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6480 /* set vol=0 Line-Out mixer amp left and right */
6481 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6482 /* unmute pin widget amp left and right (no gain on this amp) */
6483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6484 /* set vol=0 HP mixer amp left and right */
6485 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6486 /* unmute pin widget amp left and right (no gain on this amp) */
6487 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6488 /* set vol=0 Mono mixer amp left and right */
6489 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6490 /* unmute pin widget amp left and right (no gain on this amp) */
6491 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6492 /* unmute LINE-2 out pin */
6493 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6494 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6495 * Line In 2 = 0x03
6496 */
cb53c626
TI
6497 /* mute analog inputs */
6498 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6503 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6504 /* mute Front out path */
6505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6507 /* mute Headphone out path */
6508 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6510 /* mute Mono out path */
6511 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6513 { }
6514};
6515
474167d6 6516#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6517static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6518 /* Headphone and output */
6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6520 /* mono output */
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6522 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6523 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6524 /* Mic2 (front panel) pin widget for input and vref at 80% */
6525 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6526 /* Line In pin widget for input */
6527 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6528 /* Line-2 pin widget for output */
6529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6530 /* CD pin widget for input */
6531 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6532 /* unmute amp left and right */
6533 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6534 /* set connection select to line in (default select for this ADC) */
6535 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6536 /* unmute Line-Out mixer amp left and right (volume = 0) */
6537 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6538 /* mute pin widget amp left and right (no gain on this amp) */
6539 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6540 /* unmute HP mixer amp left and right (volume = 0) */
6541 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6542 /* mute pin widget amp left and right (no gain on this amp) */
6543 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6545 * Line In 2 = 0x03
6546 */
cb53c626
TI
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6554 /* Unmute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6557 /* Unmute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6560 /* Unmute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6563 { }
6564};
474167d6 6565#endif
df694daa 6566
a9111321 6567static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6568 /* Line out and output */
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6570 /* mono output */
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Headphone pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6595 * Line In 2 = 0x03
6596 */
cb53c626
TI
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6613 { }
6614};
6615
a9430dd8 6616/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6617 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6618 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6619 */
a9111321 6620static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6621 /* Disable all GPIOs */
6622 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6623 /* Internal speaker is connected to headphone pin */
6624 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6625 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6627 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6628 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6629 /* Ensure all other unused pins are disabled and muted. */
6630 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6631 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6632 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6633 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6634 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6635 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6636 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6638
6639 /* Disable digital (SPDIF) pins */
6640 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6641 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6642
ea1fb29a 6643 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6644 * when acting as an output.
6645 */
6646 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6647
f7ace40d 6648 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6649 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6652 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6655 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6657 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6658
f7ace40d
JW
6659 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6660 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6661 /* Unmute Line1 pin widget output buffer since it starts as an output.
6662 * If the pin mode is changed by the user the pin mode control will
6663 * take care of enabling the pin's input/output buffers as needed.
6664 * Therefore there's no need to enable the input buffer at this
6665 * stage.
cdcd9268 6666 */
f7ace40d 6667 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6668 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6669 * mixer ctrl)
6670 */
f7ace40d
JW
6671 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6672
6673 /* Mute capture amp left and right */
6674 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6675 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6676 * in (on mic1 pin)
6677 */
6678 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6679
6680 /* Do the same for the second ADC: mute capture input amp and
6681 * set ADC connection to line in (on mic1 pin)
6682 */
6683 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6684 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6685
6686 /* Mute all inputs to mixer widget (even unconnected ones) */
6687 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6695
6696 { }
a9430dd8
JW
6697};
6698
0bfc90e9
JW
6699/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6700 * similar laptops (adapted from Fujitsu init verbs).
6701 */
a9111321 6702static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6703 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6704 * the headphone jack. Turn this on and rely on the standard mute
6705 * methods whenever the user wants to turn these outputs off.
6706 */
6707 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6708 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6709 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6710 /* Internal speaker/Headphone jack is connected to Line-out pin */
6711 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6712 /* Internal microphone/Mic jack is connected to Mic1 pin */
6713 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6714 /* Line In jack is connected to Line1 pin */
6715 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6716 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6717 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6718 /* Ensure all other unused pins are disabled and muted. */
6719 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6720 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6721 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6722 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6723 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6724 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725 /* Disable digital (SPDIF) pins */
6726 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6727 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6728
ea1fb29a 6729 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6730 * bus when acting as outputs.
6731 */
6732 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6733 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6734
6735 /* Start with output sum widgets muted and their output gains at min */
6736 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6739 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6742 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6745
f12ab1e0
TI
6746 /* Unmute Line-out pin widget amp left and right
6747 * (no equiv mixer ctrl)
6748 */
0bfc90e9 6749 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6750 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6751 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6752 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6753 * inputs. If the pin mode is changed by the user the pin mode control
6754 * will take care of enabling the pin's input/output buffers as needed.
6755 * Therefore there's no need to enable the input buffer at this
6756 * stage.
6757 */
6758 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6759 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760
6761 /* Mute capture amp left and right */
6762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6763 /* Set ADC connection select to match default mixer setting - mic
6764 * (on mic1 pin)
6765 */
6766 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6767
6768 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6769 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6770 */
6771 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6772 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6773
6774 /* Mute all inputs to mixer widget (even unconnected ones) */
6775 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6783
6784 { }
6785};
6786
cc959489
MS
6787/* Initialisation sequence for Maxdata Favorit 100XS
6788 * (adapted from Acer init verbs).
6789 */
a9111321 6790static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6791 /* GPIO 0 enables the output jack.
6792 * Turn this on and rely on the standard mute
6793 * methods whenever the user wants to turn these outputs off.
6794 */
6795 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6796 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6797 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6798 /* Line/Mic input jack is connected to Mic1 pin */
6799 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6800 /* Ensure all other unused pins are disabled and muted. */
6801 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6802 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6803 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6804 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6805 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6806 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6808 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6809 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6810 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6811 /* Disable digital (SPDIF) pins */
6812 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6813 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6814
6815 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6816 * bus when acting as outputs.
6817 */
6818 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6819 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6820
6821 /* Start with output sum widgets muted and their output gains at min */
6822 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6825 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6827 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6828 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6830 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6831
6832 /* Unmute Line-out pin widget amp left and right
6833 * (no equiv mixer ctrl)
6834 */
6835 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6836 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6837 * inputs. If the pin mode is changed by the user the pin mode control
6838 * will take care of enabling the pin's input/output buffers as needed.
6839 * Therefore there's no need to enable the input buffer at this
6840 * stage.
6841 */
6842 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6843
6844 /* Mute capture amp left and right */
6845 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6846 /* Set ADC connection select to match default mixer setting - mic
6847 * (on mic1 pin)
6848 */
6849 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6850
6851 /* Do similar with the second ADC: mute capture input amp and
6852 * set ADC connection to mic to match ALSA's default state.
6853 */
6854 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6856
6857 /* Mute all inputs to mixer widget (even unconnected ones) */
6858 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6866
6867 { }
6868};
6869
a9111321 6870static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6871 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6872 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6873 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6874 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6875 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6876 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6877 {}
6878};
6879
a9111321 6880static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6881 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6882 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6883 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6884
6885 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6887 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6888
6889 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6890 {}
6891};
6892
6893/* toggle speaker-output according to the hp-jack state */
6894static void alc260_replacer_672v_automute(struct hda_codec *codec)
6895{
6896 unsigned int present;
6897
6898 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6899 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6900 if (present) {
82beb8fd
TI
6901 snd_hda_codec_write_cache(codec, 0x01, 0,
6902 AC_VERB_SET_GPIO_DATA, 1);
6903 snd_hda_codec_write_cache(codec, 0x0f, 0,
6904 AC_VERB_SET_PIN_WIDGET_CONTROL,
6905 PIN_HP);
bc9f98a9 6906 } else {
82beb8fd
TI
6907 snd_hda_codec_write_cache(codec, 0x01, 0,
6908 AC_VERB_SET_GPIO_DATA, 0);
6909 snd_hda_codec_write_cache(codec, 0x0f, 0,
6910 AC_VERB_SET_PIN_WIDGET_CONTROL,
6911 PIN_OUT);
bc9f98a9
KY
6912 }
6913}
6914
6915static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6916 unsigned int res)
6917{
6918 if ((res >> 26) == ALC880_HP_EVENT)
6919 alc260_replacer_672v_automute(codec);
6920}
6921
a9111321 6922static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6923 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6924 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6925 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6926 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6927 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6928 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6930 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6931 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6932 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6933 {}
6934};
6935
7cf51e48
JW
6936/* Test configuration for debugging, modelled after the ALC880 test
6937 * configuration.
6938 */
6939#ifdef CONFIG_SND_DEBUG
4c6d72d1 6940static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6941 0x02,
6942};
4c6d72d1 6943static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6944 0x04, 0x05,
6945};
a1e8d2da 6946/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6947 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6948 * is NID 0x04.
17e7aec6 6949 */
a9111321 6950static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6951 {
6952 .num_items = 7,
6953 .items = {
6954 { "MIC1 pin", 0x0 },
6955 { "MIC2 pin", 0x1 },
6956 { "LINE1 pin", 0x2 },
6957 { "LINE2 pin", 0x3 },
6958 { "CD pin", 0x4 },
6959 { "LINE-OUT pin", 0x5 },
6960 { "HP-OUT pin", 0x6 },
6961 },
6962 },
6963 {
6964 .num_items = 8,
6965 .items = {
6966 { "MIC1 pin", 0x0 },
6967 { "MIC2 pin", 0x1 },
6968 { "LINE1 pin", 0x2 },
6969 { "LINE2 pin", 0x3 },
6970 { "CD pin", 0x4 },
6971 { "Mixer", 0x5 },
6972 { "LINE-OUT pin", 0x6 },
6973 { "HP-OUT pin", 0x7 },
6974 },
7cf51e48
JW
6975 },
6976};
a9111321 6977static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6978 /* Output driver widgets */
6979 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6980 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6981 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6982 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6983 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6984 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6985
a1e8d2da
JW
6986 /* Modes for retasking pin widgets
6987 * Note: the ALC260 doesn't seem to act on requests to enable mic
6988 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6989 * mention this restriction. At this stage it's not clear whether
6990 * this behaviour is intentional or is a hardware bug in chip
6991 * revisions available at least up until early 2006. Therefore for
6992 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6993 * choices, but if it turns out that the lack of mic bias for these
6994 * NIDs is intentional we could change their modes from
6995 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6996 */
7cf51e48
JW
6997 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6998 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6999 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7000 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7001 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7002 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7003
7004 /* Loopback mixer controls */
7005 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7006 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7007 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7008 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7009 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7010 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7011 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7012 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7013 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7014 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
7015 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7016 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7017 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7018 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
7019
7020 /* Controls for GPIO pins, assuming they are configured as outputs */
7021 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7022 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7023 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7024 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7025
92621f13
JW
7026 /* Switches to allow the digital IO pins to be enabled. The datasheet
7027 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 7028 * make this output available should provide clarification.
92621f13
JW
7029 */
7030 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7031 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7032
f8225f6d
JW
7033 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7034 * this output to turn on an external amplifier.
7035 */
7036 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7037 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7038
7cf51e48
JW
7039 { } /* end */
7040};
a9111321 7041static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
7042 /* Enable all GPIOs as outputs with an initial value of 0 */
7043 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7044 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7045 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7046
7cf51e48
JW
7047 /* Enable retasking pins as output, initially without power amp */
7048 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7049 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7052 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7053 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054
92621f13
JW
7055 /* Disable digital (SPDIF) pins initially, but users can enable
7056 * them via a mixer switch. In the case of SPDIF-out, this initverb
7057 * payload also sets the generation to 0, output to be in "consumer"
7058 * PCM format, copyright asserted, no pre-emphasis and no validity
7059 * control.
7060 */
7cf51e48
JW
7061 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7062 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7063
ea1fb29a 7064 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7065 * OUT1 sum bus when acting as an output.
7066 */
7067 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7068 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7069 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7070 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7071
7072 /* Start with output sum widgets muted and their output gains at min */
7073 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7076 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7077 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7079 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7080 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7081 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7082
cdcd9268
JW
7083 /* Unmute retasking pin widget output buffers since the default
7084 * state appears to be output. As the pin mode is changed by the
7085 * user the pin mode control will take care of enabling the pin's
7086 * input/output buffers as needed.
7087 */
7cf51e48
JW
7088 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7089 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7090 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7093 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7094 /* Also unmute the mono-out pin widget */
7095 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7096
7cf51e48
JW
7097 /* Mute capture amp left and right */
7098 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7099 /* Set ADC connection select to match default mixer setting (mic1
7100 * pin)
7cf51e48
JW
7101 */
7102 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7103
7104 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7105 * set ADC connection to mic1 pin
7cf51e48
JW
7106 */
7107 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7108 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7109
7110 /* Mute all inputs to mixer widget (even unconnected ones) */
7111 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7119
7120 { }
7121};
7122#endif
7123
6330079f
TI
7124#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7125#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7126
a3bcba38
TI
7127#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7128#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7129
df694daa
KY
7130/*
7131 * for BIOS auto-configuration
7132 */
16ded525 7133
df694daa 7134static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7135 const char *pfx, int *vol_bits)
df694daa
KY
7136{
7137 hda_nid_t nid_vol;
7138 unsigned long vol_val, sw_val;
df694daa
KY
7139 int err;
7140
7141 if (nid >= 0x0f && nid < 0x11) {
7142 nid_vol = nid - 0x7;
7143 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7144 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7145 } else if (nid == 0x11) {
7146 nid_vol = nid - 0x7;
7147 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7148 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7149 } else if (nid >= 0x12 && nid <= 0x15) {
7150 nid_vol = 0x08;
7151 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7152 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7153 } else
7154 return 0; /* N/A */
ea1fb29a 7155
863b4518
TI
7156 if (!(*vol_bits & (1 << nid_vol))) {
7157 /* first control for the volume widget */
0afe5f89 7158 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7159 if (err < 0)
7160 return err;
7161 *vol_bits |= (1 << nid_vol);
7162 }
0afe5f89 7163 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7164 if (err < 0)
df694daa
KY
7165 return err;
7166 return 1;
7167}
7168
7169/* add playback controls from the parsed DAC table */
7170static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7171 const struct auto_pin_cfg *cfg)
7172{
7173 hda_nid_t nid;
7174 int err;
863b4518 7175 int vols = 0;
df694daa
KY
7176
7177 spec->multiout.num_dacs = 1;
7178 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7179 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7180
7181 nid = cfg->line_out_pins[0];
7182 if (nid) {
23112d6d
TI
7183 const char *pfx;
7184 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7185 pfx = "Master";
7186 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7187 pfx = "Speaker";
7188 else
7189 pfx = "Front";
7190 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7191 if (err < 0)
7192 return err;
7193 }
7194
82bc955f 7195 nid = cfg->speaker_pins[0];
df694daa 7196 if (nid) {
863b4518 7197 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7198 if (err < 0)
7199 return err;
7200 }
7201
eb06ed8f 7202 nid = cfg->hp_pins[0];
df694daa 7203 if (nid) {
863b4518
TI
7204 err = alc260_add_playback_controls(spec, nid, "Headphone",
7205 &vols);
df694daa
KY
7206 if (err < 0)
7207 return err;
7208 }
f12ab1e0 7209 return 0;
df694daa
KY
7210}
7211
7212/* create playback/capture controls for input pins */
05f5f477 7213static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7214 const struct auto_pin_cfg *cfg)
7215{
05f5f477 7216 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7217}
7218
7219static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7220 hda_nid_t nid, int pin_type,
7221 int sel_idx)
7222{
f6c7e546 7223 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7224 /* need the manual connection? */
7225 if (nid >= 0x12) {
7226 int idx = nid - 0x12;
7227 snd_hda_codec_write(codec, idx + 0x0b, 0,
7228 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7229 }
7230}
7231
7232static void alc260_auto_init_multi_out(struct hda_codec *codec)
7233{
7234 struct alc_spec *spec = codec->spec;
7235 hda_nid_t nid;
7236
f12ab1e0 7237 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7238 if (nid) {
7239 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7240 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7241 }
ea1fb29a 7242
82bc955f 7243 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7244 if (nid)
7245 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7246
eb06ed8f 7247 nid = spec->autocfg.hp_pins[0];
df694daa 7248 if (nid)
baba8ee9 7249 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7250}
df694daa
KY
7251
7252#define ALC260_PIN_CD_NID 0x16
7253static void alc260_auto_init_analog_input(struct hda_codec *codec)
7254{
7255 struct alc_spec *spec = codec->spec;
66ceeb6b 7256 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7257 int i;
7258
66ceeb6b
TI
7259 for (i = 0; i < cfg->num_inputs; i++) {
7260 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7261 if (nid >= 0x12) {
30ea098f 7262 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7263 if (nid != ALC260_PIN_CD_NID &&
7264 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7265 snd_hda_codec_write(codec, nid, 0,
7266 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7267 AMP_OUT_MUTE);
7268 }
7269 }
7270}
7271
7f311a46
TI
7272#define alc260_auto_init_input_src alc880_auto_init_input_src
7273
df694daa
KY
7274/*
7275 * generic initialization of ADC, input mixers and output mixers
7276 */
a9111321 7277static const struct hda_verb alc260_volume_init_verbs[] = {
df694daa
KY
7278 /*
7279 * Unmute ADC0-1 and set the default input to mic-in
7280 */
7281 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7282 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7283 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7284 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7285
df694daa
KY
7286 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7287 * mixer widget
f12ab1e0
TI
7288 * Note: PASD motherboards uses the Line In 2 as the input for
7289 * front panel mic (mic 2)
df694daa
KY
7290 */
7291 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7292 /* mute analog inputs */
7293 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7295 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7297 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7298
7299 /*
7300 * Set up output mixers (0x08 - 0x0a)
7301 */
7302 /* set vol=0 to output mixers */
7303 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7304 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7305 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 /* set up input amps for analog loopback */
7307 /* Amp Indices: DAC = 0, mixer = 1 */
7308 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7310 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7312 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7313 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7314
df694daa
KY
7315 { }
7316};
7317
7318static int alc260_parse_auto_config(struct hda_codec *codec)
7319{
7320 struct alc_spec *spec = codec->spec;
df694daa 7321 int err;
4c6d72d1 7322 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7323
f12ab1e0
TI
7324 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7325 alc260_ignore);
7326 if (err < 0)
df694daa 7327 return err;
f12ab1e0
TI
7328 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7329 if (err < 0)
4a471b7d 7330 return err;
603c4019 7331 if (!spec->kctls.list)
df694daa 7332 return 0; /* can't find valid BIOS pin config */
05f5f477 7333 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7334 if (err < 0)
df694daa
KY
7335 return err;
7336
7337 spec->multiout.max_channels = 2;
7338
0852d7a6 7339 if (spec->autocfg.dig_outs)
df694daa 7340 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7341 if (spec->kctls.list)
d88897ea 7342 add_mixer(spec, spec->kctls.list);
df694daa 7343
d88897ea 7344 add_verb(spec, alc260_volume_init_verbs);
df694daa 7345
a1e8d2da 7346 spec->num_mux_defs = 1;
61b9b9b1 7347 spec->input_mux = &spec->private_imux[0];
df694daa 7348
6227cdce 7349 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7350
df694daa
KY
7351 return 1;
7352}
7353
ae6b813a
TI
7354/* additional initialization for auto-configuration model */
7355static void alc260_auto_init(struct hda_codec *codec)
df694daa 7356{
f6c7e546 7357 struct alc_spec *spec = codec->spec;
df694daa
KY
7358 alc260_auto_init_multi_out(codec);
7359 alc260_auto_init_analog_input(codec);
7f311a46 7360 alc260_auto_init_input_src(codec);
757899ac 7361 alc_auto_init_digital(codec);
f6c7e546 7362 if (spec->unsol_event)
7fb0d78f 7363 alc_inithook(codec);
df694daa
KY
7364}
7365
cb53c626 7366#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7367static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7368 { 0x07, HDA_INPUT, 0 },
7369 { 0x07, HDA_INPUT, 1 },
7370 { 0x07, HDA_INPUT, 2 },
7371 { 0x07, HDA_INPUT, 3 },
7372 { 0x07, HDA_INPUT, 4 },
7373 { } /* end */
7374};
7375#endif
7376
fc091769
TI
7377/*
7378 * Pin config fixes
7379 */
7380enum {
7381 PINFIX_HP_DC5750,
7382};
7383
fc091769
TI
7384static const struct alc_fixup alc260_fixups[] = {
7385 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7386 .type = ALC_FIXUP_PINS,
7387 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7388 { 0x11, 0x90130110 }, /* speaker */
7389 { }
7390 }
fc091769
TI
7391 },
7392};
7393
a9111321 7394static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7395 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7396 {}
7397};
7398
df694daa
KY
7399/*
7400 * ALC260 configurations
7401 */
ea734963 7402static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7403 [ALC260_BASIC] = "basic",
7404 [ALC260_HP] = "hp",
7405 [ALC260_HP_3013] = "hp-3013",
2922c9af 7406 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7407 [ALC260_FUJITSU_S702X] = "fujitsu",
7408 [ALC260_ACER] = "acer",
bc9f98a9
KY
7409 [ALC260_WILL] = "will",
7410 [ALC260_REPLACER_672V] = "replacer",
cc959489 7411 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7412#ifdef CONFIG_SND_DEBUG
f5fcc13c 7413 [ALC260_TEST] = "test",
7cf51e48 7414#endif
f5fcc13c
TI
7415 [ALC260_AUTO] = "auto",
7416};
7417
a9111321 7418static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7419 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7420 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7421 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7422 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7423 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7424 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7425 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7426 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7427 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7428 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7429 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7432 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7435 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7436 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7437 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7438 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7439 {}
7440};
7441
a9111321 7442static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7443 [ALC260_BASIC] = {
7444 .mixers = { alc260_base_output_mixer,
45bdd1c1 7445 alc260_input_mixer },
df694daa
KY
7446 .init_verbs = { alc260_init_verbs },
7447 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7448 .dac_nids = alc260_dac_nids,
f9e336f6 7449 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7450 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7451 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7452 .channel_mode = alc260_modes,
7453 .input_mux = &alc260_capture_source,
7454 },
7455 [ALC260_HP] = {
bec15c3a 7456 .mixers = { alc260_hp_output_mixer,
f9e336f6 7457 alc260_input_mixer },
bec15c3a
TI
7458 .init_verbs = { alc260_init_verbs,
7459 alc260_hp_unsol_verbs },
df694daa
KY
7460 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7461 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7462 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7463 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7464 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7465 .channel_mode = alc260_modes,
7466 .input_mux = &alc260_capture_source,
e9427969
TI
7467 .unsol_event = alc_sku_unsol_event,
7468 .setup = alc260_hp_setup,
7469 .init_hook = alc_inithook,
df694daa 7470 },
3f878308
KY
7471 [ALC260_HP_DC7600] = {
7472 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7473 alc260_input_mixer },
3f878308
KY
7474 .init_verbs = { alc260_init_verbs,
7475 alc260_hp_dc7600_verbs },
7476 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7477 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7478 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7479 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7480 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7481 .channel_mode = alc260_modes,
7482 .input_mux = &alc260_capture_source,
e9427969
TI
7483 .unsol_event = alc_sku_unsol_event,
7484 .setup = alc260_hp_3012_setup,
7485 .init_hook = alc_inithook,
3f878308 7486 },
df694daa
KY
7487 [ALC260_HP_3013] = {
7488 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7489 alc260_input_mixer },
bec15c3a
TI
7490 .init_verbs = { alc260_hp_3013_init_verbs,
7491 alc260_hp_3013_unsol_verbs },
df694daa
KY
7492 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7493 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7494 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7495 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7496 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7497 .channel_mode = alc260_modes,
7498 .input_mux = &alc260_capture_source,
e9427969
TI
7499 .unsol_event = alc_sku_unsol_event,
7500 .setup = alc260_hp_3013_setup,
7501 .init_hook = alc_inithook,
df694daa
KY
7502 },
7503 [ALC260_FUJITSU_S702X] = {
f9e336f6 7504 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7505 .init_verbs = { alc260_fujitsu_init_verbs },
7506 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7507 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7508 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7509 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7510 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7511 .channel_mode = alc260_modes,
a1e8d2da
JW
7512 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7513 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7514 },
0bfc90e9 7515 [ALC260_ACER] = {
f9e336f6 7516 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7517 .init_verbs = { alc260_acer_init_verbs },
7518 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7519 .dac_nids = alc260_dac_nids,
7520 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7521 .adc_nids = alc260_dual_adc_nids,
7522 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7523 .channel_mode = alc260_modes,
a1e8d2da
JW
7524 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7525 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7526 },
cc959489
MS
7527 [ALC260_FAVORIT100] = {
7528 .mixers = { alc260_favorit100_mixer },
7529 .init_verbs = { alc260_favorit100_init_verbs },
7530 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7531 .dac_nids = alc260_dac_nids,
7532 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7533 .adc_nids = alc260_dual_adc_nids,
7534 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7535 .channel_mode = alc260_modes,
7536 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7537 .input_mux = alc260_favorit100_capture_sources,
7538 },
bc9f98a9 7539 [ALC260_WILL] = {
f9e336f6 7540 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7541 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7542 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7543 .dac_nids = alc260_dac_nids,
7544 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7545 .adc_nids = alc260_adc_nids,
7546 .dig_out_nid = ALC260_DIGOUT_NID,
7547 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7548 .channel_mode = alc260_modes,
7549 .input_mux = &alc260_capture_source,
7550 },
7551 [ALC260_REPLACER_672V] = {
f9e336f6 7552 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7553 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7554 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7555 .dac_nids = alc260_dac_nids,
7556 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7557 .adc_nids = alc260_adc_nids,
7558 .dig_out_nid = ALC260_DIGOUT_NID,
7559 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7560 .channel_mode = alc260_modes,
7561 .input_mux = &alc260_capture_source,
7562 .unsol_event = alc260_replacer_672v_unsol_event,
7563 .init_hook = alc260_replacer_672v_automute,
7564 },
7cf51e48
JW
7565#ifdef CONFIG_SND_DEBUG
7566 [ALC260_TEST] = {
f9e336f6 7567 .mixers = { alc260_test_mixer },
7cf51e48
JW
7568 .init_verbs = { alc260_test_init_verbs },
7569 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7570 .dac_nids = alc260_test_dac_nids,
7571 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7572 .adc_nids = alc260_test_adc_nids,
7573 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7574 .channel_mode = alc260_modes,
a1e8d2da
JW
7575 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7576 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7577 },
7578#endif
df694daa
KY
7579};
7580
7581static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7582{
7583 struct alc_spec *spec;
df694daa 7584 int err, board_config;
1da177e4 7585
e560d8d8 7586 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7587 if (spec == NULL)
7588 return -ENOMEM;
7589
7590 codec->spec = spec;
7591
f5fcc13c
TI
7592 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7593 alc260_models,
7594 alc260_cfg_tbl);
7595 if (board_config < 0) {
9a11f1aa 7596 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7597 codec->chip_name);
df694daa 7598 board_config = ALC260_AUTO;
16ded525 7599 }
1da177e4 7600
b5bfbc67
TI
7601 if (board_config == ALC260_AUTO) {
7602 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7603 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7604 }
fc091769 7605
df694daa
KY
7606 if (board_config == ALC260_AUTO) {
7607 /* automatic parse from the BIOS config */
7608 err = alc260_parse_auto_config(codec);
7609 if (err < 0) {
7610 alc_free(codec);
7611 return err;
f12ab1e0 7612 } else if (!err) {
9c7f852e
TI
7613 printk(KERN_INFO
7614 "hda_codec: Cannot set up configuration "
7615 "from BIOS. Using base mode...\n");
df694daa
KY
7616 board_config = ALC260_BASIC;
7617 }
a9430dd8 7618 }
e9edcee0 7619
680cd536
KK
7620 err = snd_hda_attach_beep_device(codec, 0x1);
7621 if (err < 0) {
7622 alc_free(codec);
7623 return err;
7624 }
7625
df694daa 7626 if (board_config != ALC260_AUTO)
e9c364c0 7627 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7628
1da177e4
LT
7629 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7630 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7631 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7632
a3bcba38
TI
7633 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7634 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7635
4ef0ef19
TI
7636 if (!spec->adc_nids && spec->input_mux) {
7637 /* check whether NID 0x04 is valid */
7638 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7639 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7640 /* get type */
7641 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7642 spec->adc_nids = alc260_adc_nids_alt;
7643 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7644 } else {
7645 spec->adc_nids = alc260_adc_nids;
7646 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7647 }
7648 }
b59bdf3b 7649 set_capture_mixer(codec);
45bdd1c1 7650 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7651
b5bfbc67 7652 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7653
2134ea4f
TI
7654 spec->vmaster_nid = 0x08;
7655
1da177e4 7656 codec->patch_ops = alc_patch_ops;
df694daa 7657 if (board_config == ALC260_AUTO)
ae6b813a 7658 spec->init_hook = alc260_auto_init;
1c716153 7659 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7660#ifdef CONFIG_SND_HDA_POWER_SAVE
7661 if (!spec->loopback.amplist)
7662 spec->loopback.amplist = alc260_loopbacks;
7663#endif
1da177e4
LT
7664
7665 return 0;
7666}
7667
e9edcee0 7668
1da177e4 7669/*
4953550a 7670 * ALC882/883/885/888/889 support
1da177e4
LT
7671 *
7672 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7673 * configuration. Each pin widget can choose any input DACs and a mixer.
7674 * Each ADC is connected from a mixer of all inputs. This makes possible
7675 * 6-channel independent captures.
7676 *
7677 * In addition, an independent DAC for the multi-playback (not used in this
7678 * driver yet).
7679 */
df694daa
KY
7680#define ALC882_DIGOUT_NID 0x06
7681#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7682#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7683#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7684#define ALC1200_DIGOUT_NID 0x10
7685
1da177e4 7686
a9111321 7687static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7688 { 8, NULL }
7689};
7690
4953550a 7691/* DACs */
4c6d72d1 7692static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7693 /* front, rear, clfe, rear_surr */
7694 0x02, 0x03, 0x04, 0x05
7695};
4953550a 7696#define alc883_dac_nids alc882_dac_nids
1da177e4 7697
4953550a 7698/* ADCs */
df694daa
KY
7699#define alc882_adc_nids alc880_adc_nids
7700#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7701#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7702static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7703static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7704#define alc889_adc_nids alc880_adc_nids
1da177e4 7705
4c6d72d1
TI
7706static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7707static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7708#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7709static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7710#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7711
1da177e4
LT
7712/* input MUX */
7713/* FIXME: should be a matrix-type input source selection */
7714
a9111321 7715static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7716 .num_items = 4,
7717 .items = {
7718 { "Mic", 0x0 },
7719 { "Front Mic", 0x1 },
7720 { "Line", 0x2 },
7721 { "CD", 0x4 },
7722 },
7723};
41d5545d 7724
4953550a
TI
7725#define alc883_capture_source alc882_capture_source
7726
a9111321 7727static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7728 .num_items = 3,
7729 .items = {
7730 { "Front Mic", 0x0 },
7731 { "Mic", 0x3 },
7732 { "Line", 0x2 },
7733 },
7734};
7735
a9111321 7736static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7737 .num_items = 3,
7738 .items = {
7739 { "Mic", 0x1 },
b8f171e7 7740 { "Line", 0x7 },
41d5545d
KS
7741 { "CD", 0x4 },
7742 },
7743};
7744
a9111321 7745static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7746 .num_items = 2,
7747 .items = {
7748 { "Line", 0x2 },
7749 { "CD", 0x4 },
7750 },
7751};
7752
a9111321 7753static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7754 .num_items = 4,
7755 .items = {
7756 { "Mic", 0x1 },
7757 { "Front Mic", 0x0 },
7758 { "Line", 0x2 },
7759 { "CD", 0x4 },
7760 },
7761};
7762
a9111321 7763static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7764 .num_items = 2,
7765 .items = {
7766 { "Mic", 0x1 },
7767 { "Line", 0x2 },
7768 },
7769};
7770
a9111321 7771static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7772 .num_items = 4,
7773 .items = {
7774 { "Mic", 0x0 },
28c4edb7 7775 { "Internal Mic", 0x1 },
4953550a
TI
7776 { "Line", 0x2 },
7777 { "CD", 0x4 },
7778 },
7779};
7780
a9111321 7781static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7782 .num_items = 2,
7783 .items = {
7784 { "Mic", 0x0 },
28c4edb7 7785 { "Internal Mic", 0x1 },
4953550a
TI
7786 },
7787};
7788
a9111321 7789static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7790 .num_items = 3,
7791 .items = {
7792 { "Mic", 0x0 },
7793 { "Front Mic", 0x1 },
7794 { "Line", 0x4 },
7795 },
7796};
7797
a9111321 7798static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7799 .num_items = 2,
7800 .items = {
7801 { "Mic", 0x0 },
7802 { "Line", 0x2 },
7803 },
7804};
7805
a9111321 7806static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7807 .num_items = 2,
7808 .items = {
7809 { "Mic", 0x0 },
7810 /* Front Mic (0x01) unused */
7811 { "Line", 0x2 },
7812 /* Line 2 (0x03) unused */
af901ca1 7813 /* CD (0x04) unused? */
4953550a
TI
7814 },
7815};
7816
a9111321 7817static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7818 .num_items = 2,
7819 .items = {
7820 { "Mic", 0x01 },
7821 { "Line", 0x2 }, /* Not sure! */
7822 },
7823};
7824
4953550a
TI
7825/*
7826 * 2ch mode
7827 */
a9111321 7828static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7829 { 2, NULL }
7830};
7831
272a527c
KY
7832/*
7833 * 2ch mode
7834 */
a9111321 7835static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 { } /* end */
7841};
7842
4953550a
TI
7843/*
7844 * 4ch mode
7845 */
a9111321 7846static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7847 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7848 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7851 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7852 { } /* end */
7853};
7854
272a527c
KY
7855/*
7856 * 6ch mode
7857 */
a9111321 7858static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7859 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7860 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7861 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7862 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7863 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7864 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7865 { } /* end */
7866};
7867
a9111321 7868static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7869 { 2, alc882_3ST_ch2_init },
4953550a 7870 { 4, alc882_3ST_ch4_init },
272a527c
KY
7871 { 6, alc882_3ST_ch6_init },
7872};
7873
4953550a
TI
7874#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7875
a65cc60f 7876/*
7877 * 2ch mode
7878 */
a9111321 7879static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7880 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7881 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7882 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7883 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7884 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7885 { } /* end */
7886};
7887
7888/*
7889 * 4ch mode
7890 */
a9111321 7891static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7892 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7894 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7895 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7897 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7898 { } /* end */
7899};
7900
7901/*
7902 * 6ch mode
7903 */
a9111321 7904static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7905 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7906 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7908 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7909 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7911 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7912 { } /* end */
7913};
7914
a9111321 7915static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7916 { 2, alc883_3ST_ch2_clevo_init },
7917 { 4, alc883_3ST_ch4_clevo_init },
7918 { 6, alc883_3ST_ch6_clevo_init },
7919};
7920
7921
df694daa
KY
7922/*
7923 * 6ch mode
7924 */
a9111321 7925static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7926 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7927 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7928 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { } /* end */
7931};
7932
7933/*
7934 * 8ch mode
7935 */
a9111321 7936static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7937 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7938 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { } /* end */
7942};
7943
a9111321 7944static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7945 { 6, alc882_sixstack_ch6_init },
7946 { 8, alc882_sixstack_ch8_init },
7947};
7948
76e6f5a9
RH
7949
7950/* Macbook Air 2,1 */
7951
a9111321 7952static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7953 { 2, NULL },
7954};
7955
87350ad0 7956/*
def319f9 7957 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7958 */
7959
7960/*
7961 * 2ch mode
7962 */
a9111321 7963static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7964 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7965 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7967 { } /* end */
7968};
7969
7970/*
a3f730af 7971 * 4ch mode
87350ad0 7972 */
a9111321 7973static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7974 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7975 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7976 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7977 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7979 { } /* end */
7980};
7981
a9111321 7982static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7983 { 2, alc885_mbp_ch2_init },
a3f730af 7984 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7985};
7986
92b9de83
KS
7987/*
7988 * 2ch
7989 * Speakers/Woofer/HP = Front
7990 * LineIn = Input
7991 */
a9111321 7992static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7993 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7994 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7995 { } /* end */
7996};
7997
7998/*
7999 * 6ch mode
8000 * Speakers/HP = Front
8001 * Woofer = LFE
8002 * LineIn = Surround
8003 */
a9111321 8004static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
8005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8006 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8008 { } /* end */
8009};
8010
a9111321 8011static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
8012 { 2, alc885_mb5_ch2_init },
8013 { 6, alc885_mb5_ch6_init },
8014};
87350ad0 8015
d01aecdf 8016#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
8017
8018/*
8019 * 2ch mode
8020 */
a9111321 8021static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
8022 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8023 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8024 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8025 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8026 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8027 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8028 { } /* end */
8029};
8030
8031/*
8032 * 4ch mode
8033 */
a9111321 8034static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
8035 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8036 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8037 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8038 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8039 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8041 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8042 { } /* end */
8043};
8044
8045/*
8046 * 6ch mode
8047 */
a9111321 8048static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8049 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8050 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8051 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8052 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8053 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8054 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8055 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8056 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8057 { } /* end */
8058};
8059
8060/*
8061 * 8ch mode
8062 */
a9111321 8063static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8064 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8065 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8066 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8067 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8068 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8069 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8070 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8071 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8072 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8073 { } /* end */
8074};
8075
a9111321 8076static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8077 { 2, alc883_4ST_ch2_init },
8078 { 4, alc883_4ST_ch4_init },
8079 { 6, alc883_4ST_ch6_init },
8080 { 8, alc883_4ST_ch8_init },
8081};
8082
8083
8084/*
8085 * 2ch mode
8086 */
a9111321 8087static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8088 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8089 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8090 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8091 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8092 { } /* end */
8093};
8094
8095/*
8096 * 4ch mode
8097 */
a9111321 8098static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8099 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8100 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8101 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8102 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8103 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8104 { } /* end */
8105};
8106
8107/*
8108 * 6ch mode
8109 */
a9111321 8110static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8111 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8112 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8113 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8114 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8115 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8116 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8117 { } /* end */
8118};
8119
a9111321 8120static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8121 { 2, alc883_3ST_ch2_intel_init },
8122 { 4, alc883_3ST_ch4_intel_init },
8123 { 6, alc883_3ST_ch6_intel_init },
8124};
8125
dd7714c9
WF
8126/*
8127 * 2ch mode
8128 */
a9111321 8129static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8130 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8131 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8135 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8136 { } /* end */
8137};
8138
87a8c370
JK
8139/*
8140 * 6ch mode
8141 */
a9111321 8142static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8143 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8144 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8145 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8146 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8147 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8148 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8149 { } /* end */
8150};
8151
8152/*
8153 * 8ch mode
8154 */
a9111321 8155static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8156 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8157 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8158 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8159 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8160 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8161 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8162 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8163 { } /* end */
8164};
8165
a9111321 8166static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8167 { 2, alc889_ch2_intel_init },
87a8c370
JK
8168 { 6, alc889_ch6_intel_init },
8169 { 8, alc889_ch8_intel_init },
8170};
8171
4953550a
TI
8172/*
8173 * 6ch mode
8174 */
a9111321 8175static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8176 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8177 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8178 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { } /* end */
8181};
8182
8183/*
8184 * 8ch mode
8185 */
a9111321 8186static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8187 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8188 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { } /* end */
8192};
8193
a9111321 8194static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8195 { 6, alc883_sixstack_ch6_init },
8196 { 8, alc883_sixstack_ch8_init },
8197};
8198
8199
1da177e4
LT
8200/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8201 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8202 */
a9111321 8203static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8204 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8205 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8206 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8207 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8208 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8209 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8210 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8211 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8212 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8213 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8214 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8215 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8216 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8218 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8220 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8222 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8223 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8224 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8225 { } /* end */
8226};
8227
76e6f5a9
RH
8228/* Macbook Air 2,1 same control for HP and internal Speaker */
8229
a9111321 8230static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8231 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8232 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8233 { }
8234};
8235
8236
a9111321 8237static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8238 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8239 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8241 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8242 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8243 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8244 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8245 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8246 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8247 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8249 { } /* end */
8250};
41d5545d 8251
a9111321 8252static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8253 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8254 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8255 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8256 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8257 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8258 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8260 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8262 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8264 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8265 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8267 { } /* end */
8268};
92b9de83 8269
a9111321 8270static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8271 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8272 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8273 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8274 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8275 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8276 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8277 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8278 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8280 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8281 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8282 { } /* end */
8283};
8284
a9111321 8285static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8287 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8288 { } /* end */
8289};
8290
8291
a9111321 8292static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8293 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8294 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8295 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8296 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8298 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8300 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8301 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8302 { } /* end */
8303};
8304
a9111321 8305static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8306 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8307 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8308 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8309 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8310 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8312 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8314 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8315 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8316 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8317 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8318 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8319 { } /* end */
8320};
8321
8322/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8323 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8324 */
a9111321 8325static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8326 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8327 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8331 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8333 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8335 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8337 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8338 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8339 { } /* end */
8340};
8341
a9111321 8342static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8343 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8344 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8346 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8347 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8351 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8352 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8353 { } /* end */
8354};
8355
a9111321 8356static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8357 {
8358 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8359 .name = "Channel Mode",
8360 .info = alc_ch_mode_info,
8361 .get = alc_ch_mode_get,
8362 .put = alc_ch_mode_put,
8363 },
8364 { } /* end */
8365};
8366
a9111321 8367static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8368 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8371 /* Rear mixer */
05acb863
TI
8372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8374 /* CLFE mixer */
05acb863
TI
8375 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8377 /* Side mixer */
05acb863
TI
8378 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8380
e9edcee0 8381 /* Front Pin: output 0 (0x0c) */
05acb863 8382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8384 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8385 /* Rear Pin: output 1 (0x0d) */
05acb863 8386 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8387 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8388 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8389 /* CLFE Pin: output 2 (0x0e) */
05acb863 8390 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8391 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8392 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8393 /* Side Pin: output 3 (0x0f) */
05acb863 8394 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8395 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8396 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8397 /* Mic (rear) pin: input vref at 80% */
16ded525 8398 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8399 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Front Mic pin: input vref at 80% */
16ded525 8401 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8402 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line In pin: input */
05acb863 8404 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8405 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8406 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8407 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8408 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8409 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8410 /* CD pin widget for input */
05acb863 8411 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8412
8413 /* FIXME: use matrix-type input source selection */
8414 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8415 /* Input mixer2 */
05acb863 8416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8417 /* Input mixer3 */
05acb863 8418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8419 /* ADC2: mute amp left and right */
8420 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8421 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8422 /* ADC3: mute amp left and right */
8423 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8424 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8425
8426 { }
8427};
8428
a9111321 8429static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8430 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8431 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8435 /* ADC1: mute amp left and right */
8436 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8437 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8438 { }
8439};
8440
a9111321 8441static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8442 /* change to EAPD mode */
8443 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8444 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8445 { }
4b146cb0
TI
8446};
8447
a9111321 8448static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8449 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8450 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 { }
8452};
8453
a9111321 8454static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8455 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8457 {}
8458};
87a8c370 8459
a9111321 8460static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8461 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8462 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8464 /* Rear mixer */
88102f3f
KY
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8467 /* CLFE mixer */
88102f3f
KY
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8470 /* Side mixer */
88102f3f
KY
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8473
8474 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8475 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8476 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8477 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* Front Pin: output 0 (0x0c) */
8479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8482 /* Rear Pin: output 1 (0x0d) */
8483 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8486 /* CLFE Pin: output 2 (0x0e) */
8487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8488 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8489 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8490 /* Side Pin: output 3 (0x0f) */
8491 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8492 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8493 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8494 /* Mic (rear) pin: input vref at 80% */
8495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8496 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8497 /* Front Mic pin: input vref at 80% */
8498 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8499 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8500 /* Line In pin: input */
8501 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8502 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8503
8504 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8505 /* Input mixer1 */
88102f3f 8506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8507 /* Input mixer2 */
8508 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8509 /* Input mixer3 */
88102f3f 8510 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8511 /* ADC2: mute amp left and right */
8512 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8513 /* ADC3: mute amp left and right */
8514 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8515
8516 { }
8517};
8518
a9111321 8519static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8520 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8523 { }
8524};
8525
8526
8527/* Unmute Selector 24h and set the default input to front mic */
a9111321 8528static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8529 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8531 { }
8532};
8533
8534
4953550a
TI
8535#define alc883_init_verbs alc882_base_init_verbs
8536
9102cd1c 8537/* Mac Pro test */
a9111321 8538static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8539 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8540 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8541 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8542 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8543 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8544 /* FIXME: this looks suspicious...
d355c82a
JK
8545 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8546 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8547 */
9102cd1c
TD
8548 { } /* end */
8549};
8550
a9111321 8551static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8552 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8556 /* Front Pin: output 0 (0x0c) */
8557 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8558 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8559 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8560 /* Front Mic pin: input vref at 80% */
8561 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8562 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8563 /* Speaker: output */
8564 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8565 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8566 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8567 /* Headphone output (output 0 - 0x0c) */
8568 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8569 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8570 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8571
8572 /* FIXME: use matrix-type input source selection */
8573 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8574 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8579 /* Input mixer2 */
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8584 /* Input mixer3 */
8585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8589 /* ADC1: mute amp left and right */
8590 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8591 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* ADC2: mute amp left and right */
8593 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8595 /* ADC3: mute amp left and right */
8596 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8597 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8598
8599 { }
8600};
f12ab1e0 8601
41d5545d 8602/* Macbook 5,1 */
a9111321 8603static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8604 /* DACs */
8605 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8606 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8609 /* Front mixer */
41d5545d
KS
8610 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8613 /* Surround mixer */
8614 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8617 /* LFE mixer */
8618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8621 /* HP mixer */
8622 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8625 /* Front Pin (0x0c) */
41d5545d
KS
8626 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8627 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8628 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8629 /* LFE Pin (0x0e) */
8630 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8631 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8632 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8633 /* HP Pin (0x0f) */
41d5545d
KS
8634 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8635 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8636 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8638 /* Front Mic pin: input vref at 80% */
8639 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8640 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8641 /* Line In pin */
8642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8644
b8f171e7
AM
8645 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8648 { }
8649};
8650
e458b1fa 8651/* Macmini 3,1 */
a9111321 8652static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8653 /* DACs */
8654 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8655 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 /* Front mixer */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* Surround mixer */
8663 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8666 /* LFE mixer */
8667 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8670 /* HP mixer */
8671 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8674 /* Front Pin (0x0c) */
8675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8677 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8678 /* LFE Pin (0x0e) */
8679 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8680 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8681 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8682 /* HP Pin (0x0f) */
8683 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8684 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8685 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8686 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8687 /* Line In pin */
8688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8690
8691 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8695 { }
8696};
8697
76e6f5a9 8698
a9111321 8699static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8700 /*Internal and HP Speaker Mixer*/
8701 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8704 /*Internal Speaker Pin (0x0c)*/
8705 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8706 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8707 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8708 /* HP Pin: output 0 (0x0e) */
8709 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8710 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8711 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8712 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8713 /* Line in (is hp when jack connected)*/
8714 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8715 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8716
8717 { }
8718 };
8719
8720
87350ad0 8721/* Macbook Pro rev3 */
a9111321 8722static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8723 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8724 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8727 /* Rear mixer */
8728 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8731 /* HP mixer */
8732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8735 /* Front Pin: output 0 (0x0c) */
8736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8738 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8739 /* HP Pin: output 0 (0x0e) */
87350ad0 8740 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8741 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8742 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8743 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8744 /* Mic (rear) pin: input vref at 80% */
8745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8746 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8747 /* Front Mic pin: input vref at 80% */
8748 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8749 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8750 /* Line In pin: use output 1 when in LineOut mode */
8751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8752 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8753 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8754
8755 /* FIXME: use matrix-type input source selection */
8756 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8757 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8758 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8762 /* Input mixer2 */
8763 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8767 /* Input mixer3 */
8768 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8772 /* ADC1: mute amp left and right */
8773 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8774 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8775 /* ADC2: mute amp left and right */
8776 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8777 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8778 /* ADC3: mute amp left and right */
8779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8781
8782 { }
8783};
8784
4b7e1803 8785/* iMac 9,1 */
a9111321 8786static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8787 /* Internal Speaker Pin (0x0c) */
8788 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8789 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8790 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8792 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8793 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8794 /* HP Pin: Rear */
4b7e1803
JM
8795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8797 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8798 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8799 /* Line in Rear */
8800 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8801 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8802 /* Front Mic pin: input vref at 80% */
8803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8804 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8805 /* Rear mixer */
8806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8809 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8810 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8813 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8814 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8818 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8819 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8823 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8824 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8828 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8830 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8831 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8832 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8833 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8834 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8837 { }
8838};
8839
c54728d8 8840/* iMac 24 mixer. */
a9111321 8841static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8842 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8843 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8844 { } /* end */
8845};
8846
8847/* iMac 24 init verbs. */
a9111321 8848static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8849 /* Internal speakers: output 0 (0x0c) */
8850 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8851 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8852 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8853 /* Internal speakers: output 0 (0x0c) */
8854 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8856 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8857 /* Headphone: output 0 (0x0c) */
8858 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8859 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8860 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8862 /* Front Mic: input vref at 80% */
8863 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8864 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8865 { }
8866};
8867
8868/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8869static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8870{
a9fd4f3f 8871 struct alc_spec *spec = codec->spec;
c54728d8 8872
a9fd4f3f
TI
8873 spec->autocfg.hp_pins[0] = 0x14;
8874 spec->autocfg.speaker_pins[0] = 0x18;
8875 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8876 spec->automute = 1;
8877 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8878}
8879
9d54f08b
TI
8880#define alc885_mb5_setup alc885_imac24_setup
8881#define alc885_macmini3_setup alc885_imac24_setup
8882
76e6f5a9
RH
8883/* Macbook Air 2,1 */
8884static void alc885_mba21_setup(struct hda_codec *codec)
8885{
8886 struct alc_spec *spec = codec->spec;
8887
8888 spec->autocfg.hp_pins[0] = 0x14;
8889 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8890 spec->automute = 1;
8891 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8892}
8893
8894
8895
4f5d1706 8896static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8897{
a9fd4f3f 8898 struct alc_spec *spec = codec->spec;
87350ad0 8899
a9fd4f3f
TI
8900 spec->autocfg.hp_pins[0] = 0x15;
8901 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8902 spec->automute = 1;
8903 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8904}
8905
9d54f08b 8906static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8907{
9d54f08b 8908 struct alc_spec *spec = codec->spec;
4b7e1803 8909
9d54f08b 8910 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8911 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8912 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8913 spec->automute = 1;
8914 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8915}
87350ad0 8916
a9111321 8917static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8918 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8920
8921 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8922 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8923
272a527c
KY
8924 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8925 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8927
8928 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8929 { } /* end */
8930};
8931
8932/* toggle speaker-output according to the hp-jack state */
8933static void alc882_targa_automute(struct hda_codec *codec)
8934{
a9fd4f3f 8935 struct alc_spec *spec = codec->spec;
d922b51d 8936 alc_hp_automute(codec);
82beb8fd 8937 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8938 spec->jack_present ? 1 : 3);
8939}
8940
4f5d1706 8941static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8942{
8943 struct alc_spec *spec = codec->spec;
8944
8945 spec->autocfg.hp_pins[0] = 0x14;
8946 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8947 spec->automute = 1;
8948 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8949}
8950
8951static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8952{
a9fd4f3f 8953 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8954 alc882_targa_automute(codec);
272a527c
KY
8955}
8956
a9111321 8957static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8958 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8960
8961 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8962 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8964
272a527c
KY
8965 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8966 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8967 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8968
8969 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8970 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8971 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8972 { } /* end */
8973};
8974
a9111321 8975static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8976 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8978
8979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8981 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8982
914759b7
TI
8983 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8984 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8985 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8986
8987 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8988 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8989 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8990 { } /* end */
8991};
8992
9102cd1c
TD
8993static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8994{
8995 unsigned int gpiostate, gpiomask, gpiodir;
8996
8997 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8998 AC_VERB_GET_GPIO_DATA, 0);
8999
9000 if (!muted)
9001 gpiostate |= (1 << pin);
9002 else
9003 gpiostate &= ~(1 << pin);
9004
9005 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9006 AC_VERB_GET_GPIO_MASK, 0);
9007 gpiomask |= (1 << pin);
9008
9009 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9010 AC_VERB_GET_GPIO_DIRECTION, 0);
9011 gpiodir |= (1 << pin);
9012
9013
9014 snd_hda_codec_write(codec, codec->afg, 0,
9015 AC_VERB_SET_GPIO_MASK, gpiomask);
9016 snd_hda_codec_write(codec, codec->afg, 0,
9017 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9018
9019 msleep(1);
9020
9021 snd_hda_codec_write(codec, codec->afg, 0,
9022 AC_VERB_SET_GPIO_DATA, gpiostate);
9023}
9024
7debbe51
TI
9025/* set up GPIO at initialization */
9026static void alc885_macpro_init_hook(struct hda_codec *codec)
9027{
9028 alc882_gpio_mute(codec, 0, 0);
9029 alc882_gpio_mute(codec, 1, 0);
9030}
9031
9032/* set up GPIO and update auto-muting at initialization */
9033static void alc885_imac24_init_hook(struct hda_codec *codec)
9034{
9035 alc885_macpro_init_hook(codec);
d922b51d 9036 alc_hp_automute(codec);
7debbe51
TI
9037}
9038
df694daa
KY
9039/*
9040 * generic initialization of ADC, input mixers and output mixers
9041 */
a9111321 9042static const struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
9043 /*
9044 * Unmute ADC0-2 and set the default input to mic-in
9045 */
4953550a
TI
9046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9049 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 9050
4953550a
TI
9051 /*
9052 * Set up output mixers (0x0c - 0x0f)
9053 */
9054 /* set vol=0 to output mixers */
9055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9056 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9057 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9059 /* set up input amps for analog loopback */
9060 /* Amp Indices: DAC = 0, mixer = 1 */
9061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9063 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9065 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9067 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9069 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9070 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9071
4953550a
TI
9072 /* FIXME: use matrix-type input source selection */
9073 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9074 /* Input mixer2 */
88102f3f 9075 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9076 /* Input mixer3 */
88102f3f 9077 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9078 { }
9c7f852e
TI
9079};
9080
eb4c41d3 9081/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9082static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9083 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9084 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9085 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9086 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9087 { } /* end */
9088};
9089
9090/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9091static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9092 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9093 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9094 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9095 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9096 { } /* end */
9097};
9098
9099/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9100static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9101 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9102 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9103 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9104 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9105 { } /* end */
9106};
9107
9108/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9109static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9110 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9111 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9112 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9113 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9114 { } /* end */
9115};
9116
a9111321 9117static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9118 { 2, alc889A_mb31_ch2_init },
9119 { 4, alc889A_mb31_ch4_init },
9120 { 5, alc889A_mb31_ch5_init },
9121 { 6, alc889A_mb31_ch6_init },
9122};
9123
a9111321 9124static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9125 /* eanable EAPD on medion laptop */
9126 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9127 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9128 { }
9129};
9130
4953550a 9131#define alc883_base_mixer alc882_base_mixer
834be88d 9132
a9111321 9133static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9136 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9138 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9139 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9145 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9147 { } /* end */
9148};
9149
a9111321 9150static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9151 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9154 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9155 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9158 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9159 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9160 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9161 { } /* end */
9162};
9163
a9111321 9164static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9165 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9166 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9168 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9170 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9172 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9173 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9175 { } /* end */
9176};
9177
a9111321 9178static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9179 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9180 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9181 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9182 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9183 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9185 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9190 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9192 { } /* end */
9193};
df694daa 9194
a9111321 9195static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9196 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9197 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9198 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9201 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9202 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9203 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9204 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9205 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9206 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9208 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9210 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9211 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9213 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9214 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9215 { } /* end */
9216};
9217
a9111321 9218static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9219 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9220 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9221 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9222 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9223 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9224 HDA_OUTPUT),
9225 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9226 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9227 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9229 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9230 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9235 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9236 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9237 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9238 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9239 { } /* end */
9240};
9241
a9111321 9242static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9243 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9244 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9245 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9246 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9247 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9248 HDA_OUTPUT),
9249 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9251 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9252 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9253 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9254 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9255 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9256 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9259 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9260 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9261 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9262 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9263 { } /* end */
9264};
9265
a9111321 9266static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9267 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9268 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9269 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9270 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9271 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9272 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9273 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9274 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9276 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9277 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9278 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9279 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9280 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9283 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9284 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9285 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9286 { } /* end */
9287};
9288
a9111321 9289static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9290 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9291 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9292 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9294 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9295 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9296 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9297 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9299 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9300 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9301 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9302 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9303 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9304 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9306 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9307 { } /* end */
f12ab1e0 9308};
ccc656ce 9309
a9111321 9310static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9311 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9312 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9313 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9314 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9315 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9316 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9317 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9318 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9319 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9320 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9321 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9322 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9323 { } /* end */
f12ab1e0 9324};
ccc656ce 9325
a9111321 9326static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9327 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9328 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9329 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9330 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9331 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9332 { } /* end */
9333};
9334
a9111321 9335static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9336 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9337 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9338 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9339 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9340 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9342 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9343 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9344 { } /* end */
f12ab1e0 9345};
bc9f98a9 9346
a9111321 9347static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9348 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9349 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9350 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9351 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9352 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9353 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9354 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9355 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9356 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9357 { } /* end */
ea1fb29a 9358};
272a527c 9359
a9111321 9360static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9361 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9362 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9363 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9366 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9367 { } /* end */
9368};
9369
a9111321 9370static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9371 /* Unmute front mixer */
9372 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9374
9375 /* Set speaker pin to front mixer */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377
9378 /* Init headphone pin */
9379 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9381 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9382 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9383
9384 { } /* end */
9385};
9386
9387/* toggle speaker-output according to the hp-jack state */
9388static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9389{
9390 struct alc_spec *spec = codec->spec;
9391
9392 spec->autocfg.hp_pins[0] = 0x1a;
9393 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9394 spec->automute = 1;
9395 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9396}
9397
a9111321 9398static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9399 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9400 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9401 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9402 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9403 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9405 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9406 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9407 { } /* end */
d1a991a6 9408};
2880a867 9409
a9111321 9410static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9411 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9412 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9413 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9414 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9415 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9416 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9417 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9418 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9420 { } /* end */
9421};
9422
a9111321 9423static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9424 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9425 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9426 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9427 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9428 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9429 0x0d, 1, 0x0, HDA_OUTPUT),
9430 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9431 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9432 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9433 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9434 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9435 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9436 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9438 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9443 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9444 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9445 { } /* end */
9446};
9447
a9111321 9448static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9449 /* Output mixers */
9450 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9451 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9452 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9453 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9454 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9455 HDA_OUTPUT),
9456 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9457 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9458 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9459 /* Output switches */
9460 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9461 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9462 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9463 /* Boost mixers */
5f99f86a
DH
9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9465 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9466 /* Input mixers */
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9468 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9469 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9470 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9471 { } /* end */
9472};
9473
a9111321 9474static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9475 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9476 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9477 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9479 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9480 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9481 { } /* end */
9482};
9483
a9111321 9484static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9485 .ops = &snd_hda_bind_vol,
9486 .values = {
9487 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9488 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9489 0
9490 },
9491};
9492
a9111321 9493static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9494 .ops = &snd_hda_bind_sw,
9495 .values = {
9496 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9497 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9498 0
9499 },
9500};
9501
a9111321 9502static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9503 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9504 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9505 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9509 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9510 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9511 { } /* end */
9512};
df694daa 9513
a9111321 9514static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9515 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9516 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9517 {
9518 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9519 /* .name = "Capture Source", */
9520 .name = "Input Source",
9521 .count = 1,
9522 .info = alc_mux_enum_info,
9523 .get = alc_mux_enum_get,
9524 .put = alc_mux_enum_put,
9525 },
9526 { } /* end */
9527};
9c7f852e 9528
a9111321 9529static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9530 {
9531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9532 .name = "Channel Mode",
9533 .info = alc_ch_mode_info,
9534 .get = alc_ch_mode_get,
9535 .put = alc_ch_mode_put,
9536 },
9537 { } /* end */
9c7f852e
TI
9538};
9539
a8848bd6 9540/* toggle speaker-output according to the hp-jack state */
4f5d1706 9541static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9542{
a9fd4f3f 9543 struct alc_spec *spec = codec->spec;
a8848bd6 9544
a9fd4f3f
TI
9545 spec->autocfg.hp_pins[0] = 0x15;
9546 spec->autocfg.speaker_pins[0] = 0x14;
9547 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9548 spec->automute = 1;
9549 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9550}
9551
a9111321 9552static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9553 /* HP */
9554 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9555 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9556 /* Subwoofer */
9557 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9558 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9559
9560 /* enable unsolicited event */
9561 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9562 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9563
9564 { } /* end */
9565};
9566
a9111321 9567static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9568 /* HP */
9569 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9570 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9571 /* Int speaker */
9572 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9573
9574 /* enable unsolicited event */
9575 /*
9576 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9577 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9578 */
9579
9580 { } /* end */
9581};
9582
a9111321 9583static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9584 /* HP */
9585 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9586 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9587 /* Int speaker */
9588 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9590
9591 /* enable unsolicited event */
9592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9593 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9594
9595 { } /* end */
9596};
9597
a9111321 9598static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9599 /* HP */
9600 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9601 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9602 /* Subwoofer */
9603 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9604 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9605
9606 /* enable unsolicited event */
9607 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9608
9609 { } /* end */
9610};
9611
a9111321 9612static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9615
9616 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9618
64a8be74
DH
9619/* Connect Line-Out side jack (SPDIF) to Side */
9620 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9621 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9622 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9623/* Connect Mic jack to CLFE */
9624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9626 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9627/* Connect Line-in jack to Surround */
9628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9630 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9631/* Connect HP out jack to Front */
9632 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9633 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9634 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9635
9636 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9637
9638 { } /* end */
9639};
9640
a9111321 9641static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9642 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9643 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9644 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9645 { } /* end */
9646};
9647
a9111321 9648static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9649 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9650 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9651 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9653 { } /* end */
9654};
9655
a9111321 9656static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9659 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9660 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9661 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9662 { } /* end */
9663};
9664
a9111321 9665static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9666 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9668
9669 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9670
9671 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9672 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9673 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9674 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9675 { } /* end */
9676};
9677
a9111321 9678static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9681 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9685 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9687 { } /* end */
9688};
9689
a9111321 9690static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9691 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9692 { }
9693};
9694
a9111321 9695static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9696 /* HP */
9697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9698 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9699
9700 /* enable unsolicited event */
9701 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9702
9703 { } /* end */
9704};
9705
4f5d1706 9706static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9707{
a9fd4f3f 9708 struct alc_spec *spec = codec->spec;
8718b700 9709
a9fd4f3f
TI
9710 spec->autocfg.hp_pins[0] = 0x1b;
9711 spec->autocfg.speaker_pins[0] = 0x14;
9712 spec->autocfg.speaker_pins[1] = 0x16;
9713 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9714 spec->automute = 1;
9715 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9716}
9717
a9111321 9718static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9719 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9720 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9722 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9723 { } /* end */
5795b9e6
CM
9724};
9725
3ea0d7cf
HRK
9726/*
9727 * 2ch mode
9728 */
a9111321 9729static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9732 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9733 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9734 { } /* end */
8341de60
CM
9735};
9736
3ea0d7cf
HRK
9737/*
9738 * 4ch mode
9739 */
a9111321 9740static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9741 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9742 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9743 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9744 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9745 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9746 { } /* end */
9747};
9748
9749/*
9750 * 6ch mode
9751 */
a9111321 9752static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9753 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9754 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9755 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9756 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9757 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9758 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9759 { } /* end */
8341de60
CM
9760};
9761
a9111321 9762static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9763 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9764 { 4, alc888_3st_hp_4ch_init },
4723c022 9765 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9766};
9767
e6a5e1b7 9768static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9769{
e6a5e1b7 9770 struct alc_spec *spec = codec->spec;
47fd830a 9771
e6a5e1b7
TI
9772 spec->autocfg.hp_pins[0] = 0x1b;
9773 spec->autocfg.line_out_pins[0] = 0x14;
9774 spec->autocfg.speaker_pins[0] = 0x15;
9775 spec->automute = 1;
9776 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9777}
9778
272a527c 9779/* toggle speaker-output according to the hp-jack state */
dc427170 9780static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9781{
a9fd4f3f 9782 struct alc_spec *spec = codec->spec;
272a527c 9783
a9fd4f3f
TI
9784 spec->autocfg.hp_pins[0] = 0x14;
9785 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9786 spec->automute = 1;
9787 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9788}
9789
ccc656ce 9790/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9791#define alc883_targa_init_hook alc882_targa_init_hook
9792#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9793
4f5d1706 9794static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9795{
a9fd4f3f
TI
9796 struct alc_spec *spec = codec->spec;
9797
9798 spec->autocfg.hp_pins[0] = 0x15;
9799 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9800 spec->automute = 1;
9801 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9802}
9803
9804static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9805{
d922b51d 9806 alc_hp_automute(codec);
eeb43387 9807 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9808}
9809
9810static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9811 unsigned int res)
9812{
0c4cc443 9813 switch (res >> 26) {
0c4cc443 9814 case ALC880_MIC_EVENT:
eeb43387 9815 alc88x_simple_mic_automute(codec);
0c4cc443 9816 break;
a9fd4f3f 9817 default:
d922b51d 9818 alc_sku_unsol_event(codec, res);
a9fd4f3f 9819 break;
0c4cc443 9820 }
368c7a95
J
9821}
9822
fb97dc67 9823/* toggle speaker-output according to the hp-jack state */
4f5d1706 9824static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9825{
a9fd4f3f 9826 struct alc_spec *spec = codec->spec;
fb97dc67 9827
a9fd4f3f
TI
9828 spec->autocfg.hp_pins[0] = 0x14;
9829 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9830 spec->automute = 1;
9831 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9832}
9833
4f5d1706 9834static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9835{
a9fd4f3f 9836 struct alc_spec *spec = codec->spec;
189609ae 9837
a9fd4f3f
TI
9838 spec->autocfg.hp_pins[0] = 0x1b;
9839 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9840 spec->automute = 1;
9841 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9842}
9843
e6a5e1b7 9844static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9845{
e6a5e1b7 9846 struct alc_spec *spec = codec->spec;
bc9f98a9 9847
e6a5e1b7
TI
9848 spec->autocfg.hp_pins[0] = 0x1b;
9849 spec->autocfg.line_out_pins[0] = 0x14;
9850 spec->autocfg.speaker_pins[0] = 0x15;
9851 spec->automute = 1;
9852 spec->detect_line = 1;
9853 spec->automute_lines = 1;
9854 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9855}
9856
676a9b53 9857/* toggle speaker-output according to the hp-jack state */
4f5d1706 9858static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9859{
a9fd4f3f 9860 struct alc_spec *spec = codec->spec;
676a9b53 9861
a9fd4f3f
TI
9862 spec->autocfg.hp_pins[0] = 0x14;
9863 spec->autocfg.speaker_pins[0] = 0x15;
9864 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9865 spec->automute = 1;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9867}
9868
a9111321 9869static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9870 /* HP Pin: output 0 (0x0c) */
9871 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9872 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9873 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9874 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9875 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9876 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9877 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9878 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9879 /* eanable EAPD on medion laptop */
9880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9881 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9882 /* enable unsolicited event */
9883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9884 { }
9885};
9886
4f5d1706 9887static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9888{
a9fd4f3f 9889 struct alc_spec *spec = codec->spec;
5795b9e6 9890
a9fd4f3f
TI
9891 spec->autocfg.hp_pins[0] = 0x1b;
9892 spec->autocfg.speaker_pins[0] = 0x14;
9893 spec->autocfg.speaker_pins[1] = 0x15;
9894 spec->autocfg.speaker_pins[2] = 0x16;
9895 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9896 spec->automute = 1;
9897 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9898}
9899
4f5d1706 9900static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9901{
a9fd4f3f 9902 struct alc_spec *spec = codec->spec;
e2757d5e 9903
a9fd4f3f
TI
9904 spec->autocfg.hp_pins[0] = 0x1b;
9905 spec->autocfg.speaker_pins[0] = 0x14;
9906 spec->autocfg.speaker_pins[1] = 0x15;
9907 spec->autocfg.speaker_pins[2] = 0x16;
9908 spec->autocfg.speaker_pins[3] = 0x17;
9909 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9910 spec->automute = 1;
9911 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9912}
9913
4f5d1706 9914static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9915{
9916 struct alc_spec *spec = codec->spec;
9917
9918 spec->autocfg.hp_pins[0] = 0x15;
9919 spec->autocfg.speaker_pins[0] = 0x14;
9920 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9921 spec->automute = 1;
9922 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9923}
9924
a9111321 9925static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9926 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9927 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9929 /* enable unsolicited event */
9930 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9931 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9932 { } /* end */
9933};
9934
4f5d1706 9935static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9936{
a9fd4f3f 9937 struct alc_spec *spec = codec->spec;
e2757d5e 9938
a9fd4f3f
TI
9939 spec->autocfg.hp_pins[0] = 0x1b;
9940 spec->autocfg.speaker_pins[0] = 0x14;
9941 spec->autocfg.speaker_pins[1] = 0x15;
9942 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9943 spec->ext_mic.pin = 0x18;
9944 spec->int_mic.pin = 0x19;
9945 spec->ext_mic.mux_idx = 0;
9946 spec->int_mic.mux_idx = 1;
9947 spec->auto_mic = 1;
d922b51d
TI
9948 spec->automute = 1;
9949 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9950}
9951
a9111321 9952static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9954 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9956 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9958 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9959 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9960 /* enable unsolicited event */
9961 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9962 { } /* end */
9963};
9964
e2757d5e
KY
9965static void alc883_eee1601_inithook(struct hda_codec *codec)
9966{
a9fd4f3f
TI
9967 struct alc_spec *spec = codec->spec;
9968
9969 spec->autocfg.hp_pins[0] = 0x14;
9970 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9971 alc_hp_automute(codec);
e2757d5e
KY
9972}
9973
a9111321 9974static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9975 /* Init rear pin (used as headphone output) */
9976 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9977 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9979 /* Init line pin (used as output in 4ch and 6ch mode) */
9980 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9981 /* Init line 2 pin (used as headphone out by default) */
9982 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9983 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9984 { } /* end */
9985};
9986
9987/* Mute speakers according to the headphone jack state */
9988static void alc889A_mb31_automute(struct hda_codec *codec)
9989{
9990 unsigned int present;
9991
9992 /* Mute only in 2ch or 4ch mode */
9993 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9994 == 0x00) {
864f92be 9995 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9996 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9997 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9998 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9999 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10000 }
10001}
10002
10003static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10004{
10005 if ((res >> 26) == ALC880_HP_EVENT)
10006 alc889A_mb31_automute(codec);
10007}
10008
4953550a 10009
cb53c626 10010#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 10011#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
10012#endif
10013
def319f9 10014/* pcm configuration: identical with ALC880 */
4953550a
TI
10015#define alc882_pcm_analog_playback alc880_pcm_analog_playback
10016#define alc882_pcm_analog_capture alc880_pcm_analog_capture
10017#define alc882_pcm_digital_playback alc880_pcm_digital_playback
10018#define alc882_pcm_digital_capture alc880_pcm_digital_capture
10019
4c6d72d1 10020static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
10021 ALC1200_DIGOUT_NID, 0,
10022};
10023
4c6d72d1 10024static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
10025 ALC883_DIGOUT_NID, 0,
10026};
9c7f852e
TI
10027
10028/*
10029 * configuration and preset
10030 */
ea734963 10031static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
10032 [ALC882_3ST_DIG] = "3stack-dig",
10033 [ALC882_6ST_DIG] = "6stack-dig",
10034 [ALC882_ARIMA] = "arima",
10035 [ALC882_W2JC] = "w2jc",
10036 [ALC882_TARGA] = "targa",
10037 [ALC882_ASUS_A7J] = "asus-a7j",
10038 [ALC882_ASUS_A7M] = "asus-a7m",
10039 [ALC885_MACPRO] = "macpro",
10040 [ALC885_MB5] = "mb5",
e458b1fa 10041 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 10042 [ALC885_MBA21] = "mba21",
4953550a
TI
10043 [ALC885_MBP3] = "mbp3",
10044 [ALC885_IMAC24] = "imac24",
4b7e1803 10045 [ALC885_IMAC91] = "imac91",
4953550a 10046 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10047 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10048 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10049 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10050 [ALC883_TARGA_DIG] = "targa-dig",
10051 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10052 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10053 [ALC883_ACER] = "acer",
2880a867 10054 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10055 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10056 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10057 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10058 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10059 [ALC883_MEDION] = "medion",
7ad7b218 10060 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10061 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10062 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10063 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10064 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10065 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10066 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10067 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10068 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10069 [ALC883_MITAC] = "mitac",
a65cc60f 10070 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10071 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10072 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10073 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10074 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10075 [ALC889A_INTEL] = "intel-alc889a",
10076 [ALC889_INTEL] = "intel-x58",
3ab90935 10077 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10078 [ALC889A_MB31] = "mb31",
3e1647c5 10079 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10080 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10081};
10082
a9111321 10083static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10084 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10085
ac3e3741 10086 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10087 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10088 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10089 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10090 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10091 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10092 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10093 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10094 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10095 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10096 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10097 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10098 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10099 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10100 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10101 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10102 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10103 ALC888_ACER_ASPIRE_6530G),
cc374c47 10104 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10105 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10106 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10107 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10108 /* default Acer -- disabled as it causes more problems.
10109 * model=auto should work fine now
10110 */
10111 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10112
5795b9e6 10113 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10114
25985edc 10115 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10116 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10117 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10118 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10119 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10120 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10121
10122 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10123 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10124 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10125 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10126 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10127 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10128 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10129 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10130 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10131 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10132 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10133
10134 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10135 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10136 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10137 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10138 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10139 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10140 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10141 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10142 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10143
6f3bf657 10144 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10145 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10146 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10147 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10148 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10149 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10150 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10151 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10152 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10153 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10154 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10155 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10156 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10157 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10158 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10159 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10160 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10162 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10163 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10164 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10165 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10167 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10168 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10169 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10170 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10171 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10172 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10173 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10174 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10175
ac3e3741 10176 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10177 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10178 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10179 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10180 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10181 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10182 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10183 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10184 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10185 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10186 ALC883_FUJITSU_PI2515),
bfb53037 10187 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10188 ALC888_FUJITSU_XA3530),
272a527c 10189 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10190 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10191 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10192 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10193 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10194 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10195 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10196 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10197
17bba1b7
J
10198 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10199 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10200 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10201 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10202 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10203 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10204 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10205
4953550a 10206 {}
f3cd3f5d
WF
10207};
10208
4953550a 10209/* codec SSID table for Intel Mac */
a9111321 10210static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10211 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10212 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10213 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10214 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10215 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10216 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10217 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10218 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10219 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10220 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10221 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10222 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10223 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10224 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10225 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10226 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10227 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10228 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10229 * so apparently no perfect solution yet
4953550a
TI
10230 */
10231 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10232 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10233 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10234 {} /* terminator */
b25c9da1
WF
10235};
10236
a9111321 10237static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10238 [ALC882_3ST_DIG] = {
10239 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10240 .init_verbs = { alc882_base_init_verbs,
10241 alc882_adc1_init_verbs },
4953550a
TI
10242 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10243 .dac_nids = alc882_dac_nids,
10244 .dig_out_nid = ALC882_DIGOUT_NID,
10245 .dig_in_nid = ALC882_DIGIN_NID,
10246 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10247 .channel_mode = alc882_ch_modes,
10248 .need_dac_fix = 1,
10249 .input_mux = &alc882_capture_source,
10250 },
10251 [ALC882_6ST_DIG] = {
10252 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10253 .init_verbs = { alc882_base_init_verbs,
10254 alc882_adc1_init_verbs },
4953550a
TI
10255 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10256 .dac_nids = alc882_dac_nids,
10257 .dig_out_nid = ALC882_DIGOUT_NID,
10258 .dig_in_nid = ALC882_DIGIN_NID,
10259 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10260 .channel_mode = alc882_sixstack_modes,
10261 .input_mux = &alc882_capture_source,
10262 },
10263 [ALC882_ARIMA] = {
10264 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10265 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10266 alc882_eapd_verbs },
4953550a
TI
10267 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10268 .dac_nids = alc882_dac_nids,
10269 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10270 .channel_mode = alc882_sixstack_modes,
10271 .input_mux = &alc882_capture_source,
10272 },
10273 [ALC882_W2JC] = {
10274 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10275 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10276 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10277 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10278 .dac_nids = alc882_dac_nids,
10279 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10280 .channel_mode = alc880_threestack_modes,
10281 .need_dac_fix = 1,
10282 .input_mux = &alc882_capture_source,
10283 .dig_out_nid = ALC882_DIGOUT_NID,
10284 },
76e6f5a9
RH
10285 [ALC885_MBA21] = {
10286 .mixers = { alc885_mba21_mixer },
10287 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10288 .num_dacs = 2,
10289 .dac_nids = alc882_dac_nids,
10290 .channel_mode = alc885_mba21_ch_modes,
10291 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10292 .input_mux = &alc882_capture_source,
d922b51d 10293 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10294 .setup = alc885_mba21_setup,
d922b51d 10295 .init_hook = alc_hp_automute,
76e6f5a9 10296 },
4953550a
TI
10297 [ALC885_MBP3] = {
10298 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10299 .init_verbs = { alc885_mbp3_init_verbs,
10300 alc880_gpio1_init_verbs },
be0ae923 10301 .num_dacs = 2,
4953550a 10302 .dac_nids = alc882_dac_nids,
be0ae923
TI
10303 .hp_nid = 0x04,
10304 .channel_mode = alc885_mbp_4ch_modes,
10305 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10306 .input_mux = &alc882_capture_source,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10309 .unsol_event = alc_sku_unsol_event,
4f5d1706 10310 .setup = alc885_mbp3_setup,
d922b51d 10311 .init_hook = alc_hp_automute,
4953550a
TI
10312 },
10313 [ALC885_MB5] = {
10314 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10315 .init_verbs = { alc885_mb5_init_verbs,
10316 alc880_gpio1_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .channel_mode = alc885_mb5_6ch_modes,
10320 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10321 .input_mux = &mb5_capture_source,
10322 .dig_out_nid = ALC882_DIGOUT_NID,
10323 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10324 .unsol_event = alc_sku_unsol_event,
9d54f08b 10325 .setup = alc885_mb5_setup,
d922b51d 10326 .init_hook = alc_hp_automute,
4953550a 10327 },
e458b1fa
LY
10328 [ALC885_MACMINI3] = {
10329 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10330 .init_verbs = { alc885_macmini3_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
10334 .channel_mode = alc885_macmini3_6ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10336 .input_mux = &macmini3_capture_source,
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10339 .unsol_event = alc_sku_unsol_event,
9d54f08b 10340 .setup = alc885_macmini3_setup,
d922b51d 10341 .init_hook = alc_hp_automute,
e458b1fa 10342 },
4953550a
TI
10343 [ALC885_MACPRO] = {
10344 .mixers = { alc882_macpro_mixer },
10345 .init_verbs = { alc882_macpro_init_verbs },
10346 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10347 .dac_nids = alc882_dac_nids,
10348 .dig_out_nid = ALC882_DIGOUT_NID,
10349 .dig_in_nid = ALC882_DIGIN_NID,
10350 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10351 .channel_mode = alc882_ch_modes,
10352 .input_mux = &alc882_capture_source,
10353 .init_hook = alc885_macpro_init_hook,
10354 },
10355 [ALC885_IMAC24] = {
10356 .mixers = { alc885_imac24_mixer },
10357 .init_verbs = { alc885_imac24_init_verbs },
10358 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10359 .dac_nids = alc882_dac_nids,
10360 .dig_out_nid = ALC882_DIGOUT_NID,
10361 .dig_in_nid = ALC882_DIGIN_NID,
10362 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10363 .channel_mode = alc882_ch_modes,
10364 .input_mux = &alc882_capture_source,
d922b51d 10365 .unsol_event = alc_sku_unsol_event,
4f5d1706 10366 .setup = alc885_imac24_setup,
4953550a
TI
10367 .init_hook = alc885_imac24_init_hook,
10368 },
4b7e1803 10369 [ALC885_IMAC91] = {
b7cccc52 10370 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10371 .init_verbs = { alc885_imac91_init_verbs,
10372 alc880_gpio1_init_verbs },
10373 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10374 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10375 .channel_mode = alc885_mba21_ch_modes,
10376 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10377 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10378 .dig_out_nid = ALC882_DIGOUT_NID,
10379 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10380 .unsol_event = alc_sku_unsol_event,
9d54f08b 10381 .setup = alc885_imac91_setup,
d922b51d 10382 .init_hook = alc_hp_automute,
4b7e1803 10383 },
4953550a
TI
10384 [ALC882_TARGA] = {
10385 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10386 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10387 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10388 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10389 .dac_nids = alc882_dac_nids,
10390 .dig_out_nid = ALC882_DIGOUT_NID,
10391 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10392 .adc_nids = alc882_adc_nids,
10393 .capsrc_nids = alc882_capsrc_nids,
10394 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10395 .channel_mode = alc882_3ST_6ch_modes,
10396 .need_dac_fix = 1,
10397 .input_mux = &alc882_capture_source,
d922b51d 10398 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10399 .setup = alc882_targa_setup,
10400 .init_hook = alc882_targa_automute,
4953550a
TI
10401 },
10402 [ALC882_ASUS_A7J] = {
10403 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10404 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10405 alc882_asus_a7j_verbs},
4953550a
TI
10406 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10407 .dac_nids = alc882_dac_nids,
10408 .dig_out_nid = ALC882_DIGOUT_NID,
10409 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10410 .adc_nids = alc882_adc_nids,
10411 .capsrc_nids = alc882_capsrc_nids,
10412 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10413 .channel_mode = alc882_3ST_6ch_modes,
10414 .need_dac_fix = 1,
10415 .input_mux = &alc882_capture_source,
10416 },
10417 [ALC882_ASUS_A7M] = {
10418 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10419 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10420 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10421 alc882_asus_a7m_verbs },
10422 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10423 .dac_nids = alc882_dac_nids,
10424 .dig_out_nid = ALC882_DIGOUT_NID,
10425 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10426 .channel_mode = alc880_threestack_modes,
10427 .need_dac_fix = 1,
10428 .input_mux = &alc882_capture_source,
10429 },
9c7f852e
TI
10430 [ALC883_3ST_2ch_DIG] = {
10431 .mixers = { alc883_3ST_2ch_mixer },
10432 .init_verbs = { alc883_init_verbs },
10433 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10434 .dac_nids = alc883_dac_nids,
10435 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10436 .dig_in_nid = ALC883_DIGIN_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .input_mux = &alc883_capture_source,
10440 },
10441 [ALC883_3ST_6ch_DIG] = {
10442 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10443 .init_verbs = { alc883_init_verbs },
10444 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10445 .dac_nids = alc883_dac_nids,
10446 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10447 .dig_in_nid = ALC883_DIGIN_NID,
10448 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10449 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10450 .need_dac_fix = 1,
9c7f852e 10451 .input_mux = &alc883_capture_source,
f12ab1e0 10452 },
9c7f852e
TI
10453 [ALC883_3ST_6ch] = {
10454 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10455 .init_verbs = { alc883_init_verbs },
10456 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10457 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10460 .need_dac_fix = 1,
9c7f852e 10461 .input_mux = &alc883_capture_source,
f12ab1e0 10462 },
17bba1b7
J
10463 [ALC883_3ST_6ch_INTEL] = {
10464 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10465 .init_verbs = { alc883_init_verbs },
10466 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10467 .dac_nids = alc883_dac_nids,
10468 .dig_out_nid = ALC883_DIGOUT_NID,
10469 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10470 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10471 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10472 .channel_mode = alc883_3ST_6ch_intel_modes,
10473 .need_dac_fix = 1,
10474 .input_mux = &alc883_3stack_6ch_intel,
10475 },
87a8c370
JK
10476 [ALC889A_INTEL] = {
10477 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10478 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10479 alc_hp15_unsol_verbs },
87a8c370
JK
10480 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10481 .dac_nids = alc883_dac_nids,
10482 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10483 .adc_nids = alc889_adc_nids,
10484 .dig_out_nid = ALC883_DIGOUT_NID,
10485 .dig_in_nid = ALC883_DIGIN_NID,
10486 .slave_dig_outs = alc883_slave_dig_outs,
10487 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10488 .channel_mode = alc889_8ch_intel_modes,
10489 .capsrc_nids = alc889_capsrc_nids,
10490 .input_mux = &alc889_capture_source,
4f5d1706 10491 .setup = alc889_automute_setup,
d922b51d
TI
10492 .init_hook = alc_hp_automute,
10493 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10494 .need_dac_fix = 1,
10495 },
10496 [ALC889_INTEL] = {
10497 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10498 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10499 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10500 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10501 .dac_nids = alc883_dac_nids,
10502 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10503 .adc_nids = alc889_adc_nids,
10504 .dig_out_nid = ALC883_DIGOUT_NID,
10505 .dig_in_nid = ALC883_DIGIN_NID,
10506 .slave_dig_outs = alc883_slave_dig_outs,
10507 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10508 .channel_mode = alc889_8ch_intel_modes,
10509 .capsrc_nids = alc889_capsrc_nids,
10510 .input_mux = &alc889_capture_source,
4f5d1706 10511 .setup = alc889_automute_setup,
6732bd0d 10512 .init_hook = alc889_intel_init_hook,
d922b51d 10513 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10514 .need_dac_fix = 1,
10515 },
9c7f852e
TI
10516 [ALC883_6ST_DIG] = {
10517 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10518 .init_verbs = { alc883_init_verbs },
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
10521 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10522 .dig_in_nid = ALC883_DIGIN_NID,
10523 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10524 .channel_mode = alc883_sixstack_modes,
10525 .input_mux = &alc883_capture_source,
10526 },
ccc656ce 10527 [ALC883_TARGA_DIG] = {
c259249f 10528 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10529 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10530 alc883_targa_verbs},
ccc656ce
KY
10531 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10532 .dac_nids = alc883_dac_nids,
10533 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10534 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10535 .channel_mode = alc883_3ST_6ch_modes,
10536 .need_dac_fix = 1,
10537 .input_mux = &alc883_capture_source,
c259249f 10538 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10539 .setup = alc882_targa_setup,
10540 .init_hook = alc882_targa_automute,
ccc656ce
KY
10541 },
10542 [ALC883_TARGA_2ch_DIG] = {
c259249f 10543 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10544 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10545 alc883_targa_verbs},
ccc656ce
KY
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10548 .adc_nids = alc883_adc_nids_alt,
10549 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10550 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10551 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10552 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10553 .channel_mode = alc883_3ST_2ch_modes,
10554 .input_mux = &alc883_capture_source,
c259249f 10555 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10556 .setup = alc882_targa_setup,
10557 .init_hook = alc882_targa_automute,
ccc656ce 10558 },
64a8be74 10559 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10560 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10561 alc883_chmode_mixer },
64a8be74 10562 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10563 alc883_targa_verbs },
64a8be74
DH
10564 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10565 .dac_nids = alc883_dac_nids,
10566 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10567 .adc_nids = alc883_adc_nids_rev,
10568 .capsrc_nids = alc883_capsrc_nids_rev,
10569 .dig_out_nid = ALC883_DIGOUT_NID,
10570 .dig_in_nid = ALC883_DIGIN_NID,
10571 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10572 .channel_mode = alc883_4ST_8ch_modes,
10573 .need_dac_fix = 1,
10574 .input_mux = &alc883_capture_source,
c259249f 10575 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10576 .setup = alc882_targa_setup,
10577 .init_hook = alc882_targa_automute,
64a8be74 10578 },
bab282b9 10579 [ALC883_ACER] = {
676a9b53 10580 .mixers = { alc883_base_mixer },
bab282b9
VA
10581 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10582 * and the headphone jack. Turn this on and rely on the
10583 * standard mute methods whenever the user wants to turn
10584 * these outputs off.
10585 */
10586 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10588 .dac_nids = alc883_dac_nids,
bab282b9
VA
10589 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10590 .channel_mode = alc883_3ST_2ch_modes,
10591 .input_mux = &alc883_capture_source,
10592 },
2880a867 10593 [ALC883_ACER_ASPIRE] = {
676a9b53 10594 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10595 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10596 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10597 .dac_nids = alc883_dac_nids,
10598 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10599 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10600 .channel_mode = alc883_3ST_2ch_modes,
10601 .input_mux = &alc883_capture_source,
d922b51d 10602 .unsol_event = alc_sku_unsol_event,
4f5d1706 10603 .setup = alc883_acer_aspire_setup,
d922b51d 10604 .init_hook = alc_hp_automute,
d1a991a6 10605 },
5b2d1eca 10606 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10607 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10610 alc888_acer_aspire_4930g_verbs },
10611 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10612 .dac_nids = alc883_dac_nids,
10613 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10614 .adc_nids = alc883_adc_nids_rev,
10615 .capsrc_nids = alc883_capsrc_nids_rev,
10616 .dig_out_nid = ALC883_DIGOUT_NID,
10617 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10618 .channel_mode = alc883_3ST_6ch_modes,
10619 .need_dac_fix = 1,
973b8cb0 10620 .const_channel_count = 6,
5b2d1eca 10621 .num_mux_defs =
ef8ef5fb
VP
10622 ARRAY_SIZE(alc888_2_capture_sources),
10623 .input_mux = alc888_2_capture_sources,
d922b51d 10624 .unsol_event = alc_sku_unsol_event,
4f5d1706 10625 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10626 .init_hook = alc_hp_automute,
d2fd4b09
TV
10627 },
10628 [ALC888_ACER_ASPIRE_6530G] = {
10629 .mixers = { alc888_acer_aspire_6530_mixer },
10630 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10631 alc888_acer_aspire_6530g_verbs },
10632 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10633 .dac_nids = alc883_dac_nids,
10634 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10635 .adc_nids = alc883_adc_nids_rev,
10636 .capsrc_nids = alc883_capsrc_nids_rev,
10637 .dig_out_nid = ALC883_DIGOUT_NID,
10638 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10639 .channel_mode = alc883_3ST_2ch_modes,
10640 .num_mux_defs =
10641 ARRAY_SIZE(alc888_2_capture_sources),
10642 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10643 .unsol_event = alc_sku_unsol_event,
4f5d1706 10644 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10645 .init_hook = alc_hp_automute,
5b2d1eca 10646 },
3b315d70 10647 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10648 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10649 alc883_chmode_mixer },
10650 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10651 alc889_acer_aspire_8930g_verbs,
10652 alc889_eapd_verbs},
3b315d70
HM
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
018df418
HM
10655 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10656 .adc_nids = alc889_adc_nids,
10657 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10660 .channel_mode = alc883_3ST_6ch_modes,
10661 .need_dac_fix = 1,
10662 .const_channel_count = 6,
10663 .num_mux_defs =
018df418
HM
10664 ARRAY_SIZE(alc889_capture_sources),
10665 .input_mux = alc889_capture_sources,
d922b51d 10666 .unsol_event = alc_sku_unsol_event,
4f5d1706 10667 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10668 .init_hook = alc_hp_automute,
f5de24b0 10669#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10670 .power_hook = alc_power_eapd,
f5de24b0 10671#endif
3b315d70 10672 },
fc86f954
DK
10673 [ALC888_ACER_ASPIRE_7730G] = {
10674 .mixers = { alc883_3ST_6ch_mixer,
10675 alc883_chmode_mixer },
10676 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10677 alc888_acer_aspire_7730G_verbs },
10678 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10679 .dac_nids = alc883_dac_nids,
10680 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10681 .adc_nids = alc883_adc_nids_rev,
10682 .capsrc_nids = alc883_capsrc_nids_rev,
10683 .dig_out_nid = ALC883_DIGOUT_NID,
10684 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10685 .channel_mode = alc883_3ST_6ch_modes,
10686 .need_dac_fix = 1,
10687 .const_channel_count = 6,
10688 .input_mux = &alc883_capture_source,
d922b51d 10689 .unsol_event = alc_sku_unsol_event,
d9477207 10690 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10691 .init_hook = alc_hp_automute,
fc86f954 10692 },
c07584c8
TD
10693 [ALC883_MEDION] = {
10694 .mixers = { alc883_fivestack_mixer,
10695 alc883_chmode_mixer },
10696 .init_verbs = { alc883_init_verbs,
b373bdeb 10697 alc883_medion_eapd_verbs },
c07584c8
TD
10698 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10699 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10700 .adc_nids = alc883_adc_nids_alt,
10701 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10702 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10703 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10704 .channel_mode = alc883_sixstack_modes,
10705 .input_mux = &alc883_capture_source,
b373bdeb 10706 },
7ad7b218
MC
10707 [ALC883_MEDION_WIM2160] = {
10708 .mixers = { alc883_medion_wim2160_mixer },
10709 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10710 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10711 .dac_nids = alc883_dac_nids,
10712 .dig_out_nid = ALC883_DIGOUT_NID,
10713 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10714 .adc_nids = alc883_adc_nids,
10715 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10716 .channel_mode = alc883_3ST_2ch_modes,
10717 .input_mux = &alc883_capture_source,
d922b51d 10718 .unsol_event = alc_sku_unsol_event,
7ad7b218 10719 .setup = alc883_medion_wim2160_setup,
d922b51d 10720 .init_hook = alc_hp_automute,
7ad7b218 10721 },
b373bdeb 10722 [ALC883_LAPTOP_EAPD] = {
676a9b53 10723 .mixers = { alc883_base_mixer },
b373bdeb
AN
10724 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10725 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10726 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10727 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10728 .channel_mode = alc883_3ST_2ch_modes,
10729 .input_mux = &alc883_capture_source,
10730 },
a65cc60f 10731 [ALC883_CLEVO_M540R] = {
10732 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10733 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10734 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10735 .dac_nids = alc883_dac_nids,
10736 .dig_out_nid = ALC883_DIGOUT_NID,
10737 .dig_in_nid = ALC883_DIGIN_NID,
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10739 .channel_mode = alc883_3ST_6ch_clevo_modes,
10740 .need_dac_fix = 1,
10741 .input_mux = &alc883_capture_source,
10742 /* This machine has the hardware HP auto-muting, thus
10743 * we need no software mute via unsol event
10744 */
10745 },
0c4cc443
HRK
10746 [ALC883_CLEVO_M720] = {
10747 .mixers = { alc883_clevo_m720_mixer },
10748 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10753 .channel_mode = alc883_3ST_2ch_modes,
10754 .input_mux = &alc883_capture_source,
0c4cc443 10755 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10756 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10757 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10758 },
bc9f98a9
KY
10759 [ALC883_LENOVO_101E_2ch] = {
10760 .mixers = { alc883_lenovo_101e_2ch_mixer},
10761 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10762 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10763 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10764 .adc_nids = alc883_adc_nids_alt,
10765 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10766 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10767 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10768 .channel_mode = alc883_3ST_2ch_modes,
10769 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10770 .setup = alc883_lenovo_101e_setup,
10771 .unsol_event = alc_sku_unsol_event,
10772 .init_hook = alc_inithook,
bc9f98a9 10773 },
272a527c
KY
10774 [ALC883_LENOVO_NB0763] = {
10775 .mixers = { alc883_lenovo_nb0763_mixer },
10776 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10777 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10778 .dac_nids = alc883_dac_nids,
272a527c
KY
10779 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10780 .channel_mode = alc883_3ST_2ch_modes,
10781 .need_dac_fix = 1,
10782 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10783 .unsol_event = alc_sku_unsol_event,
dc427170 10784 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10785 .init_hook = alc_hp_automute,
272a527c
KY
10786 },
10787 [ALC888_LENOVO_MS7195_DIG] = {
10788 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10789 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10790 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10791 .dac_nids = alc883_dac_nids,
10792 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10793 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10794 .channel_mode = alc883_3ST_6ch_modes,
10795 .need_dac_fix = 1,
10796 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10797 .unsol_event = alc_sku_unsol_event,
10798 .setup = alc888_lenovo_ms7195_setup,
10799 .init_hook = alc_inithook,
189609ae
KY
10800 },
10801 [ALC883_HAIER_W66] = {
c259249f 10802 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10803 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10804 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10805 .dac_nids = alc883_dac_nids,
10806 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10807 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10808 .channel_mode = alc883_3ST_2ch_modes,
10809 .input_mux = &alc883_capture_source,
d922b51d 10810 .unsol_event = alc_sku_unsol_event,
4f5d1706 10811 .setup = alc883_haier_w66_setup,
d922b51d 10812 .init_hook = alc_hp_automute,
eea6419e 10813 },
4723c022 10814 [ALC888_3ST_HP] = {
eea6419e 10815 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10816 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10817 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10818 .dac_nids = alc883_dac_nids,
4723c022
CM
10819 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10820 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10821 .need_dac_fix = 1,
10822 .input_mux = &alc883_capture_source,
d922b51d 10823 .unsol_event = alc_sku_unsol_event,
4f5d1706 10824 .setup = alc888_3st_hp_setup,
d922b51d 10825 .init_hook = alc_hp_automute,
8341de60 10826 },
5795b9e6 10827 [ALC888_6ST_DELL] = {
f24dbdc6 10828 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10829 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10833 .dig_in_nid = ALC883_DIGIN_NID,
10834 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10835 .channel_mode = alc883_sixstack_modes,
10836 .input_mux = &alc883_capture_source,
d922b51d 10837 .unsol_event = alc_sku_unsol_event,
4f5d1706 10838 .setup = alc888_6st_dell_setup,
d922b51d 10839 .init_hook = alc_hp_automute,
5795b9e6 10840 },
a8848bd6
AS
10841 [ALC883_MITAC] = {
10842 .mixers = { alc883_mitac_mixer },
10843 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10846 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10847 .channel_mode = alc883_3ST_2ch_modes,
10848 .input_mux = &alc883_capture_source,
d922b51d 10849 .unsol_event = alc_sku_unsol_event,
4f5d1706 10850 .setup = alc883_mitac_setup,
d922b51d 10851 .init_hook = alc_hp_automute,
a8848bd6 10852 },
fb97dc67
J
10853 [ALC883_FUJITSU_PI2515] = {
10854 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10855 .init_verbs = { alc883_init_verbs,
10856 alc883_2ch_fujitsu_pi2515_verbs},
10857 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10858 .dac_nids = alc883_dac_nids,
10859 .dig_out_nid = ALC883_DIGOUT_NID,
10860 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10861 .channel_mode = alc883_3ST_2ch_modes,
10862 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10863 .unsol_event = alc_sku_unsol_event,
4f5d1706 10864 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10865 .init_hook = alc_hp_automute,
fb97dc67 10866 },
ef8ef5fb
VP
10867 [ALC888_FUJITSU_XA3530] = {
10868 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10869 .init_verbs = { alc883_init_verbs,
10870 alc888_fujitsu_xa3530_verbs },
10871 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10872 .dac_nids = alc883_dac_nids,
10873 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10874 .adc_nids = alc883_adc_nids_rev,
10875 .capsrc_nids = alc883_capsrc_nids_rev,
10876 .dig_out_nid = ALC883_DIGOUT_NID,
10877 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10878 .channel_mode = alc888_4ST_8ch_intel_modes,
10879 .num_mux_defs =
10880 ARRAY_SIZE(alc888_2_capture_sources),
10881 .input_mux = alc888_2_capture_sources,
d922b51d 10882 .unsol_event = alc_sku_unsol_event,
4f5d1706 10883 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10884 .init_hook = alc_hp_automute,
ef8ef5fb 10885 },
e2757d5e
KY
10886 [ALC888_LENOVO_SKY] = {
10887 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10888 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10889 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10890 .dac_nids = alc883_dac_nids,
10891 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10892 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10893 .channel_mode = alc883_sixstack_modes,
10894 .need_dac_fix = 1,
10895 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10896 .unsol_event = alc_sku_unsol_event,
4f5d1706 10897 .setup = alc888_lenovo_sky_setup,
d922b51d 10898 .init_hook = alc_hp_automute,
e2757d5e
KY
10899 },
10900 [ALC888_ASUS_M90V] = {
10901 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10902 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10903 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10904 .dac_nids = alc883_dac_nids,
10905 .dig_out_nid = ALC883_DIGOUT_NID,
10906 .dig_in_nid = ALC883_DIGIN_NID,
10907 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10908 .channel_mode = alc883_3ST_6ch_modes,
10909 .need_dac_fix = 1,
10910 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10911 .unsol_event = alc_sku_unsol_event,
10912 .setup = alc883_mode2_setup,
10913 .init_hook = alc_inithook,
e2757d5e
KY
10914 },
10915 [ALC888_ASUS_EEE1601] = {
10916 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10917 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10918 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10919 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10920 .dac_nids = alc883_dac_nids,
10921 .dig_out_nid = ALC883_DIGOUT_NID,
10922 .dig_in_nid = ALC883_DIGIN_NID,
10923 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10924 .channel_mode = alc883_3ST_2ch_modes,
10925 .need_dac_fix = 1,
10926 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10927 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10928 .init_hook = alc883_eee1601_inithook,
10929 },
3ab90935
WF
10930 [ALC1200_ASUS_P5Q] = {
10931 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10932 .init_verbs = { alc883_init_verbs },
10933 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10934 .dac_nids = alc883_dac_nids,
10935 .dig_out_nid = ALC1200_DIGOUT_NID,
10936 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10937 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10938 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10939 .channel_mode = alc883_sixstack_modes,
10940 .input_mux = &alc883_capture_source,
10941 },
eb4c41d3
TS
10942 [ALC889A_MB31] = {
10943 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10944 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10945 alc880_gpio1_init_verbs },
10946 .adc_nids = alc883_adc_nids,
10947 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10948 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10949 .dac_nids = alc883_dac_nids,
10950 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10951 .channel_mode = alc889A_mb31_6ch_modes,
10952 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10953 .input_mux = &alc889A_mb31_capture_source,
10954 .dig_out_nid = ALC883_DIGOUT_NID,
10955 .unsol_event = alc889A_mb31_unsol_event,
10956 .init_hook = alc889A_mb31_automute,
10957 },
3e1647c5
GG
10958 [ALC883_SONY_VAIO_TT] = {
10959 .mixers = { alc883_vaiott_mixer },
10960 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10961 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10962 .dac_nids = alc883_dac_nids,
10963 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10964 .channel_mode = alc883_3ST_2ch_modes,
10965 .input_mux = &alc883_capture_source,
d922b51d 10966 .unsol_event = alc_sku_unsol_event,
4f5d1706 10967 .setup = alc883_vaiott_setup,
d922b51d 10968 .init_hook = alc_hp_automute,
3e1647c5 10969 },
9c7f852e
TI
10970};
10971
10972
4953550a
TI
10973/*
10974 * Pin config fixes
10975 */
10976enum {
954a29c8 10977 PINFIX_ABIT_AW9D_MAX,
32eea388 10978 PINFIX_LENOVO_Y530,
954a29c8 10979 PINFIX_PB_M5210,
c3d226ab 10980 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10981};
10982
f8f25ba3
TI
10983static const struct alc_fixup alc882_fixups[] = {
10984 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10985 .type = ALC_FIXUP_PINS,
10986 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10987 { 0x15, 0x01080104 }, /* side */
10988 { 0x16, 0x01011012 }, /* rear */
10989 { 0x17, 0x01016011 }, /* clfe */
10990 { }
10991 }
f8f25ba3 10992 },
32eea388
DH
10993 [PINFIX_LENOVO_Y530] = {
10994 .type = ALC_FIXUP_PINS,
10995 .v.pins = (const struct alc_pincfg[]) {
10996 { 0x15, 0x99130112 }, /* rear int speakers */
10997 { 0x16, 0x99130111 }, /* subwoofer */
10998 { }
10999 }
11000 },
954a29c8 11001 [PINFIX_PB_M5210] = {
b5bfbc67
TI
11002 .type = ALC_FIXUP_VERBS,
11003 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
11004 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11005 {}
11006 }
954a29c8 11007 },
c3d226ab 11008 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
11009 .type = ALC_FIXUP_SKU,
11010 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 11011 },
4953550a
TI
11012};
11013
a9111321 11014static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 11015 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 11016 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 11017 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 11018 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
11019 {}
11020};
11021
9c7f852e
TI
11022/*
11023 * BIOS auto configuration
11024 */
05f5f477
TI
11025static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11026 const struct auto_pin_cfg *cfg)
11027{
11028 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11029}
11030
4953550a 11031static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 11032 hda_nid_t nid, int pin_type,
489008cd 11033 hda_nid_t dac)
9c7f852e 11034{
f12ab1e0
TI
11035 int idx;
11036
489008cd 11037 /* set as output */
f6c7e546 11038 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
11039
11040 if (dac == 0x25)
9c7f852e 11041 idx = 4;
489008cd
TI
11042 else if (dac >= 0x02 && dac <= 0x05)
11043 idx = dac - 2;
f9700d5a 11044 else
489008cd 11045 return;
9c7f852e 11046 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11047}
11048
4953550a 11049static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11050{
11051 struct alc_spec *spec = codec->spec;
11052 int i;
11053
11054 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11055 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11056 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11057 if (nid)
4953550a 11058 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11059 spec->multiout.dac_nids[i]);
9c7f852e
TI
11060 }
11061}
11062
4953550a 11063static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11064{
11065 struct alc_spec *spec = codec->spec;
489008cd 11066 hda_nid_t pin, dac;
5855fb80 11067 int i;
9c7f852e 11068
0a3fabe3
DH
11069 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11070 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11071 pin = spec->autocfg.hp_pins[i];
11072 if (!pin)
11073 break;
11074 dac = spec->multiout.hp_nid;
11075 if (!dac)
11076 dac = spec->multiout.dac_nids[0]; /* to front */
11077 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11078 }
489008cd 11079 }
0a3fabe3
DH
11080
11081 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11082 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11083 pin = spec->autocfg.speaker_pins[i];
11084 if (!pin)
11085 break;
11086 dac = spec->multiout.extra_out_nid[0];
11087 if (!dac)
11088 dac = spec->multiout.dac_nids[0]; /* to front */
11089 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11090 }
489008cd 11091 }
9c7f852e
TI
11092}
11093
4953550a 11094static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11095{
11096 struct alc_spec *spec = codec->spec;
66ceeb6b 11097 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11098 int i;
11099
66ceeb6b
TI
11100 for (i = 0; i < cfg->num_inputs; i++) {
11101 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11102 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11103 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11104 snd_hda_codec_write(codec, nid, 0,
11105 AC_VERB_SET_AMP_GAIN_MUTE,
11106 AMP_OUT_MUTE);
11107 }
11108}
11109
11110static void alc882_auto_init_input_src(struct hda_codec *codec)
11111{
11112 struct alc_spec *spec = codec->spec;
11113 int c;
11114
11115 for (c = 0; c < spec->num_adc_nids; c++) {
11116 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11117 hda_nid_t nid = spec->capsrc_nids[c];
11118 unsigned int mux_idx;
11119 const struct hda_input_mux *imux;
11120 int conns, mute, idx, item;
11121
10696aa0
TI
11122 /* mute ADC */
11123 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11124 AC_VERB_SET_AMP_GAIN_MUTE,
11125 AMP_IN_MUTE(0));
11126
4953550a
TI
11127 conns = snd_hda_get_connections(codec, nid, conn_list,
11128 ARRAY_SIZE(conn_list));
11129 if (conns < 0)
11130 continue;
11131 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11132 imux = &spec->input_mux[mux_idx];
5311114d
TI
11133 if (!imux->num_items && mux_idx > 0)
11134 imux = &spec->input_mux[0];
4953550a
TI
11135 for (idx = 0; idx < conns; idx++) {
11136 /* if the current connection is the selected one,
11137 * unmute it as default - otherwise mute it
11138 */
11139 mute = AMP_IN_MUTE(idx);
11140 for (item = 0; item < imux->num_items; item++) {
11141 if (imux->items[item].index == idx) {
11142 if (spec->cur_mux[c] == item)
11143 mute = AMP_IN_UNMUTE(idx);
11144 break;
11145 }
11146 }
11147 /* check if we have a selector or mixer
11148 * we could check for the widget type instead, but
11149 * just check for Amp-In presence (in case of mixer
11150 * without amp-in there is something wrong, this
11151 * function shouldn't be used or capsrc nid is wrong)
11152 */
11153 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11154 snd_hda_codec_write(codec, nid, 0,
11155 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11156 mute);
11157 else if (mute != AMP_IN_MUTE(idx))
11158 snd_hda_codec_write(codec, nid, 0,
11159 AC_VERB_SET_CONNECT_SEL,
11160 idx);
9c7f852e
TI
11161 }
11162 }
11163}
11164
4953550a
TI
11165/* add mic boosts if needed */
11166static int alc_auto_add_mic_boost(struct hda_codec *codec)
11167{
11168 struct alc_spec *spec = codec->spec;
66ceeb6b 11169 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11170 int i, err;
53e8c323 11171 int type_idx = 0;
4953550a 11172 hda_nid_t nid;
5322bf27 11173 const char *prev_label = NULL;
4953550a 11174
66ceeb6b 11175 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11176 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11177 break;
11178 nid = cfg->inputs[i].pin;
11179 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11180 const char *label;
11181 char boost_label[32];
11182
11183 label = hda_get_autocfg_input_label(codec, cfg, i);
11184 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11185 type_idx++;
11186 else
11187 type_idx = 0;
5322bf27
DH
11188 prev_label = label;
11189
11190 snprintf(boost_label, sizeof(boost_label),
11191 "%s Boost Volume", label);
11192 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11193 boost_label, type_idx,
4953550a 11194 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11195 if (err < 0)
11196 return err;
11197 }
4953550a
TI
11198 }
11199 return 0;
11200}
f511b01c 11201
9c7f852e 11202/* almost identical with ALC880 parser... */
4953550a 11203static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11204{
11205 struct alc_spec *spec = codec->spec;
4c6d72d1 11206 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11207 int err;
9c7f852e 11208
05f5f477
TI
11209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11210 alc882_ignore);
9c7f852e
TI
11211 if (err < 0)
11212 return err;
05f5f477
TI
11213 if (!spec->autocfg.line_outs)
11214 return 0; /* can't find valid BIOS pin config */
776e184e 11215
05f5f477 11216 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11217 if (err < 0)
11218 return err;
11219 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11220 if (err < 0)
11221 return err;
569ed348 11222 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11223 if (err < 0)
11224 return err;
11225 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11226 "Headphone");
05f5f477
TI
11227 if (err < 0)
11228 return err;
11229 err = alc880_auto_create_extra_out(spec,
11230 spec->autocfg.speaker_pins[0],
11231 "Speaker");
11232 if (err < 0)
11233 return err;
05f5f477 11234 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11235 if (err < 0)
11236 return err;
11237
05f5f477
TI
11238 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11239
757899ac 11240 alc_auto_parse_digital(codec);
05f5f477
TI
11241
11242 if (spec->kctls.list)
11243 add_mixer(spec, spec->kctls.list);
11244
11245 add_verb(spec, alc883_auto_init_verbs);
4953550a 11246 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11247 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11248 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11249
05f5f477
TI
11250 spec->num_mux_defs = 1;
11251 spec->input_mux = &spec->private_imux[0];
11252
6227cdce 11253 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11254
11255 err = alc_auto_add_mic_boost(codec);
11256 if (err < 0)
11257 return err;
61b9b9b1 11258
776e184e 11259 return 1; /* config found */
9c7f852e
TI
11260}
11261
11262/* additional initialization for auto-configuration model */
4953550a 11263static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11264{
f6c7e546 11265 struct alc_spec *spec = codec->spec;
4953550a
TI
11266 alc882_auto_init_multi_out(codec);
11267 alc882_auto_init_hp_out(codec);
11268 alc882_auto_init_analog_input(codec);
11269 alc882_auto_init_input_src(codec);
757899ac 11270 alc_auto_init_digital(codec);
f6c7e546 11271 if (spec->unsol_event)
7fb0d78f 11272 alc_inithook(codec);
9c7f852e
TI
11273}
11274
4953550a 11275static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11276{
11277 struct alc_spec *spec;
11278 int err, board_config;
11279
11280 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11281 if (spec == NULL)
11282 return -ENOMEM;
11283
11284 codec->spec = spec;
11285
4953550a
TI
11286 switch (codec->vendor_id) {
11287 case 0x10ec0882:
11288 case 0x10ec0885:
11289 break;
11290 default:
11291 /* ALC883 and variants */
11292 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11293 break;
11294 }
2c3bf9ab 11295
4953550a
TI
11296 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11297 alc882_models,
11298 alc882_cfg_tbl);
11299
11300 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11301 board_config = snd_hda_check_board_codec_sid_config(codec,
11302 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11303
11304 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11305 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11306 codec->chip_name);
11307 board_config = ALC882_AUTO;
9c7f852e
TI
11308 }
11309
b5bfbc67
TI
11310 if (board_config == ALC882_AUTO) {
11311 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11312 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11313 }
4953550a 11314
90622917
DH
11315 alc_auto_parse_customize_define(codec);
11316
4953550a 11317 if (board_config == ALC882_AUTO) {
9c7f852e 11318 /* automatic parse from the BIOS config */
4953550a 11319 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11320 if (err < 0) {
11321 alc_free(codec);
11322 return err;
f12ab1e0 11323 } else if (!err) {
9c7f852e
TI
11324 printk(KERN_INFO
11325 "hda_codec: Cannot set up configuration "
11326 "from BIOS. Using base mode...\n");
4953550a 11327 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11328 }
11329 }
11330
dc1eae25 11331 if (has_cdefine_beep(codec)) {
8af2591d
TI
11332 err = snd_hda_attach_beep_device(codec, 0x1);
11333 if (err < 0) {
11334 alc_free(codec);
11335 return err;
11336 }
680cd536
KK
11337 }
11338
4953550a 11339 if (board_config != ALC882_AUTO)
e9c364c0 11340 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11341
4953550a
TI
11342 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11343 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11344 /* FIXME: setup DAC5 */
11345 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11346 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11347
11348 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11349 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11350
4953550a 11351 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11352 int i, j;
4953550a
TI
11353 spec->num_adc_nids = 0;
11354 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11355 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11356 hda_nid_t cap;
d11f74c6 11357 hda_nid_t items[16];
4953550a
TI
11358 hda_nid_t nid = alc882_adc_nids[i];
11359 unsigned int wcap = get_wcaps(codec, nid);
11360 /* get type */
a22d543a 11361 wcap = get_wcaps_type(wcap);
4953550a
TI
11362 if (wcap != AC_WID_AUD_IN)
11363 continue;
11364 spec->private_adc_nids[spec->num_adc_nids] = nid;
11365 err = snd_hda_get_connections(codec, nid, &cap, 1);
11366 if (err < 0)
11367 continue;
d11f74c6
TI
11368 err = snd_hda_get_connections(codec, cap, items,
11369 ARRAY_SIZE(items));
11370 if (err < 0)
11371 continue;
11372 for (j = 0; j < imux->num_items; j++)
11373 if (imux->items[j].index >= err)
11374 break;
11375 if (j < imux->num_items)
11376 continue;
4953550a
TI
11377 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11378 spec->num_adc_nids++;
61b9b9b1 11379 }
4953550a
TI
11380 spec->adc_nids = spec->private_adc_nids;
11381 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11382 }
11383
b59bdf3b 11384 set_capture_mixer(codec);
da00c244 11385
dc1eae25 11386 if (has_cdefine_beep(codec))
da00c244 11387 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11388
b5bfbc67 11389 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11390
2134ea4f
TI
11391 spec->vmaster_nid = 0x0c;
11392
9c7f852e 11393 codec->patch_ops = alc_patch_ops;
4953550a
TI
11394 if (board_config == ALC882_AUTO)
11395 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11396
11397 alc_init_jacks(codec);
cb53c626
TI
11398#ifdef CONFIG_SND_HDA_POWER_SAVE
11399 if (!spec->loopback.amplist)
4953550a 11400 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11401#endif
9c7f852e
TI
11402
11403 return 0;
11404}
11405
4953550a 11406
9c7f852e
TI
11407/*
11408 * ALC262 support
11409 */
11410
11411#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11412#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11413
11414#define alc262_dac_nids alc260_dac_nids
11415#define alc262_adc_nids alc882_adc_nids
11416#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11417#define alc262_capsrc_nids alc882_capsrc_nids
11418#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11419
11420#define alc262_modes alc260_modes
11421#define alc262_capture_source alc882_capture_source
11422
4c6d72d1 11423static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11424 /* ADC0 */
11425 0x09
11426};
11427
4c6d72d1 11428static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11429
a9111321 11430static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11431 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11432 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11434 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11435 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11436 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11438 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11439 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11440 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11441 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11442 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11443 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11444 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11447 { } /* end */
11448};
11449
ce875f07 11450/* update HP, line and mono-out pins according to the master switch */
e9427969 11451#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11452
e9427969 11453static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11454{
11455 struct alc_spec *spec = codec->spec;
864f92be 11456
e9427969
TI
11457 spec->autocfg.hp_pins[0] = 0x1b;
11458 spec->autocfg.speaker_pins[0] = 0x16;
11459 spec->automute = 1;
11460 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11461}
11462
e9427969 11463static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11464{
11465 struct alc_spec *spec = codec->spec;
864f92be 11466
e9427969
TI
11467 spec->autocfg.hp_pins[0] = 0x15;
11468 spec->autocfg.speaker_pins[0] = 0x16;
11469 spec->automute = 1;
11470 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11471}
11472
b72519b5 11473#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11474#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11475
b72519b5
TI
11476#define ALC262_HP_MASTER_SWITCH \
11477 { \
11478 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11479 .name = "Master Playback Switch", \
11480 .info = snd_ctl_boolean_mono_info, \
11481 .get = alc262_hp_master_sw_get, \
11482 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11483 }, \
11484 { \
11485 .iface = NID_MAPPING, \
11486 .name = "Master Playback Switch", \
11487 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11488 }
11489
5b0cb1d8 11490
a9111321 11491static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11492 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11493 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11494 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11496 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11497 HDA_OUTPUT),
11498 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11499 HDA_OUTPUT),
9c7f852e
TI
11500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11503 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11504 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11505 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11506 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11507 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11510 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11511 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11512 { } /* end */
11513};
11514
a9111321 11515static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11516 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11517 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11518 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11520 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11521 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11522 HDA_OUTPUT),
11523 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11524 HDA_OUTPUT),
cd7509a4
KY
11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11528 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11529 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11532 { } /* end */
11533};
11534
a9111321 11535static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11536 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11537 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11538 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11539 { } /* end */
11540};
11541
66d2a9d6 11542/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11543static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11544{
11545 struct alc_spec *spec = codec->spec;
66d2a9d6 11546
a9fd4f3f 11547 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11548 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11549 spec->automute = 1;
11550 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11551}
11552
a9111321 11553static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11554 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11555 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11556 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11557 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11559 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11561 { } /* end */
11562};
11563
a9111321 11564static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11565 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11566 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11567
11568 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11569 { }
11570};
11571
a9111321 11572static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11573 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11574 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11575 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11576 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11577 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11578 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11579 { } /* end */
11580};
11581
a9111321 11582static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11583 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11584 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11585 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11586 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11588 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11589 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11590 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11591 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11593 {}
11594};
11595
a9111321 11596static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11597 .num_items = 1,
11598 .items = {
11599 { "Line", 0x1 },
11600 },
11601};
11602
42171c17 11603/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11604#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11605#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11606#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11607
11608#define ALC262_HIPPO_MASTER_SWITCH \
11609 { \
11610 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11611 .name = "Master Playback Switch", \
11612 .info = snd_ctl_boolean_mono_info, \
11613 .get = alc262_hippo_master_sw_get, \
11614 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11615 }, \
11616 { \
11617 .iface = NID_MAPPING, \
11618 .name = "Master Playback Switch", \
11619 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11620 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11621 }
42171c17 11622
a9111321 11623static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11624 ALC262_HIPPO_MASTER_SWITCH,
11625 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11626 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11627 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11629 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11630 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11631 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11632 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11633 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11634 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11635 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11637 { } /* end */
11638};
11639
a9111321 11640static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11641 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11642 ALC262_HIPPO_MASTER_SWITCH,
11643 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11644 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11645 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11646 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11649 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11650 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11651 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11652 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11653 { } /* end */
11654};
11655
11656/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11657static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11658{
11659 struct alc_spec *spec = codec->spec;
11660
11661 spec->autocfg.hp_pins[0] = 0x15;
11662 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11663 spec->automute = 1;
11664 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11665}
11666
4f5d1706 11667static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11668{
11669 struct alc_spec *spec = codec->spec;
11670
11671 spec->autocfg.hp_pins[0] = 0x1b;
11672 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11673 spec->automute = 1;
11674 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11675}
11676
11677
a9111321 11678static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11679 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11680 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11681 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11682 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11683 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11684 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11685 { } /* end */
11686};
11687
a9111321 11688static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11689 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11690 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11691 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11692 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11693 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11695 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11696 { } /* end */
11697};
272a527c 11698
a9111321 11699static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11700 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11701 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11702 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11703 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11704 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11705 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11707 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11708 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11709 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11710 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11711 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11712 { } /* end */
11713};
11714
a9111321 11715static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11716 /* Headphone automute */
11717 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11718 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11719 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11720
11721 /* P11 AUX_IN, white 4-pin connector */
11722 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11723 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11724 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11725 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11726
11727 {}
11728};
11729
11730/* unsolicited event for HP jack sensing */
4f5d1706 11731static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11732{
a9fd4f3f 11733 struct alc_spec *spec = codec->spec;
ba340e82 11734
a9fd4f3f
TI
11735 spec->autocfg.hp_pins[0] = 0x1b;
11736 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11737 spec->automute = 1;
11738 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11739}
11740
ba340e82 11741
9c7f852e
TI
11742#define alc262_capture_mixer alc882_capture_mixer
11743#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11744
11745/*
11746 * generic initialization of ADC, input mixers and output mixers
11747 */
a9111321 11748static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11749 /*
11750 * Unmute ADC0-2 and set the default input to mic-in
11751 */
11752 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11753 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11754 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11755 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11756 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11757 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11758
cb53c626 11759 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11760 * mixer widget
f12ab1e0
TI
11761 * Note: PASD motherboards uses the Line In 2 as the input for
11762 * front panel mic (mic 2)
9c7f852e
TI
11763 */
11764 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11765 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11770
11771 /*
df694daa
KY
11772 * Set up output mixers (0x0c - 0x0e)
11773 */
11774 /* set vol=0 to output mixers */
11775 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11776 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11777 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11778 /* set up input amps for analog loopback */
11779 /* Amp Indices: DAC = 0, mixer = 1 */
11780 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11782 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11784 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11786
11787 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11788 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11789 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11791 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11792 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11793
11794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11795 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11796 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11797 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11798 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11799
df694daa
KY
11800 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11801 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11802
df694daa
KY
11803 /* FIXME: use matrix-type input source selection */
11804 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11805 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11806 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11810 /* Input mixer2 */
11811 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11815 /* Input mixer3 */
11816 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11820
11821 { }
11822};
1da177e4 11823
a9111321 11824static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11825 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11826 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11827 { }
11828};
11829
a9111321 11830static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11831 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11832 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11833 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11834
11835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11836 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11837 {}
11838};
11839
a9111321 11840static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11841 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11843 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11844
11845 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11847 {}
272a527c
KY
11848};
11849
a9111321 11850static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11851 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11852 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11854 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11856 { } /* end */
11857};
11858
a9111321 11859static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11860 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11861 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11862 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11863 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11864 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11865 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11866 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11867 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11868 {}
11869};
11870
4f5d1706 11871static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11872{
a9fd4f3f
TI
11873 struct alc_spec *spec = codec->spec;
11874
11875 spec->autocfg.hp_pins[0] = 0x15;
11876 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11877 spec->ext_mic.pin = 0x18;
11878 spec->ext_mic.mux_idx = 0;
11879 spec->int_mic.pin = 0x12;
11880 spec->int_mic.mux_idx = 9;
11881 spec->auto_mic = 1;
d922b51d
TI
11882 spec->automute = 1;
11883 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11884}
11885
e8f9ae2a
PT
11886/*
11887 * nec model
11888 * 0x15 = headphone
11889 * 0x16 = internal speaker
11890 * 0x18 = external mic
11891 */
11892
a9111321 11893static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11894 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11895 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11896
11897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11899 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11900
11901 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11902 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11903 { } /* end */
11904};
11905
a9111321 11906static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11907 /* Unmute Speaker */
11908 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11909
11910 /* Headphone */
11911 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11912 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11913
11914 /* External mic to headphone */
11915 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11916 /* External mic to speaker */
11917 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11918 {}
11919};
11920
834be88d
TI
11921/*
11922 * fujitsu model
5d9fab2d
TV
11923 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11924 * 0x1b = port replicator headphone out
834be88d
TI
11925 */
11926
11927#define ALC_HP_EVENT 0x37
11928
a9111321 11929static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11930 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11933 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11934 {}
11935};
11936
a9111321 11937static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11939 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11940 {}
11941};
11942
a9111321 11943static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11944 /* Front Mic pin: input vref at 50% */
11945 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11946 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11947 {}
11948};
11949
a9111321 11950static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11951 .num_items = 3,
834be88d
TI
11952 .items = {
11953 { "Mic", 0x0 },
28c4edb7 11954 { "Internal Mic", 0x1 },
834be88d
TI
11955 { "CD", 0x4 },
11956 },
11957};
11958
a9111321 11959static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11960 .num_items = 5,
11961 .items = {
11962 { "Mic", 0x0 },
accbe498 11963 { "Front Mic", 0x1 },
9c7f852e
TI
11964 { "Line", 0x2 },
11965 { "CD", 0x4 },
11966 { "AUX IN", 0x6 },
11967 },
11968};
11969
a9111321 11970static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11971 .num_items = 4,
11972 .items = {
11973 { "Mic", 0x0 },
11974 { "Front Mic", 0x2 },
11975 { "Line", 0x1 },
11976 { "CD", 0x4 },
11977 },
11978};
11979
0f0f391c 11980static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11981{
11982 struct alc_spec *spec = codec->spec;
834be88d 11983
0f0f391c
TI
11984 spec->autocfg.hp_pins[0] = 0x14;
11985 spec->autocfg.hp_pins[1] = 0x1b;
11986 spec->autocfg.speaker_pins[0] = 0x15;
11987 spec->automute = 1;
11988 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11989}
11990
834be88d 11991/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11992static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11993 .ops = &snd_hda_bind_vol,
11994 .values = {
11995 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11996 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11997 0
11998 },
11999};
834be88d 12000
a9111321 12001static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 12002 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
12003 {
12004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12005 .name = "Master Playback Switch",
0f0f391c
TI
12006 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12007 .info = snd_ctl_boolean_mono_info,
12008 .get = alc262_hp_master_sw_get,
12009 .put = alc262_hp_master_sw_put,
834be88d 12010 },
5b0cb1d8
JK
12011 {
12012 .iface = NID_MAPPING,
12013 .name = "Master Playback Switch",
12014 .private_value = 0x1b,
12015 },
834be88d
TI
12016 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12017 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12018 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
12019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12022 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12023 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
12024 { } /* end */
12025};
12026
0f0f391c 12027static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 12028{
0f0f391c 12029 struct alc_spec *spec = codec->spec;
0e31daf7 12030
0f0f391c
TI
12031 spec->autocfg.hp_pins[0] = 0x1b;
12032 spec->autocfg.speaker_pins[0] = 0x14;
12033 spec->autocfg.speaker_pins[1] = 0x16;
12034 spec->automute = 1;
12035 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
12036}
12037
a9111321 12038static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
12039 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12040 {
12041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12042 .name = "Master Playback Switch",
0f0f391c
TI
12043 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12044 .info = snd_ctl_boolean_mono_info,
12045 .get = alc262_hp_master_sw_get,
12046 .put = alc262_hp_master_sw_put,
0e31daf7
J
12047 },
12048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12050 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12053 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12054 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12055 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12056 { } /* end */
12057};
12058
a9111321 12059static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12060 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12061 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12063 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12064 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12065 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12066 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12067 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12068 { } /* end */
12069};
12070
304dcaac 12071/* additional init verbs for Benq laptops */
a9111321 12072static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12073 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12074 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12075 {}
12076};
12077
a9111321 12078static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12079 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12081
12082 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12083 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12084 {}
12085};
12086
f651b50b 12087/* Samsung Q1 Ultra Vista model setup */
a9111321 12088static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12089 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12090 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12094 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12095 { } /* end */
12096};
12097
a9111321 12098static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12099 /* output mixer */
12100 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12103 /* speaker */
12104 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12105 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12107 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12108 /* HP */
f651b50b 12109 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12110 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12112 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12113 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12114 /* internal mic */
12115 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12116 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12117 /* ADC, choose mic */
12118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12119 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12128 {}
12129};
12130
f651b50b
TD
12131/* mute/unmute internal speaker according to the hp jack and mute state */
12132static void alc262_ultra_automute(struct hda_codec *codec)
12133{
12134 struct alc_spec *spec = codec->spec;
12135 unsigned int mute;
f651b50b 12136
bb9f76cd
TI
12137 mute = 0;
12138 /* auto-mute only when HP is used as HP */
12139 if (!spec->cur_mux[0]) {
864f92be 12140 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12141 if (spec->jack_present)
12142 mute = HDA_AMP_MUTE;
f651b50b 12143 }
bb9f76cd
TI
12144 /* mute/unmute internal speaker */
12145 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12146 HDA_AMP_MUTE, mute);
12147 /* mute/unmute HP */
12148 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12149 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12150}
12151
12152/* unsolicited event for HP jack sensing */
12153static void alc262_ultra_unsol_event(struct hda_codec *codec,
12154 unsigned int res)
12155{
12156 if ((res >> 26) != ALC880_HP_EVENT)
12157 return;
12158 alc262_ultra_automute(codec);
12159}
12160
a9111321 12161static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12162 .num_items = 2,
12163 .items = {
12164 { "Mic", 0x1 },
12165 { "Headphone", 0x7 },
12166 },
12167};
12168
12169static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12170 struct snd_ctl_elem_value *ucontrol)
12171{
12172 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12173 struct alc_spec *spec = codec->spec;
12174 int ret;
12175
54cbc9ab 12176 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12177 if (!ret)
12178 return 0;
12179 /* reprogram the HP pin as mic or HP according to the input source */
12180 snd_hda_codec_write_cache(codec, 0x15, 0,
12181 AC_VERB_SET_PIN_WIDGET_CONTROL,
12182 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12183 alc262_ultra_automute(codec); /* mute/unmute HP */
12184 return ret;
12185}
12186
a9111321 12187static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12188 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12189 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12190 {
12191 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12192 .name = "Capture Source",
54cbc9ab
TI
12193 .info = alc_mux_enum_info,
12194 .get = alc_mux_enum_get,
bb9f76cd
TI
12195 .put = alc262_ultra_mux_enum_put,
12196 },
5b0cb1d8
JK
12197 {
12198 .iface = NID_MAPPING,
12199 .name = "Capture Source",
12200 .private_value = 0x15,
12201 },
bb9f76cd
TI
12202 { } /* end */
12203};
12204
c3fc1f50
TI
12205/* We use two mixers depending on the output pin; 0x16 is a mono output
12206 * and thus it's bound with a different mixer.
12207 * This function returns which mixer amp should be used.
12208 */
12209static int alc262_check_volbit(hda_nid_t nid)
12210{
12211 if (!nid)
12212 return 0;
12213 else if (nid == 0x16)
12214 return 2;
12215 else
12216 return 1;
12217}
12218
12219static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12220 const char *pfx, int *vbits, int idx)
c3fc1f50 12221{
c3fc1f50
TI
12222 unsigned long val;
12223 int vbit;
12224
12225 vbit = alc262_check_volbit(nid);
12226 if (!vbit)
12227 return 0;
12228 if (*vbits & vbit) /* a volume control for this mixer already there */
12229 return 0;
12230 *vbits |= vbit;
c3fc1f50
TI
12231 if (vbit == 2)
12232 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12233 else
12234 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12235 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12236}
12237
12238static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12239 const char *pfx, int idx)
c3fc1f50 12240{
c3fc1f50
TI
12241 unsigned long val;
12242
12243 if (!nid)
12244 return 0;
c3fc1f50
TI
12245 if (nid == 0x16)
12246 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12247 else
12248 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12249 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12250}
12251
df694daa 12252/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12253static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12254 const struct auto_pin_cfg *cfg)
df694daa 12255{
c3fc1f50
TI
12256 const char *pfx;
12257 int vbits;
033688a5 12258 int i, err;
df694daa
KY
12259
12260 spec->multiout.num_dacs = 1; /* only use one dac */
12261 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12262 spec->private_dac_nids[0] = 2;
df694daa 12263
ce764ab2 12264 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12265 if (!pfx)
c3fc1f50 12266 pfx = "Front";
033688a5
TI
12267 for (i = 0; i < 2; i++) {
12268 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12269 if (err < 0)
12270 return err;
12271 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12272 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12273 "Speaker", i);
12274 if (err < 0)
12275 return err;
12276 }
12277 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12278 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12279 "Headphone", i);
12280 if (err < 0)
12281 return err;
12282 }
12283 }
df694daa 12284
c3fc1f50
TI
12285 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12286 alc262_check_volbit(cfg->speaker_pins[0]) |
12287 alc262_check_volbit(cfg->hp_pins[0]);
12288 if (vbits == 1 || vbits == 2)
12289 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12290 vbits = 0;
033688a5
TI
12291 for (i = 0; i < 2; i++) {
12292 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12293 &vbits, i);
12294 if (err < 0)
12295 return err;
12296 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12297 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12298 "Speaker", &vbits, i);
12299 if (err < 0)
12300 return err;
12301 }
12302 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12303 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12304 "Headphone", &vbits, i);
12305 if (err < 0)
12306 return err;
12307 }
12308 }
f12ab1e0 12309 return 0;
df694daa
KY
12310}
12311
05f5f477 12312#define alc262_auto_create_input_ctls \
eaa9b3a7 12313 alc882_auto_create_input_ctls
df694daa
KY
12314
12315/*
12316 * generic initialization of ADC, input mixers and output mixers
12317 */
a9111321 12318static const struct hda_verb alc262_volume_init_verbs[] = {
df694daa
KY
12319 /*
12320 * Unmute ADC0-2 and set the default input to mic-in
12321 */
12322 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12323 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12324 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12325 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12326 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12327 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12328
cb53c626 12329 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12330 * mixer widget
f12ab1e0
TI
12331 * Note: PASD motherboards uses the Line In 2 as the input for
12332 * front panel mic (mic 2)
df694daa
KY
12333 */
12334 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12335 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12340
12341 /*
12342 * Set up output mixers (0x0c - 0x0f)
12343 */
12344 /* set vol=0 to output mixers */
12345 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12346 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12347 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12348
df694daa
KY
12349 /* set up input amps for analog loopback */
12350 /* Amp Indices: DAC = 0, mixer = 1 */
12351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12357
12358 /* FIXME: use matrix-type input source selection */
12359 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12360 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12361 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12365 /* Input mixer2 */
12366 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12370 /* Input mixer3 */
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12375
12376 { }
12377};
12378
a9111321 12379static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12380 /*
12381 * Unmute ADC0-2 and set the default input to mic-in
12382 */
12383 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12384 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12385 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12386 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389
cb53c626 12390 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12391 * mixer widget
f12ab1e0
TI
12392 * Note: PASD motherboards uses the Line In 2 as the input for
12393 * front panel mic (mic 2)
9c7f852e
TI
12394 */
12395 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12396 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12403
9c7f852e
TI
12404 /*
12405 * Set up output mixers (0x0c - 0x0e)
12406 */
12407 /* set vol=0 to output mixers */
12408 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12409 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411
12412 /* set up input amps for analog loopback */
12413 /* Amp Indices: DAC = 0, mixer = 1 */
12414 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12416 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420
ce875f07 12421 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12423 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12424
12425 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12426 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427
12428 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12429 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12430
12431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12432 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12433 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12434 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12435 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12436
0e4835c1 12437 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12438 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12440 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12441 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443
12444
12445 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12447 /* Input mixer1: only unmute Mic */
9c7f852e 12448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12457 /* Input mixer2 */
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12467 /* Input mixer3 */
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12477
ce875f07
TI
12478 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12479
9c7f852e
TI
12480 { }
12481};
12482
a9111321 12483static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12484 /*
12485 * Unmute ADC0-2 and set the default input to mic-in
12486 */
12487 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12488 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12489 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12490 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12491 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12492 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12493
cb53c626 12494 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12495 * mixer widget
12496 * Note: PASD motherboards uses the Line In 2 as the input for front
12497 * panel mic (mic 2)
12498 */
12499 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12500 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12508 /*
12509 * Set up output mixers (0x0c - 0x0e)
12510 */
12511 /* set vol=0 to output mixers */
12512 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12514 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12515
12516 /* set up input amps for analog loopback */
12517 /* Amp Indices: DAC = 0, mixer = 1 */
12518 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12520 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12522 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12524
12525
12526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12527 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12528 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12529 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12530 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12531 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12532 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12533
12534 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12535 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536
12537 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12538 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12539
12540 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12541 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12542 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12543 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12544 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12545 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12546
12547 /* FIXME: use matrix-type input source selection */
12548 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12549 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12555 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12556 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12557 /* Input mixer2 */
12558 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12563 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12564 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12565 /* Input mixer3 */
12566 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12571 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12573
ce875f07
TI
12574 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12575
cd7509a4
KY
12576 { }
12577};
12578
a9111321 12579static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12580
12581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12582 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12583 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12584
12585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12586 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12587 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12589
12590 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12593 {}
12594};
12595
18675e42
TI
12596/*
12597 * Pin config fixes
12598 */
12599enum {
12600 PINFIX_FSC_H270,
12601};
12602
12603static const struct alc_fixup alc262_fixups[] = {
12604 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12605 .type = ALC_FIXUP_PINS,
12606 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12607 { 0x14, 0x99130110 }, /* speaker */
12608 { 0x15, 0x0221142f }, /* front HP */
12609 { 0x1b, 0x0121141f }, /* rear HP */
12610 { }
12611 }
12612 },
18675e42
TI
12613};
12614
a9111321 12615static const struct snd_pci_quirk alc262_fixup_tbl[] = {
18675e42
TI
12616 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12617 {}
12618};
12619
9f99a638 12620
cb53c626
TI
12621#ifdef CONFIG_SND_HDA_POWER_SAVE
12622#define alc262_loopbacks alc880_loopbacks
12623#endif
12624
def319f9 12625/* pcm configuration: identical with ALC880 */
df694daa
KY
12626#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12627#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12628#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12629#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12630
12631/*
12632 * BIOS auto configuration
12633 */
12634static int alc262_parse_auto_config(struct hda_codec *codec)
12635{
12636 struct alc_spec *spec = codec->spec;
12637 int err;
4c6d72d1 12638 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12639
f12ab1e0
TI
12640 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12641 alc262_ignore);
12642 if (err < 0)
df694daa 12643 return err;
e64f14f4 12644 if (!spec->autocfg.line_outs) {
0852d7a6 12645 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12646 spec->multiout.max_channels = 2;
12647 spec->no_analog = 1;
12648 goto dig_only;
12649 }
df694daa 12650 return 0; /* can't find valid BIOS pin config */
e64f14f4 12651 }
f12ab1e0
TI
12652 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12653 if (err < 0)
12654 return err;
05f5f477 12655 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12656 if (err < 0)
df694daa
KY
12657 return err;
12658
12659 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12660
e64f14f4 12661 dig_only:
757899ac 12662 alc_auto_parse_digital(codec);
df694daa 12663
603c4019 12664 if (spec->kctls.list)
d88897ea 12665 add_mixer(spec, spec->kctls.list);
df694daa 12666
d88897ea 12667 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12668 spec->num_mux_defs = 1;
61b9b9b1 12669 spec->input_mux = &spec->private_imux[0];
df694daa 12670
776e184e
TI
12671 err = alc_auto_add_mic_boost(codec);
12672 if (err < 0)
12673 return err;
12674
6227cdce 12675 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12676
df694daa
KY
12677 return 1;
12678}
12679
12680#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12681#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12682#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12683#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12684
12685
12686/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12687static void alc262_auto_init(struct hda_codec *codec)
df694daa 12688{
f6c7e546 12689 struct alc_spec *spec = codec->spec;
df694daa
KY
12690 alc262_auto_init_multi_out(codec);
12691 alc262_auto_init_hp_out(codec);
12692 alc262_auto_init_analog_input(codec);
f511b01c 12693 alc262_auto_init_input_src(codec);
757899ac 12694 alc_auto_init_digital(codec);
f6c7e546 12695 if (spec->unsol_event)
7fb0d78f 12696 alc_inithook(codec);
df694daa
KY
12697}
12698
12699/*
12700 * configuration and preset
12701 */
ea734963 12702static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12703 [ALC262_BASIC] = "basic",
12704 [ALC262_HIPPO] = "hippo",
12705 [ALC262_HIPPO_1] = "hippo_1",
12706 [ALC262_FUJITSU] = "fujitsu",
12707 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12708 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12709 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12710 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12711 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12712 [ALC262_BENQ_T31] = "benq-t31",
12713 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12714 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12715 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12716 [ALC262_ULTRA] = "ultra",
0e31daf7 12717 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12718 [ALC262_NEC] = "nec",
ba340e82 12719 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12720 [ALC262_AUTO] = "auto",
12721};
12722
a9111321 12723static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12724 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12725 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12726 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12727 ALC262_HP_BPC),
12728 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12729 ALC262_HP_BPC),
5734a07c
TI
12730 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12731 ALC262_HP_BPC),
53eff7e1
TI
12732 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12733 ALC262_HP_BPC),
cd7509a4 12734 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12735 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12736 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12737 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12738 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12739 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12740 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12741 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12742 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12743 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12744 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12745 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12746 ALC262_HP_TC_T5735),
8c427226 12747 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12748 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12749 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12750 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12751 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12752 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12753 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12754 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12755#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12756 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12757 ALC262_SONY_ASSAMD),
c5b5165c 12758#endif
36ca6e13 12759 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12760 ALC262_TOSHIBA_RX1),
80ffe869 12761 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12762 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12763 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12764 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12765 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12766 ALC262_ULTRA),
3e420e78 12767 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12768 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12769 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12770 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12771 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12772 {}
12773};
12774
a9111321 12775static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12776 [ALC262_BASIC] = {
12777 .mixers = { alc262_base_mixer },
12778 .init_verbs = { alc262_init_verbs },
12779 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12780 .dac_nids = alc262_dac_nids,
12781 .hp_nid = 0x03,
12782 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12783 .channel_mode = alc262_modes,
a3bcba38 12784 .input_mux = &alc262_capture_source,
df694daa 12785 },
ccc656ce 12786 [ALC262_HIPPO] = {
42171c17 12787 .mixers = { alc262_hippo_mixer },
6732bd0d 12788 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12789 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12790 .dac_nids = alc262_dac_nids,
12791 .hp_nid = 0x03,
12792 .dig_out_nid = ALC262_DIGOUT_NID,
12793 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12794 .channel_mode = alc262_modes,
12795 .input_mux = &alc262_capture_source,
e9427969 12796 .unsol_event = alc_sku_unsol_event,
4f5d1706 12797 .setup = alc262_hippo_setup,
e9427969 12798 .init_hook = alc_inithook,
ccc656ce
KY
12799 },
12800 [ALC262_HIPPO_1] = {
12801 .mixers = { alc262_hippo1_mixer },
12802 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12803 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12804 .dac_nids = alc262_dac_nids,
12805 .hp_nid = 0x02,
12806 .dig_out_nid = ALC262_DIGOUT_NID,
12807 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12808 .channel_mode = alc262_modes,
12809 .input_mux = &alc262_capture_source,
e9427969 12810 .unsol_event = alc_sku_unsol_event,
4f5d1706 12811 .setup = alc262_hippo1_setup,
e9427969 12812 .init_hook = alc_inithook,
ccc656ce 12813 },
834be88d
TI
12814 [ALC262_FUJITSU] = {
12815 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12816 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12817 alc262_fujitsu_unsol_verbs },
834be88d
TI
12818 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12819 .dac_nids = alc262_dac_nids,
12820 .hp_nid = 0x03,
12821 .dig_out_nid = ALC262_DIGOUT_NID,
12822 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12823 .channel_mode = alc262_modes,
12824 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12825 .unsol_event = alc_sku_unsol_event,
12826 .setup = alc262_fujitsu_setup,
12827 .init_hook = alc_inithook,
834be88d 12828 },
9c7f852e
TI
12829 [ALC262_HP_BPC] = {
12830 .mixers = { alc262_HP_BPC_mixer },
12831 .init_verbs = { alc262_HP_BPC_init_verbs },
12832 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12833 .dac_nids = alc262_dac_nids,
12834 .hp_nid = 0x03,
12835 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12836 .channel_mode = alc262_modes,
12837 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12838 .unsol_event = alc_sku_unsol_event,
12839 .setup = alc262_hp_bpc_setup,
12840 .init_hook = alc_inithook,
f12ab1e0 12841 },
cd7509a4
KY
12842 [ALC262_HP_BPC_D7000_WF] = {
12843 .mixers = { alc262_HP_BPC_WildWest_mixer },
12844 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12845 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12846 .dac_nids = alc262_dac_nids,
12847 .hp_nid = 0x03,
12848 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12849 .channel_mode = alc262_modes,
accbe498 12850 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12851 .unsol_event = alc_sku_unsol_event,
12852 .setup = alc262_hp_wildwest_setup,
12853 .init_hook = alc_inithook,
f12ab1e0 12854 },
cd7509a4
KY
12855 [ALC262_HP_BPC_D7000_WL] = {
12856 .mixers = { alc262_HP_BPC_WildWest_mixer,
12857 alc262_HP_BPC_WildWest_option_mixer },
12858 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12859 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12860 .dac_nids = alc262_dac_nids,
12861 .hp_nid = 0x03,
12862 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12863 .channel_mode = alc262_modes,
accbe498 12864 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12865 .unsol_event = alc_sku_unsol_event,
12866 .setup = alc262_hp_wildwest_setup,
12867 .init_hook = alc_inithook,
f12ab1e0 12868 },
66d2a9d6
KY
12869 [ALC262_HP_TC_T5735] = {
12870 .mixers = { alc262_hp_t5735_mixer },
12871 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12872 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12873 .dac_nids = alc262_dac_nids,
12874 .hp_nid = 0x03,
12875 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12876 .channel_mode = alc262_modes,
12877 .input_mux = &alc262_capture_source,
dc99be47 12878 .unsol_event = alc_sku_unsol_event,
4f5d1706 12879 .setup = alc262_hp_t5735_setup,
dc99be47 12880 .init_hook = alc_inithook,
8c427226
KY
12881 },
12882 [ALC262_HP_RP5700] = {
12883 .mixers = { alc262_hp_rp5700_mixer },
12884 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12885 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12886 .dac_nids = alc262_dac_nids,
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
12889 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12890 },
304dcaac
TI
12891 [ALC262_BENQ_ED8] = {
12892 .mixers = { alc262_base_mixer },
12893 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12894 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12895 .dac_nids = alc262_dac_nids,
12896 .hp_nid = 0x03,
12897 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12898 .channel_mode = alc262_modes,
12899 .input_mux = &alc262_capture_source,
f12ab1e0 12900 },
272a527c
KY
12901 [ALC262_SONY_ASSAMD] = {
12902 .mixers = { alc262_sony_mixer },
12903 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12904 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12905 .dac_nids = alc262_dac_nids,
12906 .hp_nid = 0x02,
12907 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12908 .channel_mode = alc262_modes,
12909 .input_mux = &alc262_capture_source,
e9427969 12910 .unsol_event = alc_sku_unsol_event,
4f5d1706 12911 .setup = alc262_hippo_setup,
e9427969 12912 .init_hook = alc_inithook,
83c34218
KY
12913 },
12914 [ALC262_BENQ_T31] = {
12915 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12916 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12917 alc_hp15_unsol_verbs },
83c34218
KY
12918 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12919 .dac_nids = alc262_dac_nids,
12920 .hp_nid = 0x03,
12921 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12922 .channel_mode = alc262_modes,
12923 .input_mux = &alc262_capture_source,
e9427969 12924 .unsol_event = alc_sku_unsol_event,
4f5d1706 12925 .setup = alc262_hippo_setup,
e9427969 12926 .init_hook = alc_inithook,
ea1fb29a 12927 },
f651b50b 12928 [ALC262_ULTRA] = {
f9e336f6
TI
12929 .mixers = { alc262_ultra_mixer },
12930 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12931 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12932 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12933 .dac_nids = alc262_dac_nids,
f651b50b
TD
12934 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12935 .channel_mode = alc262_modes,
12936 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12937 .adc_nids = alc262_adc_nids, /* ADC0 */
12938 .capsrc_nids = alc262_capsrc_nids,
12939 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12940 .unsol_event = alc262_ultra_unsol_event,
12941 .init_hook = alc262_ultra_automute,
12942 },
0e31daf7
J
12943 [ALC262_LENOVO_3000] = {
12944 .mixers = { alc262_lenovo_3000_mixer },
12945 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12946 alc262_lenovo_3000_unsol_verbs,
12947 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12948 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12949 .dac_nids = alc262_dac_nids,
12950 .hp_nid = 0x03,
12951 .dig_out_nid = ALC262_DIGOUT_NID,
12952 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12953 .channel_mode = alc262_modes,
12954 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12955 .unsol_event = alc_sku_unsol_event,
12956 .setup = alc262_lenovo_3000_setup,
12957 .init_hook = alc_inithook,
0e31daf7 12958 },
e8f9ae2a
PT
12959 [ALC262_NEC] = {
12960 .mixers = { alc262_nec_mixer },
12961 .init_verbs = { alc262_nec_verbs },
12962 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12963 .dac_nids = alc262_dac_nids,
12964 .hp_nid = 0x03,
12965 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12966 .channel_mode = alc262_modes,
12967 .input_mux = &alc262_capture_source,
12968 },
4e555fe5
KY
12969 [ALC262_TOSHIBA_S06] = {
12970 .mixers = { alc262_toshiba_s06_mixer },
12971 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12972 alc262_eapd_verbs },
12973 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12974 .capsrc_nids = alc262_dmic_capsrc_nids,
12975 .dac_nids = alc262_dac_nids,
12976 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12977 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12978 .dig_out_nid = ALC262_DIGOUT_NID,
12979 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12980 .channel_mode = alc262_modes,
4f5d1706
TI
12981 .unsol_event = alc_sku_unsol_event,
12982 .setup = alc262_toshiba_s06_setup,
12983 .init_hook = alc_inithook,
4e555fe5 12984 },
9f99a638
HM
12985 [ALC262_TOSHIBA_RX1] = {
12986 .mixers = { alc262_toshiba_rx1_mixer },
12987 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12988 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12989 .dac_nids = alc262_dac_nids,
12990 .hp_nid = 0x03,
12991 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12992 .channel_mode = alc262_modes,
12993 .input_mux = &alc262_capture_source,
e9427969 12994 .unsol_event = alc_sku_unsol_event,
4f5d1706 12995 .setup = alc262_hippo_setup,
e9427969 12996 .init_hook = alc_inithook,
9f99a638 12997 },
ba340e82
TV
12998 [ALC262_TYAN] = {
12999 .mixers = { alc262_tyan_mixer },
13000 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13001 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13002 .dac_nids = alc262_dac_nids,
13003 .hp_nid = 0x02,
13004 .dig_out_nid = ALC262_DIGOUT_NID,
13005 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13006 .channel_mode = alc262_modes,
13007 .input_mux = &alc262_capture_source,
d922b51d 13008 .unsol_event = alc_sku_unsol_event,
4f5d1706 13009 .setup = alc262_tyan_setup,
d922b51d 13010 .init_hook = alc_hp_automute,
ba340e82 13011 },
df694daa
KY
13012};
13013
13014static int patch_alc262(struct hda_codec *codec)
13015{
13016 struct alc_spec *spec;
13017 int board_config;
13018 int err;
13019
dc041e0b 13020 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
13021 if (spec == NULL)
13022 return -ENOMEM;
13023
13024 codec->spec = spec;
13025#if 0
f12ab1e0
TI
13026 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13027 * under-run
13028 */
df694daa
KY
13029 {
13030 int tmp;
13031 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13032 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13033 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13034 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13035 }
13036#endif
da00c244 13037 alc_auto_parse_customize_define(codec);
df694daa 13038
2c3bf9ab
TI
13039 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13040
f5fcc13c
TI
13041 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13042 alc262_models,
13043 alc262_cfg_tbl);
cd7509a4 13044
f5fcc13c 13045 if (board_config < 0) {
9a11f1aa
TI
13046 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13047 codec->chip_name);
df694daa
KY
13048 board_config = ALC262_AUTO;
13049 }
13050
b5bfbc67
TI
13051 if (board_config == ALC262_AUTO) {
13052 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13053 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13054 }
18675e42 13055
df694daa
KY
13056 if (board_config == ALC262_AUTO) {
13057 /* automatic parse from the BIOS config */
13058 err = alc262_parse_auto_config(codec);
13059 if (err < 0) {
13060 alc_free(codec);
13061 return err;
f12ab1e0 13062 } else if (!err) {
9c7f852e
TI
13063 printk(KERN_INFO
13064 "hda_codec: Cannot set up configuration "
13065 "from BIOS. Using base mode...\n");
df694daa
KY
13066 board_config = ALC262_BASIC;
13067 }
13068 }
13069
dc1eae25 13070 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13071 err = snd_hda_attach_beep_device(codec, 0x1);
13072 if (err < 0) {
13073 alc_free(codec);
13074 return err;
13075 }
680cd536
KK
13076 }
13077
df694daa 13078 if (board_config != ALC262_AUTO)
e9c364c0 13079 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13080
df694daa
KY
13081 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13082 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13083
df694daa
KY
13084 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13085 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13086
f12ab1e0 13087 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13088 int i;
13089 /* check whether the digital-mic has to be supported */
13090 for (i = 0; i < spec->input_mux->num_items; i++) {
13091 if (spec->input_mux->items[i].index >= 9)
13092 break;
13093 }
13094 if (i < spec->input_mux->num_items) {
13095 /* use only ADC0 */
13096 spec->adc_nids = alc262_dmic_adc_nids;
13097 spec->num_adc_nids = 1;
13098 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13099 } else {
8c927b4a
TI
13100 /* all analog inputs */
13101 /* check whether NID 0x07 is valid */
13102 unsigned int wcap = get_wcaps(codec, 0x07);
13103
13104 /* get type */
a22d543a 13105 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13106 if (wcap != AC_WID_AUD_IN) {
13107 spec->adc_nids = alc262_adc_nids_alt;
13108 spec->num_adc_nids =
13109 ARRAY_SIZE(alc262_adc_nids_alt);
13110 spec->capsrc_nids = alc262_capsrc_nids_alt;
13111 } else {
13112 spec->adc_nids = alc262_adc_nids;
13113 spec->num_adc_nids =
13114 ARRAY_SIZE(alc262_adc_nids);
13115 spec->capsrc_nids = alc262_capsrc_nids;
13116 }
df694daa
KY
13117 }
13118 }
e64f14f4 13119 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13120 set_capture_mixer(codec);
dc1eae25 13121 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13122 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13123
b5bfbc67 13124 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13125
2134ea4f
TI
13126 spec->vmaster_nid = 0x0c;
13127
df694daa
KY
13128 codec->patch_ops = alc_patch_ops;
13129 if (board_config == ALC262_AUTO)
ae6b813a 13130 spec->init_hook = alc262_auto_init;
1c716153 13131 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13132
13133 alc_init_jacks(codec);
cb53c626
TI
13134#ifdef CONFIG_SND_HDA_POWER_SAVE
13135 if (!spec->loopback.amplist)
13136 spec->loopback.amplist = alc262_loopbacks;
13137#endif
ea1fb29a 13138
df694daa
KY
13139 return 0;
13140}
13141
a361d84b
KY
13142/*
13143 * ALC268 channel source setting (2 channel)
13144 */
13145#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13146#define alc268_modes alc260_modes
ea1fb29a 13147
4c6d72d1 13148static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13149 /* front, hp */
13150 0x02, 0x03
13151};
13152
4c6d72d1 13153static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13154 /* ADC0-1 */
13155 0x08, 0x07
13156};
13157
4c6d72d1 13158static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13159 /* ADC0 */
13160 0x08
13161};
13162
4c6d72d1 13163static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13164
a9111321 13165static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13166 /* output mixer control */
13167 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13168 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13174 { }
13175};
13176
a9111321 13177static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13178 /* output mixer control */
13179 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13180 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13181 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13182 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13183 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13184 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13185 { }
13186};
13187
aef9d318 13188/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13189static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13190 .ops = &snd_hda_bind_sw,
13191 .values = {
13192 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13193 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13194 0
13195 },
13196};
13197
a9111321 13198static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13199 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13200 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13201 { }
13202};
13203
a9111321 13204static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13205 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13206 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13207 { }
13208};
13209
d273809e 13210/* Toshiba specific */
a9111321 13211static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13212 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13213 { } /* end */
13214};
13215
13216/* Acer specific */
889c4395 13217/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13218static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13219 .ops = &snd_hda_bind_vol,
13220 .values = {
13221 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13222 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13223 0
13224 },
13225};
13226
0f0f391c 13227static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13228{
13229 struct alc_spec *spec = codec->spec;
889c4395 13230
0f0f391c
TI
13231 spec->autocfg.hp_pins[0] = 0x14;
13232 spec->autocfg.speaker_pins[0] = 0x15;
13233 spec->automute = 1;
13234 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13235}
13236
0f0f391c
TI
13237#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13238#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13239
a9111321 13240static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13241 /* output mixer control */
13242 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13243 {
13244 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13245 .name = "Master Playback Switch",
0f0f391c
TI
13246 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13247 .info = snd_ctl_boolean_mono_info,
13248 .get = alc268_acer_master_sw_get,
8ef355da 13249 .put = alc268_acer_master_sw_put,
8ef355da
KY
13250 },
13251 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13252 { }
13253};
13254
a9111321 13255static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13256 /* output mixer control */
13257 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13258 {
13259 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13260 .name = "Master Playback Switch",
0f0f391c
TI
13261 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13262 .info = snd_ctl_boolean_mono_info,
13263 .get = alc268_acer_master_sw_get,
d273809e 13264 .put = alc268_acer_master_sw_put,
d273809e 13265 },
5f99f86a
DH
13266 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13267 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13269 { }
13270};
13271
a9111321 13272static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13273 /* output mixer control */
13274 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13275 {
13276 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13277 .name = "Master Playback Switch",
0f0f391c
TI
13278 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13279 .info = snd_ctl_boolean_mono_info,
13280 .get = alc268_acer_master_sw_get,
c238b4f4 13281 .put = alc268_acer_master_sw_put,
c238b4f4 13282 },
5f99f86a
DH
13283 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13284 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13285 { }
13286};
13287
a9111321 13288static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13289 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13290 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13291 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13292 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13293 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13294 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13295 { }
13296};
13297
a9111321 13298static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13299 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13300 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13301 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13302 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13303 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13304 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13305 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13306 { }
13307};
13308
13309/* unsolicited event for HP jack sensing */
4f5d1706 13310#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13311
4f5d1706
TI
13312static void alc268_acer_lc_setup(struct hda_codec *codec)
13313{
13314 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13315 spec->autocfg.hp_pins[0] = 0x15;
13316 spec->autocfg.speaker_pins[0] = 0x14;
13317 spec->automute_mixer_nid[0] = 0x0f;
13318 spec->automute = 1;
13319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
13320 spec->ext_mic.pin = 0x18;
13321 spec->ext_mic.mux_idx = 0;
13322 spec->int_mic.pin = 0x12;
13323 spec->int_mic.mux_idx = 6;
13324 spec->auto_mic = 1;
8ef355da
KY
13325}
13326
a9111321 13327static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13328 /* output mixer control */
13329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13333 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13334 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13335 { }
13336};
13337
a9111321 13338static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13343 { }
13344};
13345
13346/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13347static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13348{
a9fd4f3f 13349 struct alc_spec *spec = codec->spec;
3866f0b0 13350
a9fd4f3f
TI
13351 spec->autocfg.hp_pins[0] = 0x15;
13352 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13353 spec->ext_mic.pin = 0x18;
13354 spec->ext_mic.mux_idx = 0;
13355 spec->int_mic.pin = 0x19;
13356 spec->int_mic.mux_idx = 1;
13357 spec->auto_mic = 1;
d922b51d
TI
13358 spec->automute = 1;
13359 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13360}
13361
a9111321 13362static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13368 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13369 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13370 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13371 { }
13372};
13373
a9111321 13374static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13377 { }
13378};
13379
4f5d1706 13380static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13381{
a9fd4f3f 13382 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13383 spec->autocfg.hp_pins[0] = 0x15;
13384 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13385 spec->ext_mic.pin = 0x18;
13386 spec->ext_mic.mux_idx = 0;
13387 spec->int_mic.pin = 0x19;
13388 spec->int_mic.mux_idx = 1;
13389 spec->auto_mic = 1;
d922b51d
TI
13390 spec->automute = 1;
13391 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13392}
13393
a361d84b
KY
13394/*
13395 * generic initialization of ADC, input mixers and output mixers
13396 */
a9111321 13397static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13398 /* Unmute DAC0-1 and set vol = 0 */
13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13401
13402 /*
13403 * Set up output mixers (0x0c - 0x0e)
13404 */
13405 /* set vol=0 to output mixers */
13406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13407 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13408
13409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13411
13412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13419 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13420
13421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13424 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13426
13427 /* set PCBEEP vol = 0, mute connections */
13428 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13430 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13431
a9b3aa8a 13432 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13433
a9b3aa8a
JZ
13434 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13436 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13438
a361d84b
KY
13439 { }
13440};
13441
13442/*
13443 * generic initialization of ADC, input mixers and output mixers
13444 */
a9111321 13445static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13446 /* set output DAC */
4cfb91c6
TI
13447 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13449
13450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13454 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13455
a361d84b 13456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13458 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13462
aef9d318
TI
13463 /* set PCBEEP vol = 0, mute connections */
13464 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13466 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13467
13468 { }
13469};
13470
a9111321 13471static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13472 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13473 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13474 { } /* end */
13475};
13476
a9111321 13477static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13478 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13479 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13480 _DEFINE_CAPSRC(1),
a361d84b
KY
13481 { } /* end */
13482};
13483
a9111321 13484static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13485 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13486 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13488 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13489 _DEFINE_CAPSRC(2),
a361d84b
KY
13490 { } /* end */
13491};
13492
a9111321 13493static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13494 .num_items = 4,
13495 .items = {
13496 { "Mic", 0x0 },
13497 { "Front Mic", 0x1 },
13498 { "Line", 0x2 },
13499 { "CD", 0x3 },
13500 },
13501};
13502
a9111321 13503static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13504 .num_items = 3,
13505 .items = {
13506 { "Mic", 0x0 },
13507 { "Internal Mic", 0x1 },
13508 { "Line", 0x2 },
13509 },
13510};
13511
a9111321 13512static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13513 .num_items = 3,
13514 .items = {
13515 { "Mic", 0x0 },
13516 { "Internal Mic", 0x6 },
13517 { "Line", 0x2 },
13518 },
13519};
13520
86c53bd2 13521#ifdef CONFIG_SND_DEBUG
a9111321 13522static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13523 /* Volume widgets */
13524 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13525 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13526 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13527 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13528 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13529 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13530 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13531 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13532 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13533 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13534 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13535 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13536 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13537 /* The below appears problematic on some hardwares */
13538 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13539 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13540 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13541 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13542 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13543
13544 /* Modes for retasking pin widgets */
13545 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13546 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13547 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13548 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13549
13550 /* Controls for GPIO pins, assuming they are configured as outputs */
13551 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13552 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13553 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13554 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13555
13556 /* Switches to allow the digital SPDIF output pin to be enabled.
13557 * The ALC268 does not have an SPDIF input.
13558 */
13559 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13560
13561 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13562 * this output to turn on an external amplifier.
13563 */
13564 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13565 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13566
13567 { } /* end */
13568};
13569#endif
13570
a361d84b
KY
13571/* create input playback/capture controls for the given pin */
13572static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13573 const char *ctlname, int idx)
13574{
3f3b7c1a 13575 hda_nid_t dac;
a361d84b
KY
13576 int err;
13577
3f3b7c1a
TI
13578 switch (nid) {
13579 case 0x14:
13580 case 0x16:
13581 dac = 0x02;
13582 break;
13583 case 0x15:
b08b1637
TI
13584 case 0x1a: /* ALC259/269 only */
13585 case 0x1b: /* ALC259/269 only */
531d8791 13586 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13587 dac = 0x03;
13588 break;
13589 default:
c7a9434d
TI
13590 snd_printd(KERN_WARNING "hda_codec: "
13591 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13592 return 0;
13593 }
13594 if (spec->multiout.dac_nids[0] != dac &&
13595 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13596 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13597 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13598 HDA_OUTPUT));
13599 if (err < 0)
13600 return err;
dda14410 13601 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13602 }
13603
3f3b7c1a 13604 if (nid != 0x16)
0afe5f89 13605 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13606 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13607 else /* mono */
0afe5f89 13608 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13609 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13610 if (err < 0)
13611 return err;
13612 return 0;
13613}
13614
13615/* add playback controls from the parsed DAC table */
13616static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13617 const struct auto_pin_cfg *cfg)
13618{
13619 hda_nid_t nid;
13620 int err;
13621
a361d84b 13622 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13623
13624 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13625 if (nid) {
13626 const char *name;
13627 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13628 name = "Speaker";
13629 else
13630 name = "Front";
13631 err = alc268_new_analog_output(spec, nid, name, 0);
13632 if (err < 0)
13633 return err;
13634 }
a361d84b
KY
13635
13636 nid = cfg->speaker_pins[0];
13637 if (nid == 0x1d) {
0afe5f89 13638 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13639 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13640 if (err < 0)
13641 return err;
7bfb9c03 13642 } else if (nid) {
3f3b7c1a
TI
13643 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13644 if (err < 0)
13645 return err;
a361d84b
KY
13646 }
13647 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13648 if (nid) {
13649 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13650 if (err < 0)
13651 return err;
13652 }
a361d84b
KY
13653
13654 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13655 if (nid == 0x16) {
0afe5f89 13656 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13657 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13658 if (err < 0)
13659 return err;
13660 }
ea1fb29a 13661 return 0;
a361d84b
KY
13662}
13663
13664/* create playback/capture controls for input pins */
05f5f477 13665static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13666 const struct auto_pin_cfg *cfg)
13667{
05f5f477 13668 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13669}
13670
e9af4f36
TI
13671static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13672 hda_nid_t nid, int pin_type)
13673{
13674 int idx;
13675
13676 alc_set_pin_output(codec, nid, pin_type);
13677 if (nid == 0x14 || nid == 0x16)
13678 idx = 0;
13679 else
13680 idx = 1;
13681 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13682}
13683
13684static void alc268_auto_init_multi_out(struct hda_codec *codec)
13685{
13686 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13687 int i;
13688
13689 for (i = 0; i < spec->autocfg.line_outs; i++) {
13690 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13691 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13692 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13693 }
13694}
13695
13696static void alc268_auto_init_hp_out(struct hda_codec *codec)
13697{
13698 struct alc_spec *spec = codec->spec;
13699 hda_nid_t pin;
e1ca7b4e 13700 int i;
e9af4f36 13701
e1ca7b4e
TI
13702 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13703 pin = spec->autocfg.hp_pins[i];
e9af4f36 13704 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13705 }
13706 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13707 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13708 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13709 }
13710 if (spec->autocfg.mono_out_pin)
13711 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13712 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13713}
13714
a361d84b
KY
13715static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13716{
13717 struct alc_spec *spec = codec->spec;
13718 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13719 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13720 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13721 unsigned int dac_vol1, dac_vol2;
13722
e9af4f36 13723 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13724 snd_hda_codec_write(codec, speaker_nid, 0,
13725 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13726 /* mute mixer inputs from 0x1d */
a361d84b
KY
13727 snd_hda_codec_write(codec, 0x0f, 0,
13728 AC_VERB_SET_AMP_GAIN_MUTE,
13729 AMP_IN_UNMUTE(1));
13730 snd_hda_codec_write(codec, 0x10, 0,
13731 AC_VERB_SET_AMP_GAIN_MUTE,
13732 AMP_IN_UNMUTE(1));
13733 } else {
e9af4f36 13734 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13735 snd_hda_codec_write(codec, 0x0f, 0,
13736 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13737 snd_hda_codec_write(codec, 0x10, 0,
13738 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13739 }
13740
13741 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13742 if (line_nid == 0x14)
a361d84b
KY
13743 dac_vol2 = AMP_OUT_ZERO;
13744 else if (line_nid == 0x15)
13745 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13746 if (hp_nid == 0x14)
a361d84b
KY
13747 dac_vol2 = AMP_OUT_ZERO;
13748 else if (hp_nid == 0x15)
13749 dac_vol1 = AMP_OUT_ZERO;
13750 if (line_nid != 0x16 || hp_nid != 0x16 ||
13751 spec->autocfg.line_out_pins[1] != 0x16 ||
13752 spec->autocfg.line_out_pins[2] != 0x16)
13753 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13754
13755 snd_hda_codec_write(codec, 0x02, 0,
13756 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13757 snd_hda_codec_write(codec, 0x03, 0,
13758 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13759}
13760
def319f9 13761/* pcm configuration: identical with ALC880 */
a361d84b
KY
13762#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13763#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13764#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13765#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13766
13767/*
13768 * BIOS auto configuration
13769 */
13770static int alc268_parse_auto_config(struct hda_codec *codec)
13771{
13772 struct alc_spec *spec = codec->spec;
13773 int err;
4c6d72d1 13774 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13775
13776 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13777 alc268_ignore);
13778 if (err < 0)
13779 return err;
7e0e44d4
TI
13780 if (!spec->autocfg.line_outs) {
13781 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13782 spec->multiout.max_channels = 2;
13783 spec->no_analog = 1;
13784 goto dig_only;
13785 }
a361d84b 13786 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13787 }
a361d84b
KY
13788 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13789 if (err < 0)
13790 return err;
05f5f477 13791 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13792 if (err < 0)
13793 return err;
13794
13795 spec->multiout.max_channels = 2;
13796
7e0e44d4 13797 dig_only:
a361d84b 13798 /* digital only support output */
757899ac 13799 alc_auto_parse_digital(codec);
603c4019 13800 if (spec->kctls.list)
d88897ea 13801 add_mixer(spec, spec->kctls.list);
a361d84b 13802
892981ff 13803 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13804 add_mixer(spec, alc268_beep_mixer);
aef9d318 13805
d88897ea 13806 add_verb(spec, alc268_volume_init_verbs);
5908589f 13807 spec->num_mux_defs = 2;
61b9b9b1 13808 spec->input_mux = &spec->private_imux[0];
a361d84b 13809
776e184e
TI
13810 err = alc_auto_add_mic_boost(codec);
13811 if (err < 0)
13812 return err;
13813
6227cdce 13814 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13815
a361d84b
KY
13816 return 1;
13817}
13818
a361d84b 13819#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13820#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13821
13822/* init callback for auto-configuration model -- overriding the default init */
13823static void alc268_auto_init(struct hda_codec *codec)
13824{
f6c7e546 13825 struct alc_spec *spec = codec->spec;
a361d84b
KY
13826 alc268_auto_init_multi_out(codec);
13827 alc268_auto_init_hp_out(codec);
13828 alc268_auto_init_mono_speaker_out(codec);
13829 alc268_auto_init_analog_input(codec);
ae0ebbf7 13830 alc268_auto_init_input_src(codec);
757899ac 13831 alc_auto_init_digital(codec);
f6c7e546 13832 if (spec->unsol_event)
7fb0d78f 13833 alc_inithook(codec);
a361d84b
KY
13834}
13835
13836/*
13837 * configuration and preset
13838 */
ea734963 13839static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13840 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13841 [ALC268_3ST] = "3stack",
983f8ae4 13842 [ALC268_TOSHIBA] = "toshiba",
d273809e 13843 [ALC268_ACER] = "acer",
c238b4f4 13844 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13845 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13846 [ALC268_DELL] = "dell",
f12462c5 13847 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13848#ifdef CONFIG_SND_DEBUG
13849 [ALC268_TEST] = "test",
13850#endif
a361d84b
KY
13851 [ALC268_AUTO] = "auto",
13852};
13853
a9111321 13854static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13855 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13856 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13857 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13858 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13859 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13860 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13861 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13862 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13863 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13864 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13865 /* almost compatible with toshiba but with optional digital outs;
13866 * auto-probing seems working fine
13867 */
8871e5b9 13868 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13869 ALC268_AUTO),
a361d84b 13870 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13871 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13872 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13873 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13874 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13875 {}
13876};
13877
3abf2f36 13878/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13879static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13880 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13881 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13882 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13883 ALC268_TOSHIBA),
13884 {}
13885};
13886
a9111321 13887static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13888 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13889 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13890 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc267_quanta_il1_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
13897 .hp_nid = 0x03,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
4f5d1706
TI
13900 .unsol_event = alc_sku_unsol_event,
13901 .setup = alc267_quanta_il1_setup,
13902 .init_hook = alc_inithook,
eb5a6621 13903 },
a361d84b 13904 [ALC268_3ST] = {
aef9d318
TI
13905 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
a361d84b
KY
13907 .init_verbs = { alc268_base_init_verbs },
13908 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13909 .dac_nids = alc268_dac_nids,
13910 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13911 .adc_nids = alc268_adc_nids_alt,
e1406348 13912 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13913 .hp_nid = 0x03,
13914 .dig_out_nid = ALC268_DIGOUT_NID,
13915 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13916 .channel_mode = alc268_modes,
13917 .input_mux = &alc268_capture_source,
13918 },
d1a991a6 13919 [ALC268_TOSHIBA] = {
42171c17 13920 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13921 alc268_beep_mixer },
d273809e
TI
13922 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13923 alc268_toshiba_verbs },
d1a991a6
KY
13924 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13925 .dac_nids = alc268_dac_nids,
13926 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13927 .adc_nids = alc268_adc_nids_alt,
e1406348 13928 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13929 .hp_nid = 0x03,
13930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13931 .channel_mode = alc268_modes,
13932 .input_mux = &alc268_capture_source,
e9427969 13933 .unsol_event = alc_sku_unsol_event,
4f5d1706 13934 .setup = alc268_toshiba_setup,
e9427969 13935 .init_hook = alc_inithook,
d273809e
TI
13936 },
13937 [ALC268_ACER] = {
432fd133 13938 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13939 alc268_beep_mixer },
d273809e
TI
13940 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13941 alc268_acer_verbs },
13942 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13943 .dac_nids = alc268_dac_nids,
13944 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13945 .adc_nids = alc268_adc_nids_alt,
e1406348 13946 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13947 .hp_nid = 0x02,
13948 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13949 .channel_mode = alc268_modes,
0ccb541c 13950 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13951 .unsol_event = alc_sku_unsol_event,
13952 .setup = alc268_acer_setup,
13953 .init_hook = alc_inithook,
d1a991a6 13954 },
c238b4f4
TI
13955 [ALC268_ACER_DMIC] = {
13956 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13957 alc268_beep_mixer },
13958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13959 alc268_acer_verbs },
13960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13961 .dac_nids = alc268_dac_nids,
13962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13963 .adc_nids = alc268_adc_nids_alt,
13964 .capsrc_nids = alc268_capsrc_nids,
13965 .hp_nid = 0x02,
13966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13967 .channel_mode = alc268_modes,
13968 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13969 .unsol_event = alc_sku_unsol_event,
13970 .setup = alc268_acer_setup,
13971 .init_hook = alc_inithook,
c238b4f4 13972 },
8ef355da
KY
13973 [ALC268_ACER_ASPIRE_ONE] = {
13974 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13975 alc268_beep_mixer,
fdbc6626 13976 alc268_capture_nosrc_mixer },
8ef355da
KY
13977 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13978 alc268_acer_aspire_one_verbs },
13979 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13980 .dac_nids = alc268_dac_nids,
13981 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13982 .adc_nids = alc268_adc_nids_alt,
13983 .capsrc_nids = alc268_capsrc_nids,
13984 .hp_nid = 0x03,
13985 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13986 .channel_mode = alc268_modes,
3b8510ce 13987 .unsol_event = alc_sku_unsol_event,
4f5d1706 13988 .setup = alc268_acer_lc_setup,
3b8510ce 13989 .init_hook = alc_inithook,
8ef355da 13990 },
3866f0b0 13991 [ALC268_DELL] = {
fdbc6626
TI
13992 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13993 alc268_capture_nosrc_mixer },
3866f0b0
TI
13994 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13995 alc268_dell_verbs },
13996 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13997 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13998 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13999 .adc_nids = alc268_adc_nids_alt,
14000 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
14001 .hp_nid = 0x02,
14002 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14003 .channel_mode = alc268_modes,
a9fd4f3f 14004 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
14005 .setup = alc268_dell_setup,
14006 .init_hook = alc_inithook,
3866f0b0 14007 },
f12462c5 14008 [ALC268_ZEPTO] = {
aef9d318
TI
14009 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14010 alc268_beep_mixer },
f12462c5
MT
14011 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14012 alc268_toshiba_verbs },
14013 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14014 .dac_nids = alc268_dac_nids,
14015 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14016 .adc_nids = alc268_adc_nids_alt,
e1406348 14017 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
14018 .hp_nid = 0x03,
14019 .dig_out_nid = ALC268_DIGOUT_NID,
14020 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14021 .channel_mode = alc268_modes,
14022 .input_mux = &alc268_capture_source,
e9427969 14023 .unsol_event = alc_sku_unsol_event,
4f5d1706 14024 .setup = alc268_toshiba_setup,
e9427969 14025 .init_hook = alc_inithook,
f12462c5 14026 },
86c53bd2
JW
14027#ifdef CONFIG_SND_DEBUG
14028 [ALC268_TEST] = {
14029 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14030 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14031 alc268_volume_init_verbs },
14032 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14033 .dac_nids = alc268_dac_nids,
14034 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14035 .adc_nids = alc268_adc_nids_alt,
e1406348 14036 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
14037 .hp_nid = 0x03,
14038 .dig_out_nid = ALC268_DIGOUT_NID,
14039 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14040 .channel_mode = alc268_modes,
14041 .input_mux = &alc268_capture_source,
14042 },
14043#endif
a361d84b
KY
14044};
14045
14046static int patch_alc268(struct hda_codec *codec)
14047{
14048 struct alc_spec *spec;
14049 int board_config;
22971e3a 14050 int i, has_beep, err;
a361d84b 14051
ef86f581 14052 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14053 if (spec == NULL)
14054 return -ENOMEM;
14055
14056 codec->spec = spec;
14057
14058 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14059 alc268_models,
14060 alc268_cfg_tbl);
14061
3abf2f36
TI
14062 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14063 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14064 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14065
a361d84b 14066 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14067 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14068 codec->chip_name);
a361d84b
KY
14069 board_config = ALC268_AUTO;
14070 }
14071
14072 if (board_config == ALC268_AUTO) {
14073 /* automatic parse from the BIOS config */
14074 err = alc268_parse_auto_config(codec);
14075 if (err < 0) {
14076 alc_free(codec);
14077 return err;
14078 } else if (!err) {
14079 printk(KERN_INFO
14080 "hda_codec: Cannot set up configuration "
14081 "from BIOS. Using base mode...\n");
14082 board_config = ALC268_3ST;
14083 }
14084 }
14085
14086 if (board_config != ALC268_AUTO)
e9c364c0 14087 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14088
a361d84b
KY
14089 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14090 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14091 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14092
a361d84b
KY
14093 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14094
22971e3a
TI
14095 has_beep = 0;
14096 for (i = 0; i < spec->num_mixers; i++) {
14097 if (spec->mixers[i] == alc268_beep_mixer) {
14098 has_beep = 1;
14099 break;
14100 }
14101 }
14102
14103 if (has_beep) {
14104 err = snd_hda_attach_beep_device(codec, 0x1);
14105 if (err < 0) {
14106 alc_free(codec);
14107 return err;
14108 }
14109 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14110 /* override the amp caps for beep generator */
14111 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14112 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14113 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14114 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14115 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14116 }
aef9d318 14117
7e0e44d4 14118 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14119 /* check whether NID 0x07 is valid */
14120 unsigned int wcap = get_wcaps(codec, 0x07);
14121
defb5ab2 14122 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14123 /* get type */
a22d543a 14124 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14125 if (spec->auto_mic ||
14126 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14127 spec->adc_nids = alc268_adc_nids_alt;
14128 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14129 if (spec->auto_mic)
14130 fixup_automic_adc(codec);
fdbc6626
TI
14131 if (spec->auto_mic || spec->input_mux->num_items == 1)
14132 add_mixer(spec, alc268_capture_nosrc_mixer);
14133 else
14134 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14135 } else {
14136 spec->adc_nids = alc268_adc_nids;
14137 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14138 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14139 }
14140 }
2134ea4f
TI
14141
14142 spec->vmaster_nid = 0x02;
14143
a361d84b
KY
14144 codec->patch_ops = alc_patch_ops;
14145 if (board_config == ALC268_AUTO)
14146 spec->init_hook = alc268_auto_init;
1c716153 14147 spec->shutup = alc_eapd_shutup;
ea1fb29a 14148
bf1b0225
KY
14149 alc_init_jacks(codec);
14150
a361d84b
KY
14151 return 0;
14152}
14153
f6a92248
KY
14154/*
14155 * ALC269 channel source setting (2 channel)
14156 */
14157#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14158
14159#define alc269_dac_nids alc260_dac_nids
14160
4c6d72d1 14161static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14162 /* ADC1 */
f53281e6
KY
14163 0x08,
14164};
14165
4c6d72d1 14166static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14167 0x23,
14168};
14169
4c6d72d1 14170static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14171 /* ADC1 */
14172 0x09,
14173};
14174
4c6d72d1 14175static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14176 0x22,
14177};
14178
4c6d72d1 14179static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14180 0x08, 0x09, 0x07, 0x11,
6694635d 14181};
e01bf509 14182
f6a92248
KY
14183#define alc269_modes alc260_modes
14184#define alc269_capture_source alc880_lg_lw_capture_source
14185
a9111321 14186static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14188 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14199 { } /* end */
14200};
14201
a9111321 14202static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14203 /* output mixer control */
14204 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14205 {
14206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14207 .name = "Master Playback Switch",
5e26dfd0 14208 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14209 .info = snd_hda_mixer_amp_switch_info,
14210 .get = snd_hda_mixer_amp_switch_get,
14211 .put = alc268_acer_master_sw_put,
14212 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14213 },
14214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14217 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14218 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14219 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14220 { }
14221};
14222
a9111321 14223static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14224 /* output mixer control */
14225 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14226 {
14227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14228 .name = "Master Playback Switch",
5e26dfd0 14229 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14230 .info = snd_hda_mixer_amp_switch_info,
14231 .get = snd_hda_mixer_amp_switch_get,
14232 .put = alc268_acer_master_sw_put,
14233 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14234 },
14235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14238 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14239 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14240 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14241 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14242 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14243 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14244 { }
14245};
14246
a9111321 14247static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14249 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14252 { } /* end */
14253};
14254
a9111321 14255static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14256 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14260 { } /* end */
14261};
14262
a9111321 14263static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14264 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14265 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14266 { } /* end */
14267};
14268
f53281e6 14269/* capture mixer elements */
a9111321 14270static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14271 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14272 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14275 { } /* end */
14276};
14277
a9111321 14278static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14279 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14280 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14282 { } /* end */
14283};
14284
a9111321 14285static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14286 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14287 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14290 { } /* end */
14291};
14292
a9111321 14293static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14297 { } /* end */
14298};
14299
26f5df26 14300/* FSC amilo */
84898e87 14301#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14302
a9111321 14303static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14304 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14309 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14310 { }
14311};
f6a92248 14312
a9111321 14313static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14315 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14316 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14321 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14322 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14323 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14324 { }
14325};
14326
60db6b53
KY
14327/* toggle speaker-output according to the hp-jack state */
14328static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14329{
3b8510ce 14330 alc_hp_automute(codec);
f6a92248 14331
60db6b53
KY
14332 snd_hda_codec_write(codec, 0x20, 0,
14333 AC_VERB_SET_COEF_INDEX, 0x0c);
14334 snd_hda_codec_write(codec, 0x20, 0,
14335 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14336
60db6b53
KY
14337 snd_hda_codec_write(codec, 0x20, 0,
14338 AC_VERB_SET_COEF_INDEX, 0x0c);
14339 snd_hda_codec_write(codec, 0x20, 0,
14340 AC_VERB_SET_PROC_COEF, 0x480);
14341}
f6a92248 14342
3b8510ce
TI
14343#define alc269_lifebook_speaker_automute \
14344 alc269_quanta_fl1_speaker_automute
64154835 14345
64154835
TV
14346static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14347{
14348 unsigned int present_laptop;
14349 unsigned int present_dock;
14350
864f92be
WF
14351 present_laptop = snd_hda_jack_detect(codec, 0x18);
14352 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14353
14354 /* Laptop mic port overrides dock mic port, design decision */
14355 if (present_dock)
14356 snd_hda_codec_write(codec, 0x23, 0,
14357 AC_VERB_SET_CONNECT_SEL, 0x3);
14358 if (present_laptop)
14359 snd_hda_codec_write(codec, 0x23, 0,
14360 AC_VERB_SET_CONNECT_SEL, 0x0);
14361 if (!present_dock && !present_laptop)
14362 snd_hda_codec_write(codec, 0x23, 0,
14363 AC_VERB_SET_CONNECT_SEL, 0x1);
14364}
14365
60db6b53
KY
14366static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14367 unsigned int res)
14368{
4f5d1706
TI
14369 switch (res >> 26) {
14370 case ALC880_HP_EVENT:
60db6b53 14371 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14372 break;
14373 case ALC880_MIC_EVENT:
14374 alc_mic_automute(codec);
14375 break;
14376 }
60db6b53 14377}
f6a92248 14378
64154835
TV
14379static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14380 unsigned int res)
14381{
14382 if ((res >> 26) == ALC880_HP_EVENT)
14383 alc269_lifebook_speaker_automute(codec);
14384 if ((res >> 26) == ALC880_MIC_EVENT)
14385 alc269_lifebook_mic_autoswitch(codec);
14386}
14387
4f5d1706
TI
14388static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14389{
14390 struct alc_spec *spec = codec->spec;
20645d70
TI
14391 spec->autocfg.hp_pins[0] = 0x15;
14392 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14393 spec->automute_mixer_nid[0] = 0x0c;
14394 spec->automute = 1;
14395 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14396 spec->ext_mic.pin = 0x18;
14397 spec->ext_mic.mux_idx = 0;
14398 spec->int_mic.pin = 0x19;
14399 spec->int_mic.mux_idx = 1;
14400 spec->auto_mic = 1;
14401}
14402
60db6b53
KY
14403static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14404{
14405 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14406 alc_mic_automute(codec);
60db6b53 14407}
f6a92248 14408
3b8510ce
TI
14409static void alc269_lifebook_setup(struct hda_codec *codec)
14410{
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.hp_pins[1] = 0x1a;
14414 spec->autocfg.speaker_pins[0] = 0x14;
14415 spec->automute_mixer_nid[0] = 0x0c;
14416 spec->automute = 1;
14417 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14418}
14419
64154835
TV
14420static void alc269_lifebook_init_hook(struct hda_codec *codec)
14421{
14422 alc269_lifebook_speaker_automute(codec);
14423 alc269_lifebook_mic_autoswitch(codec);
14424}
14425
a9111321 14426static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14428 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14433 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14434 {}
14435};
14436
a9111321 14437static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14439 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14442 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14444 {}
14445};
14446
a9111321 14447static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14449 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14450 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14453 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14455 {}
14456};
14457
a9111321 14458static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14460 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14463 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14466 {}
14467};
14468
a9111321 14469static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14470 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14471 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14475 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14476 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14478 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14479 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14480 { }
14481};
14482
226b1ec8 14483static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14484{
4f5d1706 14485 struct alc_spec *spec = codec->spec;
20645d70
TI
14486 spec->autocfg.hp_pins[0] = 0x15;
14487 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14491 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14493 spec->int_mic.pin = 0x19;
14494 spec->int_mic.mux_idx = 1;
4f5d1706 14495 spec->auto_mic = 1;
f53281e6
KY
14496}
14497
226b1ec8 14498static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14499{
14500 struct alc_spec *spec = codec->spec;
20645d70
TI
14501 spec->autocfg.hp_pins[0] = 0x15;
14502 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14503 spec->automute_mixer_nid[0] = 0x0c;
14504 spec->automute = 1;
14505 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14506 spec->ext_mic.pin = 0x18;
14507 spec->ext_mic.mux_idx = 0;
14508 spec->int_mic.pin = 0x12;
226b1ec8 14509 spec->int_mic.mux_idx = 5;
84898e87
KY
14510 spec->auto_mic = 1;
14511}
14512
226b1ec8 14513static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14514{
4f5d1706 14515 struct alc_spec *spec = codec->spec;
226b1ec8 14516 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14517 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14518 spec->automute_mixer_nid[0] = 0x0c;
14519 spec->automute = 1;
14520 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14521 spec->ext_mic.pin = 0x18;
14522 spec->ext_mic.mux_idx = 0;
14523 spec->int_mic.pin = 0x19;
14524 spec->int_mic.mux_idx = 1;
14525 spec->auto_mic = 1;
f53281e6
KY
14526}
14527
226b1ec8
KY
14528static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14529{
14530 struct alc_spec *spec = codec->spec;
14531 spec->autocfg.hp_pins[0] = 0x21;
14532 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14533 spec->automute_mixer_nid[0] = 0x0c;
14534 spec->automute = 1;
14535 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14536 spec->ext_mic.pin = 0x18;
14537 spec->ext_mic.mux_idx = 0;
14538 spec->int_mic.pin = 0x12;
14539 spec->int_mic.mux_idx = 6;
14540 spec->auto_mic = 1;
14541}
14542
60db6b53
KY
14543/*
14544 * generic initialization of ADC, input mixers and output mixers
14545 */
a9111321 14546static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14547 /*
14548 * Unmute ADC0 and set the default input to mic-in
14549 */
84898e87 14550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14551
14552 /*
84898e87 14553 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14554 */
14555 /* set vol=0 to output mixers */
14556 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14557 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558
14559 /* set up input amps for analog loopback */
14560 /* Amp Indices: DAC = 0, mixer = 1 */
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567
14568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14572 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575
14576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14578
84898e87
KY
14579 /* FIXME: use Mux-type input source selection */
14580 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14581 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14582 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14583
84898e87
KY
14584 /* set EAPD */
14585 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14586 { }
14587};
14588
a9111321 14589static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14590 /*
14591 * Unmute ADC0 and set the default input to mic-in
14592 */
14593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14594
14595 /*
14596 * Set up output mixers (0x02 - 0x03)
14597 */
14598 /* set vol=0 to output mixers */
14599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14600 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601
14602 /* set up input amps for analog loopback */
14603 /* Amp Indices: DAC = 0, mixer = 1 */
14604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610
14611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14612 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14613 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618
14619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14620 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621
14622 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14623 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14624 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14625 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14626
14627 /* set EAPD */
14628 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14629 { }
14630};
14631
9d0b71b1
TI
14632#define alc269_auto_create_multi_out_ctls \
14633 alc268_auto_create_multi_out_ctls
05f5f477
TI
14634#define alc269_auto_create_input_ctls \
14635 alc268_auto_create_input_ctls
f6a92248
KY
14636
14637#ifdef CONFIG_SND_HDA_POWER_SAVE
14638#define alc269_loopbacks alc880_loopbacks
14639#endif
14640
def319f9 14641/* pcm configuration: identical with ALC880 */
f6a92248
KY
14642#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14643#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14644#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14645#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14646
a9111321 14647static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14648 .substreams = 1,
14649 .channels_min = 2,
14650 .channels_max = 8,
14651 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14652 /* NID is set in alc_build_pcms */
14653 .ops = {
14654 .open = alc880_playback_pcm_open,
14655 .prepare = alc880_playback_pcm_prepare,
14656 .cleanup = alc880_playback_pcm_cleanup
14657 },
14658};
14659
a9111321 14660static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14661 .substreams = 1,
14662 .channels_min = 2,
14663 .channels_max = 2,
14664 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14665 /* NID is set in alc_build_pcms */
14666};
14667
ad35879a
TI
14668#ifdef CONFIG_SND_HDA_POWER_SAVE
14669static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14670{
14671 switch (codec->subsystem_id) {
14672 case 0x103c1586:
14673 return 1;
14674 }
14675 return 0;
14676}
14677
14678static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14679{
14680 /* update mute-LED according to the speaker mute state */
14681 if (nid == 0x01 || nid == 0x14) {
14682 int pinval;
14683 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14684 HDA_AMP_MUTE)
14685 pinval = 0x24;
14686 else
14687 pinval = 0x20;
14688 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14689 snd_hda_codec_update_cache(codec, 0x19, 0,
14690 AC_VERB_SET_PIN_WIDGET_CONTROL,
14691 pinval);
ad35879a
TI
14692 }
14693 return alc_check_power_status(codec, nid);
14694}
14695#endif /* CONFIG_SND_HDA_POWER_SAVE */
14696
840b64c0
TI
14697static int alc275_setup_dual_adc(struct hda_codec *codec)
14698{
14699 struct alc_spec *spec = codec->spec;
14700
14701 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14702 return 0;
14703 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14704 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14705 if (spec->ext_mic.pin <= 0x12) {
14706 spec->private_adc_nids[0] = 0x08;
14707 spec->private_adc_nids[1] = 0x11;
14708 spec->private_capsrc_nids[0] = 0x23;
14709 spec->private_capsrc_nids[1] = 0x22;
14710 } else {
14711 spec->private_adc_nids[0] = 0x11;
14712 spec->private_adc_nids[1] = 0x08;
14713 spec->private_capsrc_nids[0] = 0x22;
14714 spec->private_capsrc_nids[1] = 0x23;
14715 }
14716 spec->adc_nids = spec->private_adc_nids;
14717 spec->capsrc_nids = spec->private_capsrc_nids;
14718 spec->num_adc_nids = 2;
14719 spec->dual_adc_switch = 1;
14720 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14721 spec->adc_nids[0], spec->adc_nids[1]);
14722 return 1;
14723 }
14724 return 0;
14725}
14726
d433a678
TI
14727/* different alc269-variants */
14728enum {
14729 ALC269_TYPE_NORMAL,
48c88e82 14730 ALC269_TYPE_ALC258,
d433a678 14731 ALC269_TYPE_ALC259,
48c88e82
KY
14732 ALC269_TYPE_ALC269VB,
14733 ALC269_TYPE_ALC270,
d433a678
TI
14734 ALC269_TYPE_ALC271X,
14735};
14736
f6a92248
KY
14737/*
14738 * BIOS auto configuration
14739 */
14740static int alc269_parse_auto_config(struct hda_codec *codec)
14741{
14742 struct alc_spec *spec = codec->spec;
cfb9fb55 14743 int err;
4c6d72d1 14744 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14745
14746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14747 alc269_ignore);
14748 if (err < 0)
14749 return err;
14750
14751 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14752 if (err < 0)
14753 return err;
f3550d1b
TI
14754 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14755 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14756 else
14757 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14758 0x22, 0);
f6a92248
KY
14759 if (err < 0)
14760 return err;
14761
14762 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14763
757899ac 14764 alc_auto_parse_digital(codec);
f6a92248 14765
603c4019 14766 if (spec->kctls.list)
d88897ea 14767 add_mixer(spec, spec->kctls.list);
f6a92248 14768
d433a678 14769 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14770 add_verb(spec, alc269vb_init_verbs);
6227cdce 14771 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14772 } else {
14773 add_verb(spec, alc269_init_verbs);
6227cdce 14774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14775 }
14776
f6a92248 14777 spec->num_mux_defs = 1;
61b9b9b1 14778 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14779
14780 if (!alc275_setup_dual_adc(codec))
14781 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14782 sizeof(alc269_adc_candidates));
6694635d 14783
f6a92248
KY
14784 err = alc_auto_add_mic_boost(codec);
14785 if (err < 0)
14786 return err;
14787
7e0e44d4 14788 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14789 set_capture_mixer(codec);
f53281e6 14790
f6a92248
KY
14791 return 1;
14792}
14793
e9af4f36
TI
14794#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14795#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14796#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14797#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14798
14799
14800/* init callback for auto-configuration model -- overriding the default init */
14801static void alc269_auto_init(struct hda_codec *codec)
14802{
f6c7e546 14803 struct alc_spec *spec = codec->spec;
f6a92248
KY
14804 alc269_auto_init_multi_out(codec);
14805 alc269_auto_init_hp_out(codec);
14806 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14807 if (!spec->dual_adc_switch)
14808 alc269_auto_init_input_src(codec);
757899ac 14809 alc_auto_init_digital(codec);
f6c7e546 14810 if (spec->unsol_event)
7fb0d78f 14811 alc_inithook(codec);
f6a92248
KY
14812}
14813
0ec33d1f
TI
14814static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14815{
14816 int val = alc_read_coef_idx(codec, 0x04);
14817 if (power_up)
14818 val |= 1 << 11;
14819 else
14820 val &= ~(1 << 11);
14821 alc_write_coef_idx(codec, 0x04, val);
14822}
14823
5402e4cb 14824static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14825{
0ec33d1f
TI
14826 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14827 alc269_toggle_power_output(codec, 0);
977ddd6b 14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14829 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14830 msleep(150);
14831 }
977ddd6b 14832}
0ec33d1f 14833
5402e4cb 14834#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14835static int alc269_resume(struct hda_codec *codec)
14836{
977ddd6b 14837 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14838 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14839 msleep(150);
14840 }
14841
14842 codec->patch_ops.init(codec);
14843
14844 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14845 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14846 msleep(200);
14847 }
14848
0ec33d1f
TI
14849 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14850 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14851
14852 snd_hda_codec_resume_amp(codec);
14853 snd_hda_codec_resume_cache(codec);
9e5341b9 14854 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14855 return 0;
14856}
0ec33d1f 14857#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14858
1a99d4a4 14859static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14860 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14861{
14862 int coef;
14863
58701120 14864 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14865 return;
1a99d4a4
KY
14866 coef = alc_read_coef_idx(codec, 0x1e);
14867 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14868}
14869
6981d184
TI
14870static void alc271_fixup_dmic(struct hda_codec *codec,
14871 const struct alc_fixup *fix, int action)
14872{
a9111321 14873 static const struct hda_verb verbs[] = {
6981d184
TI
14874 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14875 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14876 {}
14877 };
14878 unsigned int cfg;
14879
14880 if (strcmp(codec->chip_name, "ALC271X"))
14881 return;
14882 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14883 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14884 snd_hda_sequence_write(codec, verbs);
14885}
14886
ff818c24
TI
14887enum {
14888 ALC269_FIXUP_SONY_VAIO,
74dc8909 14889 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14890 ALC269_FIXUP_DELL_M101Z,
022c92be 14891 ALC269_FIXUP_SKU_IGNORE,
ac612407 14892 ALC269_FIXUP_ASUS_G73JW,
357f915e 14893 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14894 ALC275_FIXUP_SONY_HWEQ,
6981d184 14895 ALC271_FIXUP_DMIC,
ff818c24
TI
14896};
14897
ff818c24
TI
14898static const struct alc_fixup alc269_fixups[] = {
14899 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14900 .type = ALC_FIXUP_VERBS,
14901 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14903 {}
14904 }
ff818c24 14905 },
74dc8909 14906 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14907 .type = ALC_FIXUP_VERBS,
14908 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14909 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14911 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14912 { }
b5bfbc67
TI
14913 },
14914 .chained = true,
14915 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14916 },
145a902b 14917 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14918 .type = ALC_FIXUP_VERBS,
14919 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14920 /* Enables internal speaker */
14921 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14922 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14923 {}
14924 }
14925 },
022c92be 14926 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14927 .type = ALC_FIXUP_SKU,
14928 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14929 },
ac612407 14930 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14931 .type = ALC_FIXUP_PINS,
14932 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14933 { 0x17, 0x99130111 }, /* subwoofer */
14934 { }
14935 }
14936 },
357f915e 14937 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14938 .type = ALC_FIXUP_VERBS,
14939 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14940 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14941 {}
14942 }
14943 },
1a99d4a4 14944 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14945 .type = ALC_FIXUP_FUNC,
14946 .v.func = alc269_fixup_hweq,
14947 .chained = true,
14948 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14949 },
14950 [ALC271_FIXUP_DMIC] = {
14951 .type = ALC_FIXUP_FUNC,
14952 .v.func = alc271_fixup_dmic,
14953 },
ff818c24
TI
14954};
14955
a9111321 14956static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14957 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14958 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14959 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14960 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14961 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14962 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14963 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14964 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14965 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14968 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14969 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14970 {}
14971};
14972
14973
f6a92248
KY
14974/*
14975 * configuration and preset
14976 */
ea734963 14977static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14978 [ALC269_BASIC] = "basic",
2922c9af 14979 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14980 [ALC269_AMIC] = "laptop-amic",
14981 [ALC269_DMIC] = "laptop-dmic",
64154835 14982 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14983 [ALC269_LIFEBOOK] = "lifebook",
14984 [ALC269_AUTO] = "auto",
f6a92248
KY
14985};
14986
a9111321 14987static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14988 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14989 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14990 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14991 ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 15001 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
15002 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 15028 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 15029 ALC269_DMIC),
60db6b53 15030 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
15031 ALC269_DMIC),
15032 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15033 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 15034 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 15035 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
15036 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15037 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15038 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15041 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
15042 {}
15043};
15044
a9111321 15045static const struct alc_config_preset alc269_presets[] = {
f6a92248 15046 [ALC269_BASIC] = {
f9e336f6 15047 .mixers = { alc269_base_mixer },
f6a92248
KY
15048 .init_verbs = { alc269_init_verbs },
15049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15050 .dac_nids = alc269_dac_nids,
15051 .hp_nid = 0x03,
15052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15053 .channel_mode = alc269_modes,
15054 .input_mux = &alc269_capture_source,
15055 },
60db6b53
KY
15056 [ALC269_QUANTA_FL1] = {
15057 .mixers = { alc269_quanta_fl1_mixer },
15058 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15060 .dac_nids = alc269_dac_nids,
15061 .hp_nid = 0x03,
15062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15063 .channel_mode = alc269_modes,
15064 .input_mux = &alc269_capture_source,
15065 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15066 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15067 .init_hook = alc269_quanta_fl1_init_hook,
15068 },
84898e87
KY
15069 [ALC269_AMIC] = {
15070 .mixers = { alc269_laptop_mixer },
15071 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15072 .init_verbs = { alc269_init_verbs,
84898e87 15073 alc269_laptop_amic_init_verbs },
f53281e6
KY
15074 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15075 .dac_nids = alc269_dac_nids,
15076 .hp_nid = 0x03,
15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15078 .channel_mode = alc269_modes,
3b8510ce 15079 .unsol_event = alc_sku_unsol_event,
84898e87 15080 .setup = alc269_laptop_amic_setup,
3b8510ce 15081 .init_hook = alc_inithook,
f53281e6 15082 },
84898e87
KY
15083 [ALC269_DMIC] = {
15084 .mixers = { alc269_laptop_mixer },
15085 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15086 .init_verbs = { alc269_init_verbs,
84898e87
KY
15087 alc269_laptop_dmic_init_verbs },
15088 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089 .dac_nids = alc269_dac_nids,
15090 .hp_nid = 0x03,
15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092 .channel_mode = alc269_modes,
3b8510ce 15093 .unsol_event = alc_sku_unsol_event,
84898e87 15094 .setup = alc269_laptop_dmic_setup,
3b8510ce 15095 .init_hook = alc_inithook,
84898e87
KY
15096 },
15097 [ALC269VB_AMIC] = {
15098 .mixers = { alc269vb_laptop_mixer },
15099 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15100 .init_verbs = { alc269vb_init_verbs,
15101 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15102 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103 .dac_nids = alc269_dac_nids,
15104 .hp_nid = 0x03,
15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106 .channel_mode = alc269_modes,
3b8510ce 15107 .unsol_event = alc_sku_unsol_event,
226b1ec8 15108 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15109 .init_hook = alc_inithook,
84898e87
KY
15110 },
15111 [ALC269VB_DMIC] = {
15112 .mixers = { alc269vb_laptop_mixer },
15113 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15114 .init_verbs = { alc269vb_init_verbs,
15115 alc269vb_laptop_dmic_init_verbs },
15116 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117 .dac_nids = alc269_dac_nids,
15118 .hp_nid = 0x03,
15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120 .channel_mode = alc269_modes,
3b8510ce 15121 .unsol_event = alc_sku_unsol_event,
84898e87 15122 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15123 .init_hook = alc_inithook,
f53281e6 15124 },
26f5df26 15125 [ALC269_FUJITSU] = {
45bdd1c1 15126 .mixers = { alc269_fujitsu_mixer },
84898e87 15127 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15128 .init_verbs = { alc269_init_verbs,
84898e87 15129 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15130 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131 .dac_nids = alc269_dac_nids,
15132 .hp_nid = 0x03,
15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134 .channel_mode = alc269_modes,
3b8510ce 15135 .unsol_event = alc_sku_unsol_event,
84898e87 15136 .setup = alc269_laptop_dmic_setup,
3b8510ce 15137 .init_hook = alc_inithook,
26f5df26 15138 },
64154835
TV
15139 [ALC269_LIFEBOOK] = {
15140 .mixers = { alc269_lifebook_mixer },
15141 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15142 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15143 .dac_nids = alc269_dac_nids,
15144 .hp_nid = 0x03,
15145 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15146 .channel_mode = alc269_modes,
15147 .input_mux = &alc269_capture_source,
15148 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15149 .setup = alc269_lifebook_setup,
64154835
TV
15150 .init_hook = alc269_lifebook_init_hook,
15151 },
fe3eb0a7
KY
15152 [ALC271_ACER] = {
15153 .mixers = { alc269_asus_mixer },
15154 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15155 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157 .dac_nids = alc269_dac_nids,
15158 .adc_nids = alc262_dmic_adc_nids,
15159 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15160 .capsrc_nids = alc262_dmic_capsrc_nids,
15161 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15162 .channel_mode = alc269_modes,
15163 .input_mux = &alc269_capture_source,
15164 .dig_out_nid = ALC880_DIGOUT_NID,
15165 .unsol_event = alc_sku_unsol_event,
15166 .setup = alc269vb_laptop_dmic_setup,
15167 .init_hook = alc_inithook,
15168 },
f6a92248
KY
15169};
15170
977ddd6b
KY
15171static int alc269_fill_coef(struct hda_codec *codec)
15172{
15173 int val;
15174
15175 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15176 alc_write_coef_idx(codec, 0xf, 0x960b);
15177 alc_write_coef_idx(codec, 0xe, 0x8817);
15178 }
15179
15180 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15181 alc_write_coef_idx(codec, 0xf, 0x960b);
15182 alc_write_coef_idx(codec, 0xe, 0x8814);
15183 }
15184
15185 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15186 val = alc_read_coef_idx(codec, 0x04);
15187 /* Power up output pin */
15188 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15189 }
15190
15191 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15192 val = alc_read_coef_idx(codec, 0xd);
15193 if ((val & 0x0c00) >> 10 != 0x1) {
15194 /* Capless ramp up clock control */
b896b4eb 15195 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
15196 }
15197 val = alc_read_coef_idx(codec, 0x17);
15198 if ((val & 0x01c0) >> 6 != 0x4) {
15199 /* Class D power on reset */
b896b4eb 15200 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
15201 }
15202 }
b896b4eb
KY
15203
15204 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15205 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15206
15207 val = alc_read_coef_idx(codec, 0x4); /* HP */
15208 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15209
977ddd6b
KY
15210 return 0;
15211}
15212
f6a92248
KY
15213static int patch_alc269(struct hda_codec *codec)
15214{
15215 struct alc_spec *spec;
48c88e82 15216 int board_config, coef;
f6a92248
KY
15217 int err;
15218
15219 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15220 if (spec == NULL)
15221 return -ENOMEM;
15222
15223 codec->spec = spec;
15224
da00c244
KY
15225 alc_auto_parse_customize_define(codec);
15226
c793bec5
KY
15227 if (codec->vendor_id == 0x10ec0269) {
15228 coef = alc_read_coef_idx(codec, 0);
15229 if ((coef & 0x00f0) == 0x0010) {
15230 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15231 spec->cdefine.platform_type == 1) {
15232 alc_codec_rename(codec, "ALC271X");
15233 spec->codec_variant = ALC269_TYPE_ALC271X;
15234 } else if ((coef & 0xf000) == 0x1000) {
15235 spec->codec_variant = ALC269_TYPE_ALC270;
15236 } else if ((coef & 0xf000) == 0x2000) {
15237 alc_codec_rename(codec, "ALC259");
15238 spec->codec_variant = ALC269_TYPE_ALC259;
15239 } else if ((coef & 0xf000) == 0x3000) {
15240 alc_codec_rename(codec, "ALC258");
15241 spec->codec_variant = ALC269_TYPE_ALC258;
15242 } else {
15243 alc_codec_rename(codec, "ALC269VB");
15244 spec->codec_variant = ALC269_TYPE_ALC269VB;
15245 }
15246 } else
15247 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15248 alc269_fill_coef(codec);
15249 }
977ddd6b 15250
f6a92248
KY
15251 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15252 alc269_models,
15253 alc269_cfg_tbl);
15254
15255 if (board_config < 0) {
9a11f1aa
TI
15256 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15257 codec->chip_name);
f6a92248
KY
15258 board_config = ALC269_AUTO;
15259 }
15260
b5bfbc67
TI
15261 if (board_config == ALC269_AUTO) {
15262 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15263 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15264 }
ff818c24 15265
f6a92248
KY
15266 if (board_config == ALC269_AUTO) {
15267 /* automatic parse from the BIOS config */
15268 err = alc269_parse_auto_config(codec);
15269 if (err < 0) {
15270 alc_free(codec);
15271 return err;
15272 } else if (!err) {
15273 printk(KERN_INFO
15274 "hda_codec: Cannot set up configuration "
15275 "from BIOS. Using base mode...\n");
15276 board_config = ALC269_BASIC;
15277 }
15278 }
15279
dc1eae25 15280 if (has_cdefine_beep(codec)) {
8af2591d
TI
15281 err = snd_hda_attach_beep_device(codec, 0x1);
15282 if (err < 0) {
15283 alc_free(codec);
15284 return err;
15285 }
680cd536
KK
15286 }
15287
f6a92248 15288 if (board_config != ALC269_AUTO)
e9c364c0 15289 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15290
84898e87 15291 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15292 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15293 * fix the sample rate of analog I/O to 44.1kHz
15294 */
15295 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15296 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15297 } else if (spec->dual_adc_switch) {
15298 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15299 /* switch ADC dynamically */
15300 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15301 } else {
15302 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15303 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15304 }
f6a92248
KY
15305 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15306 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15307
6694635d 15308 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15309 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15310 spec->adc_nids = alc269_adc_nids;
15311 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15312 spec->capsrc_nids = alc269_capsrc_nids;
15313 } else {
15314 spec->adc_nids = alc269vb_adc_nids;
15315 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15316 spec->capsrc_nids = alc269vb_capsrc_nids;
15317 }
84898e87
KY
15318 }
15319
f9e336f6 15320 if (!spec->cap_mixer)
b59bdf3b 15321 set_capture_mixer(codec);
dc1eae25 15322 if (has_cdefine_beep(codec))
da00c244 15323 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15324
b5bfbc67 15325 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15326
100d5eb3
TI
15327 spec->vmaster_nid = 0x02;
15328
f6a92248 15329 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15330#ifdef SND_HDA_NEEDS_RESUME
15331 codec->patch_ops.resume = alc269_resume;
15332#endif
f6a92248
KY
15333 if (board_config == ALC269_AUTO)
15334 spec->init_hook = alc269_auto_init;
5402e4cb 15335 spec->shutup = alc269_shutup;
bf1b0225
KY
15336
15337 alc_init_jacks(codec);
f6a92248
KY
15338#ifdef CONFIG_SND_HDA_POWER_SAVE
15339 if (!spec->loopback.amplist)
15340 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15341 if (alc269_mic2_for_mute_led(codec))
15342 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15343#endif
15344
15345 return 0;
15346}
15347
df694daa
KY
15348/*
15349 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15350 */
15351
15352/*
15353 * set the path ways for 2 channel output
15354 * need to set the codec line out and mic 1 pin widgets to inputs
15355 */
a9111321 15356static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15357 /* set pin widget 1Ah (line in) for input */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15359 /* set pin widget 18h (mic1/2) for input, for mic also enable
15360 * the vref
15361 */
df694daa
KY
15362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15363
9c7f852e
TI
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15365#if 0
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15368#endif
df694daa
KY
15369 { } /* end */
15370};
15371/*
15372 * 6ch mode
15373 * need to set the codec line out and mic 1 pin widgets to outputs
15374 */
a9111321 15375static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15376 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15377 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15378 /* set pin widget 18h (mic1) for output (CLFE)*/
15379 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15380
15381 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15382 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15383
9c7f852e
TI
15384 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15385#if 0
15386 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15388#endif
df694daa
KY
15389 { } /* end */
15390};
15391
a9111321 15392static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15393 { 2, alc861_threestack_ch2_init },
15394 { 6, alc861_threestack_ch6_init },
15395};
22309c3e 15396/* Set mic1 as input and unmute the mixer */
a9111321 15397static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15400 { } /* end */
15401};
15402/* Set mic1 as output and mute mixer */
a9111321 15403static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15405 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15406 { } /* end */
15407};
15408
a9111321 15409static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15410 { 2, alc861_uniwill_m31_ch2_init },
15411 { 4, alc861_uniwill_m31_ch4_init },
15412};
df694daa 15413
7cdbff94 15414/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15415static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15416 /* set pin widget 1Ah (line in) for input */
15417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15418 /* set pin widget 18h (mic1/2) for input, for mic also enable
15419 * the vref
15420 */
7cdbff94
MD
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422
15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15424#if 0
15425 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15427#endif
15428 { } /* end */
15429};
15430/* Set mic1 nad line-in as output and mute mixer */
a9111321 15431static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15432 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15433 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15434 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15435 /* set pin widget 18h (mic1) for output (CLFE)*/
15436 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15437 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15438 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15439 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15440
15441 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15442#if 0
15443 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15444 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15445#endif
15446 { } /* end */
15447};
15448
a9111321 15449static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15450 { 2, alc861_asus_ch2_init },
15451 { 6, alc861_asus_ch6_init },
15452};
15453
df694daa
KY
15454/* patch-ALC861 */
15455
a9111321 15456static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15463
15464 /*Input mixer control */
15465 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15466 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15467 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15468 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15470 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15475
df694daa
KY
15476 { } /* end */
15477};
15478
a9111321 15479static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15480 /* output mixer control */
15481 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15485 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15486
15487 /* Input mixer control */
15488 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15490 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15491 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15493 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15495 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15498
df694daa
KY
15499 {
15500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15501 .name = "Channel Mode",
15502 .info = alc_ch_mode_info,
15503 .get = alc_ch_mode_get,
15504 .put = alc_ch_mode_put,
15505 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15506 },
15507 { } /* end */
a53d1aec
TD
15508};
15509
a9111321 15510static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15511 /* output mixer control */
15512 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15515
a53d1aec 15516 { } /* end */
f12ab1e0 15517};
a53d1aec 15518
a9111321 15519static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15520 /* output mixer control */
15521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15525 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15526
15527 /* Input mixer control */
15528 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15529 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15530 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15531 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15533 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15535 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15538
22309c3e
TI
15539 {
15540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15541 .name = "Channel Mode",
15542 .info = alc_ch_mode_info,
15543 .get = alc_ch_mode_get,
15544 .put = alc_ch_mode_put,
15545 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15546 },
15547 { } /* end */
f12ab1e0 15548};
7cdbff94 15549
a9111321 15550static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15551 /* output mixer control */
15552 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15557
15558 /* Input mixer control */
15559 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15560 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15562 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15563 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15564 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15566 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15569
7cdbff94
MD
15570 {
15571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15572 .name = "Channel Mode",
15573 .info = alc_ch_mode_info,
15574 .get = alc_ch_mode_get,
15575 .put = alc_ch_mode_put,
15576 .private_value = ARRAY_SIZE(alc861_asus_modes),
15577 },
15578 { }
56bb0cab
TI
15579};
15580
15581/* additional mixer */
a9111321 15582static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15583 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15585 { }
15586};
7cdbff94 15587
df694daa
KY
15588/*
15589 * generic initialization of ADC, input mixers and output mixers
15590 */
a9111321 15591static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15592 /*
15593 * Unmute ADC0 and set the default input to mic-in
15594 */
15595 /* port-A for surround (rear panel) */
15596 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15597 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15598 /* port-B for mic-in (rear panel) with vref */
15599 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15600 /* port-C for line-in (rear panel) */
15601 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15602 /* port-D for Front */
15603 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15604 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15605 /* port-E for HP out (front panel) */
15606 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15607 /* route front PCM to HP */
9dece1d7 15608 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15609 /* port-F for mic-in (front panel) with vref */
15610 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15611 /* port-G for CLFE (rear panel) */
15612 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15613 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15614 /* port-H for side (rear panel) */
15615 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15616 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15617 /* CD-in */
15618 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* route front mic to ADC1*/
15620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15622
df694daa
KY
15623 /* Unmute DAC0~3 & spdif out*/
15624 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15628 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15629
df694daa
KY
15630 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15631 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15635
df694daa
KY
15636 /* Unmute Stereo Mixer 15 */
15637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15641
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15647 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15650 /* hp used DAC 3 (Front) */
15651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15653
15654 { }
15655};
15656
a9111321 15657static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15658 /*
15659 * Unmute ADC0 and set the default input to mic-in
15660 */
15661 /* port-A for surround (rear panel) */
15662 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15663 /* port-B for mic-in (rear panel) with vref */
15664 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15665 /* port-C for line-in (rear panel) */
15666 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15667 /* port-D for Front */
15668 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15669 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15670 /* port-E for HP out (front panel) */
15671 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15672 /* route front PCM to HP */
9dece1d7 15673 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15674 /* port-F for mic-in (front panel) with vref */
15675 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15676 /* port-G for CLFE (rear panel) */
15677 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15678 /* port-H for side (rear panel) */
15679 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15680 /* CD-in */
15681 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15682 /* route front mic to ADC1*/
15683 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 /* Unmute DAC0~3 & spdif out*/
15686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15691
df694daa
KY
15692 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15693 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15697
df694daa
KY
15698 /* Unmute Stereo Mixer 15 */
15699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15703
15704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15711 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15712 /* hp used DAC 3 (Front) */
15713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15715 { }
15716};
22309c3e 15717
a9111321 15718static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15719 /*
15720 * Unmute ADC0 and set the default input to mic-in
15721 */
15722 /* port-A for surround (rear panel) */
15723 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15724 /* port-B for mic-in (rear panel) with vref */
15725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15726 /* port-C for line-in (rear panel) */
15727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15728 /* port-D for Front */
15729 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15730 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15731 /* port-E for HP out (front panel) */
f12ab1e0
TI
15732 /* this has to be set to VREF80 */
15733 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15734 /* route front PCM to HP */
9dece1d7 15735 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15736 /* port-F for mic-in (front panel) with vref */
15737 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15738 /* port-G for CLFE (rear panel) */
15739 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15740 /* port-H for side (rear panel) */
15741 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15742 /* CD-in */
15743 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15744 /* route front mic to ADC1*/
15745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 /* Unmute DAC0~3 & spdif out*/
15748 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15753
22309c3e
TI
15754 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15755 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15758 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15759
22309c3e
TI
15760 /* Unmute Stereo Mixer 15 */
15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15765
15766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15774 /* hp used DAC 3 (Front) */
15775 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15777 { }
15778};
15779
a9111321 15780static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15781 /*
15782 * Unmute ADC0 and set the default input to mic-in
15783 */
f12ab1e0
TI
15784 /* port-A for surround (rear panel)
15785 * according to codec#0 this is the HP jack
15786 */
7cdbff94
MD
15787 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15788 /* route front PCM to HP */
15789 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15790 /* port-B for mic-in (rear panel) with vref */
15791 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15792 /* port-C for line-in (rear panel) */
15793 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15794 /* port-D for Front */
15795 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15796 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15797 /* port-E for HP out (front panel) */
f12ab1e0
TI
15798 /* this has to be set to VREF80 */
15799 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15800 /* route front PCM to HP */
9dece1d7 15801 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15802 /* port-F for mic-in (front panel) with vref */
15803 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15804 /* port-G for CLFE (rear panel) */
15805 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15806 /* port-H for side (rear panel) */
15807 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15808 /* CD-in */
15809 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15810 /* route front mic to ADC1*/
15811 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15812 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15813 /* Unmute DAC0~3 & spdif out*/
15814 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15816 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15824
7cdbff94
MD
15825 /* Unmute Stereo Mixer 15 */
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15830
15831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15839 /* hp used DAC 3 (Front) */
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15842 { }
15843};
15844
56bb0cab 15845/* additional init verbs for ASUS laptops */
a9111321 15846static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15847 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15848 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15849 { }
15850};
7cdbff94 15851
df694daa
KY
15852/*
15853 * generic initialization of ADC, input mixers and output mixers
15854 */
a9111321 15855static const struct hda_verb alc861_auto_init_verbs[] = {
df694daa
KY
15856 /*
15857 * Unmute ADC0 and set the default input to mic-in
15858 */
f12ab1e0 15859 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15861
df694daa
KY
15862 /* Unmute DAC0~3 & spdif out*/
15863 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15864 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15866 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15868
df694daa
KY
15869 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15870 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15871 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15872 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15873 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15874
df694daa
KY
15875 /* Unmute Stereo Mixer 15 */
15876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15880
1c20930a
TI
15881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15883 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15889
15890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15896 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15897 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15898
f12ab1e0 15899 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15900
15901 { }
15902};
15903
a9111321 15904static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15905 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15906
a53d1aec
TD
15907 { }
15908};
15909
15910/* toggle speaker-output according to the hp-jack state */
15911static void alc861_toshiba_automute(struct hda_codec *codec)
15912{
864f92be 15913 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15914
47fd830a
TI
15915 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15917 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15918 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15919}
15920
15921static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15922 unsigned int res)
15923{
a53d1aec
TD
15924 if ((res >> 26) == ALC880_HP_EVENT)
15925 alc861_toshiba_automute(codec);
15926}
15927
def319f9 15928/* pcm configuration: identical with ALC880 */
df694daa
KY
15929#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15930#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15931#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15932#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15933
15934
15935#define ALC861_DIGOUT_NID 0x07
15936
a9111321 15937static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15938 { 8, NULL }
15939};
15940
4c6d72d1 15941static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15942 /* front, surround, clfe, side */
15943 0x03, 0x06, 0x05, 0x04
15944};
15945
4c6d72d1 15946static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15947 /* front, clfe, surround */
15948 0x03, 0x05, 0x06
15949};
15950
4c6d72d1 15951static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15952 /* ADC0-2 */
15953 0x08,
15954};
15955
a9111321 15956static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15957 .num_items = 5,
15958 .items = {
15959 { "Mic", 0x0 },
15960 { "Front Mic", 0x3 },
15961 { "Line", 0x1 },
15962 { "CD", 0x4 },
15963 { "Mixer", 0x5 },
15964 },
15965};
15966
1c20930a
TI
15967static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15968{
15969 struct alc_spec *spec = codec->spec;
15970 hda_nid_t mix, srcs[5];
15971 int i, j, num;
15972
15973 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15974 return 0;
15975 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15976 if (num < 0)
15977 return 0;
15978 for (i = 0; i < num; i++) {
15979 unsigned int type;
a22d543a 15980 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15981 if (type != AC_WID_AUD_OUT)
15982 continue;
15983 for (j = 0; j < spec->multiout.num_dacs; j++)
15984 if (spec->multiout.dac_nids[j] == srcs[i])
15985 break;
15986 if (j >= spec->multiout.num_dacs)
15987 return srcs[i];
15988 }
15989 return 0;
15990}
15991
df694daa 15992/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15993static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15994 const struct auto_pin_cfg *cfg)
df694daa 15995{
1c20930a 15996 struct alc_spec *spec = codec->spec;
df694daa 15997 int i;
1c20930a 15998 hda_nid_t nid, dac;
df694daa
KY
15999
16000 spec->multiout.dac_nids = spec->private_dac_nids;
16001 for (i = 0; i < cfg->line_outs; i++) {
16002 nid = cfg->line_out_pins[i];
1c20930a
TI
16003 dac = alc861_look_for_dac(codec, nid);
16004 if (!dac)
16005 continue;
dda14410 16006 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 16007 }
df694daa
KY
16008 return 0;
16009}
16010
bcb2f0f5
TI
16011static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16012 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 16013{
bcb2f0f5 16014 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
16015 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16016}
16017
bcb2f0f5
TI
16018#define alc861_create_out_sw(codec, pfx, nid, chs) \
16019 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16020
df694daa 16021/* add playback controls from the parsed DAC table */
1c20930a 16022static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
16023 const struct auto_pin_cfg *cfg)
16024{
1c20930a 16025 struct alc_spec *spec = codec->spec;
ea734963 16026 static const char * const chname[4] = {
f12ab1e0
TI
16027 "Front", "Surround", NULL /*CLFE*/, "Side"
16028 };
ce764ab2 16029 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 16030 hda_nid_t nid;
ce764ab2 16031 int i, err, noutputs;
1c20930a 16032
ce764ab2
TI
16033 noutputs = cfg->line_outs;
16034 if (spec->multi_ios > 0)
16035 noutputs += spec->multi_ios;
16036
16037 for (i = 0; i < noutputs; i++) {
df694daa 16038 nid = spec->multiout.dac_nids[i];
f12ab1e0 16039 if (!nid)
df694daa 16040 continue;
bcb2f0f5 16041 if (!pfx && i == 2) {
df694daa 16042 /* Center/LFE */
1c20930a 16043 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 16044 if (err < 0)
df694daa 16045 return err;
1c20930a 16046 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 16047 if (err < 0)
df694daa
KY
16048 return err;
16049 } else {
bcb2f0f5 16050 const char *name = pfx;
5a882646
DH
16051 int index = i;
16052 if (!name) {
bcb2f0f5 16053 name = chname[i];
5a882646
DH
16054 index = 0;
16055 }
16056 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16057 if (err < 0)
df694daa
KY
16058 return err;
16059 }
16060 }
16061 return 0;
16062}
16063
1c20930a 16064static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16065{
1c20930a 16066 struct alc_spec *spec = codec->spec;
df694daa
KY
16067 int err;
16068 hda_nid_t nid;
16069
f12ab1e0 16070 if (!pin)
df694daa
KY
16071 return 0;
16072
16073 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16074 nid = alc861_look_for_dac(codec, pin);
16075 if (nid) {
16076 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16077 if (err < 0)
16078 return err;
16079 spec->multiout.hp_nid = nid;
16080 }
df694daa
KY
16081 }
16082 return 0;
16083}
16084
16085/* create playback/capture controls for input pins */
05f5f477 16086static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16087 const struct auto_pin_cfg *cfg)
df694daa 16088{
05f5f477 16089 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16090}
16091
f12ab1e0
TI
16092static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16093 hda_nid_t nid,
1c20930a 16094 int pin_type, hda_nid_t dac)
df694daa 16095{
1c20930a
TI
16096 hda_nid_t mix, srcs[5];
16097 int i, num;
16098
564c5bea
JL
16099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16100 pin_type);
1c20930a 16101 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16102 AMP_OUT_UNMUTE);
1c20930a
TI
16103 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16104 return;
16105 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16106 if (num < 0)
16107 return;
16108 for (i = 0; i < num; i++) {
16109 unsigned int mute;
16110 if (srcs[i] == dac || srcs[i] == 0x15)
16111 mute = AMP_IN_UNMUTE(i);
16112 else
16113 mute = AMP_IN_MUTE(i);
16114 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16115 mute);
16116 }
df694daa
KY
16117}
16118
16119static void alc861_auto_init_multi_out(struct hda_codec *codec)
16120{
16121 struct alc_spec *spec = codec->spec;
16122 int i;
16123
16124 for (i = 0; i < spec->autocfg.line_outs; i++) {
16125 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16126 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16127 if (nid)
baba8ee9 16128 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16129 spec->multiout.dac_nids[i]);
df694daa
KY
16130 }
16131}
16132
16133static void alc861_auto_init_hp_out(struct hda_codec *codec)
16134{
16135 struct alc_spec *spec = codec->spec;
df694daa 16136
15870f05
TI
16137 if (spec->autocfg.hp_outs)
16138 alc861_auto_set_output_and_unmute(codec,
16139 spec->autocfg.hp_pins[0],
16140 PIN_HP,
1c20930a 16141 spec->multiout.hp_nid);
15870f05
TI
16142 if (spec->autocfg.speaker_outs)
16143 alc861_auto_set_output_and_unmute(codec,
16144 spec->autocfg.speaker_pins[0],
16145 PIN_OUT,
1c20930a 16146 spec->multiout.dac_nids[0]);
df694daa
KY
16147}
16148
16149static void alc861_auto_init_analog_input(struct hda_codec *codec)
16150{
16151 struct alc_spec *spec = codec->spec;
66ceeb6b 16152 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16153 int i;
16154
66ceeb6b
TI
16155 for (i = 0; i < cfg->num_inputs; i++) {
16156 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16157 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16158 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16159 }
16160}
16161
16162/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16163/* return 1 if successful, 0 if the proper config is not found,
16164 * or a negative error code
16165 */
df694daa
KY
16166static int alc861_parse_auto_config(struct hda_codec *codec)
16167{
16168 struct alc_spec *spec = codec->spec;
16169 int err;
4c6d72d1 16170 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16171
f12ab1e0
TI
16172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16173 alc861_ignore);
16174 if (err < 0)
df694daa 16175 return err;
f12ab1e0 16176 if (!spec->autocfg.line_outs)
df694daa
KY
16177 return 0; /* can't find valid BIOS pin config */
16178
1c20930a 16179 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16180 if (err < 0)
16181 return err;
16182 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16183 if (err < 0)
16184 return err;
1c20930a 16185 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16186 if (err < 0)
16187 return err;
1c20930a 16188 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16189 if (err < 0)
16190 return err;
05f5f477 16191 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16192 if (err < 0)
df694daa
KY
16193 return err;
16194
16195 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16196
757899ac 16197 alc_auto_parse_digital(codec);
df694daa 16198
603c4019 16199 if (spec->kctls.list)
d88897ea 16200 add_mixer(spec, spec->kctls.list);
df694daa 16201
d88897ea 16202 add_verb(spec, alc861_auto_init_verbs);
df694daa 16203
a1e8d2da 16204 spec->num_mux_defs = 1;
61b9b9b1 16205 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16206
16207 spec->adc_nids = alc861_adc_nids;
16208 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16209 set_capture_mixer(codec);
df694daa 16210
6227cdce 16211 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16212
df694daa
KY
16213 return 1;
16214}
16215
ae6b813a
TI
16216/* additional initialization for auto-configuration model */
16217static void alc861_auto_init(struct hda_codec *codec)
df694daa 16218{
f6c7e546 16219 struct alc_spec *spec = codec->spec;
df694daa
KY
16220 alc861_auto_init_multi_out(codec);
16221 alc861_auto_init_hp_out(codec);
16222 alc861_auto_init_analog_input(codec);
757899ac 16223 alc_auto_init_digital(codec);
f6c7e546 16224 if (spec->unsol_event)
7fb0d78f 16225 alc_inithook(codec);
df694daa
KY
16226}
16227
cb53c626 16228#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16229static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16230 { 0x15, HDA_INPUT, 0 },
16231 { 0x15, HDA_INPUT, 1 },
16232 { 0x15, HDA_INPUT, 2 },
16233 { 0x15, HDA_INPUT, 3 },
16234 { } /* end */
16235};
16236#endif
16237
df694daa
KY
16238
16239/*
16240 * configuration and preset
16241 */
ea734963 16242static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16243 [ALC861_3ST] = "3stack",
16244 [ALC660_3ST] = "3stack-660",
16245 [ALC861_3ST_DIG] = "3stack-dig",
16246 [ALC861_6ST_DIG] = "6stack-dig",
16247 [ALC861_UNIWILL_M31] = "uniwill-m31",
16248 [ALC861_TOSHIBA] = "toshiba",
16249 [ALC861_ASUS] = "asus",
16250 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16251 [ALC861_AUTO] = "auto",
16252};
16253
a9111321 16254static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16255 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16256 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16257 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16258 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16259 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16260 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16261 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16262 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16263 * Any other models that need this preset?
16264 */
16265 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16266 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16267 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16268 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16269 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16270 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16271 /* FIXME: the below seems conflict */
16272 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16273 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16274 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16275 {}
16276};
16277
a9111321 16278static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16279 [ALC861_3ST] = {
16280 .mixers = { alc861_3ST_mixer },
16281 .init_verbs = { alc861_threestack_init_verbs },
16282 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16283 .dac_nids = alc861_dac_nids,
16284 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16285 .channel_mode = alc861_threestack_modes,
4e195a7b 16286 .need_dac_fix = 1,
df694daa
KY
16287 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16288 .adc_nids = alc861_adc_nids,
16289 .input_mux = &alc861_capture_source,
16290 },
16291 [ALC861_3ST_DIG] = {
16292 .mixers = { alc861_base_mixer },
16293 .init_verbs = { alc861_threestack_init_verbs },
16294 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16295 .dac_nids = alc861_dac_nids,
16296 .dig_out_nid = ALC861_DIGOUT_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16298 .channel_mode = alc861_threestack_modes,
4e195a7b 16299 .need_dac_fix = 1,
df694daa
KY
16300 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16301 .adc_nids = alc861_adc_nids,
16302 .input_mux = &alc861_capture_source,
16303 },
16304 [ALC861_6ST_DIG] = {
16305 .mixers = { alc861_base_mixer },
16306 .init_verbs = { alc861_base_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16308 .dac_nids = alc861_dac_nids,
16309 .dig_out_nid = ALC861_DIGOUT_NID,
16310 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16311 .channel_mode = alc861_8ch_modes,
16312 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16313 .adc_nids = alc861_adc_nids,
16314 .input_mux = &alc861_capture_source,
16315 },
9c7f852e
TI
16316 [ALC660_3ST] = {
16317 .mixers = { alc861_3ST_mixer },
16318 .init_verbs = { alc861_threestack_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16320 .dac_nids = alc660_dac_nids,
16321 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16322 .channel_mode = alc861_threestack_modes,
4e195a7b 16323 .need_dac_fix = 1,
9c7f852e
TI
16324 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325 .adc_nids = alc861_adc_nids,
16326 .input_mux = &alc861_capture_source,
16327 },
22309c3e
TI
16328 [ALC861_UNIWILL_M31] = {
16329 .mixers = { alc861_uniwill_m31_mixer },
16330 .init_verbs = { alc861_uniwill_m31_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16332 .dac_nids = alc861_dac_nids,
16333 .dig_out_nid = ALC861_DIGOUT_NID,
16334 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16335 .channel_mode = alc861_uniwill_m31_modes,
16336 .need_dac_fix = 1,
16337 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16338 .adc_nids = alc861_adc_nids,
16339 .input_mux = &alc861_capture_source,
16340 },
a53d1aec
TD
16341 [ALC861_TOSHIBA] = {
16342 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16343 .init_verbs = { alc861_base_init_verbs,
16344 alc861_toshiba_init_verbs },
a53d1aec
TD
16345 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16346 .dac_nids = alc861_dac_nids,
16347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16348 .channel_mode = alc883_3ST_2ch_modes,
16349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16350 .adc_nids = alc861_adc_nids,
16351 .input_mux = &alc861_capture_source,
16352 .unsol_event = alc861_toshiba_unsol_event,
16353 .init_hook = alc861_toshiba_automute,
16354 },
7cdbff94
MD
16355 [ALC861_ASUS] = {
16356 .mixers = { alc861_asus_mixer },
16357 .init_verbs = { alc861_asus_init_verbs },
16358 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16359 .dac_nids = alc861_dac_nids,
16360 .dig_out_nid = ALC861_DIGOUT_NID,
16361 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16362 .channel_mode = alc861_asus_modes,
16363 .need_dac_fix = 1,
16364 .hp_nid = 0x06,
16365 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16366 .adc_nids = alc861_adc_nids,
16367 .input_mux = &alc861_capture_source,
16368 },
56bb0cab
TI
16369 [ALC861_ASUS_LAPTOP] = {
16370 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16371 .init_verbs = { alc861_asus_init_verbs,
16372 alc861_asus_laptop_init_verbs },
16373 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16374 .dac_nids = alc861_dac_nids,
16375 .dig_out_nid = ALC861_DIGOUT_NID,
16376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16377 .channel_mode = alc883_3ST_2ch_modes,
16378 .need_dac_fix = 1,
16379 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16380 .adc_nids = alc861_adc_nids,
16381 .input_mux = &alc861_capture_source,
16382 },
16383};
df694daa 16384
cfc9b06f
TI
16385/* Pin config fixes */
16386enum {
16387 PINFIX_FSC_AMILO_PI1505,
16388};
16389
cfc9b06f
TI
16390static const struct alc_fixup alc861_fixups[] = {
16391 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16392 .type = ALC_FIXUP_PINS,
16393 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16394 { 0x0b, 0x0221101f }, /* HP */
16395 { 0x0f, 0x90170310 }, /* speaker */
16396 { }
16397 }
cfc9b06f
TI
16398 },
16399};
16400
a9111321 16401static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16402 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16403 {}
16404};
df694daa
KY
16405
16406static int patch_alc861(struct hda_codec *codec)
16407{
16408 struct alc_spec *spec;
16409 int board_config;
16410 int err;
16411
dc041e0b 16412 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16413 if (spec == NULL)
16414 return -ENOMEM;
16415
f12ab1e0 16416 codec->spec = spec;
df694daa 16417
f5fcc13c
TI
16418 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16419 alc861_models,
16420 alc861_cfg_tbl);
9c7f852e 16421
f5fcc13c 16422 if (board_config < 0) {
9a11f1aa
TI
16423 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16424 codec->chip_name);
df694daa
KY
16425 board_config = ALC861_AUTO;
16426 }
16427
b5bfbc67
TI
16428 if (board_config == ALC861_AUTO) {
16429 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16430 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16431 }
cfc9b06f 16432
df694daa
KY
16433 if (board_config == ALC861_AUTO) {
16434 /* automatic parse from the BIOS config */
16435 err = alc861_parse_auto_config(codec);
16436 if (err < 0) {
16437 alc_free(codec);
16438 return err;
f12ab1e0 16439 } else if (!err) {
9c7f852e
TI
16440 printk(KERN_INFO
16441 "hda_codec: Cannot set up configuration "
16442 "from BIOS. Using base mode...\n");
df694daa
KY
16443 board_config = ALC861_3ST_DIG;
16444 }
16445 }
16446
680cd536
KK
16447 err = snd_hda_attach_beep_device(codec, 0x23);
16448 if (err < 0) {
16449 alc_free(codec);
16450 return err;
16451 }
16452
df694daa 16453 if (board_config != ALC861_AUTO)
e9c364c0 16454 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16455
df694daa
KY
16456 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16457 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16458
df694daa
KY
16459 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16460 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16461
c7a8eb10
TI
16462 if (!spec->cap_mixer)
16463 set_capture_mixer(codec);
45bdd1c1
TI
16464 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16465
2134ea4f
TI
16466 spec->vmaster_nid = 0x03;
16467
b5bfbc67 16468 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16469
df694daa 16470 codec->patch_ops = alc_patch_ops;
c97259df 16471 if (board_config == ALC861_AUTO) {
ae6b813a 16472 spec->init_hook = alc861_auto_init;
c97259df
DC
16473#ifdef CONFIG_SND_HDA_POWER_SAVE
16474 spec->power_hook = alc_power_eapd;
16475#endif
16476 }
cb53c626
TI
16477#ifdef CONFIG_SND_HDA_POWER_SAVE
16478 if (!spec->loopback.amplist)
16479 spec->loopback.amplist = alc861_loopbacks;
16480#endif
ea1fb29a 16481
1da177e4
LT
16482 return 0;
16483}
16484
f32610ed
JS
16485/*
16486 * ALC861-VD support
16487 *
16488 * Based on ALC882
16489 *
16490 * In addition, an independent DAC
16491 */
16492#define ALC861VD_DIGOUT_NID 0x06
16493
4c6d72d1 16494static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16495 /* front, surr, clfe, side surr */
16496 0x02, 0x03, 0x04, 0x05
16497};
16498
16499/* dac_nids for ALC660vd are in a different order - according to
16500 * Realtek's driver.
def319f9 16501 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16502 * of ALC660vd codecs, but for now there is only 3stack mixer
16503 * - and it is the same as in 861vd.
16504 * adc_nids in ALC660vd are (is) the same as in 861vd
16505 */
4c6d72d1 16506static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16507 /* front, rear, clfe, rear_surr */
16508 0x02, 0x04, 0x03
16509};
16510
4c6d72d1 16511static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16512 /* ADC0 */
16513 0x09,
16514};
16515
4c6d72d1 16516static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16517
f32610ed
JS
16518/* input MUX */
16519/* FIXME: should be a matrix-type input source selection */
a9111321 16520static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16521 .num_items = 4,
16522 .items = {
16523 { "Mic", 0x0 },
16524 { "Front Mic", 0x1 },
16525 { "Line", 0x2 },
16526 { "CD", 0x4 },
16527 },
16528};
16529
a9111321 16530static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16531 .num_items = 2,
272a527c 16532 .items = {
8607f7c4 16533 { "Mic", 0x0 },
28c4edb7 16534 { "Internal Mic", 0x1 },
272a527c
KY
16535 },
16536};
16537
a9111321 16538static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16539 .num_items = 2,
16540 .items = {
16541 { "Front Mic", 0x0 },
16542 { "ATAPI Mic", 0x1 },
16543 },
16544};
16545
f32610ed
JS
16546/*
16547 * 2ch mode
16548 */
a9111321 16549static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16550 { 2, NULL }
16551};
16552
16553/*
16554 * 6ch mode
16555 */
a9111321 16556static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16557 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16558 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16560 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16561 { } /* end */
16562};
16563
16564/*
16565 * 8ch mode
16566 */
a9111321 16567static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16572 { } /* end */
16573};
16574
a9111321 16575static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16576 { 6, alc861vd_6stack_ch6_init },
16577 { 8, alc861vd_6stack_ch8_init },
16578};
16579
a9111321 16580static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16581 {
16582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16583 .name = "Channel Mode",
16584 .info = alc_ch_mode_info,
16585 .get = alc_ch_mode_get,
16586 .put = alc_ch_mode_put,
16587 },
16588 { } /* end */
16589};
16590
f32610ed
JS
16591/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16592 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16593 */
a9111321 16594static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16597
16598 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16599 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16600
16601 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16602 HDA_OUTPUT),
16603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16604 HDA_OUTPUT),
16605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16607
16608 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16609 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16610
16611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16612
5f99f86a 16613 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16616
5f99f86a 16617 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16620
16621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16623
16624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16626
f32610ed
JS
16627 { } /* end */
16628};
16629
a9111321 16630static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16633
16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16635
5f99f86a 16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16639
5f99f86a 16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16643
16644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16646
16647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16649
f32610ed
JS
16650 { } /* end */
16651};
16652
a9111321 16653static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16656 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16657
16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16659
5f99f86a 16660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16663
5f99f86a 16664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16667
16668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16670
16671 { } /* end */
16672};
16673
b419f346 16674/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16675 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16676 */
a9111321 16677static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16682 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16685 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16686 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16687 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16688 { } /* end */
16689};
16690
d1a991a6
KY
16691/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16692 * Front Mic=0x18, ATAPI Mic = 0x19,
16693 */
a9111321 16694static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16698 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16701 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16702 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16703
d1a991a6
KY
16704 { } /* end */
16705};
16706
f32610ed
JS
16707/*
16708 * generic initialization of ADC, input mixers and output mixers
16709 */
a9111321 16710static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16711 /*
16712 * Unmute ADC0 and set the default input to mic-in
16713 */
16714 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16716
16717 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16718 * the analog-loopback mixer widget
16719 */
16720 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16726
16727 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16732
16733 /*
16734 * Set up output mixers (0x02 - 0x05)
16735 */
16736 /* set vol=0 to output mixers */
16737 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16741
16742 /* set up input amps for analog loopback */
16743 /* Amp Indices: DAC = 0, mixer = 1 */
16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16752
16753 { }
16754};
16755
16756/*
16757 * 3-stack pin configuration:
16758 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16759 */
a9111321 16760static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16761 /*
16762 * Set pin mode and muting
16763 */
16764 /* set front pin widgets 0x14 for output */
16765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16768
16769 /* Mic (rear) pin: input vref at 80% */
16770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16772 /* Front Mic pin: input vref at 80% */
16773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16775 /* Line In pin: input */
16776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16782 /* CD pin widget for input */
16783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16784
16785 { }
16786};
16787
16788/*
16789 * 6-stack pin configuration:
16790 */
a9111321 16791static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16792 /*
16793 * Set pin mode and muting
16794 */
16795 /* set front pin widgets 0x14 for output */
16796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16799
16800 /* Rear Pin: output 1 (0x0d) */
16801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16804 /* CLFE Pin: output 2 (0x0e) */
16805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16807 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16808 /* Side Pin: output 3 (0x0f) */
16809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16812
16813 /* Mic (rear) pin: input vref at 80% */
16814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16816 /* Front Mic pin: input vref at 80% */
16817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16819 /* Line In pin: input */
16820 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16821 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16822 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16826 /* CD pin widget for input */
16827 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16828
16829 { }
16830};
16831
a9111321 16832static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16834 { }
16835};
16836
a9111321 16837static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16838 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16839 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16840 { }
16841};
16842
a9111321 16843static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16849 {}
16850};
16851
4f5d1706 16852static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16853{
a9fd4f3f 16854 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16855 spec->autocfg.hp_pins[0] = 0x1b;
16856 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16857 spec->automute = 1;
16858 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16859}
16860
16861static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16862{
d922b51d 16863 alc_hp_automute(codec);
eeb43387 16864 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16865}
16866
16867static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16868 unsigned int res)
16869{
16870 switch (res >> 26) {
bdd148a3 16871 case ALC880_MIC_EVENT:
eeb43387 16872 alc88x_simple_mic_automute(codec);
bdd148a3 16873 break;
a9fd4f3f 16874 default:
d922b51d 16875 alc_sku_unsol_event(codec, res);
a9fd4f3f 16876 break;
bdd148a3
KY
16877 }
16878}
16879
a9111321 16880static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16882 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16885
16886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16892 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16894
272a527c
KY
16895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16901 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16903
16904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16911 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16912
16913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16917
16918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16921
16922 { } /* end */
16923};
16924
16925/* toggle speaker-output according to the hp-jack state */
4f5d1706 16926static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16927{
a9fd4f3f 16928 struct alc_spec *spec = codec->spec;
272a527c 16929
a9fd4f3f
TI
16930 spec->autocfg.hp_pins[0] = 0x15;
16931 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16932 spec->automute = 1;
16933 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16934}
16935
cb53c626
TI
16936#ifdef CONFIG_SND_HDA_POWER_SAVE
16937#define alc861vd_loopbacks alc880_loopbacks
16938#endif
16939
def319f9 16940/* pcm configuration: identical with ALC880 */
f32610ed
JS
16941#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16942#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16943#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16944#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16945
16946/*
16947 * configuration and preset
16948 */
ea734963 16949static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16950 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16951 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16952 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16953 [ALC861VD_3ST] = "3stack",
16954 [ALC861VD_3ST_DIG] = "3stack-digout",
16955 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16956 [ALC861VD_LENOVO] = "lenovo",
272a527c 16957 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16958 [ALC861VD_HP] = "hp",
f32610ed
JS
16959 [ALC861VD_AUTO] = "auto",
16960};
16961
a9111321 16962static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16963 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16964 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16965 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16966 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16967 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16968 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16969 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16970 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16971 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16972 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16973 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16974 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16975 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16976 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16977 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16978 {}
16979};
16980
a9111321 16981static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16982 [ALC660VD_3ST] = {
16983 .mixers = { alc861vd_3st_mixer },
16984 .init_verbs = { alc861vd_volume_init_verbs,
16985 alc861vd_3stack_init_verbs },
16986 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16987 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16988 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16989 .channel_mode = alc861vd_3stack_2ch_modes,
16990 .input_mux = &alc861vd_capture_source,
16991 },
6963f84c
MC
16992 [ALC660VD_3ST_DIG] = {
16993 .mixers = { alc861vd_3st_mixer },
16994 .init_verbs = { alc861vd_volume_init_verbs,
16995 alc861vd_3stack_init_verbs },
16996 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16997 .dac_nids = alc660vd_dac_nids,
16998 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16999 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17000 .channel_mode = alc861vd_3stack_2ch_modes,
17001 .input_mux = &alc861vd_capture_source,
17002 },
f32610ed
JS
17003 [ALC861VD_3ST] = {
17004 .mixers = { alc861vd_3st_mixer },
17005 .init_verbs = { alc861vd_volume_init_verbs,
17006 alc861vd_3stack_init_verbs },
17007 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17008 .dac_nids = alc861vd_dac_nids,
17009 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17010 .channel_mode = alc861vd_3stack_2ch_modes,
17011 .input_mux = &alc861vd_capture_source,
17012 },
17013 [ALC861VD_3ST_DIG] = {
17014 .mixers = { alc861vd_3st_mixer },
17015 .init_verbs = { alc861vd_volume_init_verbs,
17016 alc861vd_3stack_init_verbs },
17017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17018 .dac_nids = alc861vd_dac_nids,
17019 .dig_out_nid = ALC861VD_DIGOUT_NID,
17020 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17021 .channel_mode = alc861vd_3stack_2ch_modes,
17022 .input_mux = &alc861vd_capture_source,
17023 },
17024 [ALC861VD_6ST_DIG] = {
17025 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17026 .init_verbs = { alc861vd_volume_init_verbs,
17027 alc861vd_6stack_init_verbs },
17028 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17029 .dac_nids = alc861vd_dac_nids,
17030 .dig_out_nid = ALC861VD_DIGOUT_NID,
17031 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17032 .channel_mode = alc861vd_6stack_modes,
17033 .input_mux = &alc861vd_capture_source,
17034 },
bdd148a3
KY
17035 [ALC861VD_LENOVO] = {
17036 .mixers = { alc861vd_lenovo_mixer },
17037 .init_verbs = { alc861vd_volume_init_verbs,
17038 alc861vd_3stack_init_verbs,
17039 alc861vd_eapd_verbs,
17040 alc861vd_lenovo_unsol_verbs },
17041 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17042 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
17043 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17044 .channel_mode = alc861vd_3stack_2ch_modes,
17045 .input_mux = &alc861vd_capture_source,
17046 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17047 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17048 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 17049 },
272a527c
KY
17050 [ALC861VD_DALLAS] = {
17051 .mixers = { alc861vd_dallas_mixer },
17052 .init_verbs = { alc861vd_dallas_verbs },
17053 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17054 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17055 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17056 .channel_mode = alc861vd_3stack_2ch_modes,
17057 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 17058 .unsol_event = alc_sku_unsol_event,
4f5d1706 17059 .setup = alc861vd_dallas_setup,
d922b51d 17060 .init_hook = alc_hp_automute,
d1a991a6
KY
17061 },
17062 [ALC861VD_HP] = {
17063 .mixers = { alc861vd_hp_mixer },
17064 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17065 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17066 .dac_nids = alc861vd_dac_nids,
d1a991a6 17067 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17069 .channel_mode = alc861vd_3stack_2ch_modes,
17070 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17071 .unsol_event = alc_sku_unsol_event,
4f5d1706 17072 .setup = alc861vd_dallas_setup,
d922b51d 17073 .init_hook = alc_hp_automute,
ea1fb29a 17074 },
13c94744
TI
17075 [ALC660VD_ASUS_V1S] = {
17076 .mixers = { alc861vd_lenovo_mixer },
17077 .init_verbs = { alc861vd_volume_init_verbs,
17078 alc861vd_3stack_init_verbs,
17079 alc861vd_eapd_verbs,
17080 alc861vd_lenovo_unsol_verbs },
17081 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17082 .dac_nids = alc660vd_dac_nids,
17083 .dig_out_nid = ALC861VD_DIGOUT_NID,
17084 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17085 .channel_mode = alc861vd_3stack_2ch_modes,
17086 .input_mux = &alc861vd_capture_source,
17087 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17088 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17089 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17090 },
f32610ed
JS
17091};
17092
17093/*
17094 * BIOS auto configuration
17095 */
05f5f477
TI
17096static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17097 const struct auto_pin_cfg *cfg)
17098{
7167594a 17099 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17100}
17101
17102
f32610ed
JS
17103static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17104 hda_nid_t nid, int pin_type, int dac_idx)
17105{
f6c7e546 17106 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17107}
17108
17109static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17110{
17111 struct alc_spec *spec = codec->spec;
17112 int i;
17113
17114 for (i = 0; i <= HDA_SIDE; i++) {
17115 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17116 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17117 if (nid)
17118 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17119 pin_type, i);
f32610ed
JS
17120 }
17121}
17122
17123
17124static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17125{
17126 struct alc_spec *spec = codec->spec;
17127 hda_nid_t pin;
17128
17129 pin = spec->autocfg.hp_pins[0];
def319f9 17130 if (pin) /* connect to front and use dac 0 */
f32610ed 17131 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17132 pin = spec->autocfg.speaker_pins[0];
17133 if (pin)
17134 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17135}
17136
f32610ed
JS
17137#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17138
17139static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17140{
17141 struct alc_spec *spec = codec->spec;
66ceeb6b 17142 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17143 int i;
17144
66ceeb6b
TI
17145 for (i = 0; i < cfg->num_inputs; i++) {
17146 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17147 if (alc_is_input_pin(codec, nid)) {
30ea098f 17148 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17149 if (nid != ALC861VD_PIN_CD_NID &&
17150 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17151 snd_hda_codec_write(codec, nid, 0,
17152 AC_VERB_SET_AMP_GAIN_MUTE,
17153 AMP_OUT_MUTE);
17154 }
17155 }
17156}
17157
f511b01c
TI
17158#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17159
f32610ed
JS
17160#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17161#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17162
17163/* add playback controls from the parsed DAC table */
569ed348 17164/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17165 * different NIDs for mute/unmute switch and volume control */
17166static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17167 const struct auto_pin_cfg *cfg)
17168{
ea734963
TI
17169 static const char * const chname[4] = {
17170 "Front", "Surround", "CLFE", "Side"
17171 };
ce764ab2 17172 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17173 hda_nid_t nid_v, nid_s;
ce764ab2 17174 int i, err, noutputs;
f32610ed 17175
ce764ab2
TI
17176 noutputs = cfg->line_outs;
17177 if (spec->multi_ios > 0)
17178 noutputs += spec->multi_ios;
17179
17180 for (i = 0; i < noutputs; i++) {
f12ab1e0 17181 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17182 continue;
17183 nid_v = alc861vd_idx_to_mixer_vol(
17184 alc880_dac_to_idx(
17185 spec->multiout.dac_nids[i]));
17186 nid_s = alc861vd_idx_to_mixer_switch(
17187 alc880_dac_to_idx(
17188 spec->multiout.dac_nids[i]));
17189
bcb2f0f5 17190 if (!pfx && i == 2) {
f32610ed 17191 /* Center/LFE */
0afe5f89
TI
17192 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17193 "Center",
f12ab1e0
TI
17194 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17195 HDA_OUTPUT));
17196 if (err < 0)
f32610ed 17197 return err;
0afe5f89
TI
17198 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17199 "LFE",
f12ab1e0
TI
17200 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17201 HDA_OUTPUT));
17202 if (err < 0)
f32610ed 17203 return err;
0afe5f89
TI
17204 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17205 "Center",
f12ab1e0
TI
17206 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17207 HDA_INPUT));
17208 if (err < 0)
f32610ed 17209 return err;
0afe5f89
TI
17210 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17211 "LFE",
f12ab1e0
TI
17212 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17213 HDA_INPUT));
17214 if (err < 0)
f32610ed
JS
17215 return err;
17216 } else {
bcb2f0f5 17217 const char *name = pfx;
5a882646
DH
17218 int index = i;
17219 if (!name) {
bcb2f0f5 17220 name = chname[i];
5a882646
DH
17221 index = 0;
17222 }
bcb2f0f5 17223 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17224 name, index,
f12ab1e0
TI
17225 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17226 HDA_OUTPUT));
17227 if (err < 0)
f32610ed 17228 return err;
bcb2f0f5 17229 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17230 name, index,
bdd148a3 17231 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17232 HDA_INPUT));
17233 if (err < 0)
f32610ed
JS
17234 return err;
17235 }
17236 }
17237 return 0;
17238}
17239
17240/* add playback controls for speaker and HP outputs */
17241/* Based on ALC880 version. But ALC861VD has separate,
17242 * different NIDs for mute/unmute switch and volume control */
17243static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17244 hda_nid_t pin, const char *pfx)
17245{
17246 hda_nid_t nid_v, nid_s;
17247 int err;
f32610ed 17248
f12ab1e0 17249 if (!pin)
f32610ed
JS
17250 return 0;
17251
17252 if (alc880_is_fixed_pin(pin)) {
17253 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17254 /* specify the DAC as the extra output */
f12ab1e0 17255 if (!spec->multiout.hp_nid)
f32610ed
JS
17256 spec->multiout.hp_nid = nid_v;
17257 else
17258 spec->multiout.extra_out_nid[0] = nid_v;
17259 /* control HP volume/switch on the output mixer amp */
17260 nid_v = alc861vd_idx_to_mixer_vol(
17261 alc880_fixed_pin_idx(pin));
17262 nid_s = alc861vd_idx_to_mixer_switch(
17263 alc880_fixed_pin_idx(pin));
17264
0afe5f89 17265 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17266 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17267 if (err < 0)
f32610ed 17268 return err;
0afe5f89 17269 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17270 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17271 if (err < 0)
f32610ed
JS
17272 return err;
17273 } else if (alc880_is_multi_pin(pin)) {
17274 /* set manual connection */
17275 /* we have only a switch on HP-out PIN */
0afe5f89 17276 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17277 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17278 if (err < 0)
f32610ed
JS
17279 return err;
17280 }
17281 return 0;
17282}
17283
17284/* parse the BIOS configuration and set up the alc_spec
17285 * return 1 if successful, 0 if the proper config is not found,
17286 * or a negative error code
17287 * Based on ALC880 version - had to change it to override
17288 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17289static int alc861vd_parse_auto_config(struct hda_codec *codec)
17290{
17291 struct alc_spec *spec = codec->spec;
17292 int err;
4c6d72d1 17293 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17294
f12ab1e0
TI
17295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17296 alc861vd_ignore);
17297 if (err < 0)
f32610ed 17298 return err;
f12ab1e0 17299 if (!spec->autocfg.line_outs)
f32610ed
JS
17300 return 0; /* can't find valid BIOS pin config */
17301
f12ab1e0 17302 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17303 if (err < 0)
17304 return err;
17305 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17306 if (err < 0)
17307 return err;
17308 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17309 if (err < 0)
17310 return err;
17311 err = alc861vd_auto_create_extra_out(spec,
17312 spec->autocfg.speaker_pins[0],
17313 "Speaker");
17314 if (err < 0)
17315 return err;
17316 err = alc861vd_auto_create_extra_out(spec,
17317 spec->autocfg.hp_pins[0],
17318 "Headphone");
17319 if (err < 0)
17320 return err;
05f5f477 17321 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17322 if (err < 0)
f32610ed
JS
17323 return err;
17324
17325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17326
757899ac 17327 alc_auto_parse_digital(codec);
f32610ed 17328
603c4019 17329 if (spec->kctls.list)
d88897ea 17330 add_mixer(spec, spec->kctls.list);
f32610ed 17331
d88897ea 17332 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17333
17334 spec->num_mux_defs = 1;
61b9b9b1 17335 spec->input_mux = &spec->private_imux[0];
f32610ed 17336
776e184e
TI
17337 err = alc_auto_add_mic_boost(codec);
17338 if (err < 0)
17339 return err;
17340
6227cdce 17341 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17342
f32610ed
JS
17343 return 1;
17344}
17345
17346/* additional initialization for auto-configuration model */
17347static void alc861vd_auto_init(struct hda_codec *codec)
17348{
f6c7e546 17349 struct alc_spec *spec = codec->spec;
f32610ed
JS
17350 alc861vd_auto_init_multi_out(codec);
17351 alc861vd_auto_init_hp_out(codec);
17352 alc861vd_auto_init_analog_input(codec);
f511b01c 17353 alc861vd_auto_init_input_src(codec);
757899ac 17354 alc_auto_init_digital(codec);
f6c7e546 17355 if (spec->unsol_event)
7fb0d78f 17356 alc_inithook(codec);
f32610ed
JS
17357}
17358
f8f25ba3
TI
17359enum {
17360 ALC660VD_FIX_ASUS_GPIO1
17361};
17362
17363/* reset GPIO1 */
f8f25ba3
TI
17364static const struct alc_fixup alc861vd_fixups[] = {
17365 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17366 .type = ALC_FIXUP_VERBS,
17367 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17368 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17369 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17370 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17371 { }
17372 }
f8f25ba3
TI
17373 },
17374};
17375
a9111321 17376static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17377 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17378 {}
17379};
17380
f32610ed
JS
17381static int patch_alc861vd(struct hda_codec *codec)
17382{
17383 struct alc_spec *spec;
17384 int err, board_config;
17385
17386 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17387 if (spec == NULL)
17388 return -ENOMEM;
17389
17390 codec->spec = spec;
17391
17392 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17393 alc861vd_models,
17394 alc861vd_cfg_tbl);
17395
17396 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17397 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17398 codec->chip_name);
f32610ed
JS
17399 board_config = ALC861VD_AUTO;
17400 }
17401
b5bfbc67
TI
17402 if (board_config == ALC861VD_AUTO) {
17403 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17404 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17405 }
f8f25ba3 17406
f32610ed
JS
17407 if (board_config == ALC861VD_AUTO) {
17408 /* automatic parse from the BIOS config */
17409 err = alc861vd_parse_auto_config(codec);
17410 if (err < 0) {
17411 alc_free(codec);
17412 return err;
f12ab1e0 17413 } else if (!err) {
f32610ed
JS
17414 printk(KERN_INFO
17415 "hda_codec: Cannot set up configuration "
17416 "from BIOS. Using base mode...\n");
17417 board_config = ALC861VD_3ST;
17418 }
17419 }
17420
680cd536
KK
17421 err = snd_hda_attach_beep_device(codec, 0x23);
17422 if (err < 0) {
17423 alc_free(codec);
17424 return err;
17425 }
17426
f32610ed 17427 if (board_config != ALC861VD_AUTO)
e9c364c0 17428 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17429
2f893286 17430 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17431 /* always turn on EAPD */
d88897ea 17432 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17433 }
17434
f32610ed
JS
17435 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17436 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17437
f32610ed
JS
17438 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17439 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17440
dd704698
TI
17441 if (!spec->adc_nids) {
17442 spec->adc_nids = alc861vd_adc_nids;
17443 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17444 }
17445 if (!spec->capsrc_nids)
17446 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17447
b59bdf3b 17448 set_capture_mixer(codec);
45bdd1c1 17449 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17450
2134ea4f
TI
17451 spec->vmaster_nid = 0x02;
17452
b5bfbc67 17453 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17454
f32610ed
JS
17455 codec->patch_ops = alc_patch_ops;
17456
17457 if (board_config == ALC861VD_AUTO)
17458 spec->init_hook = alc861vd_auto_init;
1c716153 17459 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17460#ifdef CONFIG_SND_HDA_POWER_SAVE
17461 if (!spec->loopback.amplist)
17462 spec->loopback.amplist = alc861vd_loopbacks;
17463#endif
f32610ed
JS
17464
17465 return 0;
17466}
17467
bc9f98a9
KY
17468/*
17469 * ALC662 support
17470 *
17471 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17472 * configuration. Each pin widget can choose any input DACs and a mixer.
17473 * Each ADC is connected from a mixer of all inputs. This makes possible
17474 * 6-channel independent captures.
17475 *
17476 * In addition, an independent DAC for the multi-playback (not used in this
17477 * driver yet).
17478 */
17479#define ALC662_DIGOUT_NID 0x06
17480#define ALC662_DIGIN_NID 0x0a
17481
4c6d72d1 17482static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17483 /* front, rear, clfe */
bc9f98a9
KY
17484 0x02, 0x03, 0x04
17485};
17486
4c6d72d1 17487static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17488 0x02, 0x03
17489};
17490
4c6d72d1 17491static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17492 /* ADC1-2 */
b59bdf3b 17493 0x09, 0x08
bc9f98a9 17494};
e1406348 17495
4c6d72d1 17496static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17497 /* ADC1-2 */
17498 0x08,
17499};
17500
4c6d72d1
TI
17501static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17502static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17503
e1406348 17504
bc9f98a9
KY
17505/* input MUX */
17506/* FIXME: should be a matrix-type input source selection */
a9111321 17507static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17508 .num_items = 4,
17509 .items = {
17510 { "Mic", 0x0 },
17511 { "Front Mic", 0x1 },
17512 { "Line", 0x2 },
17513 { "CD", 0x4 },
17514 },
17515};
17516
a9111321 17517static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17518 .num_items = 2,
17519 .items = {
17520 { "Mic", 0x1 },
17521 { "Line", 0x2 },
17522 },
17523};
291702f0 17524
a9111321 17525static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17526 .num_items = 3,
17527 .items = {
17528 { "Mic", 0x0 },
17529 { "Front Mic", 0x1 },
17530 { "Line", 0x2 },
17531 },
17532};
17533
4f5d1706 17534#if 0 /* set to 1 for testing other input sources below */
a9111321 17535static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17536 .num_items = 16,
17537 .items = {
17538 { "Autoselect Mic", 0x0 },
17539 { "Internal Mic", 0x1 },
17540 { "In-0x02", 0x2 },
17541 { "In-0x03", 0x3 },
17542 { "In-0x04", 0x4 },
17543 { "In-0x05", 0x5 },
17544 { "In-0x06", 0x6 },
17545 { "In-0x07", 0x7 },
17546 { "In-0x08", 0x8 },
17547 { "In-0x09", 0x9 },
17548 { "In-0x0a", 0x0a },
17549 { "In-0x0b", 0x0b },
17550 { "In-0x0c", 0x0c },
17551 { "In-0x0d", 0x0d },
17552 { "In-0x0e", 0x0e },
17553 { "In-0x0f", 0x0f },
17554 },
17555};
17556#endif
17557
bc9f98a9
KY
17558/*
17559 * 2ch mode
17560 */
a9111321 17561static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17562 { 2, NULL }
17563};
17564
17565/*
17566 * 2ch mode
17567 */
a9111321 17568static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17573 { } /* end */
17574};
17575
17576/*
17577 * 6ch mode
17578 */
a9111321 17579static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17580 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17581 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17582 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17583 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17585 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17586 { } /* end */
17587};
17588
a9111321 17589static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17590 { 2, alc662_3ST_ch2_init },
17591 { 6, alc662_3ST_ch6_init },
17592};
17593
17594/*
17595 * 2ch mode
17596 */
a9111321 17597static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17598 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17599 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17600 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17601 { } /* end */
17602};
17603
17604/*
17605 * 6ch mode
17606 */
a9111321 17607static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17608 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17611 { } /* end */
17612};
17613
a9111321 17614static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17615 { 2, alc662_sixstack_ch6_init },
17616 { 6, alc662_sixstack_ch8_init },
17617};
17618
17619/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17620 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17621 */
17622
a9111321 17623static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17624 /* output mixer control */
17625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17626 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17628 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17631 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634
17635 /*Input mixer control */
17636 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17637 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17639 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17644 { } /* end */
17645};
17646
a9111321 17647static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17648 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17649 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17659 { } /* end */
17660};
17661
a9111321 17662static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17666 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17669 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17680 { } /* end */
17681};
17682
a9111321 17683static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17685 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17686 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17687 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17693 { } /* end */
17694};
17695
a9111321 17696static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17697 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17698 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17699
5f99f86a 17700 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17703
5f99f86a 17704 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17707 { } /* end */
17708};
17709
a9111321 17710static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17711 ALC262_HIPPO_MASTER_SWITCH,
17712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17716 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17721 { } /* end */
17722};
17723
a9111321 17724static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17725 .ops = &snd_hda_bind_vol,
17726 .values = {
17727 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17728 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17729 0
17730 },
17731};
17732
a9111321 17733static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17734 .ops = &snd_hda_bind_sw,
17735 .values = {
17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17738 0
17739 },
17740};
17741
a9111321 17742static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17747 { } /* end */
17748};
17749
a9111321 17750static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17751 .ops = &snd_hda_bind_sw,
17752 .values = {
17753 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17754 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17755 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17756 0
17757 },
17758};
17759
a9111321 17760static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17761 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17762 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17765 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17766 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17767
17768 { } /* end */
17769};
17770
a9111321 17771static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17772 .ops = &snd_hda_bind_sw,
17773 .values = {
17774 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17775 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17777 0
17778 },
17779};
17780
a9111321 17781static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17782 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17783 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17786 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17787 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17788 { } /* end */
17789};
17790
a9111321 17791static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17798 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17799 { } /* end */
17800};
17801
a9111321 17802static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17803 .ops = &snd_hda_bind_vol,
17804 .values = {
17805 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17807 0
17808 },
17809};
17810
a9111321 17811static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17812 .ops = &snd_hda_bind_sw,
17813 .values = {
17814 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17815 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17816 0
17817 },
17818};
17819
a9111321 17820static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17821 HDA_BIND_VOL("Master Playback Volume",
17822 &alc663_asus_two_bind_master_vol),
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17828 { } /* end */
17829};
17830
a9111321 17831static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17832 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17833 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17838 { } /* end */
17839};
17840
a9111321 17841static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17843 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17845 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17847
17848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17850 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17852 { } /* end */
17853};
17854
a9111321 17855static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17859
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17866 { } /* end */
17867};
17868
a9111321 17869static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17870 .ops = &snd_hda_bind_sw,
17871 .values = {
17872 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17873 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17874 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17875 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17876 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17877 0
17878 },
17879};
17880
a9111321 17881static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17882 .ops = &snd_hda_bind_sw,
17883 .values = {
17884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17885 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17886 0
17887 },
17888};
17889
a9111321 17890static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17891 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17892 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17893 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17894 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17895 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17896 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17897 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17900 { } /* end */
17901};
17902
a9111321 17903static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17904 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17905 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17906 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17907 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17908 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17911 { } /* end */
17912};
17913
17914
a9111321 17915static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17916 {
17917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17918 .name = "Channel Mode",
17919 .info = alc_ch_mode_info,
17920 .get = alc_ch_mode_get,
17921 .put = alc_ch_mode_put,
17922 },
17923 { } /* end */
17924};
17925
a9111321 17926static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17927 /* ADC: mute amp left and right */
17928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17930
b60dd394
KY
17931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17937
17938 /* Front Pin: output 0 (0x0c) */
17939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941
17942 /* Rear Pin: output 1 (0x0d) */
17943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945
17946 /* CLFE Pin: output 2 (0x0e) */
17947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949
17950 /* Mic (rear) pin: input vref at 80% */
17951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17953 /* Front Mic pin: input vref at 80% */
17954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17956 /* Line In pin: input */
17957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17963 /* CD pin widget for input */
17964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17965
17966 /* FIXME: use matrix-type input source selection */
17967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17968 /* Input mixer */
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17971
a7f2371f
TI
17972 { }
17973};
17974
a9111321 17975static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17976 /* always trun on EAPD */
17977 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17978 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17979 { }
17980};
17981
a9111321 17982static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17985 {}
17986};
17987
a9111321 17988static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
bc9f98a9
KY
17992};
17993
8c427226 17994/* Set Unsolicited Event*/
a9111321 17995static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17998 {}
17999};
18000
a9111321 18001static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
18004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
18006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18010 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18011 {}
18012};
18013
a9111321 18014static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
18015 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {}
18023};
18024
a9111321 18025static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18032 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18033 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 {}
18035};
6dda9f4a 18036
a9111321 18037static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
18038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18045 {}
18046};
6dda9f4a 18047
a9111321 18048static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18055 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18059 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18060 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {}
18062};
18063
a9111321 18064static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18076 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18077 {}
18078};
18079
a9111321 18080static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
18081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18083 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18084
18085 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18086 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18087 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18088
18089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18090 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18091 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18092 {}
18093};
18094
a9111321 18095static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
18096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18099
18100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18102 {}
18103};
18104
a9111321 18105static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
18106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111};
18112
a9111321 18113static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18119 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126};
18127
a9111321 18128static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
18129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18134 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18135 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18138 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18139 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18140 {}
18141};
18142
a9111321 18143static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18156 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18159 {}
18160};
18161
a9111321 18162static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
18163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18168 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18170 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18171 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18172 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18173 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18177 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18178 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179 {}
18180};
18181
a9111321 18182static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
18183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18185 { } /* end */
18186};
18187
a9111321 18188static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
18189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18191 { } /* end */
18192};
18193
e6a5e1b7 18194static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18195{
e6a5e1b7 18196 struct alc_spec *spec = codec->spec;
bc9f98a9 18197
e6a5e1b7
TI
18198 spec->autocfg.hp_pins[0] = 0x1b;
18199 spec->autocfg.line_out_pins[0] = 0x14;
18200 spec->autocfg.speaker_pins[0] = 0x15;
18201 spec->automute = 1;
18202 spec->detect_line = 1;
18203 spec->automute_lines = 1;
18204 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18205}
18206
4f5d1706
TI
18207static void alc662_eeepc_setup(struct hda_codec *codec)
18208{
18209 struct alc_spec *spec = codec->spec;
18210
18211 alc262_hippo1_setup(codec);
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217}
18218
4f5d1706 18219static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18220{
42171c17
TI
18221 struct alc_spec *spec = codec->spec;
18222
18223 spec->autocfg.hp_pins[0] = 0x14;
18224 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18225 spec->automute = 1;
18226 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18227}
18228
4f5d1706
TI
18229static void alc663_m51va_setup(struct hda_codec *codec)
18230{
18231 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18232 spec->autocfg.hp_pins[0] = 0x21;
18233 spec->autocfg.speaker_pins[0] = 0x14;
18234 spec->automute_mixer_nid[0] = 0x0c;
18235 spec->automute = 1;
18236 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18237 spec->ext_mic.pin = 0x18;
18238 spec->ext_mic.mux_idx = 0;
18239 spec->int_mic.pin = 0x12;
ebb83eeb 18240 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18241 spec->auto_mic = 1;
18242}
18243
f1d4e28b 18244/* ***************** Mode1 ******************************/
ebb83eeb
KY
18245static void alc663_mode1_setup(struct hda_codec *codec)
18246{
18247 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18248 spec->autocfg.hp_pins[0] = 0x21;
18249 spec->autocfg.speaker_pins[0] = 0x14;
18250 spec->automute_mixer_nid[0] = 0x0c;
18251 spec->automute = 1;
18252 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18253 spec->ext_mic.pin = 0x18;
18254 spec->ext_mic.mux_idx = 0;
18255 spec->int_mic.pin = 0x19;
18256 spec->int_mic.mux_idx = 1;
18257 spec->auto_mic = 1;
18258}
18259
f1d4e28b 18260/* ***************** Mode2 ******************************/
3b8510ce 18261static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18262{
3b8510ce
TI
18263 struct alc_spec *spec = codec->spec;
18264 spec->autocfg.hp_pins[0] = 0x1b;
18265 spec->autocfg.speaker_pins[0] = 0x14;
18266 spec->automute = 1;
18267 spec->automute_mode = ALC_AUTOMUTE_PIN;
18268 spec->ext_mic.pin = 0x18;
18269 spec->ext_mic.mux_idx = 0;
18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
f1d4e28b
KY
18273}
18274
f1d4e28b 18275/* ***************** Mode3 ******************************/
3b8510ce 18276static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18277{
3b8510ce
TI
18278 struct alc_spec *spec = codec->spec;
18279 spec->autocfg.hp_pins[0] = 0x21;
18280 spec->autocfg.hp_pins[0] = 0x15;
18281 spec->autocfg.speaker_pins[0] = 0x14;
18282 spec->automute = 1;
18283 spec->automute_mode = ALC_AUTOMUTE_PIN;
18284 spec->ext_mic.pin = 0x18;
18285 spec->ext_mic.mux_idx = 0;
18286 spec->int_mic.pin = 0x19;
18287 spec->int_mic.mux_idx = 1;
18288 spec->auto_mic = 1;
f1d4e28b
KY
18289}
18290
f1d4e28b 18291/* ***************** Mode4 ******************************/
3b8510ce 18292static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18293{
3b8510ce
TI
18294 struct alc_spec *spec = codec->spec;
18295 spec->autocfg.hp_pins[0] = 0x21;
18296 spec->autocfg.speaker_pins[0] = 0x14;
18297 spec->autocfg.speaker_pins[1] = 0x16;
18298 spec->automute_mixer_nid[0] = 0x0c;
18299 spec->automute_mixer_nid[1] = 0x0e;
18300 spec->automute = 1;
18301 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
f1d4e28b
KY
18307}
18308
f1d4e28b 18309/* ***************** Mode5 ******************************/
3b8510ce 18310static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18311{
3b8510ce
TI
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x15;
18314 spec->autocfg.speaker_pins[0] = 0x14;
18315 spec->autocfg.speaker_pins[1] = 0x16;
18316 spec->automute_mixer_nid[0] = 0x0c;
18317 spec->automute_mixer_nid[1] = 0x0e;
18318 spec->automute = 1;
18319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x19;
18323 spec->int_mic.mux_idx = 1;
18324 spec->auto_mic = 1;
f1d4e28b
KY
18325}
18326
f1d4e28b 18327/* ***************** Mode6 ******************************/
3b8510ce 18328static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18329{
3b8510ce
TI
18330 struct alc_spec *spec = codec->spec;
18331 spec->autocfg.hp_pins[0] = 0x1b;
18332 spec->autocfg.hp_pins[0] = 0x15;
18333 spec->autocfg.speaker_pins[0] = 0x14;
18334 spec->automute_mixer_nid[0] = 0x0c;
18335 spec->automute = 1;
18336 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18337 spec->ext_mic.pin = 0x18;
18338 spec->ext_mic.mux_idx = 0;
18339 spec->int_mic.pin = 0x19;
18340 spec->int_mic.mux_idx = 1;
18341 spec->auto_mic = 1;
f1d4e28b
KY
18342}
18343
ebb83eeb 18344/* ***************** Mode7 ******************************/
3b8510ce 18345static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18346{
3b8510ce
TI
18347 struct alc_spec *spec = codec->spec;
18348 spec->autocfg.hp_pins[0] = 0x1b;
18349 spec->autocfg.hp_pins[0] = 0x21;
18350 spec->autocfg.speaker_pins[0] = 0x14;
18351 spec->autocfg.speaker_pins[0] = 0x17;
18352 spec->automute = 1;
18353 spec->automute_mode = ALC_AUTOMUTE_PIN;
18354 spec->ext_mic.pin = 0x18;
18355 spec->ext_mic.mux_idx = 0;
18356 spec->int_mic.pin = 0x19;
18357 spec->int_mic.mux_idx = 1;
18358 spec->auto_mic = 1;
ebb83eeb
KY
18359}
18360
18361/* ***************** Mode8 ******************************/
3b8510ce 18362static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18363{
3b8510ce
TI
18364 struct alc_spec *spec = codec->spec;
18365 spec->autocfg.hp_pins[0] = 0x21;
18366 spec->autocfg.hp_pins[1] = 0x15;
18367 spec->autocfg.speaker_pins[0] = 0x14;
18368 spec->autocfg.speaker_pins[0] = 0x17;
18369 spec->automute = 1;
18370 spec->automute_mode = ALC_AUTOMUTE_PIN;
18371 spec->ext_mic.pin = 0x18;
18372 spec->ext_mic.mux_idx = 0;
18373 spec->int_mic.pin = 0x12;
18374 spec->int_mic.mux_idx = 9;
18375 spec->auto_mic = 1;
ebb83eeb
KY
18376}
18377
e6a5e1b7 18378static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18379{
e6a5e1b7
TI
18380 struct alc_spec *spec = codec->spec;
18381 spec->autocfg.hp_pins[0] = 0x21;
18382 spec->autocfg.line_out_pins[0] = 0x15;
18383 spec->autocfg.speaker_pins[0] = 0x14;
18384 spec->automute = 1;
18385 spec->automute_mode = ALC_AUTOMUTE_AMP;
18386 spec->detect_line = 1;
18387 spec->automute_lines = 1;
18388 spec->ext_mic.pin = 0x18;
18389 spec->ext_mic.mux_idx = 0;
18390 spec->int_mic.pin = 0x12;
18391 spec->int_mic.mux_idx = 9;
18392 spec->auto_mic = 1;
6dda9f4a
KY
18393}
18394
4f5d1706
TI
18395#define alc663_g50v_setup alc663_m51va_setup
18396
a9111321 18397static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18398 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18399 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18400
5f99f86a 18401 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18402 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18403 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18404
5f99f86a 18405 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18408 { } /* end */
18409};
18410
a9111321 18411static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18412 /* Master Playback automatically created from Speaker and Headphone */
18413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18416 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18417
8607f7c4
DH
18418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18420 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18421
28c4edb7
DH
18422 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18423 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18424 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18425 { } /* end */
18426};
18427
cb53c626
TI
18428#ifdef CONFIG_SND_HDA_POWER_SAVE
18429#define alc662_loopbacks alc880_loopbacks
18430#endif
18431
bc9f98a9 18432
def319f9 18433/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18434#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18435#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18436#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18437#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18438
18439/*
18440 * configuration and preset
18441 */
ea734963 18442static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18443 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18444 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18445 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18446 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18447 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18448 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18449 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18450 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18451 [ALC663_ASUS_M51VA] = "m51va",
18452 [ALC663_ASUS_G71V] = "g71v",
18453 [ALC663_ASUS_H13] = "h13",
18454 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18455 [ALC663_ASUS_MODE1] = "asus-mode1",
18456 [ALC662_ASUS_MODE2] = "asus-mode2",
18457 [ALC663_ASUS_MODE3] = "asus-mode3",
18458 [ALC663_ASUS_MODE4] = "asus-mode4",
18459 [ALC663_ASUS_MODE5] = "asus-mode5",
18460 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18461 [ALC663_ASUS_MODE7] = "asus-mode7",
18462 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18463 [ALC272_DELL] = "dell",
18464 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18465 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18466 [ALC662_AUTO] = "auto",
18467};
18468
a9111321 18469static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18470 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18471 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18472 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18473 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18474 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18475 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18476 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18477 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18478 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18479 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18480 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18481 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18482 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18483 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18484 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18485 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18486 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18487 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18488 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18489 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18490 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18491 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18492 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18493 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18494 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18495 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18496 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18497 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18498 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18499 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18500 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18501 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18502 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18503 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18504 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18505 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18506 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18507 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18508 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18509 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18510 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18511 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18512 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18513 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18514 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18515 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18516 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18517 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18518 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18519 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18520 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18521 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18522 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18523 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18524 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18526 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18527 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18528 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18529 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18530 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18531 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18532 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18533 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18534 ALC662_3ST_6ch_DIG),
4dee8baa 18535 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18536 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18537 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18538 ALC662_3ST_6ch_DIG),
6227cdce 18539 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18540 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18541 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18542 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18543 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18544 ALC662_3ST_6ch_DIG),
dea0a509
TI
18545 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18546 ALC663_ASUS_H13),
965b76d2 18547 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18548 {}
18549};
18550
a9111321 18551static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18552 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18553 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18554 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18556 .dac_nids = alc662_dac_nids,
18557 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18558 .dig_in_nid = ALC662_DIGIN_NID,
18559 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18560 .channel_mode = alc662_3ST_2ch_modes,
18561 .input_mux = &alc662_capture_source,
18562 },
18563 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18564 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18565 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18567 .dac_nids = alc662_dac_nids,
18568 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18569 .dig_in_nid = ALC662_DIGIN_NID,
18570 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18571 .channel_mode = alc662_3ST_6ch_modes,
18572 .need_dac_fix = 1,
18573 .input_mux = &alc662_capture_source,
f12ab1e0 18574 },
bc9f98a9 18575 [ALC662_3ST_6ch] = {
f9e336f6 18576 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18577 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18579 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18581 .channel_mode = alc662_3ST_6ch_modes,
18582 .need_dac_fix = 1,
18583 .input_mux = &alc662_capture_source,
f12ab1e0 18584 },
bc9f98a9 18585 [ALC662_5ST_DIG] = {
f9e336f6 18586 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18587 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18589 .dac_nids = alc662_dac_nids,
18590 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18591 .dig_in_nid = ALC662_DIGIN_NID,
18592 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18593 .channel_mode = alc662_5stack_modes,
18594 .input_mux = &alc662_capture_source,
18595 },
18596 [ALC662_LENOVO_101E] = {
f9e336f6 18597 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18598 .init_verbs = { alc662_init_verbs,
18599 alc662_eapd_init_verbs,
18600 alc662_sue_init_verbs },
bc9f98a9
KY
18601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18602 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18604 .channel_mode = alc662_3ST_2ch_modes,
18605 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18606 .unsol_event = alc_sku_unsol_event,
18607 .setup = alc662_lenovo_101e_setup,
18608 .init_hook = alc_inithook,
bc9f98a9 18609 },
291702f0 18610 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18611 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18612 .init_verbs = { alc662_init_verbs,
a7f2371f 18613 alc662_eapd_init_verbs,
291702f0
KY
18614 alc662_eeepc_sue_init_verbs },
18615 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18616 .dac_nids = alc662_dac_nids,
291702f0
KY
18617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18618 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18619 .unsol_event = alc_sku_unsol_event,
4f5d1706 18620 .setup = alc662_eeepc_setup,
e9427969 18621 .init_hook = alc_inithook,
291702f0 18622 },
8c427226 18623 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18624 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18625 alc662_chmode_mixer },
18626 .init_verbs = { alc662_init_verbs,
a7f2371f 18627 alc662_eapd_init_verbs,
8c427226
KY
18628 alc662_eeepc_ep20_sue_init_verbs },
18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630 .dac_nids = alc662_dac_nids,
8c427226
KY
18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18632 .channel_mode = alc662_3ST_6ch_modes,
18633 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18634 .unsol_event = alc_sku_unsol_event,
4f5d1706 18635 .setup = alc662_eeepc_ep20_setup,
e9427969 18636 .init_hook = alc_inithook,
8c427226 18637 },
f1d4e28b 18638 [ALC662_ECS] = {
f9e336f6 18639 .mixers = { alc662_ecs_mixer },
f1d4e28b 18640 .init_verbs = { alc662_init_verbs,
a7f2371f 18641 alc662_eapd_init_verbs,
f1d4e28b
KY
18642 alc662_ecs_init_verbs },
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .dac_nids = alc662_dac_nids,
18645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18646 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18647 .unsol_event = alc_sku_unsol_event,
4f5d1706 18648 .setup = alc662_eeepc_setup,
e9427969 18649 .init_hook = alc_inithook,
f1d4e28b 18650 },
6dda9f4a 18651 [ALC663_ASUS_M51VA] = {
f9e336f6 18652 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18653 .init_verbs = { alc662_init_verbs,
18654 alc662_eapd_init_verbs,
18655 alc663_m51va_init_verbs },
6dda9f4a
KY
18656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18657 .dac_nids = alc662_dac_nids,
18658 .dig_out_nid = ALC662_DIGOUT_NID,
18659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18660 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18661 .unsol_event = alc_sku_unsol_event,
4f5d1706 18662 .setup = alc663_m51va_setup,
3b8510ce 18663 .init_hook = alc_inithook,
6dda9f4a
KY
18664 },
18665 [ALC663_ASUS_G71V] = {
f9e336f6 18666 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18667 .init_verbs = { alc662_init_verbs,
18668 alc662_eapd_init_verbs,
18669 alc663_g71v_init_verbs },
6dda9f4a
KY
18670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18671 .dac_nids = alc662_dac_nids,
18672 .dig_out_nid = ALC662_DIGOUT_NID,
18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18675 .unsol_event = alc_sku_unsol_event,
4f5d1706 18676 .setup = alc663_g71v_setup,
e6a5e1b7 18677 .init_hook = alc_inithook,
6dda9f4a
KY
18678 },
18679 [ALC663_ASUS_H13] = {
f9e336f6 18680 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18681 .init_verbs = { alc662_init_verbs,
18682 alc662_eapd_init_verbs,
18683 alc663_m51va_init_verbs },
6dda9f4a
KY
18684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18685 .dac_nids = alc662_dac_nids,
18686 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18687 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18688 .setup = alc663_m51va_setup,
18689 .unsol_event = alc_sku_unsol_event,
18690 .init_hook = alc_inithook,
6dda9f4a
KY
18691 },
18692 [ALC663_ASUS_G50V] = {
f9e336f6 18693 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18694 .init_verbs = { alc662_init_verbs,
18695 alc662_eapd_init_verbs,
18696 alc663_g50v_init_verbs },
6dda9f4a
KY
18697 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18698 .dac_nids = alc662_dac_nids,
18699 .dig_out_nid = ALC662_DIGOUT_NID,
18700 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18701 .channel_mode = alc662_3ST_6ch_modes,
18702 .input_mux = &alc663_capture_source,
3b8510ce 18703 .unsol_event = alc_sku_unsol_event,
4f5d1706 18704 .setup = alc663_g50v_setup,
3b8510ce 18705 .init_hook = alc_inithook,
6dda9f4a 18706 },
f1d4e28b 18707 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18708 .mixers = { alc663_m51va_mixer },
18709 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18710 .init_verbs = { alc662_init_verbs,
a7f2371f 18711 alc662_eapd_init_verbs,
f1d4e28b
KY
18712 alc663_21jd_amic_init_verbs },
18713 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18714 .hp_nid = 0x03,
18715 .dac_nids = alc662_dac_nids,
18716 .dig_out_nid = ALC662_DIGOUT_NID,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18719 .unsol_event = alc_sku_unsol_event,
4f5d1706 18720 .setup = alc663_mode1_setup,
3b8510ce 18721 .init_hook = alc_inithook,
f1d4e28b
KY
18722 },
18723 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18724 .mixers = { alc662_1bjd_mixer },
18725 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18726 .init_verbs = { alc662_init_verbs,
a7f2371f 18727 alc662_eapd_init_verbs,
f1d4e28b
KY
18728 alc662_1bjd_amic_init_verbs },
18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18730 .dac_nids = alc662_dac_nids,
18731 .dig_out_nid = ALC662_DIGOUT_NID,
18732 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18733 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18734 .unsol_event = alc_sku_unsol_event,
4f5d1706 18735 .setup = alc662_mode2_setup,
3b8510ce 18736 .init_hook = alc_inithook,
f1d4e28b
KY
18737 },
18738 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18739 .mixers = { alc663_two_hp_m1_mixer },
18740 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18741 .init_verbs = { alc662_init_verbs,
a7f2371f 18742 alc662_eapd_init_verbs,
f1d4e28b
KY
18743 alc663_two_hp_amic_m1_init_verbs },
18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18745 .hp_nid = 0x03,
18746 .dac_nids = alc662_dac_nids,
18747 .dig_out_nid = ALC662_DIGOUT_NID,
18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18749 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18750 .unsol_event = alc_sku_unsol_event,
4f5d1706 18751 .setup = alc663_mode3_setup,
3b8510ce 18752 .init_hook = alc_inithook,
f1d4e28b
KY
18753 },
18754 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18755 .mixers = { alc663_asus_21jd_clfe_mixer },
18756 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18757 .init_verbs = { alc662_init_verbs,
a7f2371f 18758 alc662_eapd_init_verbs,
f1d4e28b
KY
18759 alc663_21jd_amic_init_verbs},
18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18761 .hp_nid = 0x03,
18762 .dac_nids = alc662_dac_nids,
18763 .dig_out_nid = ALC662_DIGOUT_NID,
18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18765 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18766 .unsol_event = alc_sku_unsol_event,
4f5d1706 18767 .setup = alc663_mode4_setup,
3b8510ce 18768 .init_hook = alc_inithook,
f1d4e28b
KY
18769 },
18770 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18771 .mixers = { alc663_asus_15jd_clfe_mixer },
18772 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18773 .init_verbs = { alc662_init_verbs,
a7f2371f 18774 alc662_eapd_init_verbs,
f1d4e28b
KY
18775 alc663_15jd_amic_init_verbs },
18776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18777 .hp_nid = 0x03,
18778 .dac_nids = alc662_dac_nids,
18779 .dig_out_nid = ALC662_DIGOUT_NID,
18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18781 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18782 .unsol_event = alc_sku_unsol_event,
4f5d1706 18783 .setup = alc663_mode5_setup,
3b8510ce 18784 .init_hook = alc_inithook,
f1d4e28b
KY
18785 },
18786 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18787 .mixers = { alc663_two_hp_m2_mixer },
18788 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18789 .init_verbs = { alc662_init_verbs,
a7f2371f 18790 alc662_eapd_init_verbs,
f1d4e28b
KY
18791 alc663_two_hp_amic_m2_init_verbs },
18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18793 .hp_nid = 0x03,
18794 .dac_nids = alc662_dac_nids,
18795 .dig_out_nid = ALC662_DIGOUT_NID,
18796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18797 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18798 .unsol_event = alc_sku_unsol_event,
4f5d1706 18799 .setup = alc663_mode6_setup,
3b8510ce 18800 .init_hook = alc_inithook,
f1d4e28b 18801 },
ebb83eeb
KY
18802 [ALC663_ASUS_MODE7] = {
18803 .mixers = { alc663_mode7_mixer },
18804 .cap_mixer = alc662_auto_capture_mixer,
18805 .init_verbs = { alc662_init_verbs,
a7f2371f 18806 alc662_eapd_init_verbs,
ebb83eeb
KY
18807 alc663_mode7_init_verbs },
18808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18809 .hp_nid = 0x03,
18810 .dac_nids = alc662_dac_nids,
18811 .dig_out_nid = ALC662_DIGOUT_NID,
18812 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18813 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18814 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18815 .setup = alc663_mode7_setup,
3b8510ce 18816 .init_hook = alc_inithook,
ebb83eeb
KY
18817 },
18818 [ALC663_ASUS_MODE8] = {
18819 .mixers = { alc663_mode8_mixer },
18820 .cap_mixer = alc662_auto_capture_mixer,
18821 .init_verbs = { alc662_init_verbs,
a7f2371f 18822 alc662_eapd_init_verbs,
ebb83eeb
KY
18823 alc663_mode8_init_verbs },
18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18825 .hp_nid = 0x03,
18826 .dac_nids = alc662_dac_nids,
18827 .dig_out_nid = ALC662_DIGOUT_NID,
18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18830 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18831 .setup = alc663_mode8_setup,
3b8510ce 18832 .init_hook = alc_inithook,
ebb83eeb 18833 },
622e84cd
KY
18834 [ALC272_DELL] = {
18835 .mixers = { alc663_m51va_mixer },
18836 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18837 .init_verbs = { alc662_init_verbs,
18838 alc662_eapd_init_verbs,
18839 alc272_dell_init_verbs },
622e84cd 18840 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18841 .dac_nids = alc272_dac_nids,
622e84cd
KY
18842 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18843 .adc_nids = alc272_adc_nids,
18844 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18845 .capsrc_nids = alc272_capsrc_nids,
18846 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18847 .unsol_event = alc_sku_unsol_event,
4f5d1706 18848 .setup = alc663_m51va_setup,
3b8510ce 18849 .init_hook = alc_inithook,
622e84cd
KY
18850 },
18851 [ALC272_DELL_ZM1] = {
18852 .mixers = { alc663_m51va_mixer },
18853 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eapd_init_verbs,
18856 alc272_dell_zm1_init_verbs },
622e84cd 18857 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18858 .dac_nids = alc272_dac_nids,
622e84cd
KY
18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18860 .adc_nids = alc662_adc_nids,
b59bdf3b 18861 .num_adc_nids = 1,
622e84cd
KY
18862 .capsrc_nids = alc662_capsrc_nids,
18863 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18864 .unsol_event = alc_sku_unsol_event,
4f5d1706 18865 .setup = alc663_m51va_setup,
3b8510ce 18866 .init_hook = alc_inithook,
622e84cd 18867 },
9541ba1d
CP
18868 [ALC272_SAMSUNG_NC10] = {
18869 .mixers = { alc272_nc10_mixer },
18870 .init_verbs = { alc662_init_verbs,
a7f2371f 18871 alc662_eapd_init_verbs,
9541ba1d
CP
18872 alc663_21jd_amic_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc272_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18877 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18878 .unsol_event = alc_sku_unsol_event,
4f5d1706 18879 .setup = alc663_mode4_setup,
3b8510ce 18880 .init_hook = alc_inithook,
9541ba1d 18881 },
bc9f98a9
KY
18882};
18883
18884
18885/*
18886 * BIOS auto configuration
18887 */
18888
7085ec12 18889/* convert from MIX nid to DAC */
604401a9 18890static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18891{
604401a9 18892 hda_nid_t list[5];
1304ac89
TI
18893 int i, num;
18894
18895 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18896 for (i = 0; i < num; i++) {
18897 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18898 return list[i];
18899 }
18900 return 0;
7085ec12
TI
18901}
18902
604401a9
TI
18903/* go down to the selector widget before the mixer */
18904static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18905{
18906 hda_nid_t srcs[5];
18907 int num = snd_hda_get_connections(codec, pin, srcs,
18908 ARRAY_SIZE(srcs));
18909 if (num != 1 ||
18910 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18911 return pin;
18912 return srcs[0];
18913}
18914
7085ec12 18915/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18916static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18917 hda_nid_t dac)
18918{
cc1c452e 18919 hda_nid_t mix[5];
7085ec12
TI
18920 int i, num;
18921
604401a9 18922 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18923 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18924 for (i = 0; i < num; i++) {
604401a9 18925 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18926 return mix[i];
18927 }
18928 return 0;
18929}
18930
ce764ab2
TI
18931/* select the connection from pin to DAC if needed */
18932static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18933 hda_nid_t dac)
18934{
18935 hda_nid_t mix[5];
18936 int i, num;
18937
18938 pin = alc_go_down_to_selector(codec, pin);
18939 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18940 if (num < 2)
18941 return 0;
18942 for (i = 0; i < num; i++) {
18943 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18944 snd_hda_codec_update_cache(codec, pin, 0,
18945 AC_VERB_SET_CONNECT_SEL, i);
18946 return 0;
18947 }
18948 }
18949 return 0;
18950}
18951
7085ec12 18952/* look for an empty DAC slot */
604401a9 18953static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18954{
18955 struct alc_spec *spec = codec->spec;
18956 hda_nid_t srcs[5];
18957 int i, j, num;
18958
604401a9 18959 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18960 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18961 for (i = 0; i < num; i++) {
604401a9 18962 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18963 if (!nid)
18964 continue;
18965 for (j = 0; j < spec->multiout.num_dacs; j++)
18966 if (spec->multiout.dac_nids[j] == nid)
18967 break;
18968 if (j >= spec->multiout.num_dacs)
18969 return nid;
18970 }
18971 return 0;
18972}
18973
18974/* fill in the dac_nids table from the parsed pin configuration */
18975static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18976 const struct auto_pin_cfg *cfg)
18977{
18978 struct alc_spec *spec = codec->spec;
18979 int i;
18980 hda_nid_t dac;
18981
18982 spec->multiout.dac_nids = spec->private_dac_nids;
18983 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18984 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18985 if (!dac)
18986 continue;
dda14410 18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
7085ec12
TI
18988 }
18989 return 0;
18990}
18991
bcb2f0f5
TI
18992static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18993 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18994{
bcb2f0f5 18995 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18996 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18997}
18998
bcb2f0f5
TI
18999static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19000 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 19001{
bcb2f0f5 19002 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
19003 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19004}
19005
bcb2f0f5
TI
19006#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19007 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19008#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19009 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
19010#define alc662_add_stereo_vol(spec, pfx, nid) \
19011 alc662_add_vol_ctl(spec, pfx, nid, 3)
19012#define alc662_add_stereo_sw(spec, pfx, nid) \
19013 alc662_add_sw_ctl(spec, pfx, nid, 3)
19014
bc9f98a9 19015/* add playback controls from the parsed DAC table */
7085ec12 19016static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
19017 const struct auto_pin_cfg *cfg)
19018{
7085ec12 19019 struct alc_spec *spec = codec->spec;
ea734963 19020 static const char * const chname[4] = {
bc9f98a9
KY
19021 "Front", "Surround", NULL /*CLFE*/, "Side"
19022 };
ce764ab2
TI
19023 const char *pfx = alc_get_line_out_pfx(spec, true);
19024 hda_nid_t nid, mix, pin;
19025 int i, err, noutputs;
bc9f98a9 19026
ce764ab2
TI
19027 noutputs = cfg->line_outs;
19028 if (spec->multi_ios > 0)
19029 noutputs += spec->multi_ios;
19030
19031 for (i = 0; i < noutputs; i++) {
7085ec12
TI
19032 nid = spec->multiout.dac_nids[i];
19033 if (!nid)
19034 continue;
ce764ab2
TI
19035 if (i >= cfg->line_outs)
19036 pin = spec->multi_io[i - 1].pin;
19037 else
19038 pin = cfg->line_out_pins[i];
19039 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 19040 if (!mix)
bc9f98a9 19041 continue;
bcb2f0f5 19042 if (!pfx && i == 2) {
bc9f98a9 19043 /* Center/LFE */
7085ec12 19044 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
19045 if (err < 0)
19046 return err;
7085ec12 19047 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
19048 if (err < 0)
19049 return err;
7085ec12 19050 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
19051 if (err < 0)
19052 return err;
7085ec12 19053 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19054 if (err < 0)
19055 return err;
19056 } else {
bcb2f0f5 19057 const char *name = pfx;
5a882646
DH
19058 int index = i;
19059 if (!name) {
bcb2f0f5 19060 name = chname[i];
5a882646
DH
19061 index = 0;
19062 }
19063 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19064 if (err < 0)
19065 return err;
5a882646 19066 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19067 if (err < 0)
19068 return err;
19069 }
19070 }
19071 return 0;
19072}
19073
19074/* add playback controls for speaker and HP outputs */
7085ec12
TI
19075/* return DAC nid if any new DAC is assigned */
19076static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19077 const char *pfx)
19078{
7085ec12
TI
19079 struct alc_spec *spec = codec->spec;
19080 hda_nid_t nid, mix;
bc9f98a9 19081 int err;
bc9f98a9
KY
19082
19083 if (!pin)
19084 return 0;
604401a9 19085 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19086 if (!nid) {
7085ec12
TI
19087 /* the corresponding DAC is already occupied */
19088 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19089 return 0; /* no way */
19090 /* create a switch only */
0afe5f89 19091 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19093 }
19094
604401a9 19095 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19096 if (!mix)
19097 return 0;
19098 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19099 if (err < 0)
19100 return err;
19101 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19102 if (err < 0)
19103 return err;
19104 return nid;
bc9f98a9
KY
19105}
19106
19107/* create playback/capture controls for input pins */
05f5f477 19108#define alc662_auto_create_input_ctls \
4b7348a1 19109 alc882_auto_create_input_ctls
bc9f98a9
KY
19110
19111static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19112 hda_nid_t nid, int pin_type,
7085ec12 19113 hda_nid_t dac)
bc9f98a9 19114{
7085ec12 19115 int i, num;
ce503f38 19116 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19117
f6c7e546 19118 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19119 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19120 for (i = 0; i < num; i++) {
604401a9 19121 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19122 continue;
0e53f344
TI
19123 /* need the manual connection? */
19124 if (num > 1)
19125 snd_hda_codec_write(codec, nid, 0,
19126 AC_VERB_SET_CONNECT_SEL, i);
19127 /* unmute mixer widget inputs */
19128 snd_hda_codec_write(codec, srcs[i], 0,
19129 AC_VERB_SET_AMP_GAIN_MUTE,
19130 AMP_IN_UNMUTE(0));
19131 snd_hda_codec_write(codec, srcs[i], 0,
19132 AC_VERB_SET_AMP_GAIN_MUTE,
19133 AMP_IN_UNMUTE(1));
7085ec12 19134 return;
bc9f98a9
KY
19135 }
19136}
19137
19138static void alc662_auto_init_multi_out(struct hda_codec *codec)
19139{
19140 struct alc_spec *spec = codec->spec;
7085ec12 19141 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19142 int i;
19143
19144 for (i = 0; i <= HDA_SIDE; i++) {
19145 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19146 if (nid)
baba8ee9 19147 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19148 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19149 }
19150}
19151
19152static void alc662_auto_init_hp_out(struct hda_codec *codec)
19153{
19154 struct alc_spec *spec = codec->spec;
19155 hda_nid_t pin;
19156
19157 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19158 if (pin)
19159 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19160 spec->multiout.hp_nid);
f6c7e546
TI
19161 pin = spec->autocfg.speaker_pins[0];
19162 if (pin)
7085ec12
TI
19163 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19164 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19165}
19166
bc9f98a9
KY
19167#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19168
19169static void alc662_auto_init_analog_input(struct hda_codec *codec)
19170{
19171 struct alc_spec *spec = codec->spec;
66ceeb6b 19172 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19173 int i;
19174
66ceeb6b
TI
19175 for (i = 0; i < cfg->num_inputs; i++) {
19176 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19177 if (alc_is_input_pin(codec, nid)) {
30ea098f 19178 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19179 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19180 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19181 snd_hda_codec_write(codec, nid, 0,
19182 AC_VERB_SET_AMP_GAIN_MUTE,
19183 AMP_OUT_MUTE);
19184 }
19185 }
19186}
19187
f511b01c
TI
19188#define alc662_auto_init_input_src alc882_auto_init_input_src
19189
ce764ab2
TI
19190/*
19191 * multi-io helper
19192 */
19193static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19194 unsigned int location)
19195{
19196 struct alc_spec *spec = codec->spec;
19197 struct auto_pin_cfg *cfg = &spec->autocfg;
19198 int type, i, num_pins = 0;
19199
19200 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19201 for (i = 0; i < cfg->num_inputs; i++) {
19202 hda_nid_t nid = cfg->inputs[i].pin;
19203 hda_nid_t dac;
19204 unsigned int defcfg, caps;
19205 if (cfg->inputs[i].type != type)
19206 continue;
19207 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19208 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19209 continue;
19210 if (location && get_defcfg_location(defcfg) != location)
19211 continue;
19212 caps = snd_hda_query_pin_caps(codec, nid);
19213 if (!(caps & AC_PINCAP_OUT))
19214 continue;
19215 dac = alc_auto_look_for_dac(codec, nid);
19216 if (!dac)
19217 continue;
19218 spec->multi_io[num_pins].pin = nid;
19219 spec->multi_io[num_pins].dac = dac;
19220 num_pins++;
dda14410 19221 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19222 }
19223 }
19224 spec->multiout.num_dacs = 1;
19225 if (num_pins < 2)
19226 return 0;
19227 return num_pins;
19228}
19229
19230static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19231 struct snd_ctl_elem_info *uinfo)
19232{
19233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19234 struct alc_spec *spec = codec->spec;
19235
19236 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19237 uinfo->count = 1;
19238 uinfo->value.enumerated.items = spec->multi_ios + 1;
19239 if (uinfo->value.enumerated.item > spec->multi_ios)
19240 uinfo->value.enumerated.item = spec->multi_ios;
19241 sprintf(uinfo->value.enumerated.name, "%dch",
19242 (uinfo->value.enumerated.item + 1) * 2);
19243 return 0;
19244}
19245
19246static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19247 struct snd_ctl_elem_value *ucontrol)
19248{
19249 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19250 struct alc_spec *spec = codec->spec;
19251 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19252 return 0;
19253}
19254
19255static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19256{
19257 struct alc_spec *spec = codec->spec;
19258 hda_nid_t nid = spec->multi_io[idx].pin;
19259
19260 if (!spec->multi_io[idx].ctl_in)
19261 spec->multi_io[idx].ctl_in =
19262 snd_hda_codec_read(codec, nid, 0,
19263 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19264 if (output) {
19265 snd_hda_codec_update_cache(codec, nid, 0,
19266 AC_VERB_SET_PIN_WIDGET_CONTROL,
19267 PIN_OUT);
19268 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19269 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19270 HDA_AMP_MUTE, 0);
19271 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19272 } else {
19273 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19274 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19275 HDA_AMP_MUTE, HDA_AMP_MUTE);
19276 snd_hda_codec_update_cache(codec, nid, 0,
19277 AC_VERB_SET_PIN_WIDGET_CONTROL,
19278 spec->multi_io[idx].ctl_in);
19279 }
19280 return 0;
19281}
19282
19283static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19284 struct snd_ctl_elem_value *ucontrol)
19285{
19286 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19287 struct alc_spec *spec = codec->spec;
19288 int i, ch;
19289
19290 ch = ucontrol->value.enumerated.item[0];
19291 if (ch < 0 || ch > spec->multi_ios)
19292 return -EINVAL;
19293 if (ch == (spec->ext_channel_count - 1) / 2)
19294 return 0;
19295 spec->ext_channel_count = (ch + 1) * 2;
19296 for (i = 0; i < spec->multi_ios; i++)
19297 alc_set_multi_io(codec, i, i < ch);
19298 spec->multiout.max_channels = spec->ext_channel_count;
19299 return 1;
19300}
19301
a9111321 19302static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19304 .name = "Channel Mode",
19305 .info = alc_auto_ch_mode_info,
19306 .get = alc_auto_ch_mode_get,
19307 .put = alc_auto_ch_mode_put,
19308};
19309
19310static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19311{
19312 struct alc_spec *spec = codec->spec;
19313 struct auto_pin_cfg *cfg = &spec->autocfg;
19314 unsigned int location, defcfg;
19315 int num_pins;
19316
19317 if (cfg->line_outs != 1 ||
19318 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19319 return 0;
19320
19321 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19322 location = get_defcfg_location(defcfg);
19323
19324 num_pins = alc_auto_fill_multi_ios(codec, location);
19325 if (num_pins > 0) {
19326 struct snd_kcontrol_new *knew;
19327
19328 knew = alc_kcontrol_new(spec);
19329 if (!knew)
19330 return -ENOMEM;
19331 *knew = alc_auto_channel_mode_enum;
19332 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19333 if (!knew->name)
19334 return -ENOMEM;
19335
19336 spec->multi_ios = num_pins;
19337 spec->ext_channel_count = 2;
19338 spec->multiout.num_dacs = num_pins + 1;
19339 }
19340 return 0;
19341}
19342
bc9f98a9
KY
19343static int alc662_parse_auto_config(struct hda_codec *codec)
19344{
19345 struct alc_spec *spec = codec->spec;
19346 int err;
4c6d72d1 19347 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19348
19349 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19350 alc662_ignore);
19351 if (err < 0)
19352 return err;
19353 if (!spec->autocfg.line_outs)
19354 return 0; /* can't find valid BIOS pin config */
19355
7085ec12 19356 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19357 if (err < 0)
19358 return err;
19359 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19360 if (err < 0)
19361 return err;
7085ec12 19362 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19363 if (err < 0)
19364 return err;
7085ec12 19365 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19366 spec->autocfg.speaker_pins[0],
19367 "Speaker");
19368 if (err < 0)
19369 return err;
7085ec12
TI
19370 if (err)
19371 spec->multiout.extra_out_nid[0] = err;
19372 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19373 "Headphone");
19374 if (err < 0)
19375 return err;
7085ec12
TI
19376 if (err)
19377 spec->multiout.hp_nid = err;
05f5f477 19378 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19379 if (err < 0)
bc9f98a9
KY
19380 return err;
19381
19382 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19383
757899ac 19384 alc_auto_parse_digital(codec);
bc9f98a9 19385
603c4019 19386 if (spec->kctls.list)
d88897ea 19387 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19388
19389 spec->num_mux_defs = 1;
61b9b9b1 19390 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19391
ee979a14
TI
19392 err = alc_auto_add_mic_boost(codec);
19393 if (err < 0)
19394 return err;
19395
6227cdce
KY
19396 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19397 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19398 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19399 else
19400 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19401
8c87286f 19402 return 1;
bc9f98a9
KY
19403}
19404
19405/* additional initialization for auto-configuration model */
19406static void alc662_auto_init(struct hda_codec *codec)
19407{
f6c7e546 19408 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19409 alc662_auto_init_multi_out(codec);
19410 alc662_auto_init_hp_out(codec);
19411 alc662_auto_init_analog_input(codec);
f511b01c 19412 alc662_auto_init_input_src(codec);
757899ac 19413 alc_auto_init_digital(codec);
f6c7e546 19414 if (spec->unsol_event)
7fb0d78f 19415 alc_inithook(codec);
bc9f98a9
KY
19416}
19417
6be7948f 19418static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19419 const struct alc_fixup *fix, int action)
6fc398cb 19420{
b5bfbc67 19421 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19422 return;
6be7948f
TB
19423 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19424 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19425 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19426 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19427 (0 << AC_AMPCAP_MUTE_SHIFT)))
19428 printk(KERN_WARNING
19429 "hda_codec: failed to override amp caps for NID 0x2\n");
19430}
19431
6cb3b707 19432enum {
2df03514 19433 ALC662_FIXUP_ASPIRE,
6cb3b707 19434 ALC662_FIXUP_IDEAPAD,
6be7948f 19435 ALC272_FIXUP_MARIO,
d2ebd479 19436 ALC662_FIXUP_CZC_P10T,
94024cd1 19437 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19438};
19439
19440static const struct alc_fixup alc662_fixups[] = {
2df03514 19441 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19442 .type = ALC_FIXUP_PINS,
19443 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19444 { 0x15, 0x99130112 }, /* subwoofer */
19445 { }
19446 }
19447 },
6cb3b707 19448 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19449 .type = ALC_FIXUP_PINS,
19450 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19451 { 0x17, 0x99130112 }, /* subwoofer */
19452 { }
19453 }
19454 },
6be7948f 19455 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19456 .type = ALC_FIXUP_FUNC,
19457 .v.func = alc272_fixup_mario,
d2ebd479
AA
19458 },
19459 [ALC662_FIXUP_CZC_P10T] = {
19460 .type = ALC_FIXUP_VERBS,
19461 .v.verbs = (const struct hda_verb[]) {
19462 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19463 {}
19464 }
19465 },
94024cd1
DH
19466 [ALC662_FIXUP_SKU_IGNORE] = {
19467 .type = ALC_FIXUP_SKU,
19468 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19469 },
6cb3b707
DH
19470};
19471
a9111321 19472static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19473 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19474 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19475 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19476 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19477 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19478 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19479 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19480 {}
19481};
19482
6be7948f
TB
19483static const struct alc_model_fixup alc662_fixup_models[] = {
19484 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19485 {}
19486};
6cb3b707
DH
19487
19488
bc9f98a9
KY
19489static int patch_alc662(struct hda_codec *codec)
19490{
19491 struct alc_spec *spec;
19492 int err, board_config;
693194f3 19493 int coef;
bc9f98a9
KY
19494
19495 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19496 if (!spec)
19497 return -ENOMEM;
19498
19499 codec->spec = spec;
19500
da00c244
KY
19501 alc_auto_parse_customize_define(codec);
19502
2c3bf9ab
TI
19503 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19504
693194f3
KY
19505 coef = alc_read_coef_idx(codec, 0);
19506 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19507 alc_codec_rename(codec, "ALC661");
693194f3
KY
19508 else if (coef & (1 << 14) &&
19509 codec->bus->pci->subsystem_vendor == 0x1025 &&
19510 spec->cdefine.platform_type == 1)
c027ddcd 19511 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19512 else if (coef == 0x4011)
19513 alc_codec_rename(codec, "ALC656");
274693f3 19514
bc9f98a9
KY
19515 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19516 alc662_models,
19517 alc662_cfg_tbl);
19518 if (board_config < 0) {
9a11f1aa
TI
19519 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19520 codec->chip_name);
bc9f98a9
KY
19521 board_config = ALC662_AUTO;
19522 }
19523
19524 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19525 alc_pick_fixup(codec, alc662_fixup_models,
19526 alc662_fixup_tbl, alc662_fixups);
19527 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19528 /* automatic parse from the BIOS config */
19529 err = alc662_parse_auto_config(codec);
19530 if (err < 0) {
19531 alc_free(codec);
19532 return err;
8c87286f 19533 } else if (!err) {
bc9f98a9
KY
19534 printk(KERN_INFO
19535 "hda_codec: Cannot set up configuration "
19536 "from BIOS. Using base mode...\n");
19537 board_config = ALC662_3ST_2ch_DIG;
19538 }
19539 }
19540
dc1eae25 19541 if (has_cdefine_beep(codec)) {
8af2591d
TI
19542 err = snd_hda_attach_beep_device(codec, 0x1);
19543 if (err < 0) {
19544 alc_free(codec);
19545 return err;
19546 }
680cd536
KK
19547 }
19548
bc9f98a9 19549 if (board_config != ALC662_AUTO)
e9c364c0 19550 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19551
bc9f98a9
KY
19552 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19553 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19554
bc9f98a9
KY
19555 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19556 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19557
dd704698
TI
19558 if (!spec->adc_nids) {
19559 spec->adc_nids = alc662_adc_nids;
19560 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19561 }
19562 if (!spec->capsrc_nids)
19563 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19564
f9e336f6 19565 if (!spec->cap_mixer)
b59bdf3b 19566 set_capture_mixer(codec);
cec27c89 19567
dc1eae25 19568 if (has_cdefine_beep(codec)) {
da00c244
KY
19569 switch (codec->vendor_id) {
19570 case 0x10ec0662:
19571 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19572 break;
19573 case 0x10ec0272:
19574 case 0x10ec0663:
19575 case 0x10ec0665:
19576 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19577 break;
19578 case 0x10ec0273:
19579 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19580 break;
19581 }
cec27c89 19582 }
2134ea4f
TI
19583 spec->vmaster_nid = 0x02;
19584
b5bfbc67
TI
19585 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19586
bc9f98a9 19587 codec->patch_ops = alc_patch_ops;
b5bfbc67 19588 if (board_config == ALC662_AUTO)
bc9f98a9 19589 spec->init_hook = alc662_auto_init;
1c716153 19590 spec->shutup = alc_eapd_shutup;
6cb3b707 19591
bf1b0225
KY
19592 alc_init_jacks(codec);
19593
cb53c626
TI
19594#ifdef CONFIG_SND_HDA_POWER_SAVE
19595 if (!spec->loopback.amplist)
19596 spec->loopback.amplist = alc662_loopbacks;
19597#endif
bc9f98a9
KY
19598
19599 return 0;
19600}
19601
274693f3
KY
19602static int patch_alc888(struct hda_codec *codec)
19603{
19604 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19605 kfree(codec->chip_name);
01e0f137
KY
19606 if (codec->vendor_id == 0x10ec0887)
19607 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19608 else
19609 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19610 if (!codec->chip_name) {
19611 alc_free(codec);
274693f3 19612 return -ENOMEM;
ac2c92e0
TI
19613 }
19614 return patch_alc662(codec);
274693f3 19615 }
ac2c92e0 19616 return patch_alc882(codec);
274693f3
KY
19617}
19618
b478b998
KY
19619static int patch_alc899(struct hda_codec *codec)
19620{
19621 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19622 kfree(codec->chip_name);
19623 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19624 }
19625 return patch_alc882(codec);
19626}
19627
d1eb57f4
KY
19628/*
19629 * ALC680 support
19630 */
c69aefab 19631#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19632#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19633#define alc680_modes alc260_modes
19634
4c6d72d1 19635static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19636 /* Lout1, Lout2, hp */
19637 0x02, 0x03, 0x04
19638};
19639
4c6d72d1 19640static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19641 /* ADC0-2 */
19642 /* DMIC, MIC, Line-in*/
19643 0x07, 0x08, 0x09
19644};
19645
c69aefab
KY
19646/*
19647 * Analog capture ADC cgange
19648 */
66ceeb6b
TI
19649static void alc680_rec_autoswitch(struct hda_codec *codec)
19650{
19651 struct alc_spec *spec = codec->spec;
19652 struct auto_pin_cfg *cfg = &spec->autocfg;
19653 int pin_found = 0;
19654 int type_found = AUTO_PIN_LAST;
19655 hda_nid_t nid;
19656 int i;
19657
19658 for (i = 0; i < cfg->num_inputs; i++) {
19659 nid = cfg->inputs[i].pin;
06dec228 19660 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19661 continue;
19662 if (snd_hda_jack_detect(codec, nid)) {
19663 if (cfg->inputs[i].type < type_found) {
19664 type_found = cfg->inputs[i].type;
19665 pin_found = nid;
19666 }
19667 }
19668 }
19669
19670 nid = 0x07;
19671 if (pin_found)
19672 snd_hda_get_connections(codec, pin_found, &nid, 1);
19673
19674 if (nid != spec->cur_adc)
19675 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19676 spec->cur_adc = nid;
19677 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19678 spec->cur_adc_format);
19679}
19680
c69aefab
KY
19681static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19682 struct hda_codec *codec,
19683 unsigned int stream_tag,
19684 unsigned int format,
19685 struct snd_pcm_substream *substream)
19686{
19687 struct alc_spec *spec = codec->spec;
c69aefab 19688
66ceeb6b 19689 spec->cur_adc = 0x07;
c69aefab
KY
19690 spec->cur_adc_stream_tag = stream_tag;
19691 spec->cur_adc_format = format;
19692
66ceeb6b 19693 alc680_rec_autoswitch(codec);
c69aefab
KY
19694 return 0;
19695}
19696
19697static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19698 struct hda_codec *codec,
19699 struct snd_pcm_substream *substream)
19700{
19701 snd_hda_codec_cleanup_stream(codec, 0x07);
19702 snd_hda_codec_cleanup_stream(codec, 0x08);
19703 snd_hda_codec_cleanup_stream(codec, 0x09);
19704 return 0;
19705}
19706
a9111321 19707static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19708 .substreams = 1, /* can be overridden */
19709 .channels_min = 2,
19710 .channels_max = 2,
19711 /* NID is set in alc_build_pcms */
19712 .ops = {
19713 .prepare = alc680_capture_pcm_prepare,
19714 .cleanup = alc680_capture_pcm_cleanup
19715 },
19716};
19717
a9111321 19718static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19719 /* output mixer control */
19720 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19721 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19724 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19726 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19727 { }
19728};
19729
a9111321 19730static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19731 .ops = &snd_hda_bind_vol,
19732 .values = {
19733 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19734 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19735 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19736 0
19737 },
19738};
19739
a9111321 19740static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19741 .ops = &snd_hda_bind_sw,
19742 .values = {
19743 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19744 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19746 0
19747 },
19748};
19749
a9111321 19750static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19751 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19752 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19753 { } /* end */
19754};
19755
19756/*
19757 * generic initialization of ADC, input mixers and output mixers
19758 */
a9111321 19759static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19763
c69aefab
KY
19764 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19768 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19769 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19770
19771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19776
19777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19778 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19779 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19780
d1eb57f4
KY
19781 { }
19782};
19783
c69aefab
KY
19784/* toggle speaker-output according to the hp-jack state */
19785static void alc680_base_setup(struct hda_codec *codec)
19786{
19787 struct alc_spec *spec = codec->spec;
19788
19789 spec->autocfg.hp_pins[0] = 0x16;
19790 spec->autocfg.speaker_pins[0] = 0x14;
19791 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19792 spec->autocfg.num_inputs = 2;
19793 spec->autocfg.inputs[0].pin = 0x18;
19794 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19795 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19796 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19797 spec->automute = 1;
19798 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19799}
19800
19801static void alc680_unsol_event(struct hda_codec *codec,
19802 unsigned int res)
19803{
19804 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19805 alc_hp_automute(codec);
c69aefab
KY
19806 if ((res >> 26) == ALC880_MIC_EVENT)
19807 alc680_rec_autoswitch(codec);
19808}
19809
19810static void alc680_inithook(struct hda_codec *codec)
19811{
d922b51d 19812 alc_hp_automute(codec);
c69aefab
KY
19813 alc680_rec_autoswitch(codec);
19814}
19815
d1eb57f4
KY
19816/* create input playback/capture controls for the given pin */
19817static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19818 const char *ctlname, int idx)
19819{
19820 hda_nid_t dac;
19821 int err;
19822
19823 switch (nid) {
19824 case 0x14:
19825 dac = 0x02;
19826 break;
19827 case 0x15:
19828 dac = 0x03;
19829 break;
19830 case 0x16:
19831 dac = 0x04;
19832 break;
19833 default:
19834 return 0;
19835 }
19836 if (spec->multiout.dac_nids[0] != dac &&
19837 spec->multiout.dac_nids[1] != dac) {
19838 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19839 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19840 HDA_OUTPUT));
19841 if (err < 0)
19842 return err;
19843
19844 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19845 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19846
19847 if (err < 0)
19848 return err;
dda14410 19849 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19850 }
19851
19852 return 0;
19853}
19854
19855/* add playback controls from the parsed DAC table */
19856static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19857 const struct auto_pin_cfg *cfg)
19858{
19859 hda_nid_t nid;
19860 int err;
19861
19862 spec->multiout.dac_nids = spec->private_dac_nids;
19863
19864 nid = cfg->line_out_pins[0];
19865 if (nid) {
19866 const char *name;
19867 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19868 name = "Speaker";
19869 else
19870 name = "Front";
19871 err = alc680_new_analog_output(spec, nid, name, 0);
19872 if (err < 0)
19873 return err;
19874 }
19875
19876 nid = cfg->speaker_pins[0];
19877 if (nid) {
19878 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19879 if (err < 0)
19880 return err;
19881 }
19882 nid = cfg->hp_pins[0];
19883 if (nid) {
19884 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19885 if (err < 0)
19886 return err;
19887 }
19888
19889 return 0;
19890}
19891
19892static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19893 hda_nid_t nid, int pin_type)
19894{
19895 alc_set_pin_output(codec, nid, pin_type);
19896}
19897
19898static void alc680_auto_init_multi_out(struct hda_codec *codec)
19899{
19900 struct alc_spec *spec = codec->spec;
19901 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19902 if (nid) {
19903 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19904 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19905 }
19906}
19907
19908static void alc680_auto_init_hp_out(struct hda_codec *codec)
19909{
19910 struct alc_spec *spec = codec->spec;
19911 hda_nid_t pin;
19912
19913 pin = spec->autocfg.hp_pins[0];
19914 if (pin)
19915 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19916 pin = spec->autocfg.speaker_pins[0];
19917 if (pin)
19918 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19919}
19920
19921/* pcm configuration: identical with ALC880 */
19922#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19923#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19924#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19925#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19926#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19927
19928/*
19929 * BIOS auto configuration
19930 */
19931static int alc680_parse_auto_config(struct hda_codec *codec)
19932{
19933 struct alc_spec *spec = codec->spec;
19934 int err;
4c6d72d1 19935 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19936
19937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19938 alc680_ignore);
19939 if (err < 0)
19940 return err;
c69aefab 19941
d1eb57f4
KY
19942 if (!spec->autocfg.line_outs) {
19943 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19944 spec->multiout.max_channels = 2;
19945 spec->no_analog = 1;
19946 goto dig_only;
19947 }
19948 return 0; /* can't find valid BIOS pin config */
19949 }
19950 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19951 if (err < 0)
19952 return err;
19953
19954 spec->multiout.max_channels = 2;
19955
19956 dig_only:
19957 /* digital only support output */
757899ac 19958 alc_auto_parse_digital(codec);
d1eb57f4
KY
19959 if (spec->kctls.list)
19960 add_mixer(spec, spec->kctls.list);
19961
19962 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19963
19964 err = alc_auto_add_mic_boost(codec);
19965 if (err < 0)
19966 return err;
19967
19968 return 1;
19969}
19970
19971#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19972
19973/* init callback for auto-configuration model -- overriding the default init */
19974static void alc680_auto_init(struct hda_codec *codec)
19975{
19976 struct alc_spec *spec = codec->spec;
19977 alc680_auto_init_multi_out(codec);
19978 alc680_auto_init_hp_out(codec);
19979 alc680_auto_init_analog_input(codec);
757899ac 19980 alc_auto_init_digital(codec);
d1eb57f4
KY
19981 if (spec->unsol_event)
19982 alc_inithook(codec);
19983}
19984
19985/*
19986 * configuration and preset
19987 */
ea734963 19988static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19989 [ALC680_BASE] = "base",
19990 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19991};
19992
a9111321 19993static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19994 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19995 {}
19996};
19997
a9111321 19998static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19999 [ALC680_BASE] = {
20000 .mixers = { alc680_base_mixer },
c69aefab 20001 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
20002 .init_verbs = { alc680_init_verbs },
20003 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20004 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
20005 .dig_out_nid = ALC680_DIGOUT_NID,
20006 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20007 .channel_mode = alc680_modes,
c69aefab
KY
20008 .unsol_event = alc680_unsol_event,
20009 .setup = alc680_base_setup,
20010 .init_hook = alc680_inithook,
20011
d1eb57f4
KY
20012 },
20013};
20014
20015static int patch_alc680(struct hda_codec *codec)
20016{
20017 struct alc_spec *spec;
20018 int board_config;
20019 int err;
20020
20021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20022 if (spec == NULL)
20023 return -ENOMEM;
20024
20025 codec->spec = spec;
20026
20027 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20028 alc680_models,
20029 alc680_cfg_tbl);
20030
20031 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20032 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20033 codec->chip_name);
20034 board_config = ALC680_AUTO;
20035 }
20036
20037 if (board_config == ALC680_AUTO) {
20038 /* automatic parse from the BIOS config */
20039 err = alc680_parse_auto_config(codec);
20040 if (err < 0) {
20041 alc_free(codec);
20042 return err;
20043 } else if (!err) {
20044 printk(KERN_INFO
20045 "hda_codec: Cannot set up configuration "
20046 "from BIOS. Using base mode...\n");
20047 board_config = ALC680_BASE;
20048 }
20049 }
20050
20051 if (board_config != ALC680_AUTO)
20052 setup_preset(codec, &alc680_presets[board_config]);
20053
20054 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 20055 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 20056 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 20057 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
20058
20059 if (!spec->adc_nids) {
20060 spec->adc_nids = alc680_adc_nids;
20061 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20062 }
20063
20064 if (!spec->cap_mixer)
20065 set_capture_mixer(codec);
20066
20067 spec->vmaster_nid = 0x02;
20068
20069 codec->patch_ops = alc_patch_ops;
20070 if (board_config == ALC680_AUTO)
20071 spec->init_hook = alc680_auto_init;
20072
20073 return 0;
20074}
20075
1da177e4
LT
20076/*
20077 * patch entries
20078 */
a9111321 20079static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 20080 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 20081 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20082 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20083 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20084 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20085 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20086 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20088 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 20089 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 20090 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20091 .patch = patch_alc861 },
f32610ed
JS
20092 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20093 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20094 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20095 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20096 .patch = patch_alc882 },
bc9f98a9
KY
20097 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20098 .patch = patch_alc662 },
6dda9f4a 20099 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20100 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20101 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20102 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20103 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20104 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20105 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20106 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20107 .patch = patch_alc882 },
cb308f97 20108 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20109 .patch = patch_alc882 },
df694daa 20110 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20111 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20112 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20113 .patch = patch_alc882 },
274693f3 20114 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20115 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20116 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 20117 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
20118 {} /* terminator */
20119};
1289e9e8
TI
20120
20121MODULE_ALIAS("snd-hda-codec-id:10ec*");
20122
20123MODULE_LICENSE("GPL");
20124MODULE_DESCRIPTION("Realtek HD-audio codec");
20125
20126static struct hda_codec_preset_list realtek_list = {
20127 .preset = snd_hda_preset_realtek,
20128 .owner = THIS_MODULE,
20129};
20130
20131static int __init patch_realtek_init(void)
20132{
20133 return snd_hda_add_codec_preset(&realtek_list);
20134}
20135
20136static void __exit patch_realtek_exit(void)
20137{
20138 snd_hda_delete_codec_preset(&realtek_list);
20139}
20140
20141module_init(patch_realtek_init)
20142module_exit(patch_realtek_exit)