]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Unify alc*_auto_init_input_src() in patch_realtek.c
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1f0f4b80 351 hda_nid_t mixer_nid; /* analog-mixer NID */
1da177e4 352
840b64c0
TI
353 /* capture setup for dynamic dual-adc switch */
354 unsigned int cur_adc_idx;
355 hda_nid_t cur_adc;
356 unsigned int cur_adc_stream_tag;
357 unsigned int cur_adc_format;
358
1da177e4 359 /* capture source */
a1e8d2da 360 unsigned int num_mux_defs;
1da177e4
LT
361 const struct hda_input_mux *input_mux;
362 unsigned int cur_mux[3];
6c819492 363 struct alc_mic_route ext_mic;
8ed99d97 364 struct alc_mic_route dock_mic;
6c819492 365 struct alc_mic_route int_mic;
1da177e4
LT
366
367 /* channel model */
d2a6d7dc 368 const struct hda_channel_mode *channel_mode;
1da177e4 369 int num_channel_mode;
4e195a7b 370 int need_dac_fix;
3b315d70
HM
371 int const_channel_count;
372 int ext_channel_count;
1da177e4
LT
373
374 /* PCM information */
4c5186ed 375 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 376
e9edcee0
TI
377 /* dynamic controls, init_verbs and input_mux */
378 struct auto_pin_cfg autocfg;
da00c244 379 struct alc_customize_define cdefine;
603c4019 380 struct snd_array kctls;
61b9b9b1 381 struct hda_input_mux private_imux[3];
41923e44 382 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
383 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
384 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 385
ae6b813a
TI
386 /* hooks */
387 void (*init_hook)(struct hda_codec *codec);
388 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 389#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 390 void (*power_hook)(struct hda_codec *codec);
f5de24b0 391#endif
1c716153 392 void (*shutup)(struct hda_codec *codec);
ae6b813a 393
834be88d 394 /* for pin sensing */
834be88d 395 unsigned int jack_present: 1;
e6a5e1b7 396 unsigned int line_jack_present:1;
e9427969 397 unsigned int master_mute:1;
6c819492 398 unsigned int auto_mic:1;
d922b51d 399 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
400 unsigned int detect_line:1; /* Line-out detection enabled */
401 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 402 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 403
e64f14f4
TI
404 /* other flags */
405 unsigned int no_analog :1; /* digital I/O only */
840b64c0 406 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 407 unsigned int single_input_src:1;
d6cc9fab 408 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
d922b51d
TI
409
410 /* auto-mute control */
411 int automute_mode;
3b8510ce 412 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 413
4a79ba34 414 int init_amp;
d433a678 415 int codec_variant; /* flag for other variants */
e64f14f4 416
2134ea4f
TI
417 /* for virtual master */
418 hda_nid_t vmaster_nid;
cb53c626
TI
419#ifdef CONFIG_SND_HDA_POWER_SAVE
420 struct hda_loopback_check loopback;
421#endif
2c3bf9ab
TI
422
423 /* for PLL fix */
424 hda_nid_t pll_nid;
425 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
426
427 /* fix-up list */
428 int fixup_id;
429 const struct alc_fixup *fixup_list;
430 const char *fixup_name;
ce764ab2
TI
431
432 /* multi-io */
433 int multi_ios;
434 struct alc_multi_io multi_io[4];
df694daa
KY
435};
436
437/*
438 * configuration template - to be copied to the spec instance
439 */
440struct alc_config_preset {
a9111321 441 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
442 * with spec
443 */
a9111321 444 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
445 const struct hda_verb *init_verbs[5];
446 unsigned int num_dacs;
4c6d72d1 447 const hda_nid_t *dac_nids;
df694daa
KY
448 hda_nid_t dig_out_nid; /* optional */
449 hda_nid_t hp_nid; /* optional */
4c6d72d1 450 const hda_nid_t *slave_dig_outs;
df694daa 451 unsigned int num_adc_nids;
4c6d72d1
TI
452 const hda_nid_t *adc_nids;
453 const hda_nid_t *capsrc_nids;
df694daa
KY
454 hda_nid_t dig_in_nid;
455 unsigned int num_channel_mode;
456 const struct hda_channel_mode *channel_mode;
4e195a7b 457 int need_dac_fix;
3b315d70 458 int const_channel_count;
a1e8d2da 459 unsigned int num_mux_defs;
df694daa 460 const struct hda_input_mux *input_mux;
ae6b813a 461 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 462 void (*setup)(struct hda_codec *);
ae6b813a 463 void (*init_hook)(struct hda_codec *);
cb53c626 464#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 465 const struct hda_amp_list *loopbacks;
c97259df 466 void (*power_hook)(struct hda_codec *codec);
cb53c626 467#endif
1da177e4
LT
468};
469
1da177e4
LT
470
471/*
472 * input MUX handling
473 */
9c7f852e
TI
474static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
475 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
476{
477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
478 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
479 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
480 if (mux_idx >= spec->num_mux_defs)
481 mux_idx = 0;
5311114d
TI
482 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
483 mux_idx = 0;
a1e8d2da 484 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
485}
486
9c7f852e
TI
487static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
488 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
489{
490 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
491 struct alc_spec *spec = codec->spec;
492 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
493
494 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
495 return 0;
496}
497
9c7f852e
TI
498static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
500{
501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
502 struct alc_spec *spec = codec->spec;
cd896c33 503 const struct hda_input_mux *imux;
1da177e4 504 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 505 unsigned int mux_idx;
e1406348
TI
506 hda_nid_t nid = spec->capsrc_nids ?
507 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 508 unsigned int type;
1da177e4 509
cd896c33
TI
510 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
511 imux = &spec->input_mux[mux_idx];
5311114d
TI
512 if (!imux->num_items && mux_idx > 0)
513 imux = &spec->input_mux[0];
cd896c33 514
a22d543a 515 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 516 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
517 /* Matrix-mixer style (e.g. ALC882) */
518 unsigned int *cur_val = &spec->cur_mux[adc_idx];
519 unsigned int i, idx;
520
521 idx = ucontrol->value.enumerated.item[0];
522 if (idx >= imux->num_items)
523 idx = imux->num_items - 1;
524 if (*cur_val == idx)
525 return 0;
526 for (i = 0; i < imux->num_items; i++) {
527 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
528 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
529 imux->items[i].index,
530 HDA_AMP_MUTE, v);
531 }
532 *cur_val = idx;
533 return 1;
534 } else {
535 /* MUX style (e.g. ALC880) */
cd896c33 536 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
537 &spec->cur_mux[adc_idx]);
538 }
539}
e9edcee0 540
1da177e4
LT
541/*
542 * channel mode setting
543 */
9c7f852e
TI
544static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
545 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
546{
547 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
548 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
549 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
550 spec->num_channel_mode);
1da177e4
LT
551}
552
9c7f852e
TI
553static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
554 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
555{
556 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
557 struct alc_spec *spec = codec->spec;
d2a6d7dc 558 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 559 spec->num_channel_mode,
3b315d70 560 spec->ext_channel_count);
1da177e4
LT
561}
562
9c7f852e
TI
563static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
564 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
565{
566 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
567 struct alc_spec *spec = codec->spec;
4e195a7b
TI
568 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
569 spec->num_channel_mode,
3b315d70
HM
570 &spec->ext_channel_count);
571 if (err >= 0 && !spec->const_channel_count) {
572 spec->multiout.max_channels = spec->ext_channel_count;
573 if (spec->need_dac_fix)
574 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
575 }
4e195a7b 576 return err;
1da177e4
LT
577}
578
a9430dd8 579/*
4c5186ed 580 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 581 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
582 * being part of a format specifier. Maximum allowed length of a value is
583 * 63 characters plus NULL terminator.
7cf51e48
JW
584 *
585 * Note: some retasking pin complexes seem to ignore requests for input
586 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
587 * are requested. Therefore order this list so that this behaviour will not
588 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
589 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
590 * March 2006.
4c5186ed 591 */
a9111321 592static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
593 "Mic 50pc bias", "Mic 80pc bias",
594 "Line in", "Line out", "Headphone out",
4c5186ed 595};
a9111321 596static const unsigned char alc_pin_mode_values[] = {
7cf51e48 597 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
598};
599/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
600 * in the pin being assumed to be exclusively an input or an output pin. In
601 * addition, "input" pins may or may not process the mic bias option
602 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
603 * accept requests for bias as of chip versions up to March 2006) and/or
604 * wiring in the computer.
a9430dd8 605 */
a1e8d2da
JW
606#define ALC_PIN_DIR_IN 0x00
607#define ALC_PIN_DIR_OUT 0x01
608#define ALC_PIN_DIR_INOUT 0x02
609#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
610#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 611
ea1fb29a 612/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
613 * For each direction the minimum and maximum values are given.
614 */
a9111321 615static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
616 { 0, 2 }, /* ALC_PIN_DIR_IN */
617 { 3, 4 }, /* ALC_PIN_DIR_OUT */
618 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
619 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
620 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
621};
622#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
623#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
624#define alc_pin_mode_n_items(_dir) \
625 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
626
9c7f852e
TI
627static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
628 struct snd_ctl_elem_info *uinfo)
a9430dd8 629{
4c5186ed
JW
630 unsigned int item_num = uinfo->value.enumerated.item;
631 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
632
633 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 634 uinfo->count = 1;
4c5186ed
JW
635 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
636
637 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
638 item_num = alc_pin_mode_min(dir);
639 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
640 return 0;
641}
642
9c7f852e
TI
643static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
644 struct snd_ctl_elem_value *ucontrol)
a9430dd8 645{
4c5186ed 646 unsigned int i;
a9430dd8
JW
647 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
648 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 649 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 650 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
651 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
652 AC_VERB_GET_PIN_WIDGET_CONTROL,
653 0x00);
a9430dd8 654
4c5186ed
JW
655 /* Find enumerated value for current pinctl setting */
656 i = alc_pin_mode_min(dir);
4b35d2ca 657 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 658 i++;
9c7f852e 659 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
660 return 0;
661}
662
9c7f852e
TI
663static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_value *ucontrol)
a9430dd8 665{
4c5186ed 666 signed int change;
a9430dd8
JW
667 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
668 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
669 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
670 long val = *ucontrol->value.integer.value;
9c7f852e
TI
671 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_PIN_WIDGET_CONTROL,
673 0x00);
a9430dd8 674
f12ab1e0 675 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
676 val = alc_pin_mode_min(dir);
677
678 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
679 if (change) {
680 /* Set pin mode to that requested */
82beb8fd
TI
681 snd_hda_codec_write_cache(codec, nid, 0,
682 AC_VERB_SET_PIN_WIDGET_CONTROL,
683 alc_pin_mode_values[val]);
cdcd9268 684
ea1fb29a 685 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
686 * for the requested pin mode. Enum values of 2 or less are
687 * input modes.
688 *
689 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
690 * reduces noise slightly (particularly on input) so we'll
691 * do it. However, having both input and output buffers
692 * enabled simultaneously doesn't seem to be problematic if
693 * this turns out to be necessary in the future.
cdcd9268
JW
694 */
695 if (val <= 2) {
47fd830a
TI
696 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
697 HDA_AMP_MUTE, HDA_AMP_MUTE);
698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
699 HDA_AMP_MUTE, 0);
cdcd9268 700 } else {
47fd830a
TI
701 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
702 HDA_AMP_MUTE, HDA_AMP_MUTE);
703 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
704 HDA_AMP_MUTE, 0);
cdcd9268
JW
705 }
706 }
a9430dd8
JW
707 return change;
708}
709
4c5186ed 710#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 711 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 712 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
713 .info = alc_pin_mode_info, \
714 .get = alc_pin_mode_get, \
715 .put = alc_pin_mode_put, \
716 .private_value = nid | (dir<<16) }
df694daa 717
5c8f858d
JW
718/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
719 * together using a mask with more than one bit set. This control is
720 * currently used only by the ALC260 test model. At this stage they are not
721 * needed for any "production" models.
722 */
723#ifdef CONFIG_SND_DEBUG
a5ce8890 724#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 725
9c7f852e
TI
726static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
727 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
728{
729 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
730 hda_nid_t nid = kcontrol->private_value & 0xffff;
731 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
732 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
733 unsigned int val = snd_hda_codec_read(codec, nid, 0,
734 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
735
736 *valp = (val & mask) != 0;
737 return 0;
738}
9c7f852e
TI
739static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
740 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
741{
742 signed int change;
743 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
744 hda_nid_t nid = kcontrol->private_value & 0xffff;
745 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
746 long val = *ucontrol->value.integer.value;
9c7f852e
TI
747 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
748 AC_VERB_GET_GPIO_DATA,
749 0x00);
5c8f858d
JW
750
751 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
752 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
753 if (val == 0)
5c8f858d
JW
754 gpio_data &= ~mask;
755 else
756 gpio_data |= mask;
82beb8fd
TI
757 snd_hda_codec_write_cache(codec, nid, 0,
758 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
759
760 return change;
761}
762#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
763 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 764 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
765 .info = alc_gpio_data_info, \
766 .get = alc_gpio_data_get, \
767 .put = alc_gpio_data_put, \
768 .private_value = nid | (mask<<16) }
769#endif /* CONFIG_SND_DEBUG */
770
92621f13
JW
771/* A switch control to allow the enabling of the digital IO pins on the
772 * ALC260. This is incredibly simplistic; the intention of this control is
773 * to provide something in the test model allowing digital outputs to be
774 * identified if present. If models are found which can utilise these
775 * outputs a more complete mixer control can be devised for those models if
776 * necessary.
777 */
778#ifdef CONFIG_SND_DEBUG
a5ce8890 779#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 780
9c7f852e
TI
781static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
782 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
783{
784 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
785 hda_nid_t nid = kcontrol->private_value & 0xffff;
786 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
787 long *valp = ucontrol->value.integer.value;
9c7f852e 788 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 789 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
790
791 *valp = (val & mask) != 0;
792 return 0;
793}
9c7f852e
TI
794static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
795 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
796{
797 signed int change;
798 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
799 hda_nid_t nid = kcontrol->private_value & 0xffff;
800 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
801 long val = *ucontrol->value.integer.value;
9c7f852e 802 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 803 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 804 0x00);
92621f13
JW
805
806 /* Set/unset the masked control bit(s) as needed */
9c7f852e 807 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
808 if (val==0)
809 ctrl_data &= ~mask;
810 else
811 ctrl_data |= mask;
82beb8fd
TI
812 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
813 ctrl_data);
92621f13
JW
814
815 return change;
816}
817#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
818 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 819 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
820 .info = alc_spdif_ctrl_info, \
821 .get = alc_spdif_ctrl_get, \
822 .put = alc_spdif_ctrl_put, \
823 .private_value = nid | (mask<<16) }
824#endif /* CONFIG_SND_DEBUG */
825
f8225f6d
JW
826/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
827 * Again, this is only used in the ALC26x test models to help identify when
828 * the EAPD line must be asserted for features to work.
829 */
830#ifdef CONFIG_SND_DEBUG
831#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
832
833static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
834 struct snd_ctl_elem_value *ucontrol)
835{
836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
837 hda_nid_t nid = kcontrol->private_value & 0xffff;
838 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
839 long *valp = ucontrol->value.integer.value;
840 unsigned int val = snd_hda_codec_read(codec, nid, 0,
841 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
842
843 *valp = (val & mask) != 0;
844 return 0;
845}
846
847static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
848 struct snd_ctl_elem_value *ucontrol)
849{
850 int change;
851 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
852 hda_nid_t nid = kcontrol->private_value & 0xffff;
853 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
854 long val = *ucontrol->value.integer.value;
855 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
856 AC_VERB_GET_EAPD_BTLENABLE,
857 0x00);
858
859 /* Set/unset the masked control bit(s) as needed */
860 change = (!val ? 0 : mask) != (ctrl_data & mask);
861 if (!val)
862 ctrl_data &= ~mask;
863 else
864 ctrl_data |= mask;
865 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
866 ctrl_data);
867
868 return change;
869}
870
871#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
872 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 873 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
874 .info = alc_eapd_ctrl_info, \
875 .get = alc_eapd_ctrl_get, \
876 .put = alc_eapd_ctrl_put, \
877 .private_value = nid | (mask<<16) }
878#endif /* CONFIG_SND_DEBUG */
879
23f0c048
TI
880/*
881 * set up the input pin config (depending on the given auto-pin type)
882 */
883static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
884 int auto_pin_type)
885{
886 unsigned int val = PIN_IN;
887
86e2959a 888 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 889 unsigned int pincap;
954a29c8
TI
890 unsigned int oldval;
891 oldval = snd_hda_codec_read(codec, nid, 0,
892 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 893 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 894 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
895 /* if the default pin setup is vref50, we give it priority */
896 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 897 val = PIN_VREF80;
461c6c3a
TI
898 else if (pincap & AC_PINCAP_VREF_50)
899 val = PIN_VREF50;
900 else if (pincap & AC_PINCAP_VREF_100)
901 val = PIN_VREF100;
902 else if (pincap & AC_PINCAP_VREF_GRD)
903 val = PIN_VREFGRD;
23f0c048
TI
904 }
905 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
906}
907
f6837bbd
TI
908static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
909{
910 struct alc_spec *spec = codec->spec;
911 struct auto_pin_cfg *cfg = &spec->autocfg;
912
913 if (!cfg->line_outs) {
914 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
915 cfg->line_out_pins[cfg->line_outs])
916 cfg->line_outs++;
917 }
918 if (!cfg->speaker_outs) {
919 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
920 cfg->speaker_pins[cfg->speaker_outs])
921 cfg->speaker_outs++;
922 }
923 if (!cfg->hp_outs) {
924 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
925 cfg->hp_pins[cfg->hp_outs])
926 cfg->hp_outs++;
927 }
928}
929
d88897ea
TI
930/*
931 */
a9111321 932static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
933{
934 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
935 return;
936 spec->mixers[spec->num_mixers++] = mix;
937}
938
939static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
940{
941 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
942 return;
943 spec->init_verbs[spec->num_init_verbs++] = verb;
944}
945
df694daa
KY
946/*
947 * set up from the preset table
948 */
e9c364c0 949static void setup_preset(struct hda_codec *codec,
9c7f852e 950 const struct alc_config_preset *preset)
df694daa 951{
e9c364c0 952 struct alc_spec *spec = codec->spec;
df694daa
KY
953 int i;
954
955 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 956 add_mixer(spec, preset->mixers[i]);
f9e336f6 957 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
958 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
959 i++)
d88897ea 960 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 961
df694daa
KY
962 spec->channel_mode = preset->channel_mode;
963 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 964 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 965 spec->const_channel_count = preset->const_channel_count;
df694daa 966
3b315d70
HM
967 if (preset->const_channel_count)
968 spec->multiout.max_channels = preset->const_channel_count;
969 else
970 spec->multiout.max_channels = spec->channel_mode[0].channels;
971 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
972
973 spec->multiout.num_dacs = preset->num_dacs;
974 spec->multiout.dac_nids = preset->dac_nids;
975 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 976 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 977 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 978
a1e8d2da 979 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 980 if (!spec->num_mux_defs)
a1e8d2da 981 spec->num_mux_defs = 1;
df694daa
KY
982 spec->input_mux = preset->input_mux;
983
984 spec->num_adc_nids = preset->num_adc_nids;
985 spec->adc_nids = preset->adc_nids;
e1406348 986 spec->capsrc_nids = preset->capsrc_nids;
df694daa 987 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
988
989 spec->unsol_event = preset->unsol_event;
990 spec->init_hook = preset->init_hook;
cb53c626 991#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 992 spec->power_hook = preset->power_hook;
cb53c626
TI
993 spec->loopback.amplist = preset->loopbacks;
994#endif
e9c364c0
TI
995
996 if (preset->setup)
997 preset->setup(codec);
f6837bbd
TI
998
999 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
1000}
1001
bc9f98a9 1002/* Enable GPIO mask and set output */
a9111321 1003static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1004 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1006 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1007 { }
1008};
1009
a9111321 1010static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1011 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1013 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1014 { }
1015};
1016
a9111321 1017static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1018 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1020 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1021 { }
1022};
1023
2c3bf9ab
TI
1024/*
1025 * Fix hardware PLL issue
1026 * On some codecs, the analog PLL gating control must be off while
1027 * the default value is 1.
1028 */
1029static void alc_fix_pll(struct hda_codec *codec)
1030{
1031 struct alc_spec *spec = codec->spec;
1032 unsigned int val;
1033
1034 if (!spec->pll_nid)
1035 return;
1036 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1037 spec->pll_coef_idx);
1038 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1039 AC_VERB_GET_PROC_COEF, 0);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1041 spec->pll_coef_idx);
1042 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1043 val & ~(1 << spec->pll_coef_bit));
1044}
1045
1046static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1047 unsigned int coef_idx, unsigned int coef_bit)
1048{
1049 struct alc_spec *spec = codec->spec;
1050 spec->pll_nid = nid;
1051 spec->pll_coef_idx = coef_idx;
1052 spec->pll_coef_bit = coef_bit;
1053 alc_fix_pll(codec);
1054}
1055
9ad0e496
KY
1056static int alc_init_jacks(struct hda_codec *codec)
1057{
cd372fb3 1058#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1059 struct alc_spec *spec = codec->spec;
1060 int err;
1061 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1062 unsigned int mic_nid = spec->ext_mic.pin;
8ed99d97 1063 unsigned int dock_nid = spec->dock_mic.pin;
9ad0e496 1064
265a0247 1065 if (hp_nid) {
cd372fb3
TI
1066 err = snd_hda_input_jack_add(codec, hp_nid,
1067 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1068 if (err < 0)
1069 return err;
cd372fb3 1070 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1071 }
9ad0e496 1072
265a0247 1073 if (mic_nid) {
cd372fb3
TI
1074 err = snd_hda_input_jack_add(codec, mic_nid,
1075 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1076 if (err < 0)
1077 return err;
cd372fb3 1078 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1079 }
8ed99d97
TI
1080 if (dock_nid) {
1081 err = snd_hda_input_jack_add(codec, dock_nid,
1082 SND_JACK_MICROPHONE, NULL);
1083 if (err < 0)
1084 return err;
1085 snd_hda_input_jack_report(codec, dock_nid);
1086 }
cd372fb3 1087#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1088 return 0;
1089}
9ad0e496 1090
e6a5e1b7 1091static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1092{
e6a5e1b7 1093 int i, present = 0;
c9b58006 1094
e6a5e1b7
TI
1095 for (i = 0; i < num_pins; i++) {
1096 hda_nid_t nid = pins[i];
bb35febd
TI
1097 if (!nid)
1098 break;
cd372fb3 1099 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1100 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1101 }
e6a5e1b7
TI
1102 return present;
1103}
bb35febd 1104
e6a5e1b7 1105static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1106 bool mute, bool hp_out)
e6a5e1b7
TI
1107{
1108 struct alc_spec *spec = codec->spec;
1109 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1110 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1111 int i;
1112
1113 for (i = 0; i < num_pins; i++) {
1114 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1115 if (!nid)
1116 break;
3b8510ce
TI
1117 switch (spec->automute_mode) {
1118 case ALC_AUTOMUTE_PIN:
bb35febd 1119 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1120 AC_VERB_SET_PIN_WIDGET_CONTROL,
1121 pin_bits);
3b8510ce
TI
1122 break;
1123 case ALC_AUTOMUTE_AMP:
bb35febd 1124 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1125 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1126 break;
1127 case ALC_AUTOMUTE_MIXER:
1128 nid = spec->automute_mixer_nid[i];
1129 if (!nid)
1130 break;
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1132 HDA_AMP_MUTE, mute_bits);
3b8510ce 1133 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1134 HDA_AMP_MUTE, mute_bits);
3b8510ce 1135 break;
bb35febd 1136 }
a9fd4f3f 1137 }
c9b58006
KY
1138}
1139
e6a5e1b7
TI
1140/* Toggle internal speakers muting */
1141static void update_speakers(struct hda_codec *codec)
1142{
1143 struct alc_spec *spec = codec->spec;
1a1455de 1144 int on;
e6a5e1b7 1145
c0a20263
TI
1146 /* Control HP pins/amps depending on master_mute state;
1147 * in general, HP pins/amps control should be enabled in all cases,
1148 * but currently set only for master_mute, just to be safe
1149 */
1150 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1151 spec->autocfg.hp_pins, spec->master_mute, true);
1152
1a1455de
TI
1153 if (!spec->automute)
1154 on = 0;
1155 else
1156 on = spec->jack_present | spec->line_jack_present;
1157 on |= spec->master_mute;
e6a5e1b7 1158 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1159 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1160
1161 /* toggle line-out mutes if needed, too */
1a1455de
TI
1162 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1163 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1164 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1165 return;
1a1455de
TI
1166 if (!spec->automute_lines || !spec->automute)
1167 on = 0;
1168 else
1169 on = spec->jack_present;
1170 on |= spec->master_mute;
e6a5e1b7 1171 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1172 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1173}
1174
1175static void alc_hp_automute(struct hda_codec *codec)
1176{
1177 struct alc_spec *spec = codec->spec;
1178
1179 if (!spec->automute)
1180 return;
1181 spec->jack_present =
1182 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1183 spec->autocfg.hp_pins);
1184 update_speakers(codec);
1185}
1186
1187static void alc_line_automute(struct hda_codec *codec)
1188{
1189 struct alc_spec *spec = codec->spec;
1190
1191 if (!spec->automute || !spec->detect_line)
1192 return;
1193 spec->line_jack_present =
1194 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1195 spec->autocfg.line_out_pins);
1196 update_speakers(codec);
1197}
1198
8d087c76
TI
1199#define get_connection_index(codec, mux, nid) \
1200 snd_hda_get_conn_index(codec, mux, nid, 0)
6c819492 1201
840b64c0
TI
1202/* switch the current ADC according to the jack state */
1203static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1204{
1205 struct alc_spec *spec = codec->spec;
1206 unsigned int present;
1207 hda_nid_t new_adc;
1208
1209 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1210 if (present)
1211 spec->cur_adc_idx = 1;
1212 else
1213 spec->cur_adc_idx = 0;
1214 new_adc = spec->adc_nids[spec->cur_adc_idx];
1215 if (spec->cur_adc && spec->cur_adc != new_adc) {
1216 /* stream is running, let's swap the current ADC */
f0cea797 1217 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1218 spec->cur_adc = new_adc;
1219 snd_hda_codec_setup_stream(codec, new_adc,
1220 spec->cur_adc_stream_tag, 0,
1221 spec->cur_adc_format);
1222 }
1223}
1224
7fb0d78f
KY
1225static void alc_mic_automute(struct hda_codec *codec)
1226{
1227 struct alc_spec *spec = codec->spec;
8ed99d97 1228 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1229 unsigned int present, type;
1230 hda_nid_t cap_nid;
1231
b59bdf3b
TI
1232 if (!spec->auto_mic)
1233 return;
6c819492
TI
1234 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1235 return;
1236 if (snd_BUG_ON(!spec->adc_nids))
1237 return;
1238
840b64c0
TI
1239 if (spec->dual_adc_switch) {
1240 alc_dual_mic_adc_auto_switch(codec);
1241 return;
1242 }
1243
6c819492
TI
1244 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1245
8ed99d97
TI
1246 alive = &spec->int_mic;
1247 dead1 = &spec->ext_mic;
1248 dead2 = &spec->dock_mic;
1249
864f92be 1250 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1251 if (present) {
1252 alive = &spec->ext_mic;
8ed99d97
TI
1253 dead1 = &spec->int_mic;
1254 dead2 = &spec->dock_mic;
1255 }
1256 if (!present && spec->dock_mic.pin > 0) {
1257 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1258 if (present) {
1259 alive = &spec->dock_mic;
1260 dead1 = &spec->int_mic;
1261 dead2 = &spec->ext_mic;
1262 }
1263 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
6c819492
TI
1264 }
1265
6c819492
TI
1266 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1267 if (type == AC_WID_AUD_MIX) {
1268 /* Matrix-mixer style (e.g. ALC882) */
1269 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1270 alive->mux_idx,
1271 HDA_AMP_MUTE, 0);
8ed99d97
TI
1272 if (dead1->pin > 0)
1273 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1274 dead1->mux_idx,
1275 HDA_AMP_MUTE, HDA_AMP_MUTE);
1276 if (dead2->pin > 0)
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1278 dead2->mux_idx,
1279 HDA_AMP_MUTE, HDA_AMP_MUTE);
6c819492
TI
1280 } else {
1281 /* MUX style (e.g. ALC880) */
1282 snd_hda_codec_write_cache(codec, cap_nid, 0,
1283 AC_VERB_SET_CONNECT_SEL,
1284 alive->mux_idx);
1285 }
cd372fb3 1286 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1287
1288 /* FIXME: analog mixer */
7fb0d78f
KY
1289}
1290
c9b58006
KY
1291/* unsolicited event for HP jack sensing */
1292static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1293{
1294 if (codec->vendor_id == 0x10ec0880)
1295 res >>= 28;
1296 else
1297 res >>= 26;
a9fd4f3f
TI
1298 switch (res) {
1299 case ALC880_HP_EVENT:
d922b51d 1300 alc_hp_automute(codec);
a9fd4f3f 1301 break;
e6a5e1b7
TI
1302 case ALC880_FRONT_EVENT:
1303 alc_line_automute(codec);
1304 break;
a9fd4f3f 1305 case ALC880_MIC_EVENT:
7fb0d78f 1306 alc_mic_automute(codec);
a9fd4f3f
TI
1307 break;
1308 }
7fb0d78f
KY
1309}
1310
1311static void alc_inithook(struct hda_codec *codec)
1312{
d922b51d 1313 alc_hp_automute(codec);
e6a5e1b7 1314 alc_line_automute(codec);
7fb0d78f 1315 alc_mic_automute(codec);
c9b58006
KY
1316}
1317
f9423e7a
KY
1318/* additional initialization for ALC888 variants */
1319static void alc888_coef_init(struct hda_codec *codec)
1320{
1321 unsigned int tmp;
1322
1323 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1324 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1325 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1326 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1327 /* alc888S-VC */
1328 snd_hda_codec_read(codec, 0x20, 0,
1329 AC_VERB_SET_PROC_COEF, 0x830);
1330 else
1331 /* alc888-VB */
1332 snd_hda_codec_read(codec, 0x20, 0,
1333 AC_VERB_SET_PROC_COEF, 0x3030);
1334}
1335
87a8c370
JK
1336static void alc889_coef_init(struct hda_codec *codec)
1337{
1338 unsigned int tmp;
1339
1340 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1341 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1342 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1343 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1344}
1345
3fb4a508
TI
1346/* turn on/off EAPD control (only if available) */
1347static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1348{
1349 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1350 return;
1351 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1352 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1353 on ? 2 : 0);
1354}
1355
691f1fcc
TI
1356/* turn on/off EAPD controls of the codec */
1357static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1358{
1359 /* We currently only handle front, HP */
39fa84e9
TI
1360 static hda_nid_t pins[] = {
1361 0x0f, 0x10, 0x14, 0x15, 0
1362 };
1363 hda_nid_t *p;
1364 for (p = pins; *p; p++)
1365 set_eapd(codec, *p, on);
691f1fcc
TI
1366}
1367
1c716153
TI
1368/* generic shutup callback;
1369 * just turning off EPAD and a little pause for avoiding pop-noise
1370 */
1371static void alc_eapd_shutup(struct hda_codec *codec)
1372{
1373 alc_auto_setup_eapd(codec, false);
1374 msleep(200);
1375}
1376
4a79ba34 1377static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1378{
4a79ba34 1379 unsigned int tmp;
bc9f98a9 1380
39fa84e9 1381 alc_auto_setup_eapd(codec, true);
4a79ba34
TI
1382 switch (type) {
1383 case ALC_INIT_GPIO1:
bc9f98a9
KY
1384 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1385 break;
4a79ba34 1386 case ALC_INIT_GPIO2:
bc9f98a9
KY
1387 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1388 break;
4a79ba34 1389 case ALC_INIT_GPIO3:
bdd148a3
KY
1390 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1391 break;
4a79ba34 1392 case ALC_INIT_DEFAULT:
c9b58006
KY
1393 switch (codec->vendor_id) {
1394 case 0x10ec0260:
1395 snd_hda_codec_write(codec, 0x1a, 0,
1396 AC_VERB_SET_COEF_INDEX, 7);
1397 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1398 AC_VERB_GET_PROC_COEF, 0);
1399 snd_hda_codec_write(codec, 0x1a, 0,
1400 AC_VERB_SET_COEF_INDEX, 7);
1401 snd_hda_codec_write(codec, 0x1a, 0,
1402 AC_VERB_SET_PROC_COEF,
1403 tmp | 0x2010);
1404 break;
1405 case 0x10ec0262:
1406 case 0x10ec0880:
1407 case 0x10ec0882:
1408 case 0x10ec0883:
1409 case 0x10ec0885:
4a5a4c56 1410 case 0x10ec0887:
20b67ddd 1411 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1412 alc889_coef_init(codec);
c9b58006 1413 break;
f9423e7a 1414 case 0x10ec0888:
4a79ba34 1415 alc888_coef_init(codec);
f9423e7a 1416 break;
0aea778e 1417#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1418 case 0x10ec0267:
1419 case 0x10ec0268:
1420 snd_hda_codec_write(codec, 0x20, 0,
1421 AC_VERB_SET_COEF_INDEX, 7);
1422 tmp = snd_hda_codec_read(codec, 0x20, 0,
1423 AC_VERB_GET_PROC_COEF, 0);
1424 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1425 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1426 snd_hda_codec_write(codec, 0x20, 0,
1427 AC_VERB_SET_PROC_COEF,
1428 tmp | 0x3000);
1429 break;
0aea778e 1430#endif /* XXX */
bc9f98a9 1431 }
4a79ba34
TI
1432 break;
1433 }
1434}
1435
1a1455de
TI
1436static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1437 struct snd_ctl_elem_info *uinfo)
1438{
ae8a60a5
TI
1439 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1440 struct alc_spec *spec = codec->spec;
1441 static const char * const texts2[] = {
1442 "Disabled", "Enabled"
1443 };
1444 static const char * const texts3[] = {
1a1455de
TI
1445 "Disabled", "Speaker Only", "Line-Out+Speaker"
1446 };
ae8a60a5 1447 const char * const *texts;
1a1455de
TI
1448
1449 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1450 uinfo->count = 1;
ae8a60a5
TI
1451 if (spec->automute_hp_lo) {
1452 uinfo->value.enumerated.items = 3;
1453 texts = texts3;
1454 } else {
1455 uinfo->value.enumerated.items = 2;
1456 texts = texts2;
1457 }
1458 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1459 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1460 strcpy(uinfo->value.enumerated.name,
1461 texts[uinfo->value.enumerated.item]);
1462 return 0;
1463}
1464
1465static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1466 struct snd_ctl_elem_value *ucontrol)
1467{
1468 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1469 struct alc_spec *spec = codec->spec;
1470 unsigned int val;
1471 if (!spec->automute)
1472 val = 0;
1473 else if (!spec->automute_lines)
1474 val = 1;
1475 else
1476 val = 2;
1477 ucontrol->value.enumerated.item[0] = val;
1478 return 0;
1479}
1480
1481static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1482 struct snd_ctl_elem_value *ucontrol)
1483{
1484 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1485 struct alc_spec *spec = codec->spec;
1486
1487 switch (ucontrol->value.enumerated.item[0]) {
1488 case 0:
1489 if (!spec->automute)
1490 return 0;
1491 spec->automute = 0;
1492 break;
1493 case 1:
1494 if (spec->automute && !spec->automute_lines)
1495 return 0;
1496 spec->automute = 1;
1497 spec->automute_lines = 0;
1498 break;
1499 case 2:
ae8a60a5
TI
1500 if (!spec->automute_hp_lo)
1501 return -EINVAL;
1a1455de
TI
1502 if (spec->automute && spec->automute_lines)
1503 return 0;
1504 spec->automute = 1;
1505 spec->automute_lines = 1;
1506 break;
1507 default:
1508 return -EINVAL;
1509 }
1510 update_speakers(codec);
1511 return 1;
1512}
1513
a9111321 1514static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = "Auto-Mute Mode",
1517 .info = alc_automute_mode_info,
1518 .get = alc_automute_mode_get,
1519 .put = alc_automute_mode_put,
1520};
1521
1522static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1523
1524static int alc_add_automute_mode_enum(struct hda_codec *codec)
1525{
1526 struct alc_spec *spec = codec->spec;
1527 struct snd_kcontrol_new *knew;
1528
1529 knew = alc_kcontrol_new(spec);
1530 if (!knew)
1531 return -ENOMEM;
1532 *knew = alc_automute_mode_enum;
1533 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1534 if (!knew->name)
1535 return -ENOMEM;
1536 return 0;
1537}
1538
4a79ba34
TI
1539static void alc_init_auto_hp(struct hda_codec *codec)
1540{
1541 struct alc_spec *spec = codec->spec;
bb35febd 1542 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1543 int present = 0;
bb35febd 1544 int i;
4a79ba34 1545
1daf5f46
TI
1546 if (cfg->hp_pins[0])
1547 present++;
1548 if (cfg->line_out_pins[0])
1549 present++;
1550 if (cfg->speaker_pins[0])
1551 present++;
1552 if (present < 2) /* need two different output types */
1553 return;
ae8a60a5
TI
1554 if (present == 3)
1555 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1556
bb35febd 1557 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1558 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1559 sizeof(cfg->speaker_pins));
1560 cfg->speaker_outs = cfg->line_outs;
1561 }
1562
1563 if (!cfg->hp_pins[0]) {
1564 memcpy(cfg->hp_pins, cfg->line_out_pins,
1565 sizeof(cfg->hp_pins));
1566 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1567 }
1568
bb35febd 1569 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1570 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1571 if (!is_jack_detectable(codec, nid))
1a1455de 1572 continue;
bb35febd 1573 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1574 nid);
1575 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1576 AC_VERB_SET_UNSOLICITED_ENABLE,
1577 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1578 spec->automute = 1;
1579 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1580 }
1a1455de
TI
1581 if (spec->automute && cfg->line_out_pins[0] &&
1582 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1583 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1584 for (i = 0; i < cfg->line_outs; i++) {
1585 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1586 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1587 continue;
1588 snd_printdd("realtek: Enable Line-Out auto-muting "
1589 "on NID 0x%x\n", nid);
1590 snd_hda_codec_write_cache(codec, nid, 0,
1591 AC_VERB_SET_UNSOLICITED_ENABLE,
1592 AC_USRSP_EN | ALC880_FRONT_EVENT);
1593 spec->detect_line = 1;
1594 }
52d3cb88 1595 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1596 }
1597
1598 if (spec->automute) {
1a1455de
TI
1599 /* create a control for automute mode */
1600 alc_add_automute_mode_enum(codec);
ae8a60a5 1601 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1602 }
4a79ba34
TI
1603}
1604
6c819492
TI
1605static void alc_init_auto_mic(struct hda_codec *codec)
1606{
1607 struct alc_spec *spec = codec->spec;
1608 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1609 hda_nid_t fixed, ext, dock;
6c819492
TI
1610 int i;
1611
8ed99d97 1612 fixed = ext = dock = 0;
66ceeb6b
TI
1613 for (i = 0; i < cfg->num_inputs; i++) {
1614 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1615 unsigned int defcfg;
6c819492 1616 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1617 switch (snd_hda_get_input_pin_attr(defcfg)) {
1618 case INPUT_PIN_ATTR_INT:
6c819492
TI
1619 if (fixed)
1620 return; /* already occupied */
8ed99d97
TI
1621 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1622 return; /* invalid type */
6c819492
TI
1623 fixed = nid;
1624 break;
99ae28be
TI
1625 case INPUT_PIN_ATTR_UNUSED:
1626 return; /* invalid entry */
8ed99d97
TI
1627 case INPUT_PIN_ATTR_DOCK:
1628 if (dock)
1629 return; /* already occupied */
1630 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1631 return; /* invalid type */
1632 dock = nid;
1633 break;
99ae28be 1634 default:
6c819492
TI
1635 if (ext)
1636 return; /* already occupied */
8ed99d97
TI
1637 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1638 return; /* invalid type */
6c819492
TI
1639 ext = nid;
1640 break;
6c819492
TI
1641 }
1642 }
8ed99d97
TI
1643 if (!ext && dock) {
1644 ext = dock;
1645 dock = 0;
1646 }
eaa9b3a7
TI
1647 if (!ext || !fixed)
1648 return;
e35d9d6a 1649 if (!is_jack_detectable(codec, ext))
6c819492 1650 return; /* no unsol support */
8ed99d97
TI
1651 if (dock && !is_jack_detectable(codec, dock))
1652 return; /* no unsol support */
1653 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1654 ext, fixed, dock);
6c819492 1655 spec->ext_mic.pin = ext;
8ed99d97 1656 spec->dock_mic.pin = dock;
6c819492
TI
1657 spec->int_mic.pin = fixed;
1658 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1659 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1660 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1661 spec->auto_mic = 1;
1662 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1663 AC_VERB_SET_UNSOLICITED_ENABLE,
1664 AC_USRSP_EN | ALC880_MIC_EVENT);
1665 spec->unsol_event = alc_sku_unsol_event;
1666}
1667
90622917
DH
1668/* Could be any non-zero and even value. When used as fixup, tells
1669 * the driver to ignore any present sku defines.
1670 */
1671#define ALC_FIXUP_SKU_IGNORE (2)
1672
da00c244
KY
1673static int alc_auto_parse_customize_define(struct hda_codec *codec)
1674{
1675 unsigned int ass, tmp, i;
7fb56223 1676 unsigned nid = 0;
da00c244
KY
1677 struct alc_spec *spec = codec->spec;
1678
b6cbe517
TI
1679 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1680
90622917
DH
1681 if (spec->cdefine.fixup) {
1682 ass = spec->cdefine.sku_cfg;
1683 if (ass == ALC_FIXUP_SKU_IGNORE)
1684 return -1;
1685 goto do_sku;
1686 }
1687
da00c244 1688 ass = codec->subsystem_id & 0xffff;
b6cbe517 1689 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1690 goto do_sku;
1691
1692 nid = 0x1d;
1693 if (codec->vendor_id == 0x10ec0260)
1694 nid = 0x17;
1695 ass = snd_hda_codec_get_pincfg(codec, nid);
1696
1697 if (!(ass & 1)) {
1698 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1699 codec->chip_name, ass);
1700 return -1;
1701 }
1702
1703 /* check sum */
1704 tmp = 0;
1705 for (i = 1; i < 16; i++) {
1706 if ((ass >> i) & 1)
1707 tmp++;
1708 }
1709 if (((ass >> 16) & 0xf) != tmp)
1710 return -1;
1711
1712 spec->cdefine.port_connectivity = ass >> 30;
1713 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1714 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1715 spec->cdefine.customization = ass >> 8;
1716do_sku:
1717 spec->cdefine.sku_cfg = ass;
1718 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1719 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1720 spec->cdefine.swap = (ass & 0x2) >> 1;
1721 spec->cdefine.override = ass & 0x1;
1722
1723 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1724 nid, spec->cdefine.sku_cfg);
1725 snd_printd("SKU: port_connectivity=0x%x\n",
1726 spec->cdefine.port_connectivity);
1727 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1728 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1729 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1730 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1731 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1732 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1733 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1734
1735 return 0;
1736}
1737
3af9ee6b
TI
1738static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1739{
1740 int i;
1741 for (i = 0; i < nums; i++)
1742 if (list[i] == nid)
1743 return true;
1744 return false;
1745}
1746
4a79ba34
TI
1747/* check subsystem ID and set up device-specific initialization;
1748 * return 1 if initialized, 0 if invalid SSID
1749 */
1750/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1751 * 31 ~ 16 : Manufacture ID
1752 * 15 ~ 8 : SKU ID
1753 * 7 ~ 0 : Assembly ID
1754 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1755 */
1756static int alc_subsystem_id(struct hda_codec *codec,
1757 hda_nid_t porta, hda_nid_t porte,
6227cdce 1758 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1759{
1760 unsigned int ass, tmp, i;
1761 unsigned nid;
1762 struct alc_spec *spec = codec->spec;
1763
90622917
DH
1764 if (spec->cdefine.fixup) {
1765 ass = spec->cdefine.sku_cfg;
1766 if (ass == ALC_FIXUP_SKU_IGNORE)
1767 return 0;
1768 goto do_sku;
1769 }
1770
4a79ba34
TI
1771 ass = codec->subsystem_id & 0xffff;
1772 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1773 goto do_sku;
1774
1775 /* invalid SSID, check the special NID pin defcfg instead */
1776 /*
def319f9 1777 * 31~30 : port connectivity
4a79ba34
TI
1778 * 29~21 : reserve
1779 * 20 : PCBEEP input
1780 * 19~16 : Check sum (15:1)
1781 * 15~1 : Custom
1782 * 0 : override
1783 */
1784 nid = 0x1d;
1785 if (codec->vendor_id == 0x10ec0260)
1786 nid = 0x17;
1787 ass = snd_hda_codec_get_pincfg(codec, nid);
1788 snd_printd("realtek: No valid SSID, "
1789 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1790 ass, nid);
6227cdce 1791 if (!(ass & 1))
4a79ba34
TI
1792 return 0;
1793 if ((ass >> 30) != 1) /* no physical connection */
1794 return 0;
1795
1796 /* check sum */
1797 tmp = 0;
1798 for (i = 1; i < 16; i++) {
1799 if ((ass >> i) & 1)
1800 tmp++;
1801 }
1802 if (((ass >> 16) & 0xf) != tmp)
1803 return 0;
1804do_sku:
1805 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1806 ass & 0xffff, codec->vendor_id);
1807 /*
1808 * 0 : override
1809 * 1 : Swap Jack
1810 * 2 : 0 --> Desktop, 1 --> Laptop
1811 * 3~5 : External Amplifier control
1812 * 7~6 : Reserved
1813 */
1814 tmp = (ass & 0x38) >> 3; /* external Amp control */
1815 switch (tmp) {
1816 case 1:
1817 spec->init_amp = ALC_INIT_GPIO1;
1818 break;
1819 case 3:
1820 spec->init_amp = ALC_INIT_GPIO2;
1821 break;
1822 case 7:
1823 spec->init_amp = ALC_INIT_GPIO3;
1824 break;
1825 case 5:
5a8cfb4e 1826 default:
4a79ba34 1827 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1828 break;
1829 }
ea1fb29a 1830
8c427226 1831 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1832 * when the external headphone out jack is plugged"
1833 */
8c427226 1834 if (!(ass & 0x8000))
4a79ba34 1835 return 1;
c9b58006
KY
1836 /*
1837 * 10~8 : Jack location
1838 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1839 * 14~13: Resvered
1840 * 15 : 1 --> enable the function "Mute internal speaker
1841 * when the external headphone out jack is plugged"
1842 */
c9b58006 1843 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1844 hda_nid_t nid;
c9b58006
KY
1845 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1846 if (tmp == 0)
01d4825d 1847 nid = porta;
c9b58006 1848 else if (tmp == 1)
01d4825d 1849 nid = porte;
c9b58006 1850 else if (tmp == 2)
01d4825d 1851 nid = portd;
6227cdce
KY
1852 else if (tmp == 3)
1853 nid = porti;
c9b58006 1854 else
4a79ba34 1855 return 1;
3af9ee6b
TI
1856 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1857 spec->autocfg.line_outs))
1858 return 1;
01d4825d 1859 spec->autocfg.hp_pins[0] = nid;
c9b58006 1860 }
4a79ba34
TI
1861 return 1;
1862}
ea1fb29a 1863
4a79ba34 1864static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1865 hda_nid_t porta, hda_nid_t porte,
1866 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1867{
6227cdce 1868 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1869 struct alc_spec *spec = codec->spec;
1870 snd_printd("realtek: "
1871 "Enable default setup for auto mode as fallback\n");
1872 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1873 }
1a1455de
TI
1874
1875 alc_init_auto_hp(codec);
1876 alc_init_auto_mic(codec);
bc9f98a9
KY
1877}
1878
f95474ec 1879/*
f8f25ba3 1880 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1881 */
1882
1883struct alc_pincfg {
1884 hda_nid_t nid;
1885 u32 val;
1886};
1887
e1eb5f10
TB
1888struct alc_model_fixup {
1889 const int id;
1890 const char *name;
1891};
1892
f8f25ba3 1893struct alc_fixup {
b5bfbc67 1894 int type;
361fe6e9
TI
1895 bool chained;
1896 int chain_id;
b5bfbc67
TI
1897 union {
1898 unsigned int sku;
1899 const struct alc_pincfg *pins;
1900 const struct hda_verb *verbs;
1901 void (*func)(struct hda_codec *codec,
1902 const struct alc_fixup *fix,
1903 int action);
1904 } v;
f8f25ba3
TI
1905};
1906
b5bfbc67
TI
1907enum {
1908 ALC_FIXUP_INVALID,
1909 ALC_FIXUP_SKU,
1910 ALC_FIXUP_PINS,
1911 ALC_FIXUP_VERBS,
1912 ALC_FIXUP_FUNC,
1913};
1914
1915enum {
1916 ALC_FIXUP_ACT_PRE_PROBE,
1917 ALC_FIXUP_ACT_PROBE,
58701120 1918 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1919};
1920
1921static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1922{
b5bfbc67
TI
1923 struct alc_spec *spec = codec->spec;
1924 int id = spec->fixup_id;
aa1d0c52 1925#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1926 const char *modelname = spec->fixup_name;
aa1d0c52 1927#endif
b5bfbc67 1928 int depth = 0;
f95474ec 1929
b5bfbc67
TI
1930 if (!spec->fixup_list)
1931 return;
1932
1933 while (id >= 0) {
1934 const struct alc_fixup *fix = spec->fixup_list + id;
1935 const struct alc_pincfg *cfg;
1936
1937 switch (fix->type) {
1938 case ALC_FIXUP_SKU:
1939 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1940 break;;
1941 snd_printdd(KERN_INFO "hda_codec: %s: "
1942 "Apply sku override for %s\n",
1943 codec->chip_name, modelname);
1944 spec->cdefine.sku_cfg = fix->v.sku;
1945 spec->cdefine.fixup = 1;
1946 break;
1947 case ALC_FIXUP_PINS:
1948 cfg = fix->v.pins;
1949 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1950 break;
1951 snd_printdd(KERN_INFO "hda_codec: %s: "
1952 "Apply pincfg for %s\n",
1953 codec->chip_name, modelname);
1954 for (; cfg->nid; cfg++)
1955 snd_hda_codec_set_pincfg(codec, cfg->nid,
1956 cfg->val);
1957 break;
1958 case ALC_FIXUP_VERBS:
1959 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1960 break;
1961 snd_printdd(KERN_INFO "hda_codec: %s: "
1962 "Apply fix-verbs for %s\n",
1963 codec->chip_name, modelname);
1964 add_verb(codec->spec, fix->v.verbs);
1965 break;
1966 case ALC_FIXUP_FUNC:
1967 if (!fix->v.func)
1968 break;
1969 snd_printdd(KERN_INFO "hda_codec: %s: "
1970 "Apply fix-func for %s\n",
1971 codec->chip_name, modelname);
1972 fix->v.func(codec, fix, action);
1973 break;
1974 default:
1975 snd_printk(KERN_ERR "hda_codec: %s: "
1976 "Invalid fixup type %d\n",
1977 codec->chip_name, fix->type);
1978 break;
1979 }
24af2b1c 1980 if (!fix->chained)
b5bfbc67
TI
1981 break;
1982 if (++depth > 10)
1983 break;
24af2b1c 1984 id = fix->chain_id;
9d57883f 1985 }
f95474ec
TI
1986}
1987
e1eb5f10 1988static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1989 const struct alc_model_fixup *models,
1990 const struct snd_pci_quirk *quirk,
1991 const struct alc_fixup *fixlist)
e1eb5f10 1992{
b5bfbc67
TI
1993 struct alc_spec *spec = codec->spec;
1994 int id = -1;
1995 const char *name = NULL;
e1eb5f10 1996
e1eb5f10
TB
1997 if (codec->modelname && models) {
1998 while (models->name) {
1999 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2000 id = models->id;
2001 name = models->name;
e1eb5f10
TB
2002 break;
2003 }
2004 models++;
2005 }
b5bfbc67
TI
2006 }
2007 if (id < 0) {
2008 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2009 if (quirk) {
2010 id = quirk->value;
2011#ifdef CONFIG_SND_DEBUG_VERBOSE
2012 name = quirk->name;
2013#endif
2014 }
2015 }
2016
2017 spec->fixup_id = id;
2018 if (id >= 0) {
2019 spec->fixup_list = fixlist;
2020 spec->fixup_name = name;
e1eb5f10 2021 }
f95474ec
TI
2022}
2023
274693f3
KY
2024static int alc_read_coef_idx(struct hda_codec *codec,
2025 unsigned int coef_idx)
2026{
2027 unsigned int val;
2028 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2029 coef_idx);
2030 val = snd_hda_codec_read(codec, 0x20, 0,
2031 AC_VERB_GET_PROC_COEF, 0);
2032 return val;
2033}
2034
977ddd6b
KY
2035static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2036 unsigned int coef_val)
2037{
2038 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2039 coef_idx);
2040 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2041 coef_val);
2042}
2043
757899ac
TI
2044/* set right pin controls for digital I/O */
2045static void alc_auto_init_digital(struct hda_codec *codec)
2046{
2047 struct alc_spec *spec = codec->spec;
2048 int i;
1f0f4b80 2049 hda_nid_t pin, dac;
757899ac
TI
2050
2051 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2052 pin = spec->autocfg.dig_out_pins[i];
1f0f4b80
TI
2053 if (!pin)
2054 continue;
2055 snd_hda_codec_write(codec, pin, 0,
2056 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2057 if (!i)
2058 dac = spec->multiout.dig_out_nid;
2059 else
2060 dac = spec->slave_dig_outs[i - 1];
2061 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2062 continue;
2063 snd_hda_codec_write(codec, dac, 0,
2064 AC_VERB_SET_AMP_GAIN_MUTE,
2065 AMP_OUT_UNMUTE);
757899ac
TI
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;
d6cc9fab 2681 unsigned long val;
f9e336f6 2682 int err;
1da177e4 2683
5a9e02e9 2684 mutex_lock(&codec->control_mutex);
d6cc9fab
TI
2685 if (spec->vol_in_capsrc)
2686 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2687 else
2688 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2689 kcontrol->private_value = val;
f9e336f6 2690 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2691 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2692 return err;
2693}
2694
2695static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2696 unsigned int size, unsigned int __user *tlv)
2697{
2698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2699 struct alc_spec *spec = codec->spec;
d6cc9fab 2700 unsigned long val;
f9e336f6 2701 int err;
1da177e4 2702
5a9e02e9 2703 mutex_lock(&codec->control_mutex);
d6cc9fab
TI
2704 if (spec->vol_in_capsrc)
2705 val = HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[0], 3, 0, HDA_OUTPUT);
2706 else
2707 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, HDA_INPUT);
2708 kcontrol->private_value = val;
f9e336f6 2709 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2710 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2711 return err;
2712}
2713
2714typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2715 struct snd_ctl_elem_value *ucontrol);
2716
2717static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2718 struct snd_ctl_elem_value *ucontrol,
9c7a083d 2719 getput_call_t func, bool check_adc_switch)
f9e336f6
TI
2720{
2721 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2722 struct alc_spec *spec = codec->spec;
9c7a083d 2723 int i, err;
f9e336f6 2724
5a9e02e9 2725 mutex_lock(&codec->control_mutex);
9c7a083d
TI
2726 if (check_adc_switch && spec->dual_adc_switch) {
2727 for (i = 0; i < spec->num_adc_nids; i++) {
2728 kcontrol->private_value =
2729 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2730 3, 0, HDA_INPUT);
2731 err = func(kcontrol, ucontrol);
2732 if (err < 0)
2733 goto error;
2734 }
2735 } else {
2736 i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
d6cc9fab
TI
2737 if (spec->vol_in_capsrc)
2738 kcontrol->private_value =
2739 HDA_COMPOSE_AMP_VAL(spec->capsrc_nids[i],
2740 3, 0, HDA_OUTPUT);
2741 else
2742 kcontrol->private_value =
2743 val = HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
2744 3, 0, HDA_INPUT);
9c7a083d
TI
2745 err = func(kcontrol, ucontrol);
2746 }
2747 error:
5a9e02e9 2748 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2749 return err;
2750}
2751
2752static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2754{
2755 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2756 snd_hda_mixer_amp_volume_get, false);
f9e336f6
TI
2757}
2758
2759static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2761{
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2763 snd_hda_mixer_amp_volume_put, true);
f9e336f6
TI
2764}
2765
2766/* capture mixer elements */
2767#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2768
2769static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2770 struct snd_ctl_elem_value *ucontrol)
2771{
2772 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2773 snd_hda_mixer_amp_switch_get, false);
f9e336f6
TI
2774}
2775
2776static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2777 struct snd_ctl_elem_value *ucontrol)
2778{
2779 return alc_cap_getput_caller(kcontrol, ucontrol,
9c7a083d 2780 snd_hda_mixer_amp_switch_put, true);
f9e336f6
TI
2781}
2782
a23b688f 2783#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2784 { \
2785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2786 .name = "Capture Switch", \
2787 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2788 .count = num, \
2789 .info = alc_cap_sw_info, \
2790 .get = alc_cap_sw_get, \
2791 .put = alc_cap_sw_put, \
2792 }, \
2793 { \
2794 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2795 .name = "Capture Volume", \
2796 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2797 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2798 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2799 .count = num, \
2800 .info = alc_cap_vol_info, \
2801 .get = alc_cap_vol_get, \
2802 .put = alc_cap_vol_put, \
2803 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2804 }
2805
2806#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2807 { \
2808 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2809 /* .name = "Capture Source", */ \
2810 .name = "Input Source", \
2811 .count = num, \
2812 .info = alc_mux_enum_info, \
2813 .get = alc_mux_enum_get, \
2814 .put = alc_mux_enum_put, \
a23b688f
TI
2815 }
2816
2817#define DEFINE_CAPMIX(num) \
a9111321 2818static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2819 _DEFINE_CAPMIX(num), \
2820 _DEFINE_CAPSRC(num), \
2821 { } /* end */ \
2822}
2823
2824#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2825static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2826 _DEFINE_CAPMIX(num), \
2827 { } /* end */ \
f9e336f6
TI
2828}
2829
2830/* up to three ADCs */
2831DEFINE_CAPMIX(1);
2832DEFINE_CAPMIX(2);
2833DEFINE_CAPMIX(3);
a23b688f
TI
2834DEFINE_CAPMIX_NOSRC(1);
2835DEFINE_CAPMIX_NOSRC(2);
2836DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2837
2838/*
2839 * ALC880 5-stack model
2840 *
9c7f852e
TI
2841 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2842 * Side = 0x02 (0xd)
e9edcee0
TI
2843 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2844 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2845 */
2846
2847/* additional mixers to alc880_three_stack_mixer */
a9111321 2848static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2849 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2850 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2851 { } /* end */
2852};
2853
e9edcee0
TI
2854/* channel source setting (6/8 channel selection for 5-stack) */
2855/* 6ch mode */
a9111321 2856static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2857 /* set line-in to input, mute it */
2858 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2859 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2860 { } /* end */
2861};
2862
e9edcee0 2863/* 8ch mode */
a9111321 2864static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2865 /* set line-in to output, unmute it */
2866 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2867 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2868 { } /* end */
2869};
2870
a9111321 2871static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2872 { 6, alc880_fivestack_ch6_init },
2873 { 8, alc880_fivestack_ch8_init },
2874};
2875
2876
2877/*
2878 * ALC880 6-stack model
2879 *
9c7f852e
TI
2880 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2881 * Side = 0x05 (0x0f)
e9edcee0
TI
2882 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2883 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2884 */
2885
4c6d72d1 2886static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2887 /* front, rear, clfe, rear_surr */
2888 0x02, 0x03, 0x04, 0x05
f12ab1e0 2889};
e9edcee0 2890
a9111321 2891static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2892 .num_items = 4,
2893 .items = {
2894 { "Mic", 0x0 },
2895 { "Front Mic", 0x1 },
2896 { "Line", 0x2 },
2897 { "CD", 0x4 },
2898 },
2899};
2900
2901/* fixed 8-channels */
a9111321 2902static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2903 { 8, NULL },
2904};
2905
a9111321 2906static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2907 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2908 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2909 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2910 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2911 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2912 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2913 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2914 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2915 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2916 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2917 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2918 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2919 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2920 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2924 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2925 {
2926 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2927 .name = "Channel Mode",
df694daa
KY
2928 .info = alc_ch_mode_info,
2929 .get = alc_ch_mode_get,
2930 .put = alc_ch_mode_put,
16ded525
TI
2931 },
2932 { } /* end */
2933};
2934
e9edcee0
TI
2935
2936/*
2937 * ALC880 W810 model
2938 *
2939 * W810 has rear IO for:
2940 * Front (DAC 02)
2941 * Surround (DAC 03)
2942 * Center/LFE (DAC 04)
2943 * Digital out (06)
2944 *
2945 * The system also has a pair of internal speakers, and a headphone jack.
2946 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2947 *
e9edcee0
TI
2948 * There is a variable resistor to control the speaker or headphone
2949 * volume. This is a hardware-only device without a software API.
2950 *
2951 * Plugging headphones in will disable the internal speakers. This is
2952 * implemented in hardware, not via the driver using jack sense. In
2953 * a similar fashion, plugging into the rear socket marked "front" will
2954 * disable both the speakers and headphones.
2955 *
2956 * For input, there's a microphone jack, and an "audio in" jack.
2957 * These may not do anything useful with this driver yet, because I
2958 * haven't setup any initialization verbs for these yet...
2959 */
2960
4c6d72d1 2961static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2962 /* front, rear/surround, clfe */
2963 0x02, 0x03, 0x04
16ded525
TI
2964};
2965
e9edcee0 2966/* fixed 6 channels */
a9111321 2967static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2968 { 6, NULL }
2969};
2970
2971/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2972static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2973 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2974 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2975 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2976 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2977 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2978 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2979 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2980 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2981 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2982 { } /* end */
2983};
2984
2985
2986/*
2987 * Z710V model
2988 *
2989 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2990 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2991 * Line = 0x1a
e9edcee0
TI
2992 */
2993
4c6d72d1 2994static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2995 0x02
2996};
2997#define ALC880_Z71V_HP_DAC 0x03
2998
2999/* fixed 2 channels */
a9111321 3000static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
3001 { 2, NULL }
3002};
3003
a9111321 3004static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 3005 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3006 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 3007 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3008 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3009 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3010 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
3011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3013 { } /* end */
3014};
3015
e9edcee0 3016
e9edcee0
TI
3017/*
3018 * ALC880 F1734 model
3019 *
3020 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3021 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3022 */
3023
4c6d72d1 3024static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
3025 0x03
3026};
3027#define ALC880_F1734_HP_DAC 0x02
3028
a9111321 3029static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3030 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3031 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3032 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3033 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3034 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3035 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3036 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3037 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3038 { } /* end */
3039};
3040
a9111321 3041static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3042 .num_items = 2,
3043 .items = {
3044 { "Mic", 0x1 },
3045 { "CD", 0x4 },
3046 },
3047};
3048
e9edcee0 3049
e9edcee0
TI
3050/*
3051 * ALC880 ASUS model
3052 *
3053 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3054 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3055 * Mic = 0x18, Line = 0x1a
3056 */
3057
3058#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3059#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3060
a9111321 3061static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3064 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3065 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3066 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3067 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3068 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3069 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3070 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3071 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3076 {
3077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3078 .name = "Channel Mode",
df694daa
KY
3079 .info = alc_ch_mode_info,
3080 .get = alc_ch_mode_get,
3081 .put = alc_ch_mode_put,
16ded525
TI
3082 },
3083 { } /* end */
3084};
e9edcee0 3085
e9edcee0
TI
3086/*
3087 * ALC880 ASUS W1V model
3088 *
3089 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3090 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3091 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3092 */
3093
3094/* additional mixers to alc880_asus_mixer */
a9111321 3095static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3096 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3097 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3098 { } /* end */
3099};
3100
df694daa 3101/* TCL S700 */
a9111321 3102static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3103 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3104 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3105 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3107 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3111 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3112 { } /* end */
3113};
3114
ccc656ce 3115/* Uniwill */
a9111321 3116static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3117 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3118 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3119 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3120 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3121 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3122 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3123 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3124 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3125 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3126 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3127 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3128 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3132 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3133 {
3134 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3135 .name = "Channel Mode",
3136 .info = alc_ch_mode_info,
3137 .get = alc_ch_mode_get,
3138 .put = alc_ch_mode_put,
3139 },
3140 { } /* end */
3141};
3142
a9111321 3143static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3144 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3145 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3146 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3147 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3148 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3149 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3152 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3153 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3154 { } /* end */
3155};
3156
a9111321 3157static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3158 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3159 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3160 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3161 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3164 { } /* end */
3165};
3166
2134ea4f
TI
3167/*
3168 * virtual master controls
3169 */
3170
3171/*
3172 * slave controls for virtual master
3173 */
ea734963 3174static const char * const alc_slave_vols[] = {
2134ea4f
TI
3175 "Front Playback Volume",
3176 "Surround Playback Volume",
3177 "Center Playback Volume",
3178 "LFE Playback Volume",
3179 "Side Playback Volume",
3180 "Headphone Playback Volume",
3181 "Speaker Playback Volume",
3182 "Mono Playback Volume",
2134ea4f
TI
3183 "Line-Out Playback Volume",
3184 NULL,
3185};
3186
ea734963 3187static const char * const alc_slave_sws[] = {
2134ea4f
TI
3188 "Front Playback Switch",
3189 "Surround Playback Switch",
3190 "Center Playback Switch",
3191 "LFE Playback Switch",
3192 "Side Playback Switch",
3193 "Headphone Playback Switch",
3194 "Speaker Playback Switch",
3195 "Mono Playback Switch",
edb54a55 3196 "IEC958 Playback Switch",
23033b2b 3197 "Line-Out Playback Switch",
2134ea4f
TI
3198 NULL,
3199};
3200
1da177e4 3201/*
e9edcee0 3202 * build control elements
1da177e4 3203 */
603c4019 3204
5b0cb1d8
JK
3205#define NID_MAPPING (-1)
3206
3207#define SUBDEV_SPEAKER_ (0 << 6)
3208#define SUBDEV_HP_ (1 << 6)
3209#define SUBDEV_LINE_ (2 << 6)
3210#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3211#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3212#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3213
603c4019
TI
3214static void alc_free_kctls(struct hda_codec *codec);
3215
67d634c0 3216#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3217/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3218static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3219 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3220 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3221 { } /* end */
3222};
67d634c0 3223#endif
45bdd1c1 3224
1da177e4
LT
3225static int alc_build_controls(struct hda_codec *codec)
3226{
3227 struct alc_spec *spec = codec->spec;
2f44f847 3228 struct snd_kcontrol *kctl = NULL;
a9111321 3229 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3230 int i, j, err;
3231 unsigned int u;
3232 hda_nid_t nid;
1da177e4
LT
3233
3234 for (i = 0; i < spec->num_mixers; i++) {
3235 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3236 if (err < 0)
3237 return err;
3238 }
f9e336f6
TI
3239 if (spec->cap_mixer) {
3240 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3241 if (err < 0)
3242 return err;
3243 }
1da177e4 3244 if (spec->multiout.dig_out_nid) {
9c7f852e 3245 err = snd_hda_create_spdif_out_ctls(codec,
74b654c9 3246 spec->multiout.dig_out_nid,
9c7f852e 3247 spec->multiout.dig_out_nid);
1da177e4
LT
3248 if (err < 0)
3249 return err;
e64f14f4
TI
3250 if (!spec->no_analog) {
3251 err = snd_hda_create_spdif_share_sw(codec,
3252 &spec->multiout);
3253 if (err < 0)
3254 return err;
3255 spec->multiout.share_spdif = 1;
3256 }
1da177e4
LT
3257 }
3258 if (spec->dig_in_nid) {
3259 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3260 if (err < 0)
3261 return err;
3262 }
2134ea4f 3263
67d634c0 3264#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3265 /* create beep controls if needed */
3266 if (spec->beep_amp) {
a9111321 3267 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3268 for (knew = alc_beep_mixer; knew->name; knew++) {
3269 struct snd_kcontrol *kctl;
3270 kctl = snd_ctl_new1(knew, codec);
3271 if (!kctl)
3272 return -ENOMEM;
3273 kctl->private_value = spec->beep_amp;
5e26dfd0 3274 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3275 if (err < 0)
3276 return err;
3277 }
3278 }
67d634c0 3279#endif
45bdd1c1 3280
2134ea4f 3281 /* if we have no master control, let's create it */
e64f14f4
TI
3282 if (!spec->no_analog &&
3283 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3284 unsigned int vmaster_tlv[4];
2134ea4f 3285 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3286 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3287 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3288 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3289 if (err < 0)
3290 return err;
3291 }
e64f14f4
TI
3292 if (!spec->no_analog &&
3293 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3294 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3295 NULL, alc_slave_sws);
3296 if (err < 0)
3297 return err;
3298 }
3299
5b0cb1d8 3300 /* assign Capture Source enums to NID */
fbe618f2
TI
3301 if (spec->capsrc_nids || spec->adc_nids) {
3302 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3303 if (!kctl)
3304 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3305 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3306 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3307 if (!nids)
3308 nids = spec->adc_nids;
3309 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3310 if (err < 0)
3311 return err;
3312 }
5b0cb1d8
JK
3313 }
3314 if (spec->cap_mixer) {
3315 const char *kname = kctl ? kctl->id.name : NULL;
3316 for (knew = spec->cap_mixer; knew->name; knew++) {
3317 if (kname && strcmp(knew->name, kname) == 0)
3318 continue;
3319 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3320 for (i = 0; kctl && i < kctl->count; i++) {
3321 err = snd_hda_add_nid(codec, kctl, i,
3322 spec->adc_nids[i]);
3323 if (err < 0)
3324 return err;
3325 }
3326 }
3327 }
3328
3329 /* other nid->control mapping */
3330 for (i = 0; i < spec->num_mixers; i++) {
3331 for (knew = spec->mixers[i]; knew->name; knew++) {
3332 if (knew->iface != NID_MAPPING)
3333 continue;
3334 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3335 if (kctl == NULL)
3336 continue;
3337 u = knew->subdevice;
3338 for (j = 0; j < 4; j++, u >>= 8) {
3339 nid = u & 0x3f;
3340 if (nid == 0)
3341 continue;
3342 switch (u & 0xc0) {
3343 case SUBDEV_SPEAKER_:
3344 nid = spec->autocfg.speaker_pins[nid];
3345 break;
3346 case SUBDEV_LINE_:
3347 nid = spec->autocfg.line_out_pins[nid];
3348 break;
3349 case SUBDEV_HP_:
3350 nid = spec->autocfg.hp_pins[nid];
3351 break;
3352 default:
3353 continue;
3354 }
3355 err = snd_hda_add_nid(codec, kctl, 0, nid);
3356 if (err < 0)
3357 return err;
3358 }
3359 u = knew->private_value;
3360 for (j = 0; j < 4; j++, u >>= 8) {
3361 nid = u & 0xff;
3362 if (nid == 0)
3363 continue;
3364 err = snd_hda_add_nid(codec, kctl, 0, nid);
3365 if (err < 0)
3366 return err;
3367 }
3368 }
3369 }
bae84e70
TI
3370
3371 alc_free_kctls(codec); /* no longer needed */
3372
1da177e4
LT
3373 return 0;
3374}
3375
e9edcee0 3376
1da177e4
LT
3377/*
3378 * initialize the codec volumes, etc
3379 */
3380
e9edcee0
TI
3381/*
3382 * generic initialization of ADC, input mixers and output mixers
3383 */
a9111321 3384static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3385 /*
3386 * Unmute ADC0-2 and set the default input to mic-in
3387 */
71fe7b82 3388 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3389 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3390 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3391 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3392 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3393 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3394
e9edcee0
TI
3395 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3396 * mixer widget
9c7f852e
TI
3397 * Note: PASD motherboards uses the Line In 2 as the input for front
3398 * panel mic (mic 2)
1da177e4 3399 */
e9edcee0 3400 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3406 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3407 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3408
e9edcee0
TI
3409 /*
3410 * Set up output mixers (0x0c - 0x0f)
1da177e4 3411 */
e9edcee0
TI
3412 /* set vol=0 to output mixers */
3413 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3414 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3415 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3416 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3417 /* set up input amps for analog loopback */
3418 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3419 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3422 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3425 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3427
3428 { }
3429};
3430
e9edcee0
TI
3431/*
3432 * 3-stack pin configuration:
3433 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3434 */
a9111321 3435static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3436 /*
3437 * preset connection lists of input pins
3438 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3439 */
3440 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3441 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3442 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3443
3444 /*
3445 * Set pin mode and muting
3446 */
3447 /* set front pin widgets 0x14 for output */
05acb863 3448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3450 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3451 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3452 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3453 /* Mic2 (as headphone out) for HP output */
3454 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3455 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3456 /* Line In pin widget for input */
05acb863 3457 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3458 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3459 /* Line2 (as front mic) pin widget for input and vref at 80% */
3460 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3461 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3462 /* CD pin widget for input */
05acb863 3463 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3464
e9edcee0
TI
3465 { }
3466};
1da177e4 3467
e9edcee0
TI
3468/*
3469 * 5-stack pin configuration:
3470 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3471 * line-in/side = 0x1a, f-mic = 0x1b
3472 */
a9111321 3473static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3474 /*
3475 * preset connection lists of input pins
3476 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3477 */
e9edcee0
TI
3478 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3479 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3480
e9edcee0
TI
3481 /*
3482 * Set pin mode and muting
1da177e4 3483 */
e9edcee0
TI
3484 /* set pin widgets 0x14-0x17 for output */
3485 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3487 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3488 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3489 /* unmute pins for output (no gain on this amp) */
3490 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3491 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3492 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3494
3495 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3496 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3497 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3498 /* Mic2 (as headphone out) for HP output */
3499 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3500 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3501 /* Line In pin widget for input */
3502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3504 /* Line2 (as front mic) pin widget for input and vref at 80% */
3505 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3506 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3507 /* CD pin widget for input */
3508 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3509
3510 { }
3511};
3512
e9edcee0
TI
3513/*
3514 * W810 pin configuration:
3515 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3516 */
a9111321 3517static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3518 /* hphone/speaker input selector: front DAC */
3519 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3520
05acb863 3521 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3522 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3523 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3524 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3526 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3527
e9edcee0 3528 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3529 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3530
1da177e4
LT
3531 { }
3532};
3533
e9edcee0
TI
3534/*
3535 * Z71V pin configuration:
3536 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3537 */
a9111321 3538static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3539 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3542 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3543
16ded525 3544 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3545 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3547 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3548
3549 { }
3550};
3551
e9edcee0
TI
3552/*
3553 * 6-stack pin configuration:
9c7f852e
TI
3554 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3555 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3556 */
a9111321 3557static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3558 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3559
16ded525 3560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3561 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3562 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3563 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3564 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3565 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3566 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3567 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3568
16ded525 3569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3571 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3572 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3574 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3575 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3576 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3577 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3578
e9edcee0
TI
3579 { }
3580};
3581
ccc656ce
KY
3582/*
3583 * Uniwill pin configuration:
3584 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3585 * line = 0x1a
3586 */
a9111321 3587static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3588 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3589
3590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3591 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3592 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3593 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3594 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3595 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3596 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3598 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3599 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3600 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3601 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3602 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3603 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3604
3605 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3606 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3607 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3608 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3609 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3610 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3611 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3612 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3613 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3614
3615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3616 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3617
3618 { }
3619};
3620
3621/*
3622* Uniwill P53
ea1fb29a 3623* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3624 */
a9111321 3625static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3626 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3627
3628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3629 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3630 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3631 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3632 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3633 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3637 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3638 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3639 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3640
3641 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3643 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3645 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3647
3648 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3649 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3650
3651 { }
3652};
3653
a9111321 3654static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3655 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3656 { }
3657};
3658
458a4fab 3659/* auto-toggle front mic */
eeb43387 3660static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3661{
3662 unsigned int present;
3663 unsigned char bits;
ccc656ce 3664
864f92be 3665 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3666 bits = present ? HDA_AMP_MUTE : 0;
3667 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3668}
3669
4f5d1706 3670static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3671{
a9fd4f3f
TI
3672 struct alc_spec *spec = codec->spec;
3673
3674 spec->autocfg.hp_pins[0] = 0x14;
3675 spec->autocfg.speaker_pins[0] = 0x15;
3676 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3677 spec->automute = 1;
3678 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3679}
3680
3681static void alc880_uniwill_init_hook(struct hda_codec *codec)
3682{
d922b51d 3683 alc_hp_automute(codec);
eeb43387 3684 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3685}
3686
3687static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3688 unsigned int res)
3689{
3690 /* Looks like the unsol event is incompatible with the standard
3691 * definition. 4bit tag is placed at 28 bit!
3692 */
458a4fab 3693 switch (res >> 28) {
458a4fab 3694 case ALC880_MIC_EVENT:
eeb43387 3695 alc88x_simple_mic_automute(codec);
458a4fab 3696 break;
a9fd4f3f 3697 default:
d922b51d 3698 alc_sku_unsol_event(codec, res);
a9fd4f3f 3699 break;
458a4fab 3700 }
ccc656ce
KY
3701}
3702
4f5d1706 3703static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3704{
a9fd4f3f 3705 struct alc_spec *spec = codec->spec;
ccc656ce 3706
a9fd4f3f
TI
3707 spec->autocfg.hp_pins[0] = 0x14;
3708 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3709 spec->automute = 1;
3710 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3711}
3712
3713static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3714{
3715 unsigned int present;
ea1fb29a 3716
ccc656ce 3717 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3718 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3719 present &= HDA_AMP_VOLMASK;
3720 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3721 HDA_AMP_VOLMASK, present);
3722 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3723 HDA_AMP_VOLMASK, present);
ccc656ce 3724}
47fd830a 3725
ccc656ce
KY
3726static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3727 unsigned int res)
3728{
3729 /* Looks like the unsol event is incompatible with the standard
3730 * definition. 4bit tag is placed at 28 bit!
3731 */
f12ab1e0 3732 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3733 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3734 else
d922b51d 3735 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3736}
3737
e9edcee0
TI
3738/*
3739 * F1734 pin configuration:
3740 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3741 */
a9111321 3742static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3743 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3744 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3745 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3746 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3747 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3748
e9edcee0 3749 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3750 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3751 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3752 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3753
e9edcee0
TI
3754 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3755 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3758 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3759 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3760 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3761 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3762 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3763
937b4160
TI
3764 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3765 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3766
dfc0ff62
TI
3767 { }
3768};
3769
e9edcee0
TI
3770/*
3771 * ASUS pin configuration:
3772 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3773 */
a9111321 3774static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3775 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3776 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3777 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3778 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3779
3780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3781 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3782 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3783 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3784 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3785 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3786 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3787 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3788
3789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3790 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3791 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3792 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3793 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3794 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3795 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3797 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3798
e9edcee0
TI
3799 { }
3800};
16ded525 3801
e9edcee0 3802/* Enable GPIO mask and set output */
bc9f98a9
KY
3803#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3804#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3805#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3806
3807/* Clevo m520g init */
a9111321 3808static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3809 /* headphone output */
3810 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3811 /* line-out */
3812 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3813 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3814 /* Line-in */
3815 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3816 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3817 /* CD */
3818 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3819 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3820 /* Mic1 (rear panel) */
3821 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3822 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3823 /* Mic2 (front panel) */
3824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3825 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3826 /* headphone */
3827 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3828 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3829 /* change to EAPD mode */
3830 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3831 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3832
3833 { }
16ded525
TI
3834};
3835
a9111321 3836static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3837 /* change to EAPD mode */
3838 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3839 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3840
df694daa
KY
3841 /* Headphone output */
3842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3843 /* Front output*/
3844 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3845 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3846
3847 /* Line In pin widget for input */
3848 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3849 /* CD pin widget for input */
3850 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3851 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3853
3854 /* change to EAPD mode */
3855 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3856 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3857
3858 { }
3859};
16ded525 3860
e9edcee0 3861/*
ae6b813a
TI
3862 * LG m1 express dual
3863 *
3864 * Pin assignment:
3865 * Rear Line-In/Out (blue): 0x14
3866 * Build-in Mic-In: 0x15
3867 * Speaker-out: 0x17
3868 * HP-Out (green): 0x1b
3869 * Mic-In/Out (red): 0x19
3870 * SPDIF-Out: 0x1e
3871 */
3872
3873/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3874static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3875 0x05, 0x02, 0x03
3876};
3877
3878/* seems analog CD is not working */
a9111321 3879static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3880 .num_items = 3,
3881 .items = {
3882 { "Mic", 0x1 },
3883 { "Line", 0x5 },
3884 { "Internal Mic", 0x6 },
3885 },
3886};
3887
3888/* 2,4,6 channel modes */
a9111321 3889static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3890 /* set line-in and mic-in to input */
3891 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3892 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3893 { }
3894};
3895
a9111321 3896static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3897 /* set line-in to out and mic-in to input */
3898 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3899 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3900 { }
3901};
3902
a9111321 3903static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3904 /* set line-in and mic-in to output */
3905 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3906 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3907 { }
3908};
3909
a9111321 3910static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3911 { 2, alc880_lg_ch2_init },
3912 { 4, alc880_lg_ch4_init },
3913 { 6, alc880_lg_ch6_init },
3914};
3915
a9111321 3916static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3917 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3918 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3919 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3920 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3921 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3922 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3923 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3924 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3925 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3927 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3928 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3929 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3930 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3931 {
3932 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3933 .name = "Channel Mode",
3934 .info = alc_ch_mode_info,
3935 .get = alc_ch_mode_get,
3936 .put = alc_ch_mode_put,
3937 },
3938 { } /* end */
3939};
3940
a9111321 3941static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3942 /* set capture source to mic-in */
3943 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3944 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3945 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3946 /* mute all amp mixer inputs */
3947 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3948 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3949 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3950 /* line-in to input */
3951 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3952 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3953 /* built-in mic */
3954 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3955 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3956 /* speaker-out */
3957 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3958 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3959 /* mic-in to input */
3960 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3961 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3962 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3963 /* HP-out */
3964 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3965 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3966 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3967 /* jack sense */
a9fd4f3f 3968 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3969 { }
3970};
3971
3972/* toggle speaker-output according to the hp-jack state */
4f5d1706 3973static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3974{
a9fd4f3f 3975 struct alc_spec *spec = codec->spec;
ae6b813a 3976
a9fd4f3f
TI
3977 spec->autocfg.hp_pins[0] = 0x1b;
3978 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3979 spec->automute = 1;
3980 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3981}
3982
d681518a
TI
3983/*
3984 * LG LW20
3985 *
3986 * Pin assignment:
3987 * Speaker-out: 0x14
3988 * Mic-In: 0x18
e4f41da9
CM
3989 * Built-in Mic-In: 0x19
3990 * Line-In: 0x1b
3991 * HP-Out: 0x1a
d681518a
TI
3992 * SPDIF-Out: 0x1e
3993 */
3994
a9111321 3995static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3996 .num_items = 3,
d681518a
TI
3997 .items = {
3998 { "Mic", 0x0 },
3999 { "Internal Mic", 0x1 },
e4f41da9 4000 { "Line In", 0x2 },
d681518a
TI
4001 },
4002};
4003
0a8c5da3
CM
4004#define alc880_lg_lw_modes alc880_threestack_modes
4005
a9111321 4006static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
4007 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4008 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4009 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4010 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4011 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4012 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4013 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4014 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4015 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4016 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
4017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4019 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4020 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
4021 {
4022 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4023 .name = "Channel Mode",
4024 .info = alc_ch_mode_info,
4025 .get = alc_ch_mode_get,
4026 .put = alc_ch_mode_put,
4027 },
d681518a
TI
4028 { } /* end */
4029};
4030
a9111321 4031static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4032 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4033 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4034 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4035
d681518a
TI
4036 /* set capture source to mic-in */
4037 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4038 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4039 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4040 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4041 /* speaker-out */
4042 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4043 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4044 /* HP-out */
d681518a
TI
4045 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4046 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4047 /* mic-in to input */
4048 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4049 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4050 /* built-in mic */
4051 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4052 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4053 /* jack sense */
a9fd4f3f 4054 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4055 { }
4056};
4057
4058/* toggle speaker-output according to the hp-jack state */
4f5d1706 4059static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4060{
a9fd4f3f 4061 struct alc_spec *spec = codec->spec;
d681518a 4062
a9fd4f3f
TI
4063 spec->autocfg.hp_pins[0] = 0x1b;
4064 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4065 spec->automute = 1;
4066 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4067}
4068
a9111321 4069static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4070 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4071 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4074 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4075 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4076 { } /* end */
4077};
4078
a9111321 4079static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4080 .num_items = 2,
4081 .items = {
4082 { "Mic", 0x0 },
4083 { "Internal Mic", 0x1 },
4084 },
4085};
4086
a9111321 4087static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4088 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4089
4090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4091 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4092
4093 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4094 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4096 /* Mic2 (as headphone out) for HP output */
4097 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4098 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4099 /* Internal Speaker */
4100 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4101 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4102
4103 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4104 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4105
4106 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4107 { }
4108};
4109
4110/* toggle speaker-output according to the hp-jack state */
4111static void alc880_medion_rim_automute(struct hda_codec *codec)
4112{
a9fd4f3f 4113 struct alc_spec *spec = codec->spec;
d922b51d 4114 alc_hp_automute(codec);
a9fd4f3f
TI
4115 /* toggle EAPD */
4116 if (spec->jack_present)
df99cd33
TI
4117 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4118 else
4119 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4120}
4121
4122static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4123 unsigned int res)
4124{
4125 /* Looks like the unsol event is incompatible with the standard
4126 * definition. 4bit tag is placed at 28 bit!
4127 */
4128 if ((res >> 28) == ALC880_HP_EVENT)
4129 alc880_medion_rim_automute(codec);
4130}
4131
4f5d1706 4132static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4133{
4134 struct alc_spec *spec = codec->spec;
4135
4136 spec->autocfg.hp_pins[0] = 0x14;
4137 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4138 spec->automute = 1;
4139 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4140}
4141
cb53c626 4142#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4143static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4144 { 0x0b, HDA_INPUT, 0 },
4145 { 0x0b, HDA_INPUT, 1 },
4146 { 0x0b, HDA_INPUT, 2 },
4147 { 0x0b, HDA_INPUT, 3 },
4148 { 0x0b, HDA_INPUT, 4 },
4149 { } /* end */
4150};
4151
a9111321 4152static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4153 { 0x0b, HDA_INPUT, 1 },
4154 { 0x0b, HDA_INPUT, 6 },
4155 { 0x0b, HDA_INPUT, 7 },
4156 { } /* end */
4157};
4158#endif
4159
ae6b813a
TI
4160/*
4161 * Common callbacks
e9edcee0
TI
4162 */
4163
584c0c4c
TI
4164static void alc_init_special_input_src(struct hda_codec *codec);
4165
1da177e4
LT
4166static int alc_init(struct hda_codec *codec)
4167{
4168 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4169 unsigned int i;
4170
2c3bf9ab 4171 alc_fix_pll(codec);
4a79ba34 4172 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4173
e9edcee0
TI
4174 for (i = 0; i < spec->num_init_verbs; i++)
4175 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4176 alc_init_special_input_src(codec);
ae6b813a
TI
4177
4178 if (spec->init_hook)
4179 spec->init_hook(codec);
4180
58701120
TI
4181 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4182
9e5341b9 4183 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4184 return 0;
4185}
4186
ae6b813a
TI
4187static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4188{
4189 struct alc_spec *spec = codec->spec;
4190
4191 if (spec->unsol_event)
4192 spec->unsol_event(codec, res);
4193}
4194
cb53c626
TI
4195#ifdef CONFIG_SND_HDA_POWER_SAVE
4196static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4197{
4198 struct alc_spec *spec = codec->spec;
4199 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4200}
4201#endif
4202
1da177e4
LT
4203/*
4204 * Analog playback callbacks
4205 */
4206static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4207 struct hda_codec *codec,
c8b6bf9b 4208 struct snd_pcm_substream *substream)
1da177e4
LT
4209{
4210 struct alc_spec *spec = codec->spec;
9a08160b
TI
4211 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4212 hinfo);
1da177e4
LT
4213}
4214
4215static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4216 struct hda_codec *codec,
4217 unsigned int stream_tag,
4218 unsigned int format,
c8b6bf9b 4219 struct snd_pcm_substream *substream)
1da177e4
LT
4220{
4221 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4222 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4223 stream_tag, format, substream);
1da177e4
LT
4224}
4225
4226static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4227 struct hda_codec *codec,
c8b6bf9b 4228 struct snd_pcm_substream *substream)
1da177e4
LT
4229{
4230 struct alc_spec *spec = codec->spec;
4231 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4232}
4233
4234/*
4235 * Digital out
4236 */
4237static int alc880_dig_playback_pcm_open(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_open(codec, &spec->multiout);
4243}
4244
6b97eb45
TI
4245static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4246 struct hda_codec *codec,
4247 unsigned int stream_tag,
4248 unsigned int format,
4249 struct snd_pcm_substream *substream)
4250{
4251 struct alc_spec *spec = codec->spec;
4252 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4253 stream_tag, format, substream);
4254}
4255
9b5f12e5
TI
4256static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4257 struct hda_codec *codec,
4258 struct snd_pcm_substream *substream)
4259{
4260 struct alc_spec *spec = codec->spec;
4261 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4262}
4263
1da177e4
LT
4264static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4265 struct hda_codec *codec,
c8b6bf9b 4266 struct snd_pcm_substream *substream)
1da177e4
LT
4267{
4268 struct alc_spec *spec = codec->spec;
4269 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4270}
4271
4272/*
4273 * Analog capture
4274 */
6330079f 4275static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4276 struct hda_codec *codec,
4277 unsigned int stream_tag,
4278 unsigned int format,
c8b6bf9b 4279 struct snd_pcm_substream *substream)
1da177e4
LT
4280{
4281 struct alc_spec *spec = codec->spec;
4282
6330079f 4283 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4284 stream_tag, 0, format);
4285 return 0;
4286}
4287
6330079f 4288static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4289 struct hda_codec *codec,
c8b6bf9b 4290 struct snd_pcm_substream *substream)
1da177e4
LT
4291{
4292 struct alc_spec *spec = codec->spec;
4293
888afa15
TI
4294 snd_hda_codec_cleanup_stream(codec,
4295 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4296 return 0;
4297}
4298
840b64c0
TI
4299/* analog capture with dynamic dual-adc changes */
4300static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4301 struct hda_codec *codec,
4302 unsigned int stream_tag,
4303 unsigned int format,
4304 struct snd_pcm_substream *substream)
4305{
4306 struct alc_spec *spec = codec->spec;
4307 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4308 spec->cur_adc_stream_tag = stream_tag;
4309 spec->cur_adc_format = format;
4310 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4311 return 0;
4312}
4313
4314static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4315 struct hda_codec *codec,
4316 struct snd_pcm_substream *substream)
4317{
4318 struct alc_spec *spec = codec->spec;
4319 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4320 spec->cur_adc = 0;
4321 return 0;
4322}
4323
a9111321 4324static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4325 .substreams = 1,
4326 .channels_min = 2,
4327 .channels_max = 2,
4328 .nid = 0, /* fill later */
4329 .ops = {
4330 .prepare = dualmic_capture_pcm_prepare,
4331 .cleanup = dualmic_capture_pcm_cleanup
4332 },
4333};
1da177e4
LT
4334
4335/*
4336 */
a9111321 4337static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4338 .substreams = 1,
4339 .channels_min = 2,
4340 .channels_max = 8,
e9edcee0 4341 /* NID is set in alc_build_pcms */
1da177e4
LT
4342 .ops = {
4343 .open = alc880_playback_pcm_open,
4344 .prepare = alc880_playback_pcm_prepare,
4345 .cleanup = alc880_playback_pcm_cleanup
4346 },
4347};
4348
a9111321 4349static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4350 .substreams = 1,
4351 .channels_min = 2,
4352 .channels_max = 2,
4353 /* NID is set in alc_build_pcms */
4354};
4355
a9111321 4356static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4357 .substreams = 1,
4358 .channels_min = 2,
4359 .channels_max = 2,
4360 /* NID is set in alc_build_pcms */
4361};
4362
a9111321 4363static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4364 .substreams = 2, /* can be overridden */
1da177e4
LT
4365 .channels_min = 2,
4366 .channels_max = 2,
e9edcee0 4367 /* NID is set in alc_build_pcms */
1da177e4 4368 .ops = {
6330079f
TI
4369 .prepare = alc880_alt_capture_pcm_prepare,
4370 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4371 },
4372};
4373
a9111321 4374static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4375 .substreams = 1,
4376 .channels_min = 2,
4377 .channels_max = 2,
4378 /* NID is set in alc_build_pcms */
4379 .ops = {
4380 .open = alc880_dig_playback_pcm_open,
6b97eb45 4381 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4382 .prepare = alc880_dig_playback_pcm_prepare,
4383 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4384 },
4385};
4386
a9111321 4387static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4388 .substreams = 1,
4389 .channels_min = 2,
4390 .channels_max = 2,
4391 /* NID is set in alc_build_pcms */
4392};
4393
4c5186ed 4394/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4395static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4396 .substreams = 0,
4397 .channels_min = 0,
4398 .channels_max = 0,
4399};
4400
1da177e4
LT
4401static int alc_build_pcms(struct hda_codec *codec)
4402{
4403 struct alc_spec *spec = codec->spec;
4404 struct hda_pcm *info = spec->pcm_rec;
4405 int i;
4406
4407 codec->num_pcms = 1;
4408 codec->pcm_info = info;
4409
e64f14f4
TI
4410 if (spec->no_analog)
4411 goto skip_analog;
4412
812a2cca
TI
4413 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4414 "%s Analog", codec->chip_name);
1da177e4 4415 info->name = spec->stream_name_analog;
274693f3 4416
4a471b7d 4417 if (spec->stream_analog_playback) {
da3cec35
TI
4418 if (snd_BUG_ON(!spec->multiout.dac_nids))
4419 return -EINVAL;
4a471b7d
TI
4420 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4421 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4422 }
4423 if (spec->stream_analog_capture) {
da3cec35
TI
4424 if (snd_BUG_ON(!spec->adc_nids))
4425 return -EINVAL;
4a471b7d
TI
4426 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4427 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4428 }
4429
4430 if (spec->channel_mode) {
4431 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4432 for (i = 0; i < spec->num_channel_mode; i++) {
4433 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4434 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4435 }
1da177e4
LT
4436 }
4437 }
4438
e64f14f4 4439 skip_analog:
e08a007d 4440 /* SPDIF for stream index #1 */
1da177e4 4441 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4442 snprintf(spec->stream_name_digital,
4443 sizeof(spec->stream_name_digital),
4444 "%s Digital", codec->chip_name);
e08a007d 4445 codec->num_pcms = 2;
b25c9da1 4446 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4447 info = spec->pcm_rec + 1;
1da177e4 4448 info->name = spec->stream_name_digital;
8c441982
TI
4449 if (spec->dig_out_type)
4450 info->pcm_type = spec->dig_out_type;
4451 else
4452 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4453 if (spec->multiout.dig_out_nid &&
4454 spec->stream_digital_playback) {
1da177e4
LT
4455 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4456 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4457 }
4a471b7d
TI
4458 if (spec->dig_in_nid &&
4459 spec->stream_digital_capture) {
1da177e4
LT
4460 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4461 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4462 }
963f803f
TI
4463 /* FIXME: do we need this for all Realtek codec models? */
4464 codec->spdif_status_reset = 1;
1da177e4
LT
4465 }
4466
e64f14f4
TI
4467 if (spec->no_analog)
4468 return 0;
4469
e08a007d
TI
4470 /* If the use of more than one ADC is requested for the current
4471 * model, configure a second analog capture-only PCM.
4472 */
4473 /* Additional Analaog capture for index #2 */
6330079f
TI
4474 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4475 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4476 codec->num_pcms = 3;
c06134d7 4477 info = spec->pcm_rec + 2;
e08a007d 4478 info->name = spec->stream_name_analog;
6330079f
TI
4479 if (spec->alt_dac_nid) {
4480 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4481 *spec->stream_analog_alt_playback;
4482 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4483 spec->alt_dac_nid;
4484 } else {
4485 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4486 alc_pcm_null_stream;
4487 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4488 }
ce85c9ac 4489 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4490 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4491 *spec->stream_analog_alt_capture;
4492 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4493 spec->adc_nids[1];
4494 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4495 spec->num_adc_nids - 1;
4496 } else {
4497 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4498 alc_pcm_null_stream;
4499 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4500 }
4501 }
4502
1da177e4
LT
4503 return 0;
4504}
4505
a4e09aa3
TI
4506static inline void alc_shutup(struct hda_codec *codec)
4507{
1c716153
TI
4508 struct alc_spec *spec = codec->spec;
4509
4510 if (spec && spec->shutup)
4511 spec->shutup(codec);
a4e09aa3
TI
4512 snd_hda_shutup_pins(codec);
4513}
4514
603c4019
TI
4515static void alc_free_kctls(struct hda_codec *codec)
4516{
4517 struct alc_spec *spec = codec->spec;
4518
4519 if (spec->kctls.list) {
4520 struct snd_kcontrol_new *kctl = spec->kctls.list;
4521 int i;
4522 for (i = 0; i < spec->kctls.used; i++)
4523 kfree(kctl[i].name);
4524 }
4525 snd_array_free(&spec->kctls);
4526}
4527
1da177e4
LT
4528static void alc_free(struct hda_codec *codec)
4529{
e9edcee0 4530 struct alc_spec *spec = codec->spec;
e9edcee0 4531
f12ab1e0 4532 if (!spec)
e9edcee0
TI
4533 return;
4534
a4e09aa3 4535 alc_shutup(codec);
cd372fb3 4536 snd_hda_input_jack_free(codec);
603c4019 4537 alc_free_kctls(codec);
e9edcee0 4538 kfree(spec);
680cd536 4539 snd_hda_detach_beep_device(codec);
1da177e4
LT
4540}
4541
f5de24b0 4542#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4543static void alc_power_eapd(struct hda_codec *codec)
4544{
691f1fcc 4545 alc_auto_setup_eapd(codec, false);
c97259df
DC
4546}
4547
f5de24b0
HM
4548static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4549{
4550 struct alc_spec *spec = codec->spec;
a4e09aa3 4551 alc_shutup(codec);
f5de24b0 4552 if (spec && spec->power_hook)
c97259df 4553 spec->power_hook(codec);
f5de24b0
HM
4554 return 0;
4555}
4556#endif
4557
e044c39a 4558#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4559static int alc_resume(struct hda_codec *codec)
4560{
1c716153 4561 msleep(150); /* to avoid pop noise */
e044c39a
TI
4562 codec->patch_ops.init(codec);
4563 snd_hda_codec_resume_amp(codec);
4564 snd_hda_codec_resume_cache(codec);
9e5341b9 4565 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4566 return 0;
4567}
e044c39a
TI
4568#endif
4569
1da177e4
LT
4570/*
4571 */
a9111321 4572static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4573 .build_controls = alc_build_controls,
4574 .build_pcms = alc_build_pcms,
4575 .init = alc_init,
4576 .free = alc_free,
ae6b813a 4577 .unsol_event = alc_unsol_event,
e044c39a
TI
4578#ifdef SND_HDA_NEEDS_RESUME
4579 .resume = alc_resume,
4580#endif
cb53c626 4581#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4582 .suspend = alc_suspend,
cb53c626
TI
4583 .check_power_status = alc_check_power_status,
4584#endif
c97259df 4585 .reboot_notify = alc_shutup,
1da177e4
LT
4586};
4587
c027ddcd
KY
4588/* replace the codec chip_name with the given string */
4589static int alc_codec_rename(struct hda_codec *codec, const char *name)
4590{
4591 kfree(codec->chip_name);
4592 codec->chip_name = kstrdup(name, GFP_KERNEL);
4593 if (!codec->chip_name) {
4594 alc_free(codec);
4595 return -ENOMEM;
4596 }
4597 return 0;
4598}
4599
2fa522be
TI
4600/*
4601 * Test configuration for debugging
4602 *
4603 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4604 * enum controls.
4605 */
4606#ifdef CONFIG_SND_DEBUG
4c6d72d1 4607static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4608 0x02, 0x03, 0x04, 0x05
4609};
4610
a9111321 4611static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4612 .num_items = 7,
2fa522be
TI
4613 .items = {
4614 { "In-1", 0x0 },
4615 { "In-2", 0x1 },
4616 { "In-3", 0x2 },
4617 { "In-4", 0x3 },
4618 { "CD", 0x4 },
ae6b813a
TI
4619 { "Front", 0x5 },
4620 { "Surround", 0x6 },
2fa522be
TI
4621 },
4622};
4623
a9111321 4624static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4625 { 2, NULL },
fd2c326d 4626 { 4, NULL },
2fa522be 4627 { 6, NULL },
fd2c326d 4628 { 8, NULL },
2fa522be
TI
4629};
4630
9c7f852e
TI
4631static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4632 struct snd_ctl_elem_info *uinfo)
2fa522be 4633{
4c6d72d1 4634 static const char * const texts[] = {
2fa522be
TI
4635 "N/A", "Line Out", "HP Out",
4636 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4637 };
4638 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4639 uinfo->count = 1;
4640 uinfo->value.enumerated.items = 8;
4641 if (uinfo->value.enumerated.item >= 8)
4642 uinfo->value.enumerated.item = 7;
4643 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4644 return 0;
4645}
4646
9c7f852e
TI
4647static int alc_test_pin_ctl_get(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;
4652 unsigned int pin_ctl, item = 0;
4653
4654 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4655 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4656 if (pin_ctl & AC_PINCTL_OUT_EN) {
4657 if (pin_ctl & AC_PINCTL_HP_EN)
4658 item = 2;
4659 else
4660 item = 1;
4661 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4662 switch (pin_ctl & AC_PINCTL_VREFEN) {
4663 case AC_PINCTL_VREF_HIZ: item = 3; break;
4664 case AC_PINCTL_VREF_50: item = 4; break;
4665 case AC_PINCTL_VREF_GRD: item = 5; break;
4666 case AC_PINCTL_VREF_80: item = 6; break;
4667 case AC_PINCTL_VREF_100: item = 7; break;
4668 }
4669 }
4670 ucontrol->value.enumerated.item[0] = item;
4671 return 0;
4672}
4673
9c7f852e
TI
4674static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4675 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4676{
4677 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4678 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4679 static const unsigned int ctls[] = {
2fa522be
TI
4680 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4681 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4682 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4683 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4684 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4685 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4686 };
4687 unsigned int old_ctl, new_ctl;
4688
4689 old_ctl = snd_hda_codec_read(codec, nid, 0,
4690 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4691 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4692 if (old_ctl != new_ctl) {
82beb8fd
TI
4693 int val;
4694 snd_hda_codec_write_cache(codec, nid, 0,
4695 AC_VERB_SET_PIN_WIDGET_CONTROL,
4696 new_ctl);
47fd830a
TI
4697 val = ucontrol->value.enumerated.item[0] >= 3 ?
4698 HDA_AMP_MUTE : 0;
4699 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4700 HDA_AMP_MUTE, val);
2fa522be
TI
4701 return 1;
4702 }
4703 return 0;
4704}
4705
9c7f852e
TI
4706static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4707 struct snd_ctl_elem_info *uinfo)
2fa522be 4708{
4c6d72d1 4709 static const char * const texts[] = {
2fa522be
TI
4710 "Front", "Surround", "CLFE", "Side"
4711 };
4712 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4713 uinfo->count = 1;
4714 uinfo->value.enumerated.items = 4;
4715 if (uinfo->value.enumerated.item >= 4)
4716 uinfo->value.enumerated.item = 3;
4717 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4718 return 0;
4719}
4720
9c7f852e
TI
4721static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4722 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4723{
4724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4725 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4726 unsigned int sel;
4727
4728 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4729 ucontrol->value.enumerated.item[0] = sel & 3;
4730 return 0;
4731}
4732
9c7f852e
TI
4733static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4734 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4735{
4736 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4737 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4738 unsigned int sel;
4739
4740 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4741 if (ucontrol->value.enumerated.item[0] != sel) {
4742 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4743 snd_hda_codec_write_cache(codec, nid, 0,
4744 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4745 return 1;
4746 }
4747 return 0;
4748}
4749
4750#define PIN_CTL_TEST(xname,nid) { \
4751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4752 .name = xname, \
5b0cb1d8 4753 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4754 .info = alc_test_pin_ctl_info, \
4755 .get = alc_test_pin_ctl_get, \
4756 .put = alc_test_pin_ctl_put, \
4757 .private_value = nid \
4758 }
4759
4760#define PIN_SRC_TEST(xname,nid) { \
4761 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4762 .name = xname, \
5b0cb1d8 4763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4764 .info = alc_test_pin_src_info, \
4765 .get = alc_test_pin_src_get, \
4766 .put = alc_test_pin_src_put, \
4767 .private_value = nid \
4768 }
4769
a9111321 4770static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4771 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4772 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4773 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4774 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4775 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4776 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4777 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4778 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4779 PIN_CTL_TEST("Front Pin Mode", 0x14),
4780 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4781 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4782 PIN_CTL_TEST("Side Pin Mode", 0x17),
4783 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4784 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4785 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4786 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4787 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4788 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4789 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4790 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4791 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4792 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4793 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4794 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4795 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4796 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4797 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4798 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4799 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4800 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4801 {
4802 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4803 .name = "Channel Mode",
df694daa
KY
4804 .info = alc_ch_mode_info,
4805 .get = alc_ch_mode_get,
4806 .put = alc_ch_mode_put,
2fa522be
TI
4807 },
4808 { } /* end */
4809};
4810
a9111321 4811static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4812 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4814 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4815 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4817 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4818 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4819 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4820 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4821 /* Vol output for 0x0c-0x0f */
05acb863
TI
4822 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4823 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4824 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4825 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4826 /* Set output pins 0x14-0x17 */
05acb863
TI
4827 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4829 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4830 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4831 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4832 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4833 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4834 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4835 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4836 /* Set input pins 0x18-0x1c */
16ded525
TI
4837 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4838 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4839 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4840 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4841 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4842 /* Mute input pins 0x18-0x1b */
05acb863
TI
4843 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4844 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4845 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4846 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4847 /* ADC set up */
05acb863 4848 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4849 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4850 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4851 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4852 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4853 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4854 /* Analog input/passthru */
4855 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4856 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4857 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4858 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4859 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4860 { }
4861};
4862#endif
4863
1da177e4
LT
4864/*
4865 */
4866
ea734963 4867static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4868 [ALC880_3ST] = "3stack",
4869 [ALC880_TCL_S700] = "tcl",
4870 [ALC880_3ST_DIG] = "3stack-digout",
4871 [ALC880_CLEVO] = "clevo",
4872 [ALC880_5ST] = "5stack",
4873 [ALC880_5ST_DIG] = "5stack-digout",
4874 [ALC880_W810] = "w810",
4875 [ALC880_Z71V] = "z71v",
4876 [ALC880_6ST] = "6stack",
4877 [ALC880_6ST_DIG] = "6stack-digout",
4878 [ALC880_ASUS] = "asus",
4879 [ALC880_ASUS_W1V] = "asus-w1v",
4880 [ALC880_ASUS_DIG] = "asus-dig",
4881 [ALC880_ASUS_DIG2] = "asus-dig2",
4882 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4883 [ALC880_UNIWILL_P53] = "uniwill-p53",
4884 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4885 [ALC880_F1734] = "F1734",
4886 [ALC880_LG] = "lg",
4887 [ALC880_LG_LW] = "lg-lw",
df99cd33 4888 [ALC880_MEDION_RIM] = "medion",
2fa522be 4889#ifdef CONFIG_SND_DEBUG
f5fcc13c 4890 [ALC880_TEST] = "test",
2fa522be 4891#endif
f5fcc13c
TI
4892 [ALC880_AUTO] = "auto",
4893};
4894
a9111321 4895static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4896 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4897 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4898 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4899 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4900 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4901 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4902 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4903 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4904 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c 4905 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
f5fcc13c
TI
4906 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4907 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4908 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4909 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4910 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4911 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4912 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4913 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4914 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4915 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4916 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4917 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4918 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4919 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4920 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4921 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4922 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4923 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4924 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4925 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4926 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4927 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4928 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4929 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4930 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4931 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4932 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4933 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4934 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4935 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4936 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4937 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4938 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4939 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4940 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4941 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4942 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4943 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4944 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4945 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4946 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4947 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4948 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4949 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4950 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4951 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4952 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4953 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4954 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4955 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4956 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4957 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4958 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4959 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4960 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4961 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4962 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4963 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4964 /* default Intel */
4965 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4966 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4967 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4968 {}
4969};
4970
16ded525 4971/*
df694daa 4972 * ALC880 codec presets
16ded525 4973 */
a9111321 4974static const struct alc_config_preset alc880_presets[] = {
16ded525 4975 [ALC880_3ST] = {
e9edcee0 4976 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4977 .init_verbs = { alc880_volume_init_verbs,
4978 alc880_pin_3stack_init_verbs },
16ded525 4979 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4980 .dac_nids = alc880_dac_nids,
16ded525
TI
4981 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4982 .channel_mode = alc880_threestack_modes,
4e195a7b 4983 .need_dac_fix = 1,
16ded525
TI
4984 .input_mux = &alc880_capture_source,
4985 },
4986 [ALC880_3ST_DIG] = {
e9edcee0 4987 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4988 .init_verbs = { alc880_volume_init_verbs,
4989 alc880_pin_3stack_init_verbs },
16ded525 4990 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4991 .dac_nids = alc880_dac_nids,
4992 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4993 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4994 .channel_mode = alc880_threestack_modes,
4e195a7b 4995 .need_dac_fix = 1,
16ded525
TI
4996 .input_mux = &alc880_capture_source,
4997 },
df694daa
KY
4998 [ALC880_TCL_S700] = {
4999 .mixers = { alc880_tcl_s700_mixer },
5000 .init_verbs = { alc880_volume_init_verbs,
5001 alc880_pin_tcl_S700_init_verbs,
5002 alc880_gpio2_init_verbs },
5003 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5004 .dac_nids = alc880_dac_nids,
f9e336f6
TI
5005 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5006 .num_adc_nids = 1, /* single ADC */
df694daa
KY
5007 .hp_nid = 0x03,
5008 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5009 .channel_mode = alc880_2_jack_modes,
5010 .input_mux = &alc880_capture_source,
5011 },
16ded525 5012 [ALC880_5ST] = {
f12ab1e0
TI
5013 .mixers = { alc880_three_stack_mixer,
5014 alc880_five_stack_mixer},
5015 .init_verbs = { alc880_volume_init_verbs,
5016 alc880_pin_5stack_init_verbs },
16ded525
TI
5017 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5018 .dac_nids = alc880_dac_nids,
16ded525
TI
5019 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5020 .channel_mode = alc880_fivestack_modes,
5021 .input_mux = &alc880_capture_source,
5022 },
5023 [ALC880_5ST_DIG] = {
f12ab1e0
TI
5024 .mixers = { alc880_three_stack_mixer,
5025 alc880_five_stack_mixer },
5026 .init_verbs = { alc880_volume_init_verbs,
5027 alc880_pin_5stack_init_verbs },
16ded525
TI
5028 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5029 .dac_nids = alc880_dac_nids,
5030 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5031 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5032 .channel_mode = alc880_fivestack_modes,
5033 .input_mux = &alc880_capture_source,
5034 },
b6482d48
TI
5035 [ALC880_6ST] = {
5036 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5037 .init_verbs = { alc880_volume_init_verbs,
5038 alc880_pin_6stack_init_verbs },
b6482d48
TI
5039 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5040 .dac_nids = alc880_6st_dac_nids,
5041 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5042 .channel_mode = alc880_sixstack_modes,
5043 .input_mux = &alc880_6stack_capture_source,
5044 },
16ded525 5045 [ALC880_6ST_DIG] = {
e9edcee0 5046 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5047 .init_verbs = { alc880_volume_init_verbs,
5048 alc880_pin_6stack_init_verbs },
16ded525
TI
5049 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5050 .dac_nids = alc880_6st_dac_nids,
5051 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5052 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5053 .channel_mode = alc880_sixstack_modes,
5054 .input_mux = &alc880_6stack_capture_source,
5055 },
5056 [ALC880_W810] = {
e9edcee0 5057 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5058 .init_verbs = { alc880_volume_init_verbs,
5059 alc880_pin_w810_init_verbs,
b0af0de5 5060 alc880_gpio2_init_verbs },
16ded525
TI
5061 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5062 .dac_nids = alc880_w810_dac_nids,
5063 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5064 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5065 .channel_mode = alc880_w810_modes,
5066 .input_mux = &alc880_capture_source,
5067 },
5068 [ALC880_Z71V] = {
e9edcee0 5069 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5070 .init_verbs = { alc880_volume_init_verbs,
5071 alc880_pin_z71v_init_verbs },
16ded525
TI
5072 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5073 .dac_nids = alc880_z71v_dac_nids,
5074 .dig_out_nid = ALC880_DIGOUT_NID,
5075 .hp_nid = 0x03,
e9edcee0
TI
5076 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5077 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5078 .input_mux = &alc880_capture_source,
5079 },
5080 [ALC880_F1734] = {
e9edcee0 5081 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5082 .init_verbs = { alc880_volume_init_verbs,
5083 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5084 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5085 .dac_nids = alc880_f1734_dac_nids,
5086 .hp_nid = 0x02,
5087 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5088 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5089 .input_mux = &alc880_f1734_capture_source,
5090 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5091 .setup = alc880_uniwill_p53_setup,
d922b51d 5092 .init_hook = alc_hp_automute,
16ded525
TI
5093 },
5094 [ALC880_ASUS] = {
e9edcee0 5095 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5096 .init_verbs = { alc880_volume_init_verbs,
5097 alc880_pin_asus_init_verbs,
e9edcee0
TI
5098 alc880_gpio1_init_verbs },
5099 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5100 .dac_nids = alc880_asus_dac_nids,
5101 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5102 .channel_mode = alc880_asus_modes,
4e195a7b 5103 .need_dac_fix = 1,
16ded525
TI
5104 .input_mux = &alc880_capture_source,
5105 },
5106 [ALC880_ASUS_DIG] = {
e9edcee0 5107 .mixers = { alc880_asus_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 },
df694daa
KY
5119 [ALC880_ASUS_DIG2] = {
5120 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5121 .init_verbs = { alc880_volume_init_verbs,
5122 alc880_pin_asus_init_verbs,
df694daa
KY
5123 alc880_gpio2_init_verbs }, /* use GPIO2 */
5124 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5125 .dac_nids = alc880_asus_dac_nids,
5126 .dig_out_nid = ALC880_DIGOUT_NID,
5127 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5128 .channel_mode = alc880_asus_modes,
4e195a7b 5129 .need_dac_fix = 1,
df694daa
KY
5130 .input_mux = &alc880_capture_source,
5131 },
16ded525 5132 [ALC880_ASUS_W1V] = {
e9edcee0 5133 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5134 .init_verbs = { alc880_volume_init_verbs,
5135 alc880_pin_asus_init_verbs,
e9edcee0
TI
5136 alc880_gpio1_init_verbs },
5137 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5138 .dac_nids = alc880_asus_dac_nids,
16ded525 5139 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5140 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5141 .channel_mode = alc880_asus_modes,
4e195a7b 5142 .need_dac_fix = 1,
16ded525
TI
5143 .input_mux = &alc880_capture_source,
5144 },
5145 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5146 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5147 .init_verbs = { alc880_volume_init_verbs,
5148 alc880_pin_asus_init_verbs },
e9edcee0
TI
5149 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5150 .dac_nids = alc880_asus_dac_nids,
16ded525 5151 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5152 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5153 .channel_mode = alc880_asus_modes,
4e195a7b 5154 .need_dac_fix = 1,
16ded525
TI
5155 .input_mux = &alc880_capture_source,
5156 },
ccc656ce
KY
5157 [ALC880_UNIWILL] = {
5158 .mixers = { alc880_uniwill_mixer },
5159 .init_verbs = { alc880_volume_init_verbs,
5160 alc880_uniwill_init_verbs },
5161 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5162 .dac_nids = alc880_asus_dac_nids,
5163 .dig_out_nid = ALC880_DIGOUT_NID,
5164 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5165 .channel_mode = alc880_threestack_modes,
5166 .need_dac_fix = 1,
5167 .input_mux = &alc880_capture_source,
5168 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5169 .setup = alc880_uniwill_setup,
a9fd4f3f 5170 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5171 },
5172 [ALC880_UNIWILL_P53] = {
5173 .mixers = { alc880_uniwill_p53_mixer },
5174 .init_verbs = { alc880_volume_init_verbs,
5175 alc880_uniwill_p53_init_verbs },
5176 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5177 .dac_nids = alc880_asus_dac_nids,
5178 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5179 .channel_mode = alc880_threestack_modes,
5180 .input_mux = &alc880_capture_source,
5181 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5182 .setup = alc880_uniwill_p53_setup,
d922b51d 5183 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5184 },
5185 [ALC880_FUJITSU] = {
45bdd1c1 5186 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5187 .init_verbs = { alc880_volume_init_verbs,
5188 alc880_uniwill_p53_init_verbs,
5189 alc880_beep_init_verbs },
5190 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5191 .dac_nids = alc880_dac_nids,
d53d7d9e 5192 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5193 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5194 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5195 .input_mux = &alc880_capture_source,
5196 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5197 .setup = alc880_uniwill_p53_setup,
d922b51d 5198 .init_hook = alc_hp_automute,
ccc656ce 5199 },
df694daa
KY
5200 [ALC880_CLEVO] = {
5201 .mixers = { alc880_three_stack_mixer },
5202 .init_verbs = { alc880_volume_init_verbs,
5203 alc880_pin_clevo_init_verbs },
5204 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5205 .dac_nids = alc880_dac_nids,
5206 .hp_nid = 0x03,
5207 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5208 .channel_mode = alc880_threestack_modes,
4e195a7b 5209 .need_dac_fix = 1,
df694daa
KY
5210 .input_mux = &alc880_capture_source,
5211 },
ae6b813a
TI
5212 [ALC880_LG] = {
5213 .mixers = { alc880_lg_mixer },
5214 .init_verbs = { alc880_volume_init_verbs,
5215 alc880_lg_init_verbs },
5216 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5217 .dac_nids = alc880_lg_dac_nids,
5218 .dig_out_nid = ALC880_DIGOUT_NID,
5219 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5220 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5221 .need_dac_fix = 1,
ae6b813a 5222 .input_mux = &alc880_lg_capture_source,
d922b51d 5223 .unsol_event = alc_sku_unsol_event,
4f5d1706 5224 .setup = alc880_lg_setup,
d922b51d 5225 .init_hook = alc_hp_automute,
cb53c626
TI
5226#ifdef CONFIG_SND_HDA_POWER_SAVE
5227 .loopbacks = alc880_lg_loopbacks,
5228#endif
ae6b813a 5229 },
d681518a
TI
5230 [ALC880_LG_LW] = {
5231 .mixers = { alc880_lg_lw_mixer },
5232 .init_verbs = { alc880_volume_init_verbs,
5233 alc880_lg_lw_init_verbs },
0a8c5da3 5234 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5235 .dac_nids = alc880_dac_nids,
5236 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5237 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5238 .channel_mode = alc880_lg_lw_modes,
d681518a 5239 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5240 .unsol_event = alc_sku_unsol_event,
4f5d1706 5241 .setup = alc880_lg_lw_setup,
d922b51d 5242 .init_hook = alc_hp_automute,
d681518a 5243 },
df99cd33
TI
5244 [ALC880_MEDION_RIM] = {
5245 .mixers = { alc880_medion_rim_mixer },
5246 .init_verbs = { alc880_volume_init_verbs,
5247 alc880_medion_rim_init_verbs,
5248 alc_gpio2_init_verbs },
5249 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5250 .dac_nids = alc880_dac_nids,
5251 .dig_out_nid = ALC880_DIGOUT_NID,
5252 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5253 .channel_mode = alc880_2_jack_modes,
5254 .input_mux = &alc880_medion_rim_capture_source,
5255 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5256 .setup = alc880_medion_rim_setup,
5257 .init_hook = alc880_medion_rim_automute,
df99cd33 5258 },
16ded525
TI
5259#ifdef CONFIG_SND_DEBUG
5260 [ALC880_TEST] = {
e9edcee0
TI
5261 .mixers = { alc880_test_mixer },
5262 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5263 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5264 .dac_nids = alc880_test_dac_nids,
5265 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5266 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5267 .channel_mode = alc880_test_modes,
5268 .input_mux = &alc880_test_capture_source,
5269 },
5270#endif
5271};
5272
e9edcee0
TI
5273/*
5274 * Automatic parse of I/O pins from the BIOS configuration
5275 */
5276
e9edcee0
TI
5277enum {
5278 ALC_CTL_WIDGET_VOL,
5279 ALC_CTL_WIDGET_MUTE,
5280 ALC_CTL_BIND_MUTE,
5281};
a9111321 5282static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5283 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5284 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5285 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5286};
5287
ce764ab2
TI
5288static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5289{
5290 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5291 return snd_array_new(&spec->kctls);
5292}
5293
e9edcee0 5294/* add dynamic controls */
f12ab1e0 5295static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5296 int cidx, unsigned long val)
e9edcee0 5297{
c8b6bf9b 5298 struct snd_kcontrol_new *knew;
e9edcee0 5299
ce764ab2 5300 knew = alc_kcontrol_new(spec);
603c4019
TI
5301 if (!knew)
5302 return -ENOMEM;
e9edcee0 5303 *knew = alc880_control_templates[type];
543537bd 5304 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5305 if (!knew->name)
e9edcee0 5306 return -ENOMEM;
66ceeb6b 5307 knew->index = cidx;
4d02d1b6 5308 if (get_amp_nid_(val))
5e26dfd0 5309 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5310 knew->private_value = val;
e9edcee0
TI
5311 return 0;
5312}
5313
0afe5f89
TI
5314static int add_control_with_pfx(struct alc_spec *spec, int type,
5315 const char *pfx, const char *dir,
66ceeb6b 5316 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5317{
5318 char name[32];
5319 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5320 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5321}
5322
66ceeb6b
TI
5323#define add_pb_vol_ctrl(spec, type, pfx, val) \
5324 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5325#define add_pb_sw_ctrl(spec, type, pfx, val) \
5326 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5327#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5328 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5329#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5330 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5331
e9edcee0
TI
5332#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5333#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5334#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5335#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5336#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5337#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5338#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5339#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5340#define ALC880_PIN_CD_NID 0x1c
5341
6843ca16
TI
5342static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5343 bool can_be_master, int *index)
bcb2f0f5 5344{
ce764ab2 5345 struct auto_pin_cfg *cfg = &spec->autocfg;
6843ca16
TI
5346 static const char * const chname[4] = {
5347 "Front", "Surround", NULL /*CLFE*/, "Side"
5348 };
ce764ab2 5349
6843ca16 5350 *index = 0;
ce764ab2
TI
5351 if (cfg->line_outs == 1 && !spec->multi_ios &&
5352 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5353 return "Master";
5354
5355 switch (cfg->line_out_type) {
5356 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5357 if (cfg->line_outs == 1)
5358 return "Speaker";
5359 break;
bcb2f0f5 5360 case AUTO_PIN_HP_OUT:
6843ca16
TI
5361 /* for multi-io case, only the primary out */
5362 if (ch && spec->multi_ios)
5363 break;
5364 *index = ch;
bcb2f0f5
TI
5365 return "Headphone";
5366 default:
ce764ab2 5367 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5368 return "PCM";
5369 break;
5370 }
6843ca16 5371 return chname[ch];
bcb2f0f5
TI
5372}
5373
e9edcee0 5374/* create input playback/capture controls for the given pin */
f12ab1e0 5375static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5376 const char *ctlname, int ctlidx,
df694daa 5377 int idx, hda_nid_t mix_nid)
e9edcee0 5378{
df694daa 5379 int err;
e9edcee0 5380
66ceeb6b 5381 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5382 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5383 if (err < 0)
e9edcee0 5384 return err;
66ceeb6b 5385 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5386 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5387 if (err < 0)
e9edcee0
TI
5388 return err;
5389 return 0;
5390}
5391
05f5f477
TI
5392static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5393{
5394 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5395 return (pincap & AC_PINCAP_IN) != 0;
5396}
5397
d6cc9fab 5398static int alc_auto_fill_adc_caps(struct hda_codec *codec)
b7821709 5399{
d6cc9fab 5400 struct alc_spec *spec = codec->spec;
b7821709 5401 hda_nid_t nid;
d6cc9fab
TI
5402 hda_nid_t *adc_nids = spec->private_adc_nids;
5403 hda_nid_t *cap_nids = spec->private_capsrc_nids;
5404 int max_nums = ARRAY_SIZE(spec->private_adc_nids);
5405 bool indep_capsrc = false;
b7821709
TI
5406 int i, nums = 0;
5407
5408 nid = codec->start_nid;
5409 for (i = 0; i < codec->num_nodes; i++, nid++) {
5410 hda_nid_t src;
5411 const hda_nid_t *list;
5412 unsigned int caps = get_wcaps(codec, nid);
5413 int type = get_wcaps_type(caps);
5414
5415 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
5416 continue;
5417 adc_nids[nums] = nid;
5418 cap_nids[nums] = nid;
5419 src = nid;
5420 for (;;) {
5421 int n;
5422 type = get_wcaps_type(get_wcaps(codec, src));
5423 if (type == AC_WID_PIN)
5424 break;
5425 if (type == AC_WID_AUD_SEL) {
5426 cap_nids[nums] = src;
d6cc9fab 5427 indep_capsrc = true;
b7821709
TI
5428 break;
5429 }
5430 n = snd_hda_get_conn_list(codec, src, &list);
5431 if (n > 1) {
5432 cap_nids[nums] = src;
d6cc9fab 5433 indep_capsrc = true;
b7821709
TI
5434 break;
5435 } else if (n != 1)
5436 break;
5437 src = *list;
5438 }
5439 if (++nums >= max_nums)
5440 break;
5441 }
d6cc9fab
TI
5442 spec->adc_nids = spec->private_adc_nids;
5443 if (indep_capsrc)
5444 spec->capsrc_nids = spec->private_capsrc_nids;
5445 spec->num_adc_nids = nums;
b7821709
TI
5446 return nums;
5447}
5448
e9edcee0 5449/* create playback/capture controls for input pins */
b7821709 5450static int alc_auto_create_input_ctls(struct hda_codec *codec)
e9edcee0 5451{
05f5f477 5452 struct alc_spec *spec = codec->spec;
b7821709
TI
5453 const struct auto_pin_cfg *cfg = &spec->autocfg;
5454 hda_nid_t mixer = spec->mixer_nid;
61b9b9b1 5455 struct hda_input_mux *imux = &spec->private_imux[0];
b7821709 5456 int num_adcs;
b7821709 5457 int i, c, err, idx, type_idx = 0;
5322bf27 5458 const char *prev_label = NULL;
e9edcee0 5459
d6cc9fab 5460 num_adcs = alc_auto_fill_adc_caps(codec);
b7821709
TI
5461 if (num_adcs < 0)
5462 return 0;
5463
66ceeb6b 5464 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5465 hda_nid_t pin;
10a20af7 5466 const char *label;
05f5f477 5467
66ceeb6b 5468 pin = cfg->inputs[i].pin;
05f5f477
TI
5469 if (!alc_is_input_pin(codec, pin))
5470 continue;
5471
5322bf27
DH
5472 label = hda_get_autocfg_input_label(codec, cfg, i);
5473 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5474 type_idx++;
5475 else
5476 type_idx = 0;
5322bf27
DH
5477 prev_label = label;
5478
05f5f477
TI
5479 if (mixer) {
5480 idx = get_connection_index(codec, mixer, pin);
5481 if (idx >= 0) {
5482 err = new_analog_input(spec, pin,
10a20af7
TI
5483 label, type_idx,
5484 idx, mixer);
05f5f477
TI
5485 if (err < 0)
5486 return err;
5487 }
5488 }
5489
b7821709 5490 for (c = 0; c < num_adcs; c++) {
d6cc9fab
TI
5491 hda_nid_t cap = spec->capsrc_nids ?
5492 spec->capsrc_nids[c] : spec->adc_nids[c];
5493 idx = get_connection_index(codec, cap, pin);
b7821709
TI
5494 if (idx >= 0) {
5495 snd_hda_add_imux_item(imux, label, idx, NULL);
5496 break;
5497 }
5498 }
e9edcee0
TI
5499 }
5500 return 0;
5501}
5502
343a04be
TI
5503static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5504static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5505 const struct auto_pin_cfg *cfg);
5506static int alc_auto_create_hp_out(struct hda_codec *codec);
5507static int alc_auto_create_speaker_out(struct hda_codec *codec);
5508static void alc_auto_init_multi_out(struct hda_codec *codec);
5509static void alc_auto_init_extra_out(struct hda_codec *codec);
5510
f6c7e546
TI
5511static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5512 unsigned int pin_type)
5513{
5514 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5515 pin_type);
5516 /* unmute pin */
d260cdf6
TI
5517 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5518 AMP_OUT_UNMUTE);
f6c7e546
TI
5519}
5520
baba8ee9
TI
5521static int get_pin_type(int line_out_type)
5522{
5523 if (line_out_type == AUTO_PIN_HP_OUT)
5524 return PIN_HP;
5525 else
5526 return PIN_OUT;
5527}
5528
0a7f5320 5529static void alc_auto_init_analog_input(struct hda_codec *codec)
e9edcee0
TI
5530{
5531 struct alc_spec *spec = codec->spec;
66ceeb6b 5532 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5533 int i;
5534
66ceeb6b
TI
5535 for (i = 0; i < cfg->num_inputs; i++) {
5536 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5537 if (alc_is_input_pin(codec, nid)) {
30ea098f 5538 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
1f0f4b80 5539 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
f12ab1e0
TI
5540 snd_hda_codec_write(codec, nid, 0,
5541 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5542 AMP_OUT_MUTE);
5543 }
5544 }
1f0f4b80
TI
5545
5546 /* mute all loopback inputs */
5547 if (spec->mixer_nid) {
5548 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5549 for (i = 0; i < nums; i++)
5550 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5551 AC_VERB_SET_AMP_GAIN_MUTE,
5552 AMP_IN_MUTE(i));
5553 }
e9edcee0
TI
5554}
5555
cb053a82
TI
5556static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5557 int (*fill_dac)(struct hda_codec *));
d6cc9fab 5558static void alc_remove_invalid_adc_nids(struct hda_codec *codec);
f970de25 5559static void alc_auto_init_input_src(struct hda_codec *codec);
ce764ab2 5560
e9edcee0 5561/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5562/* return 1 if successful, 0 if the proper config is not found,
5563 * or a negative error code
5564 */
e9edcee0
TI
5565static int alc880_parse_auto_config(struct hda_codec *codec)
5566{
5567 struct alc_spec *spec = codec->spec;
757899ac 5568 int err;
4c6d72d1 5569 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5570
f12ab1e0
TI
5571 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5572 alc880_ignore);
5573 if (err < 0)
e9edcee0 5574 return err;
f12ab1e0 5575 if (!spec->autocfg.line_outs)
e9edcee0 5576 return 0; /* can't find valid BIOS pin config */
df694daa 5577
343a04be 5578 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
5579 if (err < 0)
5580 return err;
343a04be 5581 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
5582 if (err < 0)
5583 return err;
343a04be 5584 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
5585 if (err < 0)
5586 return err;
343a04be 5587 err = alc_auto_create_hp_out(codec);
f12ab1e0
TI
5588 if (err < 0)
5589 return err;
343a04be 5590 err = alc_auto_create_speaker_out(codec);
f12ab1e0
TI
5591 if (err < 0)
5592 return err;
b7821709 5593 err = alc_auto_create_input_ctls(codec);
f12ab1e0 5594 if (err < 0)
e9edcee0
TI
5595 return err;
5596
5597 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5598
757899ac 5599 alc_auto_parse_digital(codec);
e9edcee0 5600
603c4019 5601 if (spec->kctls.list)
d88897ea 5602 add_mixer(spec, spec->kctls.list);
e9edcee0 5603
a1e8d2da 5604 spec->num_mux_defs = 1;
61b9b9b1 5605 spec->input_mux = &spec->private_imux[0];
e9edcee0 5606
d6cc9fab
TI
5607 if (!spec->dual_adc_switch)
5608 alc_remove_invalid_adc_nids(codec);
5609
6227cdce 5610 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5611
e9edcee0
TI
5612 return 1;
5613}
5614
ae6b813a
TI
5615/* additional initialization for auto-configuration model */
5616static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5617{
f6c7e546 5618 struct alc_spec *spec = codec->spec;
343a04be
TI
5619 alc_auto_init_multi_out(codec);
5620 alc_auto_init_extra_out(codec);
0a7f5320 5621 alc_auto_init_analog_input(codec);
f970de25 5622 alc_auto_init_input_src(codec);
757899ac 5623 alc_auto_init_digital(codec);
f6c7e546 5624 if (spec->unsol_event)
7fb0d78f 5625 alc_inithook(codec);
e9edcee0
TI
5626}
5627
b59bdf3b
TI
5628/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5629 * one of two digital mic pins, e.g. on ALC272
5630 */
5631static void fixup_automic_adc(struct hda_codec *codec)
5632{
5633 struct alc_spec *spec = codec->spec;
5634 int i;
5635
5636 for (i = 0; i < spec->num_adc_nids; i++) {
5637 hda_nid_t cap = spec->capsrc_nids ?
5638 spec->capsrc_nids[i] : spec->adc_nids[i];
5639 int iidx, eidx;
5640
5641 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5642 if (iidx < 0)
5643 continue;
5644 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5645 if (eidx < 0)
5646 continue;
5647 spec->int_mic.mux_idx = iidx;
5648 spec->ext_mic.mux_idx = eidx;
5649 if (spec->capsrc_nids)
5650 spec->capsrc_nids += i;
5651 spec->adc_nids += i;
5652 spec->num_adc_nids = 1;
8ed99d97
TI
5653 /* optional dock-mic */
5654 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5655 if (eidx < 0)
5656 spec->dock_mic.pin = 0;
5657 else
5658 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5659 return;
5660 }
5661 snd_printd(KERN_INFO "hda_codec: %s: "
5662 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5663 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5664 spec->auto_mic = 0; /* disable auto-mic to be sure */
5665}
5666
748cce43
TI
5667/* select or unmute the given capsrc route */
5668static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5669 int idx)
5670{
5671 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5672 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5673 HDA_AMP_MUTE, 0);
5674 } else {
5675 snd_hda_codec_write_cache(codec, cap, 0,
5676 AC_VERB_SET_CONNECT_SEL, idx);
5677 }
5678}
5679
840b64c0
TI
5680/* set the default connection to that pin */
5681static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5682{
5683 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5684 int i;
5685
8ed99d97
TI
5686 if (!pin)
5687 return 0;
eaa9b3a7
TI
5688 for (i = 0; i < spec->num_adc_nids; i++) {
5689 hda_nid_t cap = spec->capsrc_nids ?
5690 spec->capsrc_nids[i] : spec->adc_nids[i];
5691 int idx;
5692
5693 idx = get_connection_index(codec, cap, pin);
5694 if (idx < 0)
5695 continue;
748cce43 5696 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5697 return i; /* return the found index */
5698 }
5699 return -1; /* not found */
5700}
5701
5702/* choose the ADC/MUX containing the input pin and initialize the setup */
5703static void fixup_single_adc(struct hda_codec *codec)
5704{
5705 struct alc_spec *spec = codec->spec;
66ceeb6b 5706 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5707 int i;
5708
5709 /* search for the input pin; there must be only one */
66ceeb6b 5710 if (cfg->num_inputs != 1)
eaa9b3a7 5711 return;
66ceeb6b 5712 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5713 if (i >= 0) {
5714 /* use only this ADC */
5715 if (spec->capsrc_nids)
5716 spec->capsrc_nids += i;
5717 spec->adc_nids += i;
5718 spec->num_adc_nids = 1;
584c0c4c 5719 spec->single_input_src = 1;
eaa9b3a7
TI
5720 }
5721}
5722
840b64c0
TI
5723/* initialize dual adcs */
5724static void fixup_dual_adc_switch(struct hda_codec *codec)
5725{
5726 struct alc_spec *spec = codec->spec;
5727 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5728 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5729 init_capsrc_for_pin(codec, spec->int_mic.pin);
5730}
5731
584c0c4c
TI
5732/* initialize some special cases for input sources */
5733static void alc_init_special_input_src(struct hda_codec *codec)
5734{
5735 struct alc_spec *spec = codec->spec;
5736 if (spec->dual_adc_switch)
5737 fixup_dual_adc_switch(codec);
5738 else if (spec->single_input_src)
5739 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5740}
5741
b59bdf3b 5742static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5743{
b59bdf3b 5744 struct alc_spec *spec = codec->spec;
a9111321 5745 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5746 { alc_capture_mixer_nosrc1,
5747 alc_capture_mixer_nosrc2,
5748 alc_capture_mixer_nosrc3 },
5749 { alc_capture_mixer1,
5750 alc_capture_mixer2,
5751 alc_capture_mixer3 },
f9e336f6 5752 };
d6cc9fab
TI
5753
5754 /* check whether either of ADC or MUX has a volume control */
5755 if (!(query_amp_caps(codec, spec->adc_nids[0], HDA_INPUT) &
5756 AC_AMPCAP_NUM_STEPS)) {
5757 if (!spec->capsrc_nids)
5758 return; /* no volume */
5759 if (!(query_amp_caps(codec, spec->capsrc_nids[0], HDA_OUTPUT) &
5760 AC_AMPCAP_NUM_STEPS))
5761 return; /* no volume in capsrc, too */
5762 spec->vol_in_capsrc = 1;
5763 }
5764
5765 if (spec->num_adc_nids > 0) {
eaa9b3a7 5766 int mux = 0;
d6cc9fab 5767 int num_adcs = 0;
840b64c0 5768 if (spec->dual_adc_switch)
584c0c4c 5769 num_adcs = 1;
840b64c0 5770 else if (spec->auto_mic)
b59bdf3b 5771 fixup_automic_adc(codec);
eaa9b3a7
TI
5772 else if (spec->input_mux) {
5773 if (spec->input_mux->num_items > 1)
5774 mux = 1;
5775 else if (spec->input_mux->num_items == 1)
5776 fixup_single_adc(codec);
5777 }
d6cc9fab
TI
5778 if (!num_adcs) {
5779 if (spec->num_adc_nids > 3)
5780 spec->num_adc_nids = 3;
5781 else if (!spec->num_adc_nids)
5782 return;
5783 num_adcs = spec->num_adc_nids;
5784 }
840b64c0 5785 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5786 }
f9e336f6
TI
5787}
5788
d6cc9fab
TI
5789/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5790 * active input pins
5791 */
5792static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
6694635d
TI
5793{
5794 struct alc_spec *spec = codec->spec;
66ceeb6b 5795 struct auto_pin_cfg *cfg = &spec->autocfg;
d6cc9fab
TI
5796 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5797 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5798 int i, n, nums;
6694635d 5799
d6cc9fab
TI
5800 nums = 0;
5801 for (n = 0; n < spec->num_adc_nids; n++) {
5802 hda_nid_t cap = spec->private_capsrc_nids[n];
66ceeb6b 5803 for (i = 0; i < cfg->num_inputs; i++) {
d6cc9fab
TI
5804 hda_nid_t pin = cfg->inputs[i].pin;
5805 if (get_connection_index(codec, cap, pin) < 0)
6694635d
TI
5806 break;
5807 }
66ceeb6b 5808 if (i >= cfg->num_inputs) {
d6cc9fab
TI
5809 adc_nids[nums] = spec->private_adc_nids[n];
5810 capsrc_nids[nums++] = cap;
6694635d
TI
5811 }
5812 }
d6cc9fab 5813 if (!nums) {
6694635d 5814 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d 5815 " using fallback 0x%x\n",
d6cc9fab
TI
5816 codec->chip_name, spec->private_adc_nids[0]);
5817 spec->num_adc_nids = 1;
5818 } else if (nums != spec->num_adc_nids) {
5819 memcpy(spec->private_adc_nids, adc_nids,
5820 nums * sizeof(hda_nid_t));
5821 memcpy(spec->private_capsrc_nids, capsrc_nids,
5822 nums * sizeof(hda_nid_t));
5823 spec->num_adc_nids = nums;
6694635d
TI
5824 }
5825}
5826
67d634c0 5827#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5828#define set_beep_amp(spec, nid, idx, dir) \
5829 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5830
a9111321 5831static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5832 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5833 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5834 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5835 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5836 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5837 {}
5838};
5839
5840static inline int has_cdefine_beep(struct hda_codec *codec)
5841{
5842 struct alc_spec *spec = codec->spec;
5843 const struct snd_pci_quirk *q;
5844 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5845 if (q)
5846 return q->value;
5847 return spec->cdefine.enable_pcbeep;
5848}
67d634c0
TI
5849#else
5850#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5851#define has_cdefine_beep(codec) 0
67d634c0 5852#endif
45bdd1c1
TI
5853
5854/*
5855 * OK, here we have finally the patch for ALC880
5856 */
5857
1da177e4
LT
5858static int patch_alc880(struct hda_codec *codec)
5859{
5860 struct alc_spec *spec;
5861 int board_config;
df694daa 5862 int err;
1da177e4 5863
e560d8d8 5864 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5865 if (spec == NULL)
5866 return -ENOMEM;
5867
5868 codec->spec = spec;
5869
1f0f4b80
TI
5870 spec->mixer_nid = 0x0b;
5871
f5fcc13c
TI
5872 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5873 alc880_models,
5874 alc880_cfg_tbl);
5875 if (board_config < 0) {
9a11f1aa
TI
5876 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5877 codec->chip_name);
e9edcee0 5878 board_config = ALC880_AUTO;
1da177e4 5879 }
1da177e4 5880
e9edcee0
TI
5881 if (board_config == ALC880_AUTO) {
5882 /* automatic parse from the BIOS config */
5883 err = alc880_parse_auto_config(codec);
5884 if (err < 0) {
5885 alc_free(codec);
5886 return err;
f12ab1e0 5887 } else if (!err) {
9c7f852e
TI
5888 printk(KERN_INFO
5889 "hda_codec: Cannot set up configuration "
5890 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5891 board_config = ALC880_3ST;
5892 }
1da177e4
LT
5893 }
5894
680cd536
KK
5895 err = snd_hda_attach_beep_device(codec, 0x1);
5896 if (err < 0) {
5897 alc_free(codec);
5898 return err;
5899 }
5900
df694daa 5901 if (board_config != ALC880_AUTO)
e9c364c0 5902 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5903
1da177e4
LT
5904 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5905 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5906 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5907
1da177e4
LT
5908 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5909 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5910
f12ab1e0 5911 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab
TI
5912 alc_auto_fill_adc_caps(codec);
5913 alc_remove_invalid_adc_nids(codec);
e9edcee0 5914 }
b59bdf3b 5915 set_capture_mixer(codec);
45bdd1c1 5916 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5917
2134ea4f
TI
5918 spec->vmaster_nid = 0x0c;
5919
1da177e4 5920 codec->patch_ops = alc_patch_ops;
e9edcee0 5921 if (board_config == ALC880_AUTO)
ae6b813a 5922 spec->init_hook = alc880_auto_init;
cb53c626
TI
5923#ifdef CONFIG_SND_HDA_POWER_SAVE
5924 if (!spec->loopback.amplist)
5925 spec->loopback.amplist = alc880_loopbacks;
5926#endif
1da177e4
LT
5927
5928 return 0;
5929}
5930
e9edcee0 5931
1da177e4
LT
5932/*
5933 * ALC260 support
5934 */
5935
4c6d72d1 5936static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
5937 /* front */
5938 0x02,
5939};
5940
4c6d72d1 5941static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
5942 /* ADC0 */
5943 0x04,
5944};
5945
4c6d72d1 5946static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
5947 /* ADC1 */
5948 0x05,
5949};
5950
d57fdac0
JW
5951/* NIDs used when simultaneous access to both ADCs makes sense. Note that
5952 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
5953 */
4c6d72d1 5954static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
5955 /* ADC0, ADC1 */
5956 0x04, 0x05
5957};
5958
e9edcee0
TI
5959#define ALC260_DIGOUT_NID 0x03
5960#define ALC260_DIGIN_NID 0x06
5961
a9111321 5962static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
5963 .num_items = 4,
5964 .items = {
5965 { "Mic", 0x0 },
5966 { "Front Mic", 0x1 },
5967 { "Line", 0x2 },
5968 { "CD", 0x4 },
5969 },
5970};
5971
17e7aec6 5972/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
5973 * headphone jack and the internal CD lines since these are the only pins at
5974 * which audio can appear. For flexibility, also allow the option of
5975 * recording the mixer output on the second ADC (ADC0 doesn't have a
5976 * connection to the mixer output).
a9430dd8 5977 */
a9111321 5978static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
5979 {
5980 .num_items = 3,
5981 .items = {
5982 { "Mic/Line", 0x0 },
5983 { "CD", 0x4 },
5984 { "Headphone", 0x2 },
5985 },
a9430dd8 5986 },
a1e8d2da
JW
5987 {
5988 .num_items = 4,
5989 .items = {
5990 { "Mic/Line", 0x0 },
5991 { "CD", 0x4 },
5992 { "Headphone", 0x2 },
5993 { "Mixer", 0x5 },
5994 },
5995 },
5996
a9430dd8
JW
5997};
5998
a1e8d2da
JW
5999/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6000 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6001 */
a9111321 6002static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6003 {
6004 .num_items = 4,
6005 .items = {
6006 { "Mic", 0x0 },
6007 { "Line", 0x2 },
6008 { "CD", 0x4 },
6009 { "Headphone", 0x5 },
6010 },
6011 },
6012 {
6013 .num_items = 5,
6014 .items = {
6015 { "Mic", 0x0 },
6016 { "Line", 0x2 },
6017 { "CD", 0x4 },
6018 { "Headphone", 0x6 },
6019 { "Mixer", 0x5 },
6020 },
0bfc90e9
JW
6021 },
6022};
cc959489
MS
6023
6024/* Maxdata Favorit 100XS */
a9111321 6025static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6026 {
6027 .num_items = 2,
6028 .items = {
6029 { "Line/Mic", 0x0 },
6030 { "CD", 0x4 },
6031 },
6032 },
6033 {
6034 .num_items = 3,
6035 .items = {
6036 { "Line/Mic", 0x0 },
6037 { "CD", 0x4 },
6038 { "Mixer", 0x5 },
6039 },
6040 },
6041};
6042
1da177e4
LT
6043/*
6044 * This is just place-holder, so there's something for alc_build_pcms to look
6045 * at when it calculates the maximum number of channels. ALC260 has no mixer
6046 * element which allows changing the channel mode, so the verb list is
6047 * never used.
6048 */
a9111321 6049static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6050 { 2, NULL },
6051};
6052
df694daa
KY
6053
6054/* Mixer combinations
6055 *
6056 * basic: base_output + input + pc_beep + capture
6057 * HP: base_output + input + capture_alt
6058 * HP_3013: hp_3013 + input + capture
6059 * fujitsu: fujitsu + capture
0bfc90e9 6060 * acer: acer + capture
df694daa
KY
6061 */
6062
a9111321 6063static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6064 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6065 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6066 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6067 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6068 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6069 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6070 { } /* end */
f12ab1e0 6071};
1da177e4 6072
a9111321 6073static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6074 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6075 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6076 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6077 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6078 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6079 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6080 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6081 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6082 { } /* end */
6083};
6084
bec15c3a 6085/* update HP, line and mono out pins according to the master switch */
e9427969 6086static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a 6087{
e9427969 6088 update_speakers(codec);
bec15c3a
TI
6089}
6090
6091static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6092 struct snd_ctl_elem_value *ucontrol)
6093{
6094 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6095 struct alc_spec *spec = codec->spec;
e9427969 6096 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6097 return 0;
6098}
6099
6100static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6101 struct snd_ctl_elem_value *ucontrol)
6102{
6103 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6104 struct alc_spec *spec = codec->spec;
e9427969 6105 int val = !*ucontrol->value.integer.value;
bec15c3a 6106
e9427969 6107 if (val == spec->master_mute)
bec15c3a 6108 return 0;
e9427969
TI
6109 spec->master_mute = val;
6110 alc260_hp_master_update(codec);
bec15c3a
TI
6111 return 1;
6112}
6113
a9111321 6114static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6115 {
6116 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6117 .name = "Master Playback Switch",
5b0cb1d8 6118 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6119 .info = snd_ctl_boolean_mono_info,
6120 .get = alc260_hp_master_sw_get,
6121 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6122 },
6123 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6124 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6125 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6126 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6127 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6128 HDA_OUTPUT),
6129 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6130 { } /* end */
6131};
6132
a9111321 6133static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6134 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6135 {},
6136};
6137
e9427969 6138static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6139{
6140 struct alc_spec *spec = codec->spec;
bec15c3a 6141
e9427969
TI
6142 spec->autocfg.hp_pins[0] = 0x0f;
6143 spec->autocfg.speaker_pins[0] = 0x10;
6144 spec->autocfg.speaker_pins[1] = 0x11;
6145 spec->automute = 1;
6146 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6147}
6148
a9111321 6149static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6150 {
6151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6152 .name = "Master Playback Switch",
5b0cb1d8 6153 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6154 .info = snd_ctl_boolean_mono_info,
6155 .get = alc260_hp_master_sw_get,
6156 .put = alc260_hp_master_sw_put,
bec15c3a 6157 },
df694daa
KY
6158 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6159 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6160 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6161 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6162 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6164 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6165 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6166 { } /* end */
6167};
6168
e9427969
TI
6169static void alc260_hp_3013_setup(struct hda_codec *codec)
6170{
6171 struct alc_spec *spec = codec->spec;
6172
6173 spec->autocfg.hp_pins[0] = 0x15;
6174 spec->autocfg.speaker_pins[0] = 0x10;
6175 spec->autocfg.speaker_pins[1] = 0x11;
6176 spec->automute = 1;
6177 spec->automute_mode = ALC_AUTOMUTE_PIN;
6178}
6179
a9111321 6180static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6181 .ops = &snd_hda_bind_vol,
6182 .values = {
6183 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6184 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6185 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6186 0
6187 },
6188};
6189
a9111321 6190static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6191 .ops = &snd_hda_bind_sw,
6192 .values = {
6193 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6194 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6195 0
6196 },
6197};
6198
a9111321 6199static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6200 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6201 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6202 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6203 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6204 { } /* end */
6205};
6206
a9111321 6207static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6208 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6209 {},
6210};
6211
e9427969 6212static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6213{
6214 struct alc_spec *spec = codec->spec;
bec15c3a 6215
e9427969
TI
6216 spec->autocfg.hp_pins[0] = 0x10;
6217 spec->autocfg.speaker_pins[0] = 0x0f;
6218 spec->autocfg.speaker_pins[1] = 0x11;
6219 spec->autocfg.speaker_pins[2] = 0x15;
6220 spec->automute = 1;
6221 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6222}
6223
6224/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6225 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6226 */
a9111321 6227static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6228 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6229 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6230 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6231 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6232 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6233 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6234 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6235 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6236 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6237 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6238 { } /* end */
6239};
6240
a1e8d2da
JW
6241/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6242 * versions of the ALC260 don't act on requests to enable mic bias from NID
6243 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6244 * datasheet doesn't mention this restriction. At this stage it's not clear
6245 * whether this behaviour is intentional or is a hardware bug in chip
6246 * revisions available in early 2006. Therefore for now allow the
6247 * "Headphone Jack Mode" control to span all choices, but if it turns out
6248 * that the lack of mic bias for this NID is intentional we could change the
6249 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6250 *
6251 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6252 * don't appear to make the mic bias available from the "line" jack, even
6253 * though the NID used for this jack (0x14) can supply it. The theory is
6254 * that perhaps Acer have included blocking capacitors between the ALC260
6255 * and the output jack. If this turns out to be the case for all such
6256 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6257 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6258 *
6259 * The C20x Tablet series have a mono internal speaker which is controlled
6260 * via the chip's Mono sum widget and pin complex, so include the necessary
6261 * controls for such models. On models without a "mono speaker" the control
6262 * won't do anything.
a1e8d2da 6263 */
a9111321 6264static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6265 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6266 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6267 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6268 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6269 HDA_OUTPUT),
31bffaa9 6270 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6271 HDA_INPUT),
0bfc90e9
JW
6272 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6273 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6275 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6276 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6277 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6278 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6279 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6280 { } /* end */
6281};
6282
cc959489
MS
6283/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6284 */
a9111321 6285static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6286 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6287 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6288 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6289 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6290 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6291 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6292 { } /* end */
6293};
6294
bc9f98a9
KY
6295/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6296 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6297 */
a9111321 6298static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6299 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6300 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6302 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6303 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6304 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6305 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6306 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6307 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6308 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6309 { } /* end */
6310};
6311
6312/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6313 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6314 */
a9111321 6315static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6316 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6317 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6319 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6320 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6321 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6322 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6323 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6324 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6325 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6326 { } /* end */
6327};
6328
df694daa
KY
6329/*
6330 * initialization verbs
6331 */
a9111321 6332static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6333 /* Line In pin widget for input */
05acb863 6334 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6335 /* CD pin widget for input */
05acb863 6336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6337 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6338 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6339 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6340 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6341 /* LINE-2 is used for line-out in rear */
05acb863 6342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6343 /* select line-out */
fd56f2db 6344 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6345 /* LINE-OUT pin */
05acb863 6346 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6347 /* enable HP */
05acb863 6348 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6349 /* enable Mono */
05acb863
TI
6350 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6351 /* mute capture amp left and right */
16ded525 6352 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6353 /* set connection select to line in (default select for this ADC) */
6354 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6355 /* mute capture amp left and right */
6356 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6357 /* set connection select to line in (default select for this ADC) */
6358 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6359 /* set vol=0 Line-Out mixer amp left and right */
6360 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6361 /* unmute pin widget amp left and right (no gain on this amp) */
6362 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6363 /* set vol=0 HP mixer amp left and right */
6364 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6365 /* unmute pin widget amp left and right (no gain on this amp) */
6366 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6367 /* set vol=0 Mono mixer amp left and right */
6368 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6369 /* unmute pin widget amp left and right (no gain on this amp) */
6370 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6371 /* unmute LINE-2 out pin */
6372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6373 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6374 * Line In 2 = 0x03
6375 */
cb53c626
TI
6376 /* mute analog inputs */
6377 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6378 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6379 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6380 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6381 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6382 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6383 /* mute Front out path */
6384 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6385 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6386 /* mute Headphone out path */
6387 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6388 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6389 /* mute Mono out path */
6390 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6391 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6392 { }
6393};
6394
474167d6 6395#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6396static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6397 /* Headphone and output */
6398 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6399 /* mono output */
6400 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6401 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6402 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6403 /* Mic2 (front panel) pin widget for input and vref at 80% */
6404 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6405 /* Line In pin widget for input */
6406 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6407 /* Line-2 pin widget for output */
6408 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6409 /* CD pin widget for input */
6410 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6411 /* unmute amp left and right */
6412 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6413 /* set connection select to line in (default select for this ADC) */
6414 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6415 /* unmute Line-Out mixer amp left and right (volume = 0) */
6416 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6417 /* mute pin widget amp left and right (no gain on this amp) */
6418 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6419 /* unmute HP mixer amp left and right (volume = 0) */
6420 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6421 /* mute pin widget amp left and right (no gain on this amp) */
6422 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6423 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6424 * Line In 2 = 0x03
6425 */
cb53c626
TI
6426 /* mute analog inputs */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6432 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6433 /* Unmute Front out path */
6434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6436 /* Unmute Headphone out path */
6437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6439 /* Unmute Mono out path */
6440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6441 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6442 { }
6443};
474167d6 6444#endif
df694daa 6445
a9111321 6446static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6447 /* Line out and output */
6448 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6449 /* mono output */
6450 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6453 /* Mic2 (front panel) pin widget for input and vref at 80% */
6454 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6455 /* Line In pin widget for input */
6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6457 /* Headphone pin widget for output */
6458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6459 /* CD pin widget for input */
6460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6461 /* unmute amp left and right */
6462 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6463 /* set connection select to line in (default select for this ADC) */
6464 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6465 /* unmute Line-Out mixer amp left and right (volume = 0) */
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6467 /* mute pin widget amp left and right (no gain on this amp) */
6468 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6469 /* unmute HP mixer amp left and right (volume = 0) */
6470 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6471 /* mute pin widget amp left and right (no gain on this amp) */
6472 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6473 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6474 * Line In 2 = 0x03
6475 */
cb53c626
TI
6476 /* mute analog inputs */
6477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6482 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6483 /* Unmute Front out path */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6486 /* Unmute Headphone out path */
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6489 /* Unmute Mono out path */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6492 { }
6493};
6494
a9430dd8 6495/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6496 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6497 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6498 */
a9111321 6499static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6500 /* Disable all GPIOs */
6501 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6502 /* Internal speaker is connected to headphone pin */
6503 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6504 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6506 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6507 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6508 /* Ensure all other unused pins are disabled and muted. */
6509 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6510 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6511 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6512 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6513 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6514 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6515 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6516 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6517
6518 /* Disable digital (SPDIF) pins */
6519 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6520 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6521
ea1fb29a 6522 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6523 * when acting as an output.
6524 */
6525 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6526
f7ace40d 6527 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6528 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6529 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6530 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6531 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6532 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6534 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6535 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6536 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6537
f7ace40d
JW
6538 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6539 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6540 /* Unmute Line1 pin widget output buffer since it starts as an output.
6541 * If the pin mode is changed by the user the pin mode control will
6542 * take care of enabling the pin's input/output buffers as needed.
6543 * Therefore there's no need to enable the input buffer at this
6544 * stage.
cdcd9268 6545 */
f7ace40d 6546 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6547 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6548 * mixer ctrl)
6549 */
f7ace40d
JW
6550 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6551
6552 /* Mute capture amp left and right */
6553 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6554 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6555 * in (on mic1 pin)
6556 */
6557 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6558
6559 /* Do the same for the second ADC: mute capture input amp and
6560 * set ADC connection to line in (on mic1 pin)
6561 */
6562 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6564
6565 /* Mute all inputs to mixer widget (even unconnected ones) */
6566 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6567 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6568 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6569 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6570 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6571 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6572 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6573 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6574
6575 { }
a9430dd8
JW
6576};
6577
0bfc90e9
JW
6578/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6579 * similar laptops (adapted from Fujitsu init verbs).
6580 */
a9111321 6581static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6582 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6583 * the headphone jack. Turn this on and rely on the standard mute
6584 * methods whenever the user wants to turn these outputs off.
6585 */
6586 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6587 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6588 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6589 /* Internal speaker/Headphone jack is connected to Line-out pin */
6590 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6591 /* Internal microphone/Mic jack is connected to Mic1 pin */
6592 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6593 /* Line In jack is connected to Line1 pin */
6594 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6595 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6596 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6597 /* Ensure all other unused pins are disabled and muted. */
6598 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6599 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6600 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6601 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6602 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6603 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6604 /* Disable digital (SPDIF) pins */
6605 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6606 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6607
ea1fb29a 6608 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6609 * bus when acting as outputs.
6610 */
6611 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6612 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6613
6614 /* Start with output sum widgets muted and their output gains at min */
6615 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6616 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6618 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6619 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6621 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6623 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6624
f12ab1e0
TI
6625 /* Unmute Line-out pin widget amp left and right
6626 * (no equiv mixer ctrl)
6627 */
0bfc90e9 6628 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6629 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6630 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6631 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6632 * inputs. If the pin mode is changed by the user the pin mode control
6633 * will take care of enabling the pin's input/output buffers as needed.
6634 * Therefore there's no need to enable the input buffer at this
6635 * stage.
6636 */
6637 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6638 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6639
6640 /* Mute capture amp left and right */
6641 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6642 /* Set ADC connection select to match default mixer setting - mic
6643 * (on mic1 pin)
6644 */
6645 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6646
6647 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6648 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6649 */
6650 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6651 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6652
6653 /* Mute all inputs to mixer widget (even unconnected ones) */
6654 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6655 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6656 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6657 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6658 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6659 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6660 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6661 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6662
6663 { }
6664};
6665
cc959489
MS
6666/* Initialisation sequence for Maxdata Favorit 100XS
6667 * (adapted from Acer init verbs).
6668 */
a9111321 6669static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6670 /* GPIO 0 enables the output jack.
6671 * Turn this on and rely on the standard mute
6672 * methods whenever the user wants to turn these outputs off.
6673 */
6674 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6675 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6676 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6677 /* Line/Mic input jack is connected to Mic1 pin */
6678 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6679 /* Ensure all other unused pins are disabled and muted. */
6680 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6681 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6682 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6683 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6684 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6685 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6686 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6687 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6688 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6689 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6690 /* Disable digital (SPDIF) pins */
6691 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6692 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6693
6694 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6695 * bus when acting as outputs.
6696 */
6697 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6698 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6699
6700 /* Start with output sum widgets muted and their output gains at min */
6701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6702 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6703 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6705 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6706 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6707 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6708 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6709 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6710
6711 /* Unmute Line-out pin widget amp left and right
6712 * (no equiv mixer ctrl)
6713 */
6714 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6715 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6716 * inputs. If the pin mode is changed by the user the pin mode control
6717 * will take care of enabling the pin's input/output buffers as needed.
6718 * Therefore there's no need to enable the input buffer at this
6719 * stage.
6720 */
6721 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6722
6723 /* Mute capture amp left and right */
6724 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6725 /* Set ADC connection select to match default mixer setting - mic
6726 * (on mic1 pin)
6727 */
6728 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6729
6730 /* Do similar with the second ADC: mute capture input amp and
6731 * set ADC connection to mic to match ALSA's default state.
6732 */
6733 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6735
6736 /* Mute all inputs to mixer widget (even unconnected ones) */
6737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6738 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6739 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6740 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6741 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6742 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6743 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6744 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6745
6746 { }
6747};
6748
a9111321 6749static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6750 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6751 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6752 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6753 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6754 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6755 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6756 {}
6757};
6758
a9111321 6759static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6760 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6761 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6762 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6763
6764 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6765 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6766 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6767
6768 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6769 {}
6770};
6771
6772/* toggle speaker-output according to the hp-jack state */
6773static void alc260_replacer_672v_automute(struct hda_codec *codec)
6774{
6775 unsigned int present;
6776
6777 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6778 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6779 if (present) {
82beb8fd
TI
6780 snd_hda_codec_write_cache(codec, 0x01, 0,
6781 AC_VERB_SET_GPIO_DATA, 1);
6782 snd_hda_codec_write_cache(codec, 0x0f, 0,
6783 AC_VERB_SET_PIN_WIDGET_CONTROL,
6784 PIN_HP);
bc9f98a9 6785 } else {
82beb8fd
TI
6786 snd_hda_codec_write_cache(codec, 0x01, 0,
6787 AC_VERB_SET_GPIO_DATA, 0);
6788 snd_hda_codec_write_cache(codec, 0x0f, 0,
6789 AC_VERB_SET_PIN_WIDGET_CONTROL,
6790 PIN_OUT);
bc9f98a9
KY
6791 }
6792}
6793
6794static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6795 unsigned int res)
6796{
6797 if ((res >> 26) == ALC880_HP_EVENT)
6798 alc260_replacer_672v_automute(codec);
6799}
6800
a9111321 6801static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6802 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6804 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6805 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6806 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6808 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6809 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6810 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6811 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6812 {}
6813};
6814
7cf51e48
JW
6815/* Test configuration for debugging, modelled after the ALC880 test
6816 * configuration.
6817 */
6818#ifdef CONFIG_SND_DEBUG
4c6d72d1 6819static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6820 0x02,
6821};
4c6d72d1 6822static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6823 0x04, 0x05,
6824};
a1e8d2da 6825/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6826 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6827 * is NID 0x04.
17e7aec6 6828 */
a9111321 6829static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6830 {
6831 .num_items = 7,
6832 .items = {
6833 { "MIC1 pin", 0x0 },
6834 { "MIC2 pin", 0x1 },
6835 { "LINE1 pin", 0x2 },
6836 { "LINE2 pin", 0x3 },
6837 { "CD pin", 0x4 },
6838 { "LINE-OUT pin", 0x5 },
6839 { "HP-OUT pin", 0x6 },
6840 },
6841 },
6842 {
6843 .num_items = 8,
6844 .items = {
6845 { "MIC1 pin", 0x0 },
6846 { "MIC2 pin", 0x1 },
6847 { "LINE1 pin", 0x2 },
6848 { "LINE2 pin", 0x3 },
6849 { "CD pin", 0x4 },
6850 { "Mixer", 0x5 },
6851 { "LINE-OUT pin", 0x6 },
6852 { "HP-OUT pin", 0x7 },
6853 },
7cf51e48
JW
6854 },
6855};
a9111321 6856static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6857 /* Output driver widgets */
6858 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6859 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6860 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6861 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6862 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6863 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6864
a1e8d2da
JW
6865 /* Modes for retasking pin widgets
6866 * Note: the ALC260 doesn't seem to act on requests to enable mic
6867 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6868 * mention this restriction. At this stage it's not clear whether
6869 * this behaviour is intentional or is a hardware bug in chip
6870 * revisions available at least up until early 2006. Therefore for
6871 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6872 * choices, but if it turns out that the lack of mic bias for these
6873 * NIDs is intentional we could change their modes from
6874 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6875 */
7cf51e48
JW
6876 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6877 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6878 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6879 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6880 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6881 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6882
6883 /* Loopback mixer controls */
6884 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6885 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6886 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6887 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6888 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6889 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6890 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6891 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6892 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6893 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6894 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6895 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6896 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6897 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6898
6899 /* Controls for GPIO pins, assuming they are configured as outputs */
6900 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6901 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6902 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6903 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6904
92621f13
JW
6905 /* Switches to allow the digital IO pins to be enabled. The datasheet
6906 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6907 * make this output available should provide clarification.
92621f13
JW
6908 */
6909 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6910 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6911
f8225f6d
JW
6912 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6913 * this output to turn on an external amplifier.
6914 */
6915 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6916 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6917
7cf51e48
JW
6918 { } /* end */
6919};
a9111321 6920static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6921 /* Enable all GPIOs as outputs with an initial value of 0 */
6922 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6923 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6924 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6925
7cf51e48
JW
6926 /* Enable retasking pins as output, initially without power amp */
6927 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6928 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6930 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6931 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6932 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6933
92621f13
JW
6934 /* Disable digital (SPDIF) pins initially, but users can enable
6935 * them via a mixer switch. In the case of SPDIF-out, this initverb
6936 * payload also sets the generation to 0, output to be in "consumer"
6937 * PCM format, copyright asserted, no pre-emphasis and no validity
6938 * control.
6939 */
7cf51e48
JW
6940 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6941 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6942
ea1fb29a 6943 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
6944 * OUT1 sum bus when acting as an output.
6945 */
6946 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6947 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6948 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6949 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
6950
6951 /* Start with output sum widgets muted and their output gains at min */
6952 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6953 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6954 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6955 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6956 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6957 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6958 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6959 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6960 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6961
cdcd9268
JW
6962 /* Unmute retasking pin widget output buffers since the default
6963 * state appears to be output. As the pin mode is changed by the
6964 * user the pin mode control will take care of enabling the pin's
6965 * input/output buffers as needed.
6966 */
7cf51e48
JW
6967 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6968 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6969 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6971 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6972 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6973 /* Also unmute the mono-out pin widget */
6974 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6975
7cf51e48
JW
6976 /* Mute capture amp left and right */
6977 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
6978 /* Set ADC connection select to match default mixer setting (mic1
6979 * pin)
7cf51e48
JW
6980 */
6981 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6982
6983 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 6984 * set ADC connection to mic1 pin
7cf51e48
JW
6985 */
6986 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6987 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6988
6989 /* Mute all inputs to mixer widget (even unconnected ones) */
6990 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6991 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6992 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6994 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6995 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6996 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6997 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6998
6999 { }
7000};
7001#endif
7002
6330079f
TI
7003#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7004#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7005
a3bcba38
TI
7006#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7007#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7008
df694daa
KY
7009/*
7010 * for BIOS auto-configuration
7011 */
16ded525 7012
6d86b4fb
TI
7013/* convert from pin to volume-mixer widget */
7014static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7015{
7016 if (nid >= 0x0f && nid <= 0x11)
7017 return nid - 0x7;
7018 else if (nid >= 0x12 && nid <= 0x15)
7019 return 0x08;
7020 else
7021 return 0;
7022}
7023
df694daa 7024static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7025 const char *pfx, int *vol_bits)
df694daa
KY
7026{
7027 hda_nid_t nid_vol;
7028 unsigned long vol_val, sw_val;
6d86b4fb 7029 int chs, err;
df694daa 7030
6d86b4fb
TI
7031 nid_vol = alc260_pin_to_vol_mix(nid);
7032 if (!nid_vol)
df694daa 7033 return 0; /* N/A */
6d86b4fb
TI
7034 if (nid == 0x11)
7035 chs = 2;
7036 else
7037 chs = 3;
7038 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7039 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
ea1fb29a 7040
863b4518
TI
7041 if (!(*vol_bits & (1 << nid_vol))) {
7042 /* first control for the volume widget */
0afe5f89 7043 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7044 if (err < 0)
7045 return err;
7046 *vol_bits |= (1 << nid_vol);
7047 }
0afe5f89 7048 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7049 if (err < 0)
df694daa
KY
7050 return err;
7051 return 1;
7052}
7053
7054/* add playback controls from the parsed DAC table */
7055static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7056 const struct auto_pin_cfg *cfg)
7057{
7058 hda_nid_t nid;
7059 int err;
863b4518 7060 int vols = 0;
df694daa
KY
7061
7062 spec->multiout.num_dacs = 1;
7063 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7064 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7065
7066 nid = cfg->line_out_pins[0];
7067 if (nid) {
23112d6d 7068 const char *pfx;
2e925dde
TI
7069 int index;
7070 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
23112d6d 7071 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7072 if (err < 0)
7073 return err;
7074 }
7075
82bc955f 7076 nid = cfg->speaker_pins[0];
df694daa 7077 if (nid) {
863b4518 7078 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7079 if (err < 0)
7080 return err;
7081 }
7082
eb06ed8f 7083 nid = cfg->hp_pins[0];
df694daa 7084 if (nid) {
863b4518
TI
7085 err = alc260_add_playback_controls(spec, nid, "Headphone",
7086 &vols);
df694daa
KY
7087 if (err < 0)
7088 return err;
7089 }
f12ab1e0 7090 return 0;
df694daa
KY
7091}
7092
df694daa
KY
7093static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7094 hda_nid_t nid, int pin_type,
7095 int sel_idx)
7096{
6d86b4fb
TI
7097 hda_nid_t mix;
7098
f6c7e546 7099 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7100 /* need the manual connection? */
7101 if (nid >= 0x12) {
7102 int idx = nid - 0x12;
7103 snd_hda_codec_write(codec, idx + 0x0b, 0,
7104 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa 7105 }
df694daa 7106
6d86b4fb
TI
7107 mix = alc260_pin_to_vol_mix(nid);
7108 if (!mix)
1f0f4b80 7109 return;
6d86b4fb 7110 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1f0f4b80 7111 AMP_OUT_ZERO);
6d86b4fb
TI
7112 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7113 AMP_IN_UNMUTE(0));
7114 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7115 AMP_IN_UNMUTE(1));
1f0f4b80
TI
7116}
7117
df694daa
KY
7118static void alc260_auto_init_multi_out(struct hda_codec *codec)
7119{
7120 struct alc_spec *spec = codec->spec;
7121 hda_nid_t nid;
7122
f12ab1e0 7123 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7124 if (nid) {
7125 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7126 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7127 }
ea1fb29a 7128
82bc955f 7129 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7130 if (nid)
7131 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7132
eb06ed8f 7133 nid = spec->autocfg.hp_pins[0];
df694daa 7134 if (nid)
baba8ee9 7135 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
df694daa
KY
7136}
7137
df694daa
KY
7138static int alc260_parse_auto_config(struct hda_codec *codec)
7139{
7140 struct alc_spec *spec = codec->spec;
df694daa 7141 int err;
4c6d72d1 7142 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7143
f12ab1e0
TI
7144 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7145 alc260_ignore);
7146 if (err < 0)
df694daa 7147 return err;
f12ab1e0
TI
7148 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7149 if (err < 0)
4a471b7d 7150 return err;
603c4019 7151 if (!spec->kctls.list)
df694daa 7152 return 0; /* can't find valid BIOS pin config */
b7821709 7153 err = alc_auto_create_input_ctls(codec);
f12ab1e0 7154 if (err < 0)
df694daa
KY
7155 return err;
7156
7157 spec->multiout.max_channels = 2;
7158
0852d7a6 7159 if (spec->autocfg.dig_outs)
df694daa 7160 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7161 if (spec->kctls.list)
d88897ea 7162 add_mixer(spec, spec->kctls.list);
df694daa 7163
a1e8d2da 7164 spec->num_mux_defs = 1;
61b9b9b1 7165 spec->input_mux = &spec->private_imux[0];
df694daa 7166
d6cc9fab
TI
7167 if (!spec->dual_adc_switch)
7168 alc_remove_invalid_adc_nids(codec);
7169
6227cdce 7170 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7171
df694daa
KY
7172 return 1;
7173}
7174
ae6b813a
TI
7175/* additional initialization for auto-configuration model */
7176static void alc260_auto_init(struct hda_codec *codec)
df694daa 7177{
f6c7e546 7178 struct alc_spec *spec = codec->spec;
df694daa 7179 alc260_auto_init_multi_out(codec);
0a7f5320 7180 alc_auto_init_analog_input(codec);
f970de25 7181 alc_auto_init_input_src(codec);
757899ac 7182 alc_auto_init_digital(codec);
f6c7e546 7183 if (spec->unsol_event)
7fb0d78f 7184 alc_inithook(codec);
df694daa
KY
7185}
7186
cb53c626 7187#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7188static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7189 { 0x07, HDA_INPUT, 0 },
7190 { 0x07, HDA_INPUT, 1 },
7191 { 0x07, HDA_INPUT, 2 },
7192 { 0x07, HDA_INPUT, 3 },
7193 { 0x07, HDA_INPUT, 4 },
7194 { } /* end */
7195};
7196#endif
7197
fc091769
TI
7198/*
7199 * Pin config fixes
7200 */
7201enum {
7202 PINFIX_HP_DC5750,
7203};
7204
fc091769
TI
7205static const struct alc_fixup alc260_fixups[] = {
7206 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7207 .type = ALC_FIXUP_PINS,
7208 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7209 { 0x11, 0x90130110 }, /* speaker */
7210 { }
7211 }
fc091769
TI
7212 },
7213};
7214
a9111321 7215static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7216 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7217 {}
7218};
7219
df694daa
KY
7220/*
7221 * ALC260 configurations
7222 */
ea734963 7223static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7224 [ALC260_BASIC] = "basic",
7225 [ALC260_HP] = "hp",
7226 [ALC260_HP_3013] = "hp-3013",
2922c9af 7227 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7228 [ALC260_FUJITSU_S702X] = "fujitsu",
7229 [ALC260_ACER] = "acer",
bc9f98a9
KY
7230 [ALC260_WILL] = "will",
7231 [ALC260_REPLACER_672V] = "replacer",
cc959489 7232 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7233#ifdef CONFIG_SND_DEBUG
f5fcc13c 7234 [ALC260_TEST] = "test",
7cf51e48 7235#endif
f5fcc13c
TI
7236 [ALC260_AUTO] = "auto",
7237};
7238
a9111321 7239static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7240 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7241 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7242 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7243 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7244 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7245 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7246 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7247 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7248 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7249 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7250 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7251 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7252 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7253 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7254 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7255 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7256 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7257 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7258 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7259 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7260 {}
7261};
7262
a9111321 7263static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7264 [ALC260_BASIC] = {
7265 .mixers = { alc260_base_output_mixer,
45bdd1c1 7266 alc260_input_mixer },
df694daa
KY
7267 .init_verbs = { alc260_init_verbs },
7268 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7269 .dac_nids = alc260_dac_nids,
f9e336f6 7270 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7271 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7272 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7273 .channel_mode = alc260_modes,
7274 .input_mux = &alc260_capture_source,
7275 },
7276 [ALC260_HP] = {
bec15c3a 7277 .mixers = { alc260_hp_output_mixer,
f9e336f6 7278 alc260_input_mixer },
bec15c3a
TI
7279 .init_verbs = { alc260_init_verbs,
7280 alc260_hp_unsol_verbs },
df694daa
KY
7281 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7282 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7283 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7284 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7285 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7286 .channel_mode = alc260_modes,
7287 .input_mux = &alc260_capture_source,
e9427969
TI
7288 .unsol_event = alc_sku_unsol_event,
7289 .setup = alc260_hp_setup,
7290 .init_hook = alc_inithook,
df694daa 7291 },
3f878308
KY
7292 [ALC260_HP_DC7600] = {
7293 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7294 alc260_input_mixer },
3f878308
KY
7295 .init_verbs = { alc260_init_verbs,
7296 alc260_hp_dc7600_verbs },
7297 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7298 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7299 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7300 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7301 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7302 .channel_mode = alc260_modes,
7303 .input_mux = &alc260_capture_source,
e9427969
TI
7304 .unsol_event = alc_sku_unsol_event,
7305 .setup = alc260_hp_3012_setup,
7306 .init_hook = alc_inithook,
3f878308 7307 },
df694daa
KY
7308 [ALC260_HP_3013] = {
7309 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7310 alc260_input_mixer },
bec15c3a
TI
7311 .init_verbs = { alc260_hp_3013_init_verbs,
7312 alc260_hp_3013_unsol_verbs },
df694daa
KY
7313 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7314 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7315 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7316 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7317 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7318 .channel_mode = alc260_modes,
7319 .input_mux = &alc260_capture_source,
e9427969
TI
7320 .unsol_event = alc_sku_unsol_event,
7321 .setup = alc260_hp_3013_setup,
7322 .init_hook = alc_inithook,
df694daa
KY
7323 },
7324 [ALC260_FUJITSU_S702X] = {
f9e336f6 7325 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7326 .init_verbs = { alc260_fujitsu_init_verbs },
7327 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7328 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7329 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7330 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7331 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7332 .channel_mode = alc260_modes,
a1e8d2da
JW
7333 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7334 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7335 },
0bfc90e9 7336 [ALC260_ACER] = {
f9e336f6 7337 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7338 .init_verbs = { alc260_acer_init_verbs },
7339 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7340 .dac_nids = alc260_dac_nids,
7341 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7342 .adc_nids = alc260_dual_adc_nids,
7343 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7344 .channel_mode = alc260_modes,
a1e8d2da
JW
7345 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7346 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7347 },
cc959489
MS
7348 [ALC260_FAVORIT100] = {
7349 .mixers = { alc260_favorit100_mixer },
7350 .init_verbs = { alc260_favorit100_init_verbs },
7351 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7352 .dac_nids = alc260_dac_nids,
7353 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7354 .adc_nids = alc260_dual_adc_nids,
7355 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7356 .channel_mode = alc260_modes,
7357 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7358 .input_mux = alc260_favorit100_capture_sources,
7359 },
bc9f98a9 7360 [ALC260_WILL] = {
f9e336f6 7361 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7362 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7363 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7364 .dac_nids = alc260_dac_nids,
7365 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7366 .adc_nids = alc260_adc_nids,
7367 .dig_out_nid = ALC260_DIGOUT_NID,
7368 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7369 .channel_mode = alc260_modes,
7370 .input_mux = &alc260_capture_source,
7371 },
7372 [ALC260_REPLACER_672V] = {
f9e336f6 7373 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7374 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7375 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7376 .dac_nids = alc260_dac_nids,
7377 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7378 .adc_nids = alc260_adc_nids,
7379 .dig_out_nid = ALC260_DIGOUT_NID,
7380 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7381 .channel_mode = alc260_modes,
7382 .input_mux = &alc260_capture_source,
7383 .unsol_event = alc260_replacer_672v_unsol_event,
7384 .init_hook = alc260_replacer_672v_automute,
7385 },
7cf51e48
JW
7386#ifdef CONFIG_SND_DEBUG
7387 [ALC260_TEST] = {
f9e336f6 7388 .mixers = { alc260_test_mixer },
7cf51e48
JW
7389 .init_verbs = { alc260_test_init_verbs },
7390 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7391 .dac_nids = alc260_test_dac_nids,
7392 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7393 .adc_nids = alc260_test_adc_nids,
7394 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7395 .channel_mode = alc260_modes,
a1e8d2da
JW
7396 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7397 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7398 },
7399#endif
df694daa
KY
7400};
7401
7402static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7403{
7404 struct alc_spec *spec;
df694daa 7405 int err, board_config;
1da177e4 7406
e560d8d8 7407 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7408 if (spec == NULL)
7409 return -ENOMEM;
7410
7411 codec->spec = spec;
7412
1f0f4b80
TI
7413 spec->mixer_nid = 0x07;
7414
f5fcc13c
TI
7415 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7416 alc260_models,
7417 alc260_cfg_tbl);
7418 if (board_config < 0) {
9a11f1aa 7419 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7420 codec->chip_name);
df694daa 7421 board_config = ALC260_AUTO;
16ded525 7422 }
1da177e4 7423
b5bfbc67
TI
7424 if (board_config == ALC260_AUTO) {
7425 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7426 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7427 }
fc091769 7428
df694daa
KY
7429 if (board_config == ALC260_AUTO) {
7430 /* automatic parse from the BIOS config */
7431 err = alc260_parse_auto_config(codec);
7432 if (err < 0) {
7433 alc_free(codec);
7434 return err;
f12ab1e0 7435 } else if (!err) {
9c7f852e
TI
7436 printk(KERN_INFO
7437 "hda_codec: Cannot set up configuration "
7438 "from BIOS. Using base mode...\n");
df694daa
KY
7439 board_config = ALC260_BASIC;
7440 }
a9430dd8 7441 }
e9edcee0 7442
680cd536
KK
7443 err = snd_hda_attach_beep_device(codec, 0x1);
7444 if (err < 0) {
7445 alc_free(codec);
7446 return err;
7447 }
7448
df694daa 7449 if (board_config != ALC260_AUTO)
e9c364c0 7450 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7451
1da177e4
LT
7452 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7453 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7454 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7455
a3bcba38
TI
7456 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7457 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7458
4ef0ef19 7459 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab
TI
7460 alc_auto_fill_adc_caps(codec);
7461 alc_remove_invalid_adc_nids(codec);
4ef0ef19 7462 }
b59bdf3b 7463 set_capture_mixer(codec);
45bdd1c1 7464 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7465
b5bfbc67 7466 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7467
2134ea4f
TI
7468 spec->vmaster_nid = 0x08;
7469
1da177e4 7470 codec->patch_ops = alc_patch_ops;
df694daa 7471 if (board_config == ALC260_AUTO)
ae6b813a 7472 spec->init_hook = alc260_auto_init;
1c716153 7473 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7474#ifdef CONFIG_SND_HDA_POWER_SAVE
7475 if (!spec->loopback.amplist)
7476 spec->loopback.amplist = alc260_loopbacks;
7477#endif
1da177e4
LT
7478
7479 return 0;
7480}
7481
e9edcee0 7482
1da177e4 7483/*
4953550a 7484 * ALC882/883/885/888/889 support
1da177e4
LT
7485 *
7486 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7487 * configuration. Each pin widget can choose any input DACs and a mixer.
7488 * Each ADC is connected from a mixer of all inputs. This makes possible
7489 * 6-channel independent captures.
7490 *
7491 * In addition, an independent DAC for the multi-playback (not used in this
7492 * driver yet).
7493 */
df694daa
KY
7494#define ALC882_DIGOUT_NID 0x06
7495#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7496#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7497#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7498#define ALC1200_DIGOUT_NID 0x10
7499
1da177e4 7500
a9111321 7501static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7502 { 8, NULL }
7503};
7504
4953550a 7505/* DACs */
4c6d72d1 7506static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7507 /* front, rear, clfe, rear_surr */
7508 0x02, 0x03, 0x04, 0x05
7509};
4953550a 7510#define alc883_dac_nids alc882_dac_nids
1da177e4 7511
4953550a 7512/* ADCs */
df694daa
KY
7513#define alc882_adc_nids alc880_adc_nids
7514#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7515#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7516static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7517static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7518#define alc889_adc_nids alc880_adc_nids
1da177e4 7519
4c6d72d1
TI
7520static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7521static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7522#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7523static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7524#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7525
1da177e4
LT
7526/* input MUX */
7527/* FIXME: should be a matrix-type input source selection */
7528
a9111321 7529static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7530 .num_items = 4,
7531 .items = {
7532 { "Mic", 0x0 },
7533 { "Front Mic", 0x1 },
7534 { "Line", 0x2 },
7535 { "CD", 0x4 },
7536 },
7537};
41d5545d 7538
4953550a
TI
7539#define alc883_capture_source alc882_capture_source
7540
a9111321 7541static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7542 .num_items = 3,
7543 .items = {
7544 { "Front Mic", 0x0 },
7545 { "Mic", 0x3 },
7546 { "Line", 0x2 },
7547 },
7548};
7549
a9111321 7550static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7551 .num_items = 3,
7552 .items = {
7553 { "Mic", 0x1 },
b8f171e7 7554 { "Line", 0x7 },
41d5545d
KS
7555 { "CD", 0x4 },
7556 },
7557};
7558
a9111321 7559static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7560 .num_items = 2,
7561 .items = {
7562 { "Line", 0x2 },
7563 { "CD", 0x4 },
7564 },
7565};
7566
a9111321 7567static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7568 .num_items = 4,
7569 .items = {
7570 { "Mic", 0x1 },
7571 { "Front Mic", 0x0 },
7572 { "Line", 0x2 },
7573 { "CD", 0x4 },
7574 },
7575};
7576
a9111321 7577static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7578 .num_items = 2,
7579 .items = {
7580 { "Mic", 0x1 },
7581 { "Line", 0x2 },
7582 },
7583};
7584
a9111321 7585static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7586 .num_items = 4,
7587 .items = {
7588 { "Mic", 0x0 },
28c4edb7 7589 { "Internal Mic", 0x1 },
4953550a
TI
7590 { "Line", 0x2 },
7591 { "CD", 0x4 },
7592 },
7593};
7594
a9111321 7595static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7596 .num_items = 2,
7597 .items = {
7598 { "Mic", 0x0 },
28c4edb7 7599 { "Internal Mic", 0x1 },
4953550a
TI
7600 },
7601};
7602
a9111321 7603static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7604 .num_items = 3,
7605 .items = {
7606 { "Mic", 0x0 },
7607 { "Front Mic", 0x1 },
7608 { "Line", 0x4 },
7609 },
7610};
7611
a9111321 7612static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7613 .num_items = 2,
7614 .items = {
7615 { "Mic", 0x0 },
7616 { "Line", 0x2 },
7617 },
7618};
7619
a9111321 7620static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7621 .num_items = 2,
7622 .items = {
7623 { "Mic", 0x0 },
7624 /* Front Mic (0x01) unused */
7625 { "Line", 0x2 },
7626 /* Line 2 (0x03) unused */
af901ca1 7627 /* CD (0x04) unused? */
4953550a
TI
7628 },
7629};
7630
a9111321 7631static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7632 .num_items = 2,
7633 .items = {
7634 { "Mic", 0x01 },
7635 { "Line", 0x2 }, /* Not sure! */
7636 },
7637};
7638
4953550a
TI
7639/*
7640 * 2ch mode
7641 */
a9111321 7642static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7643 { 2, NULL }
7644};
7645
272a527c
KY
7646/*
7647 * 2ch mode
7648 */
a9111321 7649static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7650 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7651 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7652 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7653 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7654 { } /* end */
7655};
7656
4953550a
TI
7657/*
7658 * 4ch mode
7659 */
a9111321 7660static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7661 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7662 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7663 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7664 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7665 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7666 { } /* end */
7667};
7668
272a527c
KY
7669/*
7670 * 6ch mode
7671 */
a9111321 7672static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7673 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7674 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7675 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7676 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7677 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7678 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7679 { } /* end */
7680};
7681
a9111321 7682static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7683 { 2, alc882_3ST_ch2_init },
4953550a 7684 { 4, alc882_3ST_ch4_init },
272a527c
KY
7685 { 6, alc882_3ST_ch6_init },
7686};
7687
4953550a
TI
7688#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7689
a65cc60f 7690/*
7691 * 2ch mode
7692 */
a9111321 7693static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7694 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7695 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7696 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7697 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7698 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7699 { } /* end */
7700};
7701
7702/*
7703 * 4ch mode
7704 */
a9111321 7705static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7706 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7707 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7708 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7709 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7710 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7711 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7712 { } /* end */
7713};
7714
7715/*
7716 * 6ch mode
7717 */
a9111321 7718static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7719 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7720 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7721 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7722 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7723 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7724 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7725 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7726 { } /* end */
7727};
7728
a9111321 7729static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7730 { 2, alc883_3ST_ch2_clevo_init },
7731 { 4, alc883_3ST_ch4_clevo_init },
7732 { 6, alc883_3ST_ch6_clevo_init },
7733};
7734
7735
df694daa
KY
7736/*
7737 * 6ch mode
7738 */
a9111321 7739static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7740 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7741 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7743 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7744 { } /* end */
7745};
7746
7747/*
7748 * 8ch mode
7749 */
a9111321 7750static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7751 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7752 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7753 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7754 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { } /* end */
7756};
7757
a9111321 7758static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7759 { 6, alc882_sixstack_ch6_init },
7760 { 8, alc882_sixstack_ch8_init },
7761};
7762
76e6f5a9
RH
7763
7764/* Macbook Air 2,1 */
7765
a9111321 7766static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7767 { 2, NULL },
7768};
7769
87350ad0 7770/*
def319f9 7771 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7772 */
7773
7774/*
7775 * 2ch mode
7776 */
a9111321 7777static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7778 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7779 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7780 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7781 { } /* end */
7782};
7783
7784/*
a3f730af 7785 * 4ch mode
87350ad0 7786 */
a9111321 7787static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7788 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7790 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7791 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7792 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7793 { } /* end */
7794};
7795
a9111321 7796static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7797 { 2, alc885_mbp_ch2_init },
a3f730af 7798 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7799};
7800
92b9de83
KS
7801/*
7802 * 2ch
7803 * Speakers/Woofer/HP = Front
7804 * LineIn = Input
7805 */
a9111321 7806static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7807 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7808 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7809 { } /* end */
7810};
7811
7812/*
7813 * 6ch mode
7814 * Speakers/HP = Front
7815 * Woofer = LFE
7816 * LineIn = Surround
7817 */
a9111321 7818static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
7819 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7820 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7821 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7822 { } /* end */
7823};
7824
a9111321 7825static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
7826 { 2, alc885_mb5_ch2_init },
7827 { 6, alc885_mb5_ch6_init },
7828};
87350ad0 7829
d01aecdf 7830#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7831
7832/*
7833 * 2ch mode
7834 */
a9111321 7835static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
7836 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7837 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7838 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7839 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7841 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7842 { } /* end */
7843};
7844
7845/*
7846 * 4ch mode
7847 */
a9111321 7848static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
7849 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7850 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7851 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7852 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7853 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7854 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7855 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7856 { } /* end */
7857};
7858
7859/*
7860 * 6ch mode
7861 */
a9111321 7862static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
7863 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7866 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7867 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7868 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7869 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7870 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7871 { } /* end */
7872};
7873
7874/*
7875 * 8ch mode
7876 */
a9111321 7877static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
7878 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7879 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7880 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7881 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7882 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7883 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7886 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7887 { } /* end */
7888};
7889
a9111321 7890static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
7891 { 2, alc883_4ST_ch2_init },
7892 { 4, alc883_4ST_ch4_init },
7893 { 6, alc883_4ST_ch6_init },
7894 { 8, alc883_4ST_ch8_init },
7895};
7896
7897
7898/*
7899 * 2ch mode
7900 */
a9111321 7901static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
7902 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7903 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7904 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7905 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7906 { } /* end */
7907};
7908
7909/*
7910 * 4ch mode
7911 */
a9111321 7912static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
7913 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7914 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7915 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7916 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7917 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7918 { } /* end */
7919};
7920
7921/*
7922 * 6ch mode
7923 */
a9111321 7924static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
7925 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7926 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7927 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7928 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7930 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7931 { } /* end */
7932};
7933
a9111321 7934static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
7935 { 2, alc883_3ST_ch2_intel_init },
7936 { 4, alc883_3ST_ch4_intel_init },
7937 { 6, alc883_3ST_ch6_intel_init },
7938};
7939
dd7714c9
WF
7940/*
7941 * 2ch mode
7942 */
a9111321 7943static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
7944 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7945 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7946 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7947 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7948 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7949 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7950 { } /* end */
7951};
7952
87a8c370
JK
7953/*
7954 * 6ch mode
7955 */
a9111321 7956static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
7957 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7958 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7959 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7960 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7961 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
7962 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7963 { } /* end */
7964};
7965
7966/*
7967 * 8ch mode
7968 */
a9111321 7969static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
7970 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7971 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7972 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7973 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7974 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
7977 { } /* end */
7978};
7979
a9111321 7980static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 7981 { 2, alc889_ch2_intel_init },
87a8c370
JK
7982 { 6, alc889_ch6_intel_init },
7983 { 8, alc889_ch8_intel_init },
7984};
7985
4953550a
TI
7986/*
7987 * 6ch mode
7988 */
a9111321 7989static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
7990 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7991 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7992 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7993 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7994 { } /* end */
7995};
7996
7997/*
7998 * 8ch mode
7999 */
a9111321 8000static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8001 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8002 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8003 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8004 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8005 { } /* end */
8006};
8007
a9111321 8008static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8009 { 6, alc883_sixstack_ch6_init },
8010 { 8, alc883_sixstack_ch8_init },
8011};
8012
8013
1da177e4
LT
8014/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8015 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8016 */
a9111321 8017static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8018 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8019 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8020 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8021 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8022 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8023 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8024 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8025 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8026 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8027 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8028 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8029 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8030 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8031 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8032 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8033 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8034 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8036 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8037 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8038 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8039 { } /* end */
8040};
8041
76e6f5a9
RH
8042/* Macbook Air 2,1 same control for HP and internal Speaker */
8043
a9111321 8044static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8045 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8046 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8047 { }
8048};
8049
8050
a9111321 8051static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8052 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8053 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8055 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8056 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8057 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8058 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8059 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8060 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8061 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8062 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8063 { } /* end */
8064};
41d5545d 8065
a9111321 8066static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8067 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8068 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8070 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8071 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8072 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8073 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8074 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8075 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8076 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8077 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8078 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8079 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8080 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8081 { } /* end */
8082};
92b9de83 8083
a9111321 8084static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8085 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8086 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8087 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8088 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8089 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8090 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8092 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8093 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8094 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8095 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8096 { } /* end */
8097};
8098
a9111321 8099static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8102 { } /* end */
8103};
8104
8105
a9111321 8106static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8107 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8108 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8109 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8110 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8111 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8116 { } /* end */
8117};
8118
a9111321 8119static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8121 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8125 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8126 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8128 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8132 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8133 { } /* end */
8134};
8135
8136/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8137 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8138 */
a9111321 8139static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8140 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8141 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8142 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8143 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8149 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8150 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8152 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8153 { } /* end */
8154};
8155
a9111321 8156static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8158 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8163 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8167 { } /* end */
8168};
8169
a9111321 8170static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8171 {
8172 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8173 .name = "Channel Mode",
8174 .info = alc_ch_mode_info,
8175 .get = alc_ch_mode_get,
8176 .put = alc_ch_mode_put,
8177 },
8178 { } /* end */
8179};
8180
a9111321 8181static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8182 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8184 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8185 /* Rear mixer */
05acb863
TI
8186 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8187 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8188 /* CLFE mixer */
05acb863
TI
8189 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8190 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8191 /* Side mixer */
05acb863
TI
8192 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8193 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8194
e9edcee0 8195 /* Front Pin: output 0 (0x0c) */
05acb863 8196 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8197 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8198 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8199 /* Rear Pin: output 1 (0x0d) */
05acb863 8200 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8201 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8203 /* CLFE Pin: output 2 (0x0e) */
05acb863 8204 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8205 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8206 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8207 /* Side Pin: output 3 (0x0f) */
05acb863 8208 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8209 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8210 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8211 /* Mic (rear) pin: input vref at 80% */
16ded525 8212 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8214 /* Front Mic pin: input vref at 80% */
16ded525 8215 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8217 /* Line In pin: input */
05acb863 8218 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8220 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8221 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8222 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8223 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8224 /* CD pin widget for input */
05acb863 8225 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8226
8227 /* FIXME: use matrix-type input source selection */
8228 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8229 /* Input mixer2 */
05acb863 8230 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8231 /* Input mixer3 */
05acb863 8232 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8233 /* ADC2: mute amp left and right */
8234 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8235 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8236 /* ADC3: mute amp left and right */
8237 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8238 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8239
8240 { }
8241};
8242
a9111321 8243static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8244 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8245 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8247 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8248 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8249 /* ADC1: mute amp left and right */
8250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8251 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8252 { }
8253};
8254
a9111321 8255static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8256 /* change to EAPD mode */
8257 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8258 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8259 { }
4b146cb0
TI
8260};
8261
a9111321 8262static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8263 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8264 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8265 { }
8266};
8267
a9111321 8268static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8269 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8271 {}
8272};
87a8c370 8273
a9111321 8274static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8275 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8276 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8277 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8278 /* Rear mixer */
88102f3f
KY
8279 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8280 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8281 /* CLFE mixer */
88102f3f
KY
8282 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8283 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8284 /* Side mixer */
88102f3f
KY
8285 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8286 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8287
8288 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8289 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8291 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8292 /* Front Pin: output 0 (0x0c) */
8293 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8294 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8295 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8296 /* Rear Pin: output 1 (0x0d) */
8297 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8298 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8299 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8300 /* CLFE Pin: output 2 (0x0e) */
8301 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8302 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8303 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8304 /* Side Pin: output 3 (0x0f) */
8305 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8306 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8307 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8308 /* Mic (rear) pin: input vref at 80% */
8309 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8310 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8311 /* Front Mic pin: input vref at 80% */
8312 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8313 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8314 /* Line In pin: input */
8315 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8316 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8317
8318 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8319 /* Input mixer1 */
88102f3f 8320 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8321 /* Input mixer2 */
8322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8323 /* Input mixer3 */
88102f3f 8324 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8325 /* ADC2: mute amp left and right */
8326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8327 /* ADC3: mute amp left and right */
8328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8329
8330 { }
8331};
8332
a9111321 8333static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8334 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8335 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8336 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8337 { }
8338};
8339
8340
8341/* Unmute Selector 24h and set the default input to front mic */
a9111321 8342static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8343 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8344 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8345 { }
8346};
8347
8348
4953550a
TI
8349#define alc883_init_verbs alc882_base_init_verbs
8350
9102cd1c 8351/* Mac Pro test */
a9111321 8352static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8353 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8354 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8356 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8357 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8358 /* FIXME: this looks suspicious...
d355c82a
JK
8359 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8360 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8361 */
9102cd1c
TD
8362 { } /* end */
8363};
8364
a9111321 8365static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8366 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8367 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370 /* Front Pin: output 0 (0x0c) */
8371 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8372 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8374 /* Front Mic pin: input vref at 80% */
8375 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8376 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8377 /* Speaker: output */
8378 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8379 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8381 /* Headphone output (output 0 - 0x0c) */
8382 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8383 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8384 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8385
8386 /* FIXME: use matrix-type input source selection */
8387 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8388 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8389 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8390 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8391 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8393 /* Input mixer2 */
8394 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8395 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8396 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8397 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8398 /* Input mixer3 */
8399 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8402 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8403 /* ADC1: mute amp left and right */
8404 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8405 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8406 /* ADC2: mute amp left and right */
8407 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8408 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* ADC3: mute amp left and right */
8410 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8411 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8412
8413 { }
8414};
f12ab1e0 8415
41d5545d 8416/* Macbook 5,1 */
a9111321 8417static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8418 /* DACs */
8419 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8420 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8421 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8422 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8423 /* Front mixer */
41d5545d
KS
8424 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8425 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8426 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8427 /* Surround mixer */
8428 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8429 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8431 /* LFE mixer */
8432 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8433 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8434 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8435 /* HP mixer */
8436 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8437 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8439 /* Front Pin (0x0c) */
41d5545d
KS
8440 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8441 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8442 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8443 /* LFE Pin (0x0e) */
8444 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8445 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8446 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8447 /* HP Pin (0x0f) */
41d5545d
KS
8448 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8449 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8450 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8451 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8452 /* Front Mic pin: input vref at 80% */
8453 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8454 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8455 /* Line In pin */
8456 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8457 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8458
b8f171e7
AM
8459 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8462 { }
8463};
8464
e458b1fa 8465/* Macmini 3,1 */
a9111321 8466static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8467 /* DACs */
8468 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8469 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8470 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8471 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8472 /* Front mixer */
8473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8476 /* Surround mixer */
8477 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8480 /* LFE mixer */
8481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8483 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8484 /* HP mixer */
8485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8486 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8487 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8488 /* Front Pin (0x0c) */
8489 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8490 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8491 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8492 /* LFE Pin (0x0e) */
8493 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8494 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8495 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8496 /* HP Pin (0x0f) */
8497 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8498 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8499 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8500 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8501 /* Line In pin */
8502 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504
8505 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8509 { }
8510};
8511
76e6f5a9 8512
a9111321 8513static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8514 /*Internal and HP Speaker Mixer*/
8515 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8518 /*Internal Speaker Pin (0x0c)*/
8519 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8520 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8521 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8522 /* HP Pin: output 0 (0x0e) */
8523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8524 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8525 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8526 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8527 /* Line in (is hp when jack connected)*/
8528 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8529 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8530
8531 { }
8532 };
8533
8534
87350ad0 8535/* Macbook Pro rev3 */
a9111321 8536static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8537 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8540 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8541 /* Rear mixer */
8542 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8543 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8544 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8545 /* HP mixer */
8546 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8547 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8548 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8549 /* Front Pin: output 0 (0x0c) */
8550 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8551 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8552 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8553 /* HP Pin: output 0 (0x0e) */
87350ad0 8554 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8555 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8557 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8558 /* Mic (rear) pin: input vref at 80% */
8559 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8560 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8561 /* Front Mic pin: input vref at 80% */
8562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8564 /* Line In pin: use output 1 when in LineOut mode */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8568
8569 /* FIXME: use matrix-type input source selection */
8570 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8571 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8572 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8573 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8575 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8576 /* Input mixer2 */
8577 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8578 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8579 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8580 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8581 /* Input mixer3 */
8582 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8583 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8584 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8585 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8586 /* ADC1: mute amp left and right */
8587 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8588 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8589 /* ADC2: mute amp left and right */
8590 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8591 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8592 /* ADC3: mute amp left and right */
8593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8594 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8595
8596 { }
8597};
8598
4b7e1803 8599/* iMac 9,1 */
a9111321 8600static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8601 /* Internal Speaker Pin (0x0c) */
8602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8603 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8604 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8605 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8606 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8608 /* HP Pin: Rear */
4b7e1803
JM
8609 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8610 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8611 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8612 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8613 /* Line in Rear */
8614 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8615 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8616 /* Front Mic pin: input vref at 80% */
8617 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8618 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8619 /* Rear mixer */
8620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8621 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8622 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8623 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8624 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8627 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8628 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8631 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8632 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8633 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8634 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8635 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8636 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8637 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8638 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8639 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8640 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8641 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8642 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8644 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8645 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8646 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8647 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8648 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8649 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8650 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8651 { }
8652};
8653
c54728d8 8654/* iMac 24 mixer. */
a9111321 8655static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8656 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8657 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8658 { } /* end */
8659};
8660
8661/* iMac 24 init verbs. */
a9111321 8662static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8663 /* Internal speakers: output 0 (0x0c) */
8664 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8665 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8666 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8667 /* Internal speakers: output 0 (0x0c) */
8668 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8669 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8670 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8671 /* Headphone: output 0 (0x0c) */
8672 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8673 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8674 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8675 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8676 /* Front Mic: input vref at 80% */
8677 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8678 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8679 { }
8680};
8681
8682/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8683static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8684{
a9fd4f3f 8685 struct alc_spec *spec = codec->spec;
c54728d8 8686
a9fd4f3f
TI
8687 spec->autocfg.hp_pins[0] = 0x14;
8688 spec->autocfg.speaker_pins[0] = 0x18;
8689 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8690 spec->automute = 1;
8691 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8692}
8693
9d54f08b
TI
8694#define alc885_mb5_setup alc885_imac24_setup
8695#define alc885_macmini3_setup alc885_imac24_setup
8696
76e6f5a9
RH
8697/* Macbook Air 2,1 */
8698static void alc885_mba21_setup(struct hda_codec *codec)
8699{
8700 struct alc_spec *spec = codec->spec;
8701
8702 spec->autocfg.hp_pins[0] = 0x14;
8703 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8704 spec->automute = 1;
8705 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8706}
8707
8708
8709
4f5d1706 8710static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8711{
a9fd4f3f 8712 struct alc_spec *spec = codec->spec;
87350ad0 8713
a9fd4f3f
TI
8714 spec->autocfg.hp_pins[0] = 0x15;
8715 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8716 spec->automute = 1;
8717 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8718}
8719
9d54f08b 8720static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8721{
9d54f08b 8722 struct alc_spec *spec = codec->spec;
4b7e1803 8723
9d54f08b 8724 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8725 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8726 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8727 spec->automute = 1;
8728 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8729}
87350ad0 8730
a9111321 8731static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8732 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8734
8735 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8736 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8737
272a527c
KY
8738 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8739 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8740 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8741
8742 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8743 { } /* end */
8744};
8745
8746/* toggle speaker-output according to the hp-jack state */
8747static void alc882_targa_automute(struct hda_codec *codec)
8748{
a9fd4f3f 8749 struct alc_spec *spec = codec->spec;
d922b51d 8750 alc_hp_automute(codec);
82beb8fd 8751 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8752 spec->jack_present ? 1 : 3);
8753}
8754
4f5d1706 8755static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8756{
8757 struct alc_spec *spec = codec->spec;
8758
8759 spec->autocfg.hp_pins[0] = 0x14;
8760 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8761 spec->automute = 1;
8762 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8763}
8764
8765static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8766{
a9fd4f3f 8767 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8768 alc882_targa_automute(codec);
272a527c
KY
8769}
8770
a9111321 8771static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8772 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8773 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8774
8775 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8776 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8777 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8778
272a527c
KY
8779 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8780 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8781 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8782
8783 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8784 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8785 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8786 { } /* end */
8787};
8788
a9111321 8789static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8790 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8791 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8792
8793 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8794 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8795 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8796
914759b7
TI
8797 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8798 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8799 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8800
8801 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8802 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8803 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8804 { } /* end */
8805};
8806
9102cd1c
TD
8807static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8808{
8809 unsigned int gpiostate, gpiomask, gpiodir;
8810
8811 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8812 AC_VERB_GET_GPIO_DATA, 0);
8813
8814 if (!muted)
8815 gpiostate |= (1 << pin);
8816 else
8817 gpiostate &= ~(1 << pin);
8818
8819 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8820 AC_VERB_GET_GPIO_MASK, 0);
8821 gpiomask |= (1 << pin);
8822
8823 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8824 AC_VERB_GET_GPIO_DIRECTION, 0);
8825 gpiodir |= (1 << pin);
8826
8827
8828 snd_hda_codec_write(codec, codec->afg, 0,
8829 AC_VERB_SET_GPIO_MASK, gpiomask);
8830 snd_hda_codec_write(codec, codec->afg, 0,
8831 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8832
8833 msleep(1);
8834
8835 snd_hda_codec_write(codec, codec->afg, 0,
8836 AC_VERB_SET_GPIO_DATA, gpiostate);
8837}
8838
7debbe51
TI
8839/* set up GPIO at initialization */
8840static void alc885_macpro_init_hook(struct hda_codec *codec)
8841{
8842 alc882_gpio_mute(codec, 0, 0);
8843 alc882_gpio_mute(codec, 1, 0);
8844}
8845
8846/* set up GPIO and update auto-muting at initialization */
8847static void alc885_imac24_init_hook(struct hda_codec *codec)
8848{
8849 alc885_macpro_init_hook(codec);
d922b51d 8850 alc_hp_automute(codec);
7debbe51
TI
8851}
8852
eb4c41d3 8853/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 8854static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
8855 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8856 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8857 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8858 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8859 { } /* end */
8860};
8861
8862/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 8863static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
8864 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8865 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8866 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8867 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8868 { } /* end */
8869};
8870
8871/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 8872static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
8873 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8874 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8875 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8876 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8877 { } /* end */
8878};
8879
8880/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 8881static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
8882 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8883 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8884 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8885 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8886 { } /* end */
8887};
8888
a9111321 8889static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
8890 { 2, alc889A_mb31_ch2_init },
8891 { 4, alc889A_mb31_ch4_init },
8892 { 5, alc889A_mb31_ch5_init },
8893 { 6, alc889A_mb31_ch6_init },
8894};
8895
a9111321 8896static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
8897 /* eanable EAPD on medion laptop */
8898 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8899 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8900 { }
8901};
8902
4953550a 8903#define alc883_base_mixer alc882_base_mixer
834be88d 8904
a9111321 8905static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
8906 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8907 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8908 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8909 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8910 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8911 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8912 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8913 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8914 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
8915 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8916 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8917 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 8918 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
8919 { } /* end */
8920};
8921
a9111321 8922static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
8923 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8924 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8925 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8926 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8928 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 8929 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8930 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8931 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8932 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
8933 { } /* end */
8934};
8935
a9111321 8936static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
8937 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8938 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8939 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8940 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8942 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 8943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 8944 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8945 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 8946 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
8947 { } /* end */
8948};
8949
a9111321 8950static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
8951 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8952 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8953 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8954 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8955 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8956 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8957 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8958 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8959 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8960 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8961 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8962 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8963 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8964 { } /* end */
8965};
df694daa 8966
a9111321 8967static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
8968 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8970 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8971 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8972 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8973 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8974 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8975 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8976 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8977 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8978 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8980 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8981 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8982 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
8983 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8984 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8985 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 8986 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
8987 { } /* end */
8988};
8989
a9111321 8990static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
8991 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8992 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8994 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8995 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
8996 HDA_OUTPUT),
8997 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8998 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8999 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9001 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9002 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9003 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9004 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9006 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9008 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9009 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9010 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9011 { } /* end */
9012};
9013
a9111321 9014static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9015 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9016 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9018 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9019 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9020 HDA_OUTPUT),
9021 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9022 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9023 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9024 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9025 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9026 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9027 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9028 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9029 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9030 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9031 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9032 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9033 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9034 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9035 { } /* end */
9036};
9037
a9111321 9038static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9039 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9040 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9041 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9042 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9043 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9044 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9045 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9046 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9047 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9048 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9049 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9050 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9051 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9053 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9054 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9055 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9056 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9057 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9058 { } /* end */
9059};
9060
a9111321 9061static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9062 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9063 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9064 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9065 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9066 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9067 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9068 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9069 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9070 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9071 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9072 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9073 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9074 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9075 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9076 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9077 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9078 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9079 { } /* end */
f12ab1e0 9080};
ccc656ce 9081
a9111321 9082static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9083 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9084 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9085 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9086 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9090 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9091 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9092 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9093 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9094 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9095 { } /* end */
f12ab1e0 9096};
ccc656ce 9097
a9111321 9098static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9099 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9100 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9102 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9103 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9104 { } /* end */
9105};
9106
a9111321 9107static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9109 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9110 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9114 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9116 { } /* end */
f12ab1e0 9117};
bc9f98a9 9118
a9111321 9119static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9120 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9122 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9123 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9124 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9128 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9129 { } /* end */
ea1fb29a 9130};
272a527c 9131
a9111321 9132static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9133 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9134 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9135 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9138 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9139 { } /* end */
9140};
9141
a9111321 9142static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9143 /* Unmute front mixer */
9144 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9145 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9146
9147 /* Set speaker pin to front mixer */
9148 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9149
9150 /* Init headphone pin */
9151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9152 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9153 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9154 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9155
9156 { } /* end */
9157};
9158
9159/* toggle speaker-output according to the hp-jack state */
9160static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9161{
9162 struct alc_spec *spec = codec->spec;
9163
9164 spec->autocfg.hp_pins[0] = 0x1a;
9165 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9166 spec->automute = 1;
9167 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9168}
9169
a9111321 9170static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9172 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9173 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9174 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9175 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9176 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9177 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9178 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9179 { } /* end */
d1a991a6 9180};
2880a867 9181
a9111321 9182static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9183 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9184 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9187 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9188 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9190 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9192 { } /* end */
9193};
9194
a9111321 9195static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
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", 0x0e, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9201 0x0d, 1, 0x0, HDA_OUTPUT),
9202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9204 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9205 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9206 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9207 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9208 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9214 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9215 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9216 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9217 { } /* end */
9218};
9219
a9111321 9220static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9221 /* Output mixers */
9222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9223 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9225 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9227 HDA_OUTPUT),
9228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9229 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9230 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9231 /* Output switches */
9232 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9233 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9234 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9235 /* Boost mixers */
5f99f86a
DH
9236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9238 /* Input mixers */
9239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9240 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9241 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9242 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9243 { } /* end */
9244};
9245
a9111321 9246static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9247 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9248 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9249 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9250 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9251 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9252 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9253 { } /* end */
9254};
9255
a9111321 9256static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9257 .ops = &snd_hda_bind_vol,
9258 .values = {
9259 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9260 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9261 0
9262 },
9263};
9264
a9111321 9265static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9266 .ops = &snd_hda_bind_sw,
9267 .values = {
9268 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9269 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9270 0
9271 },
9272};
9273
a9111321 9274static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9275 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9276 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9277 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
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),
4953550a
TI
9282 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9283 { } /* end */
9284};
df694daa 9285
a9111321 9286static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9287 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9288 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9289 {
9290 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9291 /* .name = "Capture Source", */
9292 .name = "Input Source",
9293 .count = 1,
9294 .info = alc_mux_enum_info,
9295 .get = alc_mux_enum_get,
9296 .put = alc_mux_enum_put,
9297 },
9298 { } /* end */
9299};
9c7f852e 9300
a9111321 9301static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9302 {
9303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9304 .name = "Channel Mode",
9305 .info = alc_ch_mode_info,
9306 .get = alc_ch_mode_get,
9307 .put = alc_ch_mode_put,
9308 },
9309 { } /* end */
9c7f852e
TI
9310};
9311
a8848bd6 9312/* toggle speaker-output according to the hp-jack state */
4f5d1706 9313static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9314{
a9fd4f3f 9315 struct alc_spec *spec = codec->spec;
a8848bd6 9316
a9fd4f3f
TI
9317 spec->autocfg.hp_pins[0] = 0x15;
9318 spec->autocfg.speaker_pins[0] = 0x14;
9319 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9320 spec->automute = 1;
9321 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9322}
9323
a9111321 9324static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9325 /* HP */
9326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9328 /* Subwoofer */
9329 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9330 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9331
9332 /* enable unsolicited event */
9333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9334 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9335
9336 { } /* end */
9337};
9338
a9111321 9339static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9340 /* HP */
9341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9343 /* Int speaker */
9344 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9345
9346 /* enable unsolicited event */
9347 /*
9348 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9349 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9350 */
9351
9352 { } /* end */
9353};
9354
a9111321 9355static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9356 /* HP */
9357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9359 /* Int speaker */
9360 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9362
9363 /* enable unsolicited event */
9364 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9365 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9366
9367 { } /* end */
9368};
9369
a9111321 9370static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9371 /* HP */
9372 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9373 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9374 /* Subwoofer */
9375 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9376 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9377
9378 /* enable unsolicited event */
9379 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9380
9381 { } /* end */
9382};
9383
a9111321 9384static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9385 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9387
9388 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9389 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9390
64a8be74
DH
9391/* Connect Line-Out side jack (SPDIF) to Side */
9392 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9393 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9394 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9395/* Connect Mic jack to CLFE */
9396 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9398 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9399/* Connect Line-in jack to Surround */
9400 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9401 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9402 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9403/* Connect HP out jack to Front */
9404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9407
9408 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9409
9410 { } /* end */
9411};
9412
a9111321 9413static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9414 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9415 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9416 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9417 { } /* end */
9418};
9419
a9111321 9420static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9421 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9422 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9423 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9424 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9425 { } /* end */
9426};
9427
a9111321 9428static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9430 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9431 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9432 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9433 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9434 { } /* end */
9435};
9436
a9111321 9437static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9438 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9440
9441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9442
9443 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9444 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9445 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9446 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9447 { } /* end */
9448};
9449
a9111321 9450static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9451 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9452 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9453 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9454 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9455 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9457 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9458 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9459 { } /* end */
9460};
9461
a9111321 9462static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9463 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9464 { }
9465};
9466
a9111321 9467static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9468 /* HP */
9469 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9471
9472 /* enable unsolicited event */
9473 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9474
9475 { } /* end */
9476};
9477
4f5d1706 9478static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9479{
a9fd4f3f 9480 struct alc_spec *spec = codec->spec;
8718b700 9481
a9fd4f3f
TI
9482 spec->autocfg.hp_pins[0] = 0x1b;
9483 spec->autocfg.speaker_pins[0] = 0x14;
9484 spec->autocfg.speaker_pins[1] = 0x16;
9485 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9486 spec->automute = 1;
9487 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9488}
9489
a9111321 9490static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9491 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9492 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9493 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9494 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9495 { } /* end */
5795b9e6
CM
9496};
9497
3ea0d7cf
HRK
9498/*
9499 * 2ch mode
9500 */
a9111321 9501static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9502 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9503 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9504 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9505 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9506 { } /* end */
8341de60
CM
9507};
9508
3ea0d7cf
HRK
9509/*
9510 * 4ch mode
9511 */
a9111321 9512static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9513 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9514 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9515 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9516 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9517 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9518 { } /* end */
9519};
9520
9521/*
9522 * 6ch mode
9523 */
a9111321 9524static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9525 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9526 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9527 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9528 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9529 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9530 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9531 { } /* end */
8341de60
CM
9532};
9533
a9111321 9534static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9535 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9536 { 4, alc888_3st_hp_4ch_init },
4723c022 9537 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9538};
9539
e6a5e1b7 9540static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9541{
e6a5e1b7 9542 struct alc_spec *spec = codec->spec;
47fd830a 9543
e6a5e1b7
TI
9544 spec->autocfg.hp_pins[0] = 0x1b;
9545 spec->autocfg.line_out_pins[0] = 0x14;
9546 spec->autocfg.speaker_pins[0] = 0x15;
9547 spec->automute = 1;
9548 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9549}
9550
272a527c 9551/* toggle speaker-output according to the hp-jack state */
dc427170 9552static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9553{
a9fd4f3f 9554 struct alc_spec *spec = codec->spec;
272a527c 9555
a9fd4f3f
TI
9556 spec->autocfg.hp_pins[0] = 0x14;
9557 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9558 spec->automute = 1;
9559 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9560}
9561
ccc656ce 9562/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9563#define alc883_targa_init_hook alc882_targa_init_hook
9564#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9565
4f5d1706 9566static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9567{
a9fd4f3f
TI
9568 struct alc_spec *spec = codec->spec;
9569
9570 spec->autocfg.hp_pins[0] = 0x15;
9571 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9572 spec->automute = 1;
9573 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9574}
9575
9576static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9577{
d922b51d 9578 alc_hp_automute(codec);
eeb43387 9579 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9580}
9581
9582static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9583 unsigned int res)
9584{
0c4cc443 9585 switch (res >> 26) {
0c4cc443 9586 case ALC880_MIC_EVENT:
eeb43387 9587 alc88x_simple_mic_automute(codec);
0c4cc443 9588 break;
a9fd4f3f 9589 default:
d922b51d 9590 alc_sku_unsol_event(codec, res);
a9fd4f3f 9591 break;
0c4cc443 9592 }
368c7a95
J
9593}
9594
fb97dc67 9595/* toggle speaker-output according to the hp-jack state */
4f5d1706 9596static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9597{
a9fd4f3f 9598 struct alc_spec *spec = codec->spec;
fb97dc67 9599
a9fd4f3f
TI
9600 spec->autocfg.hp_pins[0] = 0x14;
9601 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9602 spec->automute = 1;
9603 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9604}
9605
4f5d1706 9606static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9607{
a9fd4f3f 9608 struct alc_spec *spec = codec->spec;
189609ae 9609
a9fd4f3f
TI
9610 spec->autocfg.hp_pins[0] = 0x1b;
9611 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9612 spec->automute = 1;
9613 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9614}
9615
e6a5e1b7 9616static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9617{
e6a5e1b7 9618 struct alc_spec *spec = codec->spec;
bc9f98a9 9619
e6a5e1b7
TI
9620 spec->autocfg.hp_pins[0] = 0x1b;
9621 spec->autocfg.line_out_pins[0] = 0x14;
9622 spec->autocfg.speaker_pins[0] = 0x15;
9623 spec->automute = 1;
9624 spec->detect_line = 1;
9625 spec->automute_lines = 1;
9626 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9627}
9628
676a9b53 9629/* toggle speaker-output according to the hp-jack state */
4f5d1706 9630static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9631{
a9fd4f3f 9632 struct alc_spec *spec = codec->spec;
676a9b53 9633
a9fd4f3f
TI
9634 spec->autocfg.hp_pins[0] = 0x14;
9635 spec->autocfg.speaker_pins[0] = 0x15;
9636 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9637 spec->automute = 1;
9638 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9639}
9640
a9111321 9641static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9642 /* HP Pin: output 0 (0x0c) */
9643 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9644 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9645 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9646 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9647 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9648 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9649 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9650 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9651 /* eanable EAPD on medion laptop */
9652 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9653 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9654 /* enable unsolicited event */
9655 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9656 { }
9657};
9658
4f5d1706 9659static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9660{
a9fd4f3f 9661 struct alc_spec *spec = codec->spec;
5795b9e6 9662
a9fd4f3f
TI
9663 spec->autocfg.hp_pins[0] = 0x1b;
9664 spec->autocfg.speaker_pins[0] = 0x14;
9665 spec->autocfg.speaker_pins[1] = 0x15;
9666 spec->autocfg.speaker_pins[2] = 0x16;
9667 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9668 spec->automute = 1;
9669 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9670}
9671
4f5d1706 9672static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9673{
a9fd4f3f 9674 struct alc_spec *spec = codec->spec;
e2757d5e 9675
a9fd4f3f
TI
9676 spec->autocfg.hp_pins[0] = 0x1b;
9677 spec->autocfg.speaker_pins[0] = 0x14;
9678 spec->autocfg.speaker_pins[1] = 0x15;
9679 spec->autocfg.speaker_pins[2] = 0x16;
9680 spec->autocfg.speaker_pins[3] = 0x17;
9681 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9682 spec->automute = 1;
9683 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9684}
9685
4f5d1706 9686static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9687{
9688 struct alc_spec *spec = codec->spec;
9689
9690 spec->autocfg.hp_pins[0] = 0x15;
9691 spec->autocfg.speaker_pins[0] = 0x14;
9692 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9693 spec->automute = 1;
9694 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9695}
9696
a9111321 9697static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9698 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9699 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9700 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9701 /* enable unsolicited event */
9702 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9703 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9704 { } /* end */
9705};
9706
4f5d1706 9707static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9708{
a9fd4f3f 9709 struct alc_spec *spec = codec->spec;
e2757d5e 9710
a9fd4f3f
TI
9711 spec->autocfg.hp_pins[0] = 0x1b;
9712 spec->autocfg.speaker_pins[0] = 0x14;
9713 spec->autocfg.speaker_pins[1] = 0x15;
9714 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9715 spec->ext_mic.pin = 0x18;
9716 spec->int_mic.pin = 0x19;
9717 spec->ext_mic.mux_idx = 0;
9718 spec->int_mic.mux_idx = 1;
9719 spec->auto_mic = 1;
d922b51d
TI
9720 spec->automute = 1;
9721 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9722}
9723
a9111321 9724static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9725 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9726 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9727 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9728 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9729 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9730 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9731 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9732 /* enable unsolicited event */
9733 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9734 { } /* end */
9735};
9736
e2757d5e
KY
9737static void alc883_eee1601_inithook(struct hda_codec *codec)
9738{
a9fd4f3f
TI
9739 struct alc_spec *spec = codec->spec;
9740
9741 spec->autocfg.hp_pins[0] = 0x14;
9742 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9743 alc_hp_automute(codec);
e2757d5e
KY
9744}
9745
a9111321 9746static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9747 /* Init rear pin (used as headphone output) */
9748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9749 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9750 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9751 /* Init line pin (used as output in 4ch and 6ch mode) */
9752 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9753 /* Init line 2 pin (used as headphone out by default) */
9754 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9755 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9756 { } /* end */
9757};
9758
9759/* Mute speakers according to the headphone jack state */
9760static void alc889A_mb31_automute(struct hda_codec *codec)
9761{
9762 unsigned int present;
9763
9764 /* Mute only in 2ch or 4ch mode */
9765 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9766 == 0x00) {
864f92be 9767 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9768 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9769 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9770 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9771 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9772 }
9773}
9774
9775static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9776{
9777 if ((res >> 26) == ALC880_HP_EVENT)
9778 alc889A_mb31_automute(codec);
9779}
9780
4953550a 9781
cb53c626 9782#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9783#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9784#endif
9785
def319f9 9786/* pcm configuration: identical with ALC880 */
4953550a
TI
9787#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9788#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9789#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9790#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9791
4c6d72d1 9792static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9793 ALC1200_DIGOUT_NID, 0,
9794};
9795
4c6d72d1 9796static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9797 ALC883_DIGOUT_NID, 0,
9798};
9c7f852e
TI
9799
9800/*
9801 * configuration and preset
9802 */
ea734963 9803static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9804 [ALC882_3ST_DIG] = "3stack-dig",
9805 [ALC882_6ST_DIG] = "6stack-dig",
9806 [ALC882_ARIMA] = "arima",
9807 [ALC882_W2JC] = "w2jc",
9808 [ALC882_TARGA] = "targa",
9809 [ALC882_ASUS_A7J] = "asus-a7j",
9810 [ALC882_ASUS_A7M] = "asus-a7m",
9811 [ALC885_MACPRO] = "macpro",
9812 [ALC885_MB5] = "mb5",
e458b1fa 9813 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9814 [ALC885_MBA21] = "mba21",
4953550a
TI
9815 [ALC885_MBP3] = "mbp3",
9816 [ALC885_IMAC24] = "imac24",
4b7e1803 9817 [ALC885_IMAC91] = "imac91",
4953550a 9818 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
9819 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9820 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 9821 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
9822 [ALC883_TARGA_DIG] = "targa-dig",
9823 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 9824 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 9825 [ALC883_ACER] = "acer",
2880a867 9826 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 9827 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 9828 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 9829 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 9830 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 9831 [ALC883_MEDION] = "medion",
7ad7b218 9832 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 9833 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 9834 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
9835 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9836 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 9837 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 9838 [ALC883_HAIER_W66] = "haier-w66",
4723c022 9839 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 9840 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 9841 [ALC883_MITAC] = "mitac",
a65cc60f 9842 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 9843 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 9844 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 9845 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 9846 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
9847 [ALC889A_INTEL] = "intel-alc889a",
9848 [ALC889_INTEL] = "intel-x58",
3ab90935 9849 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 9850 [ALC889A_MB31] = "mb31",
3e1647c5 9851 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 9852 [ALC882_AUTO] = "auto",
f5fcc13c
TI
9853};
9854
a9111321 9855static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
9856 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9857
ac3e3741 9858 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 9859 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 9860 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
9861 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9862 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 9863 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
9864 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9865 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 9866 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 9867 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
9868 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9869 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
9870 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9871 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
9872 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9873 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 9874 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 9875 ALC888_ACER_ASPIRE_6530G),
cc374c47 9876 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 9877 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
9878 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9879 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
9880 /* default Acer -- disabled as it causes more problems.
9881 * model=auto should work fine now
9882 */
9883 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 9884
5795b9e6 9885 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 9886
25985edc 9887 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
9888 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9889 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 9890 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 9891 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 9892 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
9893
9894 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9895 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9896 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 9897 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
9898 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9899 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9900 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 9901 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 9902 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 9903 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 9904 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
9905
9906 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 9907 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 9908 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 9909 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
9910 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9911 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 9912 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 9913 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 9914 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 9915
6f3bf657 9916 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 9917 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9918 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9919 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 9920 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 9921 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 9922 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 9923 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 9924 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 9925 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9926 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9927 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 9928 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 9929 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 9930 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
9931 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9932 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9933 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 9934 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 9935 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
9936 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9937 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9938 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 9939 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 9940 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
9941 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9942 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 9943 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 9944 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 9945 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 9946 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 9947
ac3e3741 9948 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 9949 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
9950 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9951 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 9952 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 9953 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 9954 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 9955 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 9956 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 9957 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 9958 ALC883_FUJITSU_PI2515),
bfb53037 9959 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 9960 ALC888_FUJITSU_XA3530),
272a527c 9961 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 9962 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
9963 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9964 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 9965 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 9966 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 9967 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 9968 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 9969
17bba1b7
J
9970 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9971 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 9972 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
9973 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
9974 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
9975 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 9976 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 9977
4953550a 9978 {}
f3cd3f5d
WF
9979};
9980
4953550a 9981/* codec SSID table for Intel Mac */
a9111321 9982static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
9983 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
9984 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
9985 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
9986 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
9987 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
9988 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
9989 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 9990 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 9991 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 9992 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 9993 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
9994 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
9995 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
9996 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 9997 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 9998 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 9999 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10000 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10001 * so apparently no perfect solution yet
4953550a
TI
10002 */
10003 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10004 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10005 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10006 {} /* terminator */
b25c9da1
WF
10007};
10008
a9111321 10009static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10010 [ALC882_3ST_DIG] = {
10011 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10012 .init_verbs = { alc882_base_init_verbs,
10013 alc882_adc1_init_verbs },
4953550a
TI
10014 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10015 .dac_nids = alc882_dac_nids,
10016 .dig_out_nid = ALC882_DIGOUT_NID,
10017 .dig_in_nid = ALC882_DIGIN_NID,
10018 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10019 .channel_mode = alc882_ch_modes,
10020 .need_dac_fix = 1,
10021 .input_mux = &alc882_capture_source,
10022 },
10023 [ALC882_6ST_DIG] = {
10024 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10025 .init_verbs = { alc882_base_init_verbs,
10026 alc882_adc1_init_verbs },
4953550a
TI
10027 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10028 .dac_nids = alc882_dac_nids,
10029 .dig_out_nid = ALC882_DIGOUT_NID,
10030 .dig_in_nid = ALC882_DIGIN_NID,
10031 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10032 .channel_mode = alc882_sixstack_modes,
10033 .input_mux = &alc882_capture_source,
10034 },
10035 [ALC882_ARIMA] = {
10036 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10037 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10038 alc882_eapd_verbs },
4953550a
TI
10039 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10040 .dac_nids = alc882_dac_nids,
10041 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10042 .channel_mode = alc882_sixstack_modes,
10043 .input_mux = &alc882_capture_source,
10044 },
10045 [ALC882_W2JC] = {
10046 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10047 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10048 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10049 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10050 .dac_nids = alc882_dac_nids,
10051 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10052 .channel_mode = alc880_threestack_modes,
10053 .need_dac_fix = 1,
10054 .input_mux = &alc882_capture_source,
10055 .dig_out_nid = ALC882_DIGOUT_NID,
10056 },
76e6f5a9
RH
10057 [ALC885_MBA21] = {
10058 .mixers = { alc885_mba21_mixer },
10059 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10060 .num_dacs = 2,
10061 .dac_nids = alc882_dac_nids,
10062 .channel_mode = alc885_mba21_ch_modes,
10063 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10064 .input_mux = &alc882_capture_source,
d922b51d 10065 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10066 .setup = alc885_mba21_setup,
d922b51d 10067 .init_hook = alc_hp_automute,
76e6f5a9 10068 },
4953550a
TI
10069 [ALC885_MBP3] = {
10070 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10071 .init_verbs = { alc885_mbp3_init_verbs,
10072 alc880_gpio1_init_verbs },
be0ae923 10073 .num_dacs = 2,
4953550a 10074 .dac_nids = alc882_dac_nids,
be0ae923
TI
10075 .hp_nid = 0x04,
10076 .channel_mode = alc885_mbp_4ch_modes,
10077 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10078 .input_mux = &alc882_capture_source,
10079 .dig_out_nid = ALC882_DIGOUT_NID,
10080 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10081 .unsol_event = alc_sku_unsol_event,
4f5d1706 10082 .setup = alc885_mbp3_setup,
d922b51d 10083 .init_hook = alc_hp_automute,
4953550a
TI
10084 },
10085 [ALC885_MB5] = {
10086 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10087 .init_verbs = { alc885_mb5_init_verbs,
10088 alc880_gpio1_init_verbs },
10089 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10090 .dac_nids = alc882_dac_nids,
10091 .channel_mode = alc885_mb5_6ch_modes,
10092 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10093 .input_mux = &mb5_capture_source,
10094 .dig_out_nid = ALC882_DIGOUT_NID,
10095 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10096 .unsol_event = alc_sku_unsol_event,
9d54f08b 10097 .setup = alc885_mb5_setup,
d922b51d 10098 .init_hook = alc_hp_automute,
4953550a 10099 },
e458b1fa
LY
10100 [ALC885_MACMINI3] = {
10101 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10102 .init_verbs = { alc885_macmini3_init_verbs,
10103 alc880_gpio1_init_verbs },
10104 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10105 .dac_nids = alc882_dac_nids,
10106 .channel_mode = alc885_macmini3_6ch_modes,
10107 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10108 .input_mux = &macmini3_capture_source,
10109 .dig_out_nid = ALC882_DIGOUT_NID,
10110 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10111 .unsol_event = alc_sku_unsol_event,
9d54f08b 10112 .setup = alc885_macmini3_setup,
d922b51d 10113 .init_hook = alc_hp_automute,
e458b1fa 10114 },
4953550a
TI
10115 [ALC885_MACPRO] = {
10116 .mixers = { alc882_macpro_mixer },
10117 .init_verbs = { alc882_macpro_init_verbs },
10118 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10119 .dac_nids = alc882_dac_nids,
10120 .dig_out_nid = ALC882_DIGOUT_NID,
10121 .dig_in_nid = ALC882_DIGIN_NID,
10122 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10123 .channel_mode = alc882_ch_modes,
10124 .input_mux = &alc882_capture_source,
10125 .init_hook = alc885_macpro_init_hook,
10126 },
10127 [ALC885_IMAC24] = {
10128 .mixers = { alc885_imac24_mixer },
10129 .init_verbs = { alc885_imac24_init_verbs },
10130 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10131 .dac_nids = alc882_dac_nids,
10132 .dig_out_nid = ALC882_DIGOUT_NID,
10133 .dig_in_nid = ALC882_DIGIN_NID,
10134 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10135 .channel_mode = alc882_ch_modes,
10136 .input_mux = &alc882_capture_source,
d922b51d 10137 .unsol_event = alc_sku_unsol_event,
4f5d1706 10138 .setup = alc885_imac24_setup,
4953550a
TI
10139 .init_hook = alc885_imac24_init_hook,
10140 },
4b7e1803 10141 [ALC885_IMAC91] = {
b7cccc52 10142 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10143 .init_verbs = { alc885_imac91_init_verbs,
10144 alc880_gpio1_init_verbs },
10145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10146 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10147 .channel_mode = alc885_mba21_ch_modes,
10148 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10149 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10150 .dig_out_nid = ALC882_DIGOUT_NID,
10151 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10152 .unsol_event = alc_sku_unsol_event,
9d54f08b 10153 .setup = alc885_imac91_setup,
d922b51d 10154 .init_hook = alc_hp_automute,
4b7e1803 10155 },
4953550a
TI
10156 [ALC882_TARGA] = {
10157 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10158 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10159 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10160 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10161 .dac_nids = alc882_dac_nids,
10162 .dig_out_nid = ALC882_DIGOUT_NID,
10163 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10164 .adc_nids = alc882_adc_nids,
10165 .capsrc_nids = alc882_capsrc_nids,
10166 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10167 .channel_mode = alc882_3ST_6ch_modes,
10168 .need_dac_fix = 1,
10169 .input_mux = &alc882_capture_source,
d922b51d 10170 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10171 .setup = alc882_targa_setup,
10172 .init_hook = alc882_targa_automute,
4953550a
TI
10173 },
10174 [ALC882_ASUS_A7J] = {
10175 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10176 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10177 alc882_asus_a7j_verbs},
4953550a
TI
10178 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10179 .dac_nids = alc882_dac_nids,
10180 .dig_out_nid = ALC882_DIGOUT_NID,
10181 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10182 .adc_nids = alc882_adc_nids,
10183 .capsrc_nids = alc882_capsrc_nids,
10184 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10185 .channel_mode = alc882_3ST_6ch_modes,
10186 .need_dac_fix = 1,
10187 .input_mux = &alc882_capture_source,
10188 },
10189 [ALC882_ASUS_A7M] = {
10190 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10191 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10192 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10193 alc882_asus_a7m_verbs },
10194 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10195 .dac_nids = alc882_dac_nids,
10196 .dig_out_nid = ALC882_DIGOUT_NID,
10197 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10198 .channel_mode = alc880_threestack_modes,
10199 .need_dac_fix = 1,
10200 .input_mux = &alc882_capture_source,
10201 },
9c7f852e
TI
10202 [ALC883_3ST_2ch_DIG] = {
10203 .mixers = { alc883_3ST_2ch_mixer },
10204 .init_verbs = { alc883_init_verbs },
10205 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10206 .dac_nids = alc883_dac_nids,
10207 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10208 .dig_in_nid = ALC883_DIGIN_NID,
10209 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10210 .channel_mode = alc883_3ST_2ch_modes,
10211 .input_mux = &alc883_capture_source,
10212 },
10213 [ALC883_3ST_6ch_DIG] = {
10214 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10215 .init_verbs = { alc883_init_verbs },
10216 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10217 .dac_nids = alc883_dac_nids,
10218 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10219 .dig_in_nid = ALC883_DIGIN_NID,
10220 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10221 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10222 .need_dac_fix = 1,
9c7f852e 10223 .input_mux = &alc883_capture_source,
f12ab1e0 10224 },
9c7f852e
TI
10225 [ALC883_3ST_6ch] = {
10226 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10227 .init_verbs = { alc883_init_verbs },
10228 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10229 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10230 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10231 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10232 .need_dac_fix = 1,
9c7f852e 10233 .input_mux = &alc883_capture_source,
f12ab1e0 10234 },
17bba1b7
J
10235 [ALC883_3ST_6ch_INTEL] = {
10236 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10237 .init_verbs = { alc883_init_verbs },
10238 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10239 .dac_nids = alc883_dac_nids,
10240 .dig_out_nid = ALC883_DIGOUT_NID,
10241 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10242 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10243 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10244 .channel_mode = alc883_3ST_6ch_intel_modes,
10245 .need_dac_fix = 1,
10246 .input_mux = &alc883_3stack_6ch_intel,
10247 },
87a8c370
JK
10248 [ALC889A_INTEL] = {
10249 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10250 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10251 alc_hp15_unsol_verbs },
87a8c370
JK
10252 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10253 .dac_nids = alc883_dac_nids,
10254 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10255 .adc_nids = alc889_adc_nids,
10256 .dig_out_nid = ALC883_DIGOUT_NID,
10257 .dig_in_nid = ALC883_DIGIN_NID,
10258 .slave_dig_outs = alc883_slave_dig_outs,
10259 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10260 .channel_mode = alc889_8ch_intel_modes,
10261 .capsrc_nids = alc889_capsrc_nids,
10262 .input_mux = &alc889_capture_source,
4f5d1706 10263 .setup = alc889_automute_setup,
d922b51d
TI
10264 .init_hook = alc_hp_automute,
10265 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10266 .need_dac_fix = 1,
10267 },
10268 [ALC889_INTEL] = {
10269 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10270 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10271 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10272 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10273 .dac_nids = alc883_dac_nids,
10274 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10275 .adc_nids = alc889_adc_nids,
10276 .dig_out_nid = ALC883_DIGOUT_NID,
10277 .dig_in_nid = ALC883_DIGIN_NID,
10278 .slave_dig_outs = alc883_slave_dig_outs,
10279 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10280 .channel_mode = alc889_8ch_intel_modes,
10281 .capsrc_nids = alc889_capsrc_nids,
10282 .input_mux = &alc889_capture_source,
4f5d1706 10283 .setup = alc889_automute_setup,
6732bd0d 10284 .init_hook = alc889_intel_init_hook,
d922b51d 10285 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10286 .need_dac_fix = 1,
10287 },
9c7f852e
TI
10288 [ALC883_6ST_DIG] = {
10289 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10290 .init_verbs = { alc883_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10292 .dac_nids = alc883_dac_nids,
10293 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10294 .dig_in_nid = ALC883_DIGIN_NID,
10295 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10296 .channel_mode = alc883_sixstack_modes,
10297 .input_mux = &alc883_capture_source,
10298 },
ccc656ce 10299 [ALC883_TARGA_DIG] = {
c259249f 10300 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10301 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10302 alc883_targa_verbs},
ccc656ce
KY
10303 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10304 .dac_nids = alc883_dac_nids,
10305 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10306 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10307 .channel_mode = alc883_3ST_6ch_modes,
10308 .need_dac_fix = 1,
10309 .input_mux = &alc883_capture_source,
c259249f 10310 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10311 .setup = alc882_targa_setup,
10312 .init_hook = alc882_targa_automute,
ccc656ce
KY
10313 },
10314 [ALC883_TARGA_2ch_DIG] = {
c259249f 10315 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10316 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10317 alc883_targa_verbs},
ccc656ce
KY
10318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10319 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10320 .adc_nids = alc883_adc_nids_alt,
10321 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10322 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10323 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10324 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10325 .channel_mode = alc883_3ST_2ch_modes,
10326 .input_mux = &alc883_capture_source,
c259249f 10327 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10328 .setup = alc882_targa_setup,
10329 .init_hook = alc882_targa_automute,
ccc656ce 10330 },
64a8be74 10331 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10332 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10333 alc883_chmode_mixer },
64a8be74 10334 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10335 alc883_targa_verbs },
64a8be74
DH
10336 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10337 .dac_nids = alc883_dac_nids,
10338 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10339 .adc_nids = alc883_adc_nids_rev,
10340 .capsrc_nids = alc883_capsrc_nids_rev,
10341 .dig_out_nid = ALC883_DIGOUT_NID,
10342 .dig_in_nid = ALC883_DIGIN_NID,
10343 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10344 .channel_mode = alc883_4ST_8ch_modes,
10345 .need_dac_fix = 1,
10346 .input_mux = &alc883_capture_source,
c259249f 10347 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10348 .setup = alc882_targa_setup,
10349 .init_hook = alc882_targa_automute,
64a8be74 10350 },
bab282b9 10351 [ALC883_ACER] = {
676a9b53 10352 .mixers = { alc883_base_mixer },
bab282b9
VA
10353 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10354 * and the headphone jack. Turn this on and rely on the
10355 * standard mute methods whenever the user wants to turn
10356 * these outputs off.
10357 */
10358 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10359 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10360 .dac_nids = alc883_dac_nids,
bab282b9
VA
10361 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10362 .channel_mode = alc883_3ST_2ch_modes,
10363 .input_mux = &alc883_capture_source,
10364 },
2880a867 10365 [ALC883_ACER_ASPIRE] = {
676a9b53 10366 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10367 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10368 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10369 .dac_nids = alc883_dac_nids,
10370 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10371 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10372 .channel_mode = alc883_3ST_2ch_modes,
10373 .input_mux = &alc883_capture_source,
d922b51d 10374 .unsol_event = alc_sku_unsol_event,
4f5d1706 10375 .setup = alc883_acer_aspire_setup,
d922b51d 10376 .init_hook = alc_hp_automute,
d1a991a6 10377 },
5b2d1eca 10378 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10379 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10380 alc883_chmode_mixer },
10381 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10382 alc888_acer_aspire_4930g_verbs },
10383 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10384 .dac_nids = alc883_dac_nids,
10385 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10386 .adc_nids = alc883_adc_nids_rev,
10387 .capsrc_nids = alc883_capsrc_nids_rev,
10388 .dig_out_nid = ALC883_DIGOUT_NID,
10389 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10390 .channel_mode = alc883_3ST_6ch_modes,
10391 .need_dac_fix = 1,
973b8cb0 10392 .const_channel_count = 6,
5b2d1eca 10393 .num_mux_defs =
ef8ef5fb
VP
10394 ARRAY_SIZE(alc888_2_capture_sources),
10395 .input_mux = alc888_2_capture_sources,
d922b51d 10396 .unsol_event = alc_sku_unsol_event,
4f5d1706 10397 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10398 .init_hook = alc_hp_automute,
d2fd4b09
TV
10399 },
10400 [ALC888_ACER_ASPIRE_6530G] = {
10401 .mixers = { alc888_acer_aspire_6530_mixer },
10402 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10403 alc888_acer_aspire_6530g_verbs },
10404 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10405 .dac_nids = alc883_dac_nids,
10406 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10407 .adc_nids = alc883_adc_nids_rev,
10408 .capsrc_nids = alc883_capsrc_nids_rev,
10409 .dig_out_nid = ALC883_DIGOUT_NID,
10410 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10411 .channel_mode = alc883_3ST_2ch_modes,
10412 .num_mux_defs =
10413 ARRAY_SIZE(alc888_2_capture_sources),
10414 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10415 .unsol_event = alc_sku_unsol_event,
4f5d1706 10416 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10417 .init_hook = alc_hp_automute,
5b2d1eca 10418 },
3b315d70 10419 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10420 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10421 alc883_chmode_mixer },
10422 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10423 alc889_acer_aspire_8930g_verbs,
10424 alc889_eapd_verbs},
3b315d70
HM
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
018df418
HM
10427 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10428 .adc_nids = alc889_adc_nids,
10429 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10430 .dig_out_nid = ALC883_DIGOUT_NID,
10431 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10432 .channel_mode = alc883_3ST_6ch_modes,
10433 .need_dac_fix = 1,
10434 .const_channel_count = 6,
10435 .num_mux_defs =
018df418
HM
10436 ARRAY_SIZE(alc889_capture_sources),
10437 .input_mux = alc889_capture_sources,
d922b51d 10438 .unsol_event = alc_sku_unsol_event,
4f5d1706 10439 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10440 .init_hook = alc_hp_automute,
f5de24b0 10441#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10442 .power_hook = alc_power_eapd,
f5de24b0 10443#endif
3b315d70 10444 },
fc86f954
DK
10445 [ALC888_ACER_ASPIRE_7730G] = {
10446 .mixers = { alc883_3ST_6ch_mixer,
10447 alc883_chmode_mixer },
10448 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10449 alc888_acer_aspire_7730G_verbs },
10450 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10451 .dac_nids = alc883_dac_nids,
10452 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10453 .adc_nids = alc883_adc_nids_rev,
10454 .capsrc_nids = alc883_capsrc_nids_rev,
10455 .dig_out_nid = ALC883_DIGOUT_NID,
10456 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10457 .channel_mode = alc883_3ST_6ch_modes,
10458 .need_dac_fix = 1,
10459 .const_channel_count = 6,
10460 .input_mux = &alc883_capture_source,
d922b51d 10461 .unsol_event = alc_sku_unsol_event,
d9477207 10462 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10463 .init_hook = alc_hp_automute,
fc86f954 10464 },
c07584c8
TD
10465 [ALC883_MEDION] = {
10466 .mixers = { alc883_fivestack_mixer,
10467 alc883_chmode_mixer },
10468 .init_verbs = { alc883_init_verbs,
b373bdeb 10469 alc883_medion_eapd_verbs },
c07584c8
TD
10470 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10471 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10472 .adc_nids = alc883_adc_nids_alt,
10473 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10474 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10475 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10476 .channel_mode = alc883_sixstack_modes,
10477 .input_mux = &alc883_capture_source,
b373bdeb 10478 },
7ad7b218
MC
10479 [ALC883_MEDION_WIM2160] = {
10480 .mixers = { alc883_medion_wim2160_mixer },
10481 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10482 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10483 .dac_nids = alc883_dac_nids,
10484 .dig_out_nid = ALC883_DIGOUT_NID,
10485 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10486 .adc_nids = alc883_adc_nids,
10487 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10488 .channel_mode = alc883_3ST_2ch_modes,
10489 .input_mux = &alc883_capture_source,
d922b51d 10490 .unsol_event = alc_sku_unsol_event,
7ad7b218 10491 .setup = alc883_medion_wim2160_setup,
d922b51d 10492 .init_hook = alc_hp_automute,
7ad7b218 10493 },
b373bdeb 10494 [ALC883_LAPTOP_EAPD] = {
676a9b53 10495 .mixers = { alc883_base_mixer },
b373bdeb
AN
10496 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10497 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10498 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10499 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10500 .channel_mode = alc883_3ST_2ch_modes,
10501 .input_mux = &alc883_capture_source,
10502 },
a65cc60f 10503 [ALC883_CLEVO_M540R] = {
10504 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10505 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10506 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10507 .dac_nids = alc883_dac_nids,
10508 .dig_out_nid = ALC883_DIGOUT_NID,
10509 .dig_in_nid = ALC883_DIGIN_NID,
10510 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10511 .channel_mode = alc883_3ST_6ch_clevo_modes,
10512 .need_dac_fix = 1,
10513 .input_mux = &alc883_capture_source,
10514 /* This machine has the hardware HP auto-muting, thus
10515 * we need no software mute via unsol event
10516 */
10517 },
0c4cc443
HRK
10518 [ALC883_CLEVO_M720] = {
10519 .mixers = { alc883_clevo_m720_mixer },
10520 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10521 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10522 .dac_nids = alc883_dac_nids,
10523 .dig_out_nid = ALC883_DIGOUT_NID,
10524 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10525 .channel_mode = alc883_3ST_2ch_modes,
10526 .input_mux = &alc883_capture_source,
0c4cc443 10527 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10528 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10529 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10530 },
bc9f98a9
KY
10531 [ALC883_LENOVO_101E_2ch] = {
10532 .mixers = { alc883_lenovo_101e_2ch_mixer},
10533 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10534 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10535 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10536 .adc_nids = alc883_adc_nids_alt,
10537 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10538 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10539 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10540 .channel_mode = alc883_3ST_2ch_modes,
10541 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10542 .setup = alc883_lenovo_101e_setup,
10543 .unsol_event = alc_sku_unsol_event,
10544 .init_hook = alc_inithook,
bc9f98a9 10545 },
272a527c
KY
10546 [ALC883_LENOVO_NB0763] = {
10547 .mixers = { alc883_lenovo_nb0763_mixer },
10548 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10549 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10550 .dac_nids = alc883_dac_nids,
272a527c
KY
10551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10552 .channel_mode = alc883_3ST_2ch_modes,
10553 .need_dac_fix = 1,
10554 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10555 .unsol_event = alc_sku_unsol_event,
dc427170 10556 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10557 .init_hook = alc_hp_automute,
272a527c
KY
10558 },
10559 [ALC888_LENOVO_MS7195_DIG] = {
10560 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10561 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10562 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10563 .dac_nids = alc883_dac_nids,
10564 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10565 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10566 .channel_mode = alc883_3ST_6ch_modes,
10567 .need_dac_fix = 1,
10568 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10569 .unsol_event = alc_sku_unsol_event,
10570 .setup = alc888_lenovo_ms7195_setup,
10571 .init_hook = alc_inithook,
189609ae
KY
10572 },
10573 [ALC883_HAIER_W66] = {
c259249f 10574 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10575 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10577 .dac_nids = alc883_dac_nids,
10578 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10579 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10580 .channel_mode = alc883_3ST_2ch_modes,
10581 .input_mux = &alc883_capture_source,
d922b51d 10582 .unsol_event = alc_sku_unsol_event,
4f5d1706 10583 .setup = alc883_haier_w66_setup,
d922b51d 10584 .init_hook = alc_hp_automute,
eea6419e 10585 },
4723c022 10586 [ALC888_3ST_HP] = {
eea6419e 10587 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10588 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10590 .dac_nids = alc883_dac_nids,
4723c022
CM
10591 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10592 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10593 .need_dac_fix = 1,
10594 .input_mux = &alc883_capture_source,
d922b51d 10595 .unsol_event = alc_sku_unsol_event,
4f5d1706 10596 .setup = alc888_3st_hp_setup,
d922b51d 10597 .init_hook = alc_hp_automute,
8341de60 10598 },
5795b9e6 10599 [ALC888_6ST_DELL] = {
f24dbdc6 10600 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10601 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10602 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10603 .dac_nids = alc883_dac_nids,
10604 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10605 .dig_in_nid = ALC883_DIGIN_NID,
10606 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10607 .channel_mode = alc883_sixstack_modes,
10608 .input_mux = &alc883_capture_source,
d922b51d 10609 .unsol_event = alc_sku_unsol_event,
4f5d1706 10610 .setup = alc888_6st_dell_setup,
d922b51d 10611 .init_hook = alc_hp_automute,
5795b9e6 10612 },
a8848bd6
AS
10613 [ALC883_MITAC] = {
10614 .mixers = { alc883_mitac_mixer },
10615 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10619 .channel_mode = alc883_3ST_2ch_modes,
10620 .input_mux = &alc883_capture_source,
d922b51d 10621 .unsol_event = alc_sku_unsol_event,
4f5d1706 10622 .setup = alc883_mitac_setup,
d922b51d 10623 .init_hook = alc_hp_automute,
a8848bd6 10624 },
fb97dc67
J
10625 [ALC883_FUJITSU_PI2515] = {
10626 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10627 .init_verbs = { alc883_init_verbs,
10628 alc883_2ch_fujitsu_pi2515_verbs},
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .dig_out_nid = ALC883_DIGOUT_NID,
10632 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10633 .channel_mode = alc883_3ST_2ch_modes,
10634 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10635 .unsol_event = alc_sku_unsol_event,
4f5d1706 10636 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10637 .init_hook = alc_hp_automute,
fb97dc67 10638 },
ef8ef5fb
VP
10639 [ALC888_FUJITSU_XA3530] = {
10640 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10641 .init_verbs = { alc883_init_verbs,
10642 alc888_fujitsu_xa3530_verbs },
10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10644 .dac_nids = alc883_dac_nids,
10645 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10646 .adc_nids = alc883_adc_nids_rev,
10647 .capsrc_nids = alc883_capsrc_nids_rev,
10648 .dig_out_nid = ALC883_DIGOUT_NID,
10649 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10650 .channel_mode = alc888_4ST_8ch_intel_modes,
10651 .num_mux_defs =
10652 ARRAY_SIZE(alc888_2_capture_sources),
10653 .input_mux = alc888_2_capture_sources,
d922b51d 10654 .unsol_event = alc_sku_unsol_event,
4f5d1706 10655 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10656 .init_hook = alc_hp_automute,
ef8ef5fb 10657 },
e2757d5e
KY
10658 [ALC888_LENOVO_SKY] = {
10659 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10660 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10661 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10662 .dac_nids = alc883_dac_nids,
10663 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10664 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10665 .channel_mode = alc883_sixstack_modes,
10666 .need_dac_fix = 1,
10667 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10668 .unsol_event = alc_sku_unsol_event,
4f5d1706 10669 .setup = alc888_lenovo_sky_setup,
d922b51d 10670 .init_hook = alc_hp_automute,
e2757d5e
KY
10671 },
10672 [ALC888_ASUS_M90V] = {
10673 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10674 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10675 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10676 .dac_nids = alc883_dac_nids,
10677 .dig_out_nid = ALC883_DIGOUT_NID,
10678 .dig_in_nid = ALC883_DIGIN_NID,
10679 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10680 .channel_mode = alc883_3ST_6ch_modes,
10681 .need_dac_fix = 1,
10682 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10683 .unsol_event = alc_sku_unsol_event,
10684 .setup = alc883_mode2_setup,
10685 .init_hook = alc_inithook,
e2757d5e
KY
10686 },
10687 [ALC888_ASUS_EEE1601] = {
10688 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10689 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10690 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10691 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10692 .dac_nids = alc883_dac_nids,
10693 .dig_out_nid = ALC883_DIGOUT_NID,
10694 .dig_in_nid = ALC883_DIGIN_NID,
10695 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10696 .channel_mode = alc883_3ST_2ch_modes,
10697 .need_dac_fix = 1,
10698 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10699 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10700 .init_hook = alc883_eee1601_inithook,
10701 },
3ab90935
WF
10702 [ALC1200_ASUS_P5Q] = {
10703 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10704 .init_verbs = { alc883_init_verbs },
10705 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10706 .dac_nids = alc883_dac_nids,
10707 .dig_out_nid = ALC1200_DIGOUT_NID,
10708 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10709 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10710 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10711 .channel_mode = alc883_sixstack_modes,
10712 .input_mux = &alc883_capture_source,
10713 },
eb4c41d3
TS
10714 [ALC889A_MB31] = {
10715 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10716 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10717 alc880_gpio1_init_verbs },
10718 .adc_nids = alc883_adc_nids,
10719 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10720 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10721 .dac_nids = alc883_dac_nids,
10722 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10723 .channel_mode = alc889A_mb31_6ch_modes,
10724 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10725 .input_mux = &alc889A_mb31_capture_source,
10726 .dig_out_nid = ALC883_DIGOUT_NID,
10727 .unsol_event = alc889A_mb31_unsol_event,
10728 .init_hook = alc889A_mb31_automute,
10729 },
3e1647c5
GG
10730 [ALC883_SONY_VAIO_TT] = {
10731 .mixers = { alc883_vaiott_mixer },
10732 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10733 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10734 .dac_nids = alc883_dac_nids,
10735 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10736 .channel_mode = alc883_3ST_2ch_modes,
10737 .input_mux = &alc883_capture_source,
d922b51d 10738 .unsol_event = alc_sku_unsol_event,
4f5d1706 10739 .setup = alc883_vaiott_setup,
d922b51d 10740 .init_hook = alc_hp_automute,
3e1647c5 10741 },
9c7f852e
TI
10742};
10743
10744
4953550a
TI
10745/*
10746 * Pin config fixes
10747 */
10748enum {
954a29c8 10749 PINFIX_ABIT_AW9D_MAX,
32eea388 10750 PINFIX_LENOVO_Y530,
954a29c8 10751 PINFIX_PB_M5210,
c3d226ab 10752 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10753};
10754
f8f25ba3
TI
10755static const struct alc_fixup alc882_fixups[] = {
10756 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10757 .type = ALC_FIXUP_PINS,
10758 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10759 { 0x15, 0x01080104 }, /* side */
10760 { 0x16, 0x01011012 }, /* rear */
10761 { 0x17, 0x01016011 }, /* clfe */
10762 { }
10763 }
f8f25ba3 10764 },
32eea388
DH
10765 [PINFIX_LENOVO_Y530] = {
10766 .type = ALC_FIXUP_PINS,
10767 .v.pins = (const struct alc_pincfg[]) {
10768 { 0x15, 0x99130112 }, /* rear int speakers */
10769 { 0x16, 0x99130111 }, /* subwoofer */
10770 { }
10771 }
10772 },
954a29c8 10773 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10774 .type = ALC_FIXUP_VERBS,
10775 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10776 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10777 {}
10778 }
954a29c8 10779 },
c3d226ab 10780 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10781 .type = ALC_FIXUP_SKU,
10782 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10783 },
4953550a
TI
10784};
10785
a9111321 10786static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10787 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10788 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10789 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10790 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10791 {}
10792};
10793
9c7f852e
TI
10794/*
10795 * BIOS auto configuration
10796 */
f970de25 10797static void alc_auto_init_input_src(struct hda_codec *codec)
4953550a
TI
10798{
10799 struct alc_spec *spec = codec->spec;
10800 int c;
10801
f970de25
TI
10802 if (spec->dual_adc_switch)
10803 return;
10804
4953550a 10805 for (c = 0; c < spec->num_adc_nids; c++) {
f970de25 10806 hda_nid_t nid;
4953550a
TI
10807 unsigned int mux_idx;
10808 const struct hda_input_mux *imux;
10809 int conns, mute, idx, item;
7ec9c6cc 10810 unsigned int wid_type;
4953550a 10811
f970de25
TI
10812 nid = spec->capsrc_nids ?
10813 spec->capsrc_nids[c] : spec->adc_nids[c];
10696aa0 10814 /* mute ADC */
4f574b7b
TI
10815 if (query_amp_caps(codec, spec->adc_nids[c], HDA_INPUT) &
10816 AC_AMPCAP_MUTE)
10817 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
10696aa0
TI
10818 AC_VERB_SET_AMP_GAIN_MUTE,
10819 AMP_IN_MUTE(0));
4f574b7b
TI
10820 else if (query_amp_caps(codec, nid, HDA_OUTPUT) &
10821 AC_AMPCAP_MUTE)
10822 snd_hda_codec_write(codec, nid, 0,
10823 AC_VERB_SET_AMP_GAIN_MUTE,
10824 AMP_OUT_MUTE);
10696aa0 10825
1f0f4b80
TI
10826 conns = snd_hda_get_conn_list(codec, nid, NULL);
10827 if (conns <= 0)
4953550a
TI
10828 continue;
10829 mux_idx = c >= spec->num_mux_defs ? 0 : c;
10830 imux = &spec->input_mux[mux_idx];
5311114d
TI
10831 if (!imux->num_items && mux_idx > 0)
10832 imux = &spec->input_mux[0];
7ec9c6cc 10833 wid_type = get_wcaps_type(get_wcaps(codec, nid));
4953550a
TI
10834 for (idx = 0; idx < conns; idx++) {
10835 /* if the current connection is the selected one,
10836 * unmute it as default - otherwise mute it
10837 */
10838 mute = AMP_IN_MUTE(idx);
10839 for (item = 0; item < imux->num_items; item++) {
10840 if (imux->items[item].index == idx) {
10841 if (spec->cur_mux[c] == item)
10842 mute = AMP_IN_UNMUTE(idx);
10843 break;
10844 }
10845 }
7ec9c6cc
TI
10846 /* initialize the mute status if mute-amp is present */
10847 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
9c7f852e
TI
10848 snd_hda_codec_write(codec, nid, 0,
10849 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a 10850 mute);
7ec9c6cc
TI
10851 if (wid_type == AC_WID_AUD_SEL &&
10852 mute != AMP_IN_MUTE(idx))
4953550a
TI
10853 snd_hda_codec_write(codec, nid, 0,
10854 AC_VERB_SET_CONNECT_SEL,
10855 idx);
9c7f852e
TI
10856 }
10857 }
10858}
10859
4953550a
TI
10860/* add mic boosts if needed */
10861static int alc_auto_add_mic_boost(struct hda_codec *codec)
10862{
10863 struct alc_spec *spec = codec->spec;
66ceeb6b 10864 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 10865 int i, err;
53e8c323 10866 int type_idx = 0;
4953550a 10867 hda_nid_t nid;
5322bf27 10868 const char *prev_label = NULL;
4953550a 10869
66ceeb6b 10870 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 10871 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
10872 break;
10873 nid = cfg->inputs[i].pin;
10874 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
10875 const char *label;
10876 char boost_label[32];
10877
10878 label = hda_get_autocfg_input_label(codec, cfg, i);
10879 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
10880 type_idx++;
10881 else
10882 type_idx = 0;
5322bf27
DH
10883 prev_label = label;
10884
10885 snprintf(boost_label, sizeof(boost_label),
10886 "%s Boost Volume", label);
10887 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10888 boost_label, type_idx,
4953550a 10889 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
10890 if (err < 0)
10891 return err;
10892 }
4953550a
TI
10893 }
10894 return 0;
10895}
f511b01c 10896
9c7f852e 10897/* almost identical with ALC880 parser... */
4953550a 10898static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
10899{
10900 struct alc_spec *spec = codec->spec;
4c6d72d1 10901 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 10902 int err;
9c7f852e 10903
05f5f477
TI
10904 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
10905 alc882_ignore);
9c7f852e
TI
10906 if (err < 0)
10907 return err;
05f5f477
TI
10908 if (!spec->autocfg.line_outs)
10909 return 0; /* can't find valid BIOS pin config */
776e184e 10910
343a04be 10911 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
10912 if (err < 0)
10913 return err;
343a04be 10914 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
05f5f477
TI
10915 if (err < 0)
10916 return err;
343a04be 10917 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
489008cd
TI
10918 if (err < 0)
10919 return err;
343a04be 10920 err = alc_auto_create_hp_out(codec);
05f5f477
TI
10921 if (err < 0)
10922 return err;
343a04be 10923 err = alc_auto_create_speaker_out(codec);
05f5f477
TI
10924 if (err < 0)
10925 return err;
b7821709 10926 err = alc_auto_create_input_ctls(codec);
776e184e
TI
10927 if (err < 0)
10928 return err;
10929
05f5f477
TI
10930 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10931
757899ac 10932 alc_auto_parse_digital(codec);
05f5f477
TI
10933
10934 if (spec->kctls.list)
10935 add_mixer(spec, spec->kctls.list);
10936
05f5f477
TI
10937 spec->num_mux_defs = 1;
10938 spec->input_mux = &spec->private_imux[0];
10939
d6cc9fab
TI
10940 if (!spec->dual_adc_switch)
10941 alc_remove_invalid_adc_nids(codec);
10942
6227cdce 10943 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
10944
10945 err = alc_auto_add_mic_boost(codec);
10946 if (err < 0)
10947 return err;
61b9b9b1 10948
776e184e 10949 return 1; /* config found */
9c7f852e
TI
10950}
10951
10952/* additional initialization for auto-configuration model */
4953550a 10953static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 10954{
f6c7e546 10955 struct alc_spec *spec = codec->spec;
343a04be
TI
10956 alc_auto_init_multi_out(codec);
10957 alc_auto_init_extra_out(codec);
0a7f5320 10958 alc_auto_init_analog_input(codec);
f970de25 10959 alc_auto_init_input_src(codec);
757899ac 10960 alc_auto_init_digital(codec);
f6c7e546 10961 if (spec->unsol_event)
7fb0d78f 10962 alc_inithook(codec);
9c7f852e
TI
10963}
10964
4953550a 10965static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
10966{
10967 struct alc_spec *spec;
10968 int err, board_config;
10969
10970 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
10971 if (spec == NULL)
10972 return -ENOMEM;
10973
10974 codec->spec = spec;
10975
1f0f4b80
TI
10976 spec->mixer_nid = 0x0b;
10977
4953550a
TI
10978 switch (codec->vendor_id) {
10979 case 0x10ec0882:
10980 case 0x10ec0885:
10981 break;
10982 default:
10983 /* ALC883 and variants */
10984 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
10985 break;
10986 }
2c3bf9ab 10987
4953550a
TI
10988 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
10989 alc882_models,
10990 alc882_cfg_tbl);
10991
10992 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
10993 board_config = snd_hda_check_board_codec_sid_config(codec,
10994 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10995
10996 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 10997 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
10998 codec->chip_name);
10999 board_config = ALC882_AUTO;
9c7f852e
TI
11000 }
11001
b5bfbc67
TI
11002 if (board_config == ALC882_AUTO) {
11003 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11004 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11005 }
4953550a 11006
90622917
DH
11007 alc_auto_parse_customize_define(codec);
11008
4953550a 11009 if (board_config == ALC882_AUTO) {
9c7f852e 11010 /* automatic parse from the BIOS config */
4953550a 11011 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11012 if (err < 0) {
11013 alc_free(codec);
11014 return err;
f12ab1e0 11015 } else if (!err) {
9c7f852e
TI
11016 printk(KERN_INFO
11017 "hda_codec: Cannot set up configuration "
11018 "from BIOS. Using base mode...\n");
4953550a 11019 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11020 }
11021 }
11022
dc1eae25 11023 if (has_cdefine_beep(codec)) {
8af2591d
TI
11024 err = snd_hda_attach_beep_device(codec, 0x1);
11025 if (err < 0) {
11026 alc_free(codec);
11027 return err;
11028 }
680cd536
KK
11029 }
11030
4953550a 11031 if (board_config != ALC882_AUTO)
e9c364c0 11032 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11033
4953550a
TI
11034 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11035 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11036 /* FIXME: setup DAC5 */
11037 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11038 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11039
11040 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11041 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11042
4953550a 11043 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab
TI
11044 alc_auto_fill_adc_caps(codec);
11045 alc_remove_invalid_adc_nids(codec);
2f893286
KY
11046 }
11047
b59bdf3b 11048 set_capture_mixer(codec);
da00c244 11049
dc1eae25 11050 if (has_cdefine_beep(codec))
da00c244 11051 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11052
b5bfbc67 11053 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11054
2134ea4f
TI
11055 spec->vmaster_nid = 0x0c;
11056
9c7f852e 11057 codec->patch_ops = alc_patch_ops;
4953550a
TI
11058 if (board_config == ALC882_AUTO)
11059 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11060
11061 alc_init_jacks(codec);
cb53c626
TI
11062#ifdef CONFIG_SND_HDA_POWER_SAVE
11063 if (!spec->loopback.amplist)
4953550a 11064 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11065#endif
9c7f852e
TI
11066
11067 return 0;
11068}
11069
4953550a 11070
9c7f852e
TI
11071/*
11072 * ALC262 support
11073 */
11074
11075#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11076#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11077
11078#define alc262_dac_nids alc260_dac_nids
11079#define alc262_adc_nids alc882_adc_nids
11080#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11081#define alc262_capsrc_nids alc882_capsrc_nids
11082#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11083
11084#define alc262_modes alc260_modes
11085#define alc262_capture_source alc882_capture_source
11086
4c6d72d1 11087static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11088 /* ADC0 */
11089 0x09
11090};
11091
4c6d72d1 11092static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11093
a9111321 11094static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11095 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11096 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11097 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11098 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11099 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11100 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11103 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11104 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11106 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11107 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11108 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11109 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11110 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11111 { } /* end */
11112};
11113
ce875f07 11114/* update HP, line and mono-out pins according to the master switch */
e9427969 11115#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11116
e9427969 11117static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11118{
11119 struct alc_spec *spec = codec->spec;
864f92be 11120
e9427969
TI
11121 spec->autocfg.hp_pins[0] = 0x1b;
11122 spec->autocfg.speaker_pins[0] = 0x16;
11123 spec->automute = 1;
11124 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11125}
11126
e9427969 11127static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11128{
11129 struct alc_spec *spec = codec->spec;
864f92be 11130
e9427969
TI
11131 spec->autocfg.hp_pins[0] = 0x15;
11132 spec->autocfg.speaker_pins[0] = 0x16;
11133 spec->automute = 1;
11134 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11135}
11136
b72519b5 11137#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11138#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11139
b72519b5
TI
11140#define ALC262_HP_MASTER_SWITCH \
11141 { \
11142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11143 .name = "Master Playback Switch", \
11144 .info = snd_ctl_boolean_mono_info, \
11145 .get = alc262_hp_master_sw_get, \
11146 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11147 }, \
11148 { \
11149 .iface = NID_MAPPING, \
11150 .name = "Master Playback Switch", \
11151 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11152 }
11153
5b0cb1d8 11154
a9111321 11155static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11156 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11157 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11158 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11160 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11161 HDA_OUTPUT),
11162 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11163 HDA_OUTPUT),
9c7f852e
TI
11164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11165 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11166 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11167 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11168 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11169 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11170 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11171 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11172 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11173 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11174 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11175 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11176 { } /* end */
11177};
11178
a9111321 11179static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11180 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11181 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11182 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11183 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11184 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11185 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11186 HDA_OUTPUT),
11187 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11188 HDA_OUTPUT),
cd7509a4
KY
11189 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11190 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11191 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11192 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11193 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11194 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11195 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11196 { } /* end */
11197};
11198
a9111321 11199static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11200 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11201 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11202 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11203 { } /* end */
11204};
11205
66d2a9d6 11206/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11207static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11208{
11209 struct alc_spec *spec = codec->spec;
66d2a9d6 11210
a9fd4f3f 11211 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11212 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11213 spec->automute = 1;
11214 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11215}
11216
a9111321 11217static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11218 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11219 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11220 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11221 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11222 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11223 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11225 { } /* end */
11226};
11227
a9111321 11228static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11229 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11230 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11231
11232 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11233 { }
11234};
11235
a9111321 11236static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11238 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11240 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11241 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11242 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11243 { } /* end */
11244};
11245
a9111321 11246static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11247 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11248 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11249 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11250 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11251 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11252 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11253 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11254 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11255 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11256 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11257 {}
11258};
11259
a9111321 11260static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11261 .num_items = 1,
11262 .items = {
11263 { "Line", 0x1 },
11264 },
11265};
11266
42171c17 11267/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11268#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11269#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11270#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11271
11272#define ALC262_HIPPO_MASTER_SWITCH \
11273 { \
11274 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11275 .name = "Master Playback Switch", \
11276 .info = snd_ctl_boolean_mono_info, \
11277 .get = alc262_hippo_master_sw_get, \
11278 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11279 }, \
11280 { \
11281 .iface = NID_MAPPING, \
11282 .name = "Master Playback Switch", \
11283 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11284 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11285 }
42171c17 11286
a9111321 11287static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11288 ALC262_HIPPO_MASTER_SWITCH,
11289 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11290 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11291 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11292 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11293 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11294 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11295 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11297 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11298 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11299 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11300 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11301 { } /* end */
11302};
11303
a9111321 11304static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11305 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11306 ALC262_HIPPO_MASTER_SWITCH,
11307 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11308 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11309 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11310 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11311 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11312 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11313 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11314 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11315 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11316 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11317 { } /* end */
11318};
11319
11320/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11321static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11322{
11323 struct alc_spec *spec = codec->spec;
11324
11325 spec->autocfg.hp_pins[0] = 0x15;
11326 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11327 spec->automute = 1;
11328 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11329}
11330
4f5d1706 11331static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11332{
11333 struct alc_spec *spec = codec->spec;
11334
11335 spec->autocfg.hp_pins[0] = 0x1b;
11336 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11337 spec->automute = 1;
11338 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11339}
11340
11341
a9111321 11342static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11343 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11344 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11345 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11346 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11348 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11349 { } /* end */
11350};
11351
a9111321 11352static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11353 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11354 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11355 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11356 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11357 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11358 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11359 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11360 { } /* end */
11361};
272a527c 11362
a9111321 11363static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11364 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11365 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11366 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11367 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11371 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11372 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11373 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11374 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11375 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11376 { } /* end */
11377};
11378
a9111321 11379static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11380 /* Headphone automute */
11381 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11382 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11383 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11384
11385 /* P11 AUX_IN, white 4-pin connector */
11386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11387 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11388 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11389 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11390
11391 {}
11392};
11393
11394/* unsolicited event for HP jack sensing */
4f5d1706 11395static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11396{
a9fd4f3f 11397 struct alc_spec *spec = codec->spec;
ba340e82 11398
a9fd4f3f
TI
11399 spec->autocfg.hp_pins[0] = 0x1b;
11400 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11401 spec->automute = 1;
11402 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11403}
11404
ba340e82 11405
9c7f852e
TI
11406#define alc262_capture_mixer alc882_capture_mixer
11407#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11408
11409/*
11410 * generic initialization of ADC, input mixers and output mixers
11411 */
a9111321 11412static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11413 /*
11414 * Unmute ADC0-2 and set the default input to mic-in
11415 */
11416 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11417 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11418 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11419 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11420 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11421 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11422
cb53c626 11423 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11424 * mixer widget
f12ab1e0
TI
11425 * Note: PASD motherboards uses the Line In 2 as the input for
11426 * front panel mic (mic 2)
9c7f852e
TI
11427 */
11428 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11429 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11430 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11431 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11432 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11433 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11434
11435 /*
df694daa
KY
11436 * Set up output mixers (0x0c - 0x0e)
11437 */
11438 /* set vol=0 to output mixers */
11439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11440 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11441 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11442 /* set up input amps for analog loopback */
11443 /* Amp Indices: DAC = 0, mixer = 1 */
11444 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11445 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11446 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11447 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11448 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11449 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11450
11451 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11452 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11453 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11454 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11455 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11456 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11457
11458 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11459 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11460 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11461 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11462 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11463
df694daa
KY
11464 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11465 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11466
df694daa
KY
11467 /* FIXME: use matrix-type input source selection */
11468 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11469 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11470 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11473 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11474 /* Input mixer2 */
11475 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11476 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11477 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11478 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11479 /* Input mixer3 */
11480 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11481 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11482 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11483 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11484
11485 { }
11486};
1da177e4 11487
a9111321 11488static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11489 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11490 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11491 { }
11492};
11493
a9111321 11494static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11495 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11496 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11498
11499 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11500 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11501 {}
11502};
11503
a9111321 11504static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11506 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11507 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11508
11509 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11511 {}
272a527c
KY
11512};
11513
a9111321 11514static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11515 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11516 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11517 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11518 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11519 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11520 { } /* end */
11521};
11522
a9111321 11523static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11524 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11527 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11528 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11529 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11530 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11532 {}
11533};
11534
4f5d1706 11535static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11536{
a9fd4f3f
TI
11537 struct alc_spec *spec = codec->spec;
11538
11539 spec->autocfg.hp_pins[0] = 0x15;
11540 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11541 spec->ext_mic.pin = 0x18;
11542 spec->ext_mic.mux_idx = 0;
11543 spec->int_mic.pin = 0x12;
11544 spec->int_mic.mux_idx = 9;
11545 spec->auto_mic = 1;
d922b51d
TI
11546 spec->automute = 1;
11547 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11548}
11549
e8f9ae2a
PT
11550/*
11551 * nec model
11552 * 0x15 = headphone
11553 * 0x16 = internal speaker
11554 * 0x18 = external mic
11555 */
11556
a9111321 11557static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11558 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11560
11561 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11562 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11563 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11564
11565 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11566 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11567 { } /* end */
11568};
11569
a9111321 11570static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11571 /* Unmute Speaker */
11572 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11573
11574 /* Headphone */
11575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11576 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11577
11578 /* External mic to headphone */
11579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11580 /* External mic to speaker */
11581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11582 {}
11583};
11584
834be88d
TI
11585/*
11586 * fujitsu model
5d9fab2d
TV
11587 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11588 * 0x1b = port replicator headphone out
834be88d
TI
11589 */
11590
20f5e0b3 11591#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11592
a9111321 11593static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11595 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11596 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11597 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11598 {}
11599};
11600
a9111321 11601static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11602 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11603 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11604 {}
11605};
11606
a9111321 11607static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11608 /* Front Mic pin: input vref at 50% */
11609 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11611 {}
11612};
11613
a9111321 11614static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11615 .num_items = 3,
834be88d
TI
11616 .items = {
11617 { "Mic", 0x0 },
28c4edb7 11618 { "Internal Mic", 0x1 },
834be88d
TI
11619 { "CD", 0x4 },
11620 },
11621};
11622
a9111321 11623static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11624 .num_items = 5,
11625 .items = {
11626 { "Mic", 0x0 },
accbe498 11627 { "Front Mic", 0x1 },
9c7f852e
TI
11628 { "Line", 0x2 },
11629 { "CD", 0x4 },
11630 { "AUX IN", 0x6 },
11631 },
11632};
11633
a9111321 11634static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11635 .num_items = 4,
11636 .items = {
11637 { "Mic", 0x0 },
11638 { "Front Mic", 0x2 },
11639 { "Line", 0x1 },
11640 { "CD", 0x4 },
11641 },
11642};
11643
0f0f391c 11644static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11645{
11646 struct alc_spec *spec = codec->spec;
834be88d 11647
0f0f391c
TI
11648 spec->autocfg.hp_pins[0] = 0x14;
11649 spec->autocfg.hp_pins[1] = 0x1b;
11650 spec->autocfg.speaker_pins[0] = 0x15;
11651 spec->automute = 1;
11652 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11653}
11654
834be88d 11655/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11656static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11657 .ops = &snd_hda_bind_vol,
11658 .values = {
11659 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11660 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11661 0
11662 },
11663};
834be88d 11664
a9111321 11665static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11666 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11667 {
11668 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11669 .name = "Master Playback Switch",
0f0f391c
TI
11670 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11671 .info = snd_ctl_boolean_mono_info,
11672 .get = alc262_hp_master_sw_get,
11673 .put = alc262_hp_master_sw_put,
834be88d 11674 },
5b0cb1d8
JK
11675 {
11676 .iface = NID_MAPPING,
11677 .name = "Master Playback Switch",
11678 .private_value = 0x1b,
11679 },
834be88d
TI
11680 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11681 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11682 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11685 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11686 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11687 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11688 { } /* end */
11689};
11690
0f0f391c 11691static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11692{
0f0f391c 11693 struct alc_spec *spec = codec->spec;
0e31daf7 11694
0f0f391c
TI
11695 spec->autocfg.hp_pins[0] = 0x1b;
11696 spec->autocfg.speaker_pins[0] = 0x14;
11697 spec->autocfg.speaker_pins[1] = 0x16;
11698 spec->automute = 1;
11699 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11700}
11701
a9111321 11702static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11703 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11704 {
11705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11706 .name = "Master Playback Switch",
0f0f391c
TI
11707 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11708 .info = snd_ctl_boolean_mono_info,
11709 .get = alc262_hp_master_sw_get,
11710 .put = alc262_hp_master_sw_put,
0e31daf7
J
11711 },
11712 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11713 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11714 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
11715 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11716 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11717 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11718 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11719 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
11720 { } /* end */
11721};
11722
a9111321 11723static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 11724 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 11725 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
11726 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11727 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11728 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
11729 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11730 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11731 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
11732 { } /* end */
11733};
11734
304dcaac 11735/* additional init verbs for Benq laptops */
a9111321 11736static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
11737 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11738 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11739 {}
11740};
11741
a9111321 11742static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
11743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11744 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11745
11746 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11747 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11748 {}
11749};
11750
f651b50b 11751/* Samsung Q1 Ultra Vista model setup */
a9111321 11752static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
11753 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11754 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
11755 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11756 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
11757 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11758 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
11759 { } /* end */
11760};
11761
a9111321 11762static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
11763 /* output mixer */
11764 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11766 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11767 /* speaker */
11768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11769 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11771 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11772 /* HP */
f651b50b 11773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
11774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11776 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11777 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11778 /* internal mic */
11779 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11780 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11781 /* ADC, choose mic */
11782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11783 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11784 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11785 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11786 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11787 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11788 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11789 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11790 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11791 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
11792 {}
11793};
11794
f651b50b
TD
11795/* mute/unmute internal speaker according to the hp jack and mute state */
11796static void alc262_ultra_automute(struct hda_codec *codec)
11797{
11798 struct alc_spec *spec = codec->spec;
11799 unsigned int mute;
f651b50b 11800
bb9f76cd
TI
11801 mute = 0;
11802 /* auto-mute only when HP is used as HP */
11803 if (!spec->cur_mux[0]) {
864f92be 11804 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
11805 if (spec->jack_present)
11806 mute = HDA_AMP_MUTE;
f651b50b 11807 }
bb9f76cd
TI
11808 /* mute/unmute internal speaker */
11809 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11810 HDA_AMP_MUTE, mute);
11811 /* mute/unmute HP */
11812 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11813 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
11814}
11815
11816/* unsolicited event for HP jack sensing */
11817static void alc262_ultra_unsol_event(struct hda_codec *codec,
11818 unsigned int res)
11819{
11820 if ((res >> 26) != ALC880_HP_EVENT)
11821 return;
11822 alc262_ultra_automute(codec);
11823}
11824
a9111321 11825static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
11826 .num_items = 2,
11827 .items = {
11828 { "Mic", 0x1 },
11829 { "Headphone", 0x7 },
11830 },
11831};
11832
11833static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11834 struct snd_ctl_elem_value *ucontrol)
11835{
11836 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11837 struct alc_spec *spec = codec->spec;
11838 int ret;
11839
54cbc9ab 11840 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
11841 if (!ret)
11842 return 0;
11843 /* reprogram the HP pin as mic or HP according to the input source */
11844 snd_hda_codec_write_cache(codec, 0x15, 0,
11845 AC_VERB_SET_PIN_WIDGET_CONTROL,
11846 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11847 alc262_ultra_automute(codec); /* mute/unmute HP */
11848 return ret;
11849}
11850
a9111321 11851static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
11852 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11854 {
11855 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11856 .name = "Capture Source",
54cbc9ab
TI
11857 .info = alc_mux_enum_info,
11858 .get = alc_mux_enum_get,
bb9f76cd
TI
11859 .put = alc262_ultra_mux_enum_put,
11860 },
5b0cb1d8
JK
11861 {
11862 .iface = NID_MAPPING,
11863 .name = "Capture Source",
11864 .private_value = 0x15,
11865 },
bb9f76cd
TI
11866 { } /* end */
11867};
11868
c3fc1f50
TI
11869/* We use two mixers depending on the output pin; 0x16 is a mono output
11870 * and thus it's bound with a different mixer.
11871 * This function returns which mixer amp should be used.
11872 */
11873static int alc262_check_volbit(hda_nid_t nid)
11874{
11875 if (!nid)
11876 return 0;
11877 else if (nid == 0x16)
11878 return 2;
11879 else
11880 return 1;
11881}
11882
11883static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11884 const char *pfx, int *vbits, int idx)
c3fc1f50 11885{
c3fc1f50
TI
11886 unsigned long val;
11887 int vbit;
11888
11889 vbit = alc262_check_volbit(nid);
11890 if (!vbit)
11891 return 0;
11892 if (*vbits & vbit) /* a volume control for this mixer already there */
11893 return 0;
11894 *vbits |= vbit;
c3fc1f50
TI
11895 if (vbit == 2)
11896 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
11897 else
11898 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 11899 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
11900}
11901
11902static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 11903 const char *pfx, int idx)
c3fc1f50 11904{
c3fc1f50
TI
11905 unsigned long val;
11906
11907 if (!nid)
11908 return 0;
c3fc1f50
TI
11909 if (nid == 0x16)
11910 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
11911 else
11912 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 11913 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
11914}
11915
df694daa 11916/* add playback controls from the parsed DAC table */
f12ab1e0
TI
11917static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11918 const struct auto_pin_cfg *cfg)
df694daa 11919{
c3fc1f50
TI
11920 const char *pfx;
11921 int vbits;
6843ca16 11922 int i, index, err;
df694daa
KY
11923
11924 spec->multiout.num_dacs = 1; /* only use one dac */
11925 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 11926 spec->private_dac_nids[0] = 2;
df694daa 11927
033688a5 11928 for (i = 0; i < 2; i++) {
6843ca16
TI
11929 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11930 if (!pfx)
11931 pfx = "PCM";
11932 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
11933 index);
033688a5
TI
11934 if (err < 0)
11935 return err;
11936 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11937 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
11938 "Speaker", i);
11939 if (err < 0)
11940 return err;
11941 }
11942 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11943 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
11944 "Headphone", i);
11945 if (err < 0)
11946 return err;
11947 }
11948 }
df694daa 11949
c3fc1f50
TI
11950 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
11951 alc262_check_volbit(cfg->speaker_pins[0]) |
11952 alc262_check_volbit(cfg->hp_pins[0]);
c3fc1f50 11953 vbits = 0;
033688a5 11954 for (i = 0; i < 2; i++) {
6843ca16
TI
11955 pfx = alc_get_line_out_pfx(spec, i, true, &index);
11956 if (!pfx)
11957 pfx = "PCM";
033688a5
TI
11958 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
11959 &vbits, i);
11960 if (err < 0)
11961 return err;
11962 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
11963 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
11964 "Speaker", &vbits, i);
11965 if (err < 0)
11966 return err;
11967 }
11968 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
11969 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
11970 "Headphone", &vbits, i);
11971 if (err < 0)
11972 return err;
11973 }
11974 }
f12ab1e0 11975 return 0;
df694daa
KY
11976}
11977
a9111321 11978static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
11979 /*
11980 * Unmute ADC0-2 and set the default input to mic-in
11981 */
11982 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11983 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11984 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11985 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11986 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11987 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11988
cb53c626 11989 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11990 * mixer widget
f12ab1e0
TI
11991 * Note: PASD motherboards uses the Line In 2 as the input for
11992 * front panel mic (mic 2)
9c7f852e
TI
11993 */
11994 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11995 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11996 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12000 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12001 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12002
9c7f852e
TI
12003 /*
12004 * Set up output mixers (0x0c - 0x0e)
12005 */
12006 /* set vol=0 to output mixers */
12007 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12008 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12009 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12010
12011 /* set up input amps for analog loopback */
12012 /* Amp Indices: DAC = 0, mixer = 1 */
12013 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12014 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12015 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12016 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12017 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12018 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12019
ce875f07 12020 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12021 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12022 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12023
12024 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12025 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12026
12027 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12029
12030 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12032 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12033 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12034 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12035
0e4835c1 12036 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12037 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12038 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12039 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12040 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12041 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12042
12043
12044 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12045 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12046 /* Input mixer1: only unmute Mic */
9c7f852e 12047 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12048 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12049 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12050 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12051 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12052 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12053 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12054 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12055 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12056 /* Input mixer2 */
12057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12058 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12059 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12060 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12061 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12062 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12063 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12064 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12065 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12066 /* Input mixer3 */
12067 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12068 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12071 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12074 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12075 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12076
ce875f07
TI
12077 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12078
9c7f852e
TI
12079 { }
12080};
12081
a9111321 12082static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12083 /*
12084 * Unmute ADC0-2 and set the default input to mic-in
12085 */
12086 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12088 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12089 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12090 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12091 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12092
cb53c626 12093 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12094 * mixer widget
12095 * Note: PASD motherboards uses the Line In 2 as the input for front
12096 * panel mic (mic 2)
12097 */
12098 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12099 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12100 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12101 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12102 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12103 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12104 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12105 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12106 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12107 /*
12108 * Set up output mixers (0x0c - 0x0e)
12109 */
12110 /* set vol=0 to output mixers */
12111 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12112 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12113 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12114
12115 /* set up input amps for analog loopback */
12116 /* Amp Indices: DAC = 0, mixer = 1 */
12117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12123
12124
12125 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12126 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12127 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12128 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12129 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12130 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12131 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12132
12133 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12134 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12135
12136 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12137 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12138
12139 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12140 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12141 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12142 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12143 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12144 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12145
12146 /* FIXME: use matrix-type input source selection */
12147 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12148 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12149 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12150 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12151 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12152 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12153 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12154 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12155 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12156 /* Input mixer2 */
12157 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12158 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12159 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12160 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12161 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12162 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12163 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12164 /* Input mixer3 */
12165 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12166 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12167 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12168 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12169 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12170 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12171 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12172
ce875f07
TI
12173 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12174
cd7509a4
KY
12175 { }
12176};
12177
a9111321 12178static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12179
12180 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12181 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12182 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12183
12184 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12185 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12186 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12187 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12188
12189 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12190 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12191 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12192 {}
12193};
12194
18675e42
TI
12195/*
12196 * Pin config fixes
12197 */
12198enum {
12199 PINFIX_FSC_H270,
d2a19da7 12200 PINFIX_HP_Z200,
18675e42
TI
12201};
12202
12203static const struct alc_fixup alc262_fixups[] = {
12204 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12205 .type = ALC_FIXUP_PINS,
12206 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12207 { 0x14, 0x99130110 }, /* speaker */
12208 { 0x15, 0x0221142f }, /* front HP */
12209 { 0x1b, 0x0121141f }, /* rear HP */
12210 { }
12211 }
12212 },
d2a19da7
DH
12213 [PINFIX_HP_Z200] = {
12214 .type = ALC_FIXUP_PINS,
12215 .v.pins = (const struct alc_pincfg[]) {
12216 { 0x16, 0x99130120 }, /* internal speaker */
12217 { }
12218 }
12219 },
18675e42
TI
12220};
12221
a9111321 12222static const struct snd_pci_quirk alc262_fixup_tbl[] = {
d2a19da7 12223 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
18675e42
TI
12224 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12225 {}
12226};
12227
9f99a638 12228
cb53c626
TI
12229#ifdef CONFIG_SND_HDA_POWER_SAVE
12230#define alc262_loopbacks alc880_loopbacks
12231#endif
12232
def319f9 12233/* pcm configuration: identical with ALC880 */
df694daa
KY
12234#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12235#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12236#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12237#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12238
12239/*
12240 * BIOS auto configuration
12241 */
12242static int alc262_parse_auto_config(struct hda_codec *codec)
12243{
12244 struct alc_spec *spec = codec->spec;
12245 int err;
4c6d72d1 12246 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12247
f12ab1e0
TI
12248 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12249 alc262_ignore);
12250 if (err < 0)
df694daa 12251 return err;
e64f14f4 12252 if (!spec->autocfg.line_outs) {
0852d7a6 12253 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12254 spec->multiout.max_channels = 2;
12255 spec->no_analog = 1;
12256 goto dig_only;
12257 }
df694daa 12258 return 0; /* can't find valid BIOS pin config */
e64f14f4 12259 }
f12ab1e0
TI
12260 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12261 if (err < 0)
12262 return err;
b7821709 12263 err = alc_auto_create_input_ctls(codec);
f12ab1e0 12264 if (err < 0)
df694daa
KY
12265 return err;
12266
12267 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12268
e64f14f4 12269 dig_only:
757899ac 12270 alc_auto_parse_digital(codec);
df694daa 12271
603c4019 12272 if (spec->kctls.list)
d88897ea 12273 add_mixer(spec, spec->kctls.list);
df694daa 12274
a1e8d2da 12275 spec->num_mux_defs = 1;
61b9b9b1 12276 spec->input_mux = &spec->private_imux[0];
df694daa 12277
d6cc9fab
TI
12278 if (!spec->dual_adc_switch)
12279 alc_remove_invalid_adc_nids(codec);
12280
776e184e
TI
12281 err = alc_auto_add_mic_boost(codec);
12282 if (err < 0)
12283 return err;
12284
6227cdce 12285 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12286
df694daa
KY
12287 return 1;
12288}
12289
df694daa
KY
12290
12291/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12292static void alc262_auto_init(struct hda_codec *codec)
df694daa 12293{
f6c7e546 12294 struct alc_spec *spec = codec->spec;
343a04be
TI
12295 alc_auto_init_multi_out(codec);
12296 alc_auto_init_extra_out(codec);
0a7f5320 12297 alc_auto_init_analog_input(codec);
f970de25 12298 alc_auto_init_input_src(codec);
757899ac 12299 alc_auto_init_digital(codec);
f6c7e546 12300 if (spec->unsol_event)
7fb0d78f 12301 alc_inithook(codec);
df694daa
KY
12302}
12303
12304/*
12305 * configuration and preset
12306 */
ea734963 12307static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12308 [ALC262_BASIC] = "basic",
12309 [ALC262_HIPPO] = "hippo",
12310 [ALC262_HIPPO_1] = "hippo_1",
12311 [ALC262_FUJITSU] = "fujitsu",
12312 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12313 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12314 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12315 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12316 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12317 [ALC262_BENQ_T31] = "benq-t31",
12318 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12319 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12320 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12321 [ALC262_ULTRA] = "ultra",
0e31daf7 12322 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12323 [ALC262_NEC] = "nec",
ba340e82 12324 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12325 [ALC262_AUTO] = "auto",
12326};
12327
a9111321 12328static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12329 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12330 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12331 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12332 ALC262_HP_BPC),
12333 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12334 ALC262_HP_BPC),
5734a07c
TI
12335 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12336 ALC262_HP_BPC),
d2a19da7
DH
12337 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12338 ALC262_AUTO),
53eff7e1
TI
12339 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12340 ALC262_HP_BPC),
cd7509a4 12341 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12342 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12343 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12344 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12345 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12346 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12347 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12348 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12349 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12350 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12351 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12352 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12353 ALC262_HP_TC_T5735),
8c427226 12354 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12355 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12356 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12357 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12358 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12359 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12360 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12361 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12362#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12363 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12364 ALC262_SONY_ASSAMD),
c5b5165c 12365#endif
36ca6e13 12366 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12367 ALC262_TOSHIBA_RX1),
80ffe869 12368 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12369 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12370 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12371 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12372 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12373 ALC262_ULTRA),
3e420e78 12374 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12375 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12376 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12377 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12378 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12379 {}
12380};
12381
a9111321 12382static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12383 [ALC262_BASIC] = {
12384 .mixers = { alc262_base_mixer },
12385 .init_verbs = { alc262_init_verbs },
12386 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12387 .dac_nids = alc262_dac_nids,
12388 .hp_nid = 0x03,
12389 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12390 .channel_mode = alc262_modes,
a3bcba38 12391 .input_mux = &alc262_capture_source,
df694daa 12392 },
ccc656ce 12393 [ALC262_HIPPO] = {
42171c17 12394 .mixers = { alc262_hippo_mixer },
6732bd0d 12395 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12396 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12397 .dac_nids = alc262_dac_nids,
12398 .hp_nid = 0x03,
12399 .dig_out_nid = ALC262_DIGOUT_NID,
12400 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12401 .channel_mode = alc262_modes,
12402 .input_mux = &alc262_capture_source,
e9427969 12403 .unsol_event = alc_sku_unsol_event,
4f5d1706 12404 .setup = alc262_hippo_setup,
e9427969 12405 .init_hook = alc_inithook,
ccc656ce
KY
12406 },
12407 [ALC262_HIPPO_1] = {
12408 .mixers = { alc262_hippo1_mixer },
12409 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12410 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12411 .dac_nids = alc262_dac_nids,
12412 .hp_nid = 0x02,
12413 .dig_out_nid = ALC262_DIGOUT_NID,
12414 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12415 .channel_mode = alc262_modes,
12416 .input_mux = &alc262_capture_source,
e9427969 12417 .unsol_event = alc_sku_unsol_event,
4f5d1706 12418 .setup = alc262_hippo1_setup,
e9427969 12419 .init_hook = alc_inithook,
ccc656ce 12420 },
834be88d
TI
12421 [ALC262_FUJITSU] = {
12422 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12423 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12424 alc262_fujitsu_unsol_verbs },
834be88d
TI
12425 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12426 .dac_nids = alc262_dac_nids,
12427 .hp_nid = 0x03,
12428 .dig_out_nid = ALC262_DIGOUT_NID,
12429 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12430 .channel_mode = alc262_modes,
12431 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12432 .unsol_event = alc_sku_unsol_event,
12433 .setup = alc262_fujitsu_setup,
12434 .init_hook = alc_inithook,
834be88d 12435 },
9c7f852e
TI
12436 [ALC262_HP_BPC] = {
12437 .mixers = { alc262_HP_BPC_mixer },
12438 .init_verbs = { alc262_HP_BPC_init_verbs },
12439 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12440 .dac_nids = alc262_dac_nids,
12441 .hp_nid = 0x03,
12442 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12443 .channel_mode = alc262_modes,
12444 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12445 .unsol_event = alc_sku_unsol_event,
12446 .setup = alc262_hp_bpc_setup,
12447 .init_hook = alc_inithook,
f12ab1e0 12448 },
cd7509a4
KY
12449 [ALC262_HP_BPC_D7000_WF] = {
12450 .mixers = { alc262_HP_BPC_WildWest_mixer },
12451 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12452 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12453 .dac_nids = alc262_dac_nids,
12454 .hp_nid = 0x03,
12455 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12456 .channel_mode = alc262_modes,
accbe498 12457 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12458 .unsol_event = alc_sku_unsol_event,
12459 .setup = alc262_hp_wildwest_setup,
12460 .init_hook = alc_inithook,
f12ab1e0 12461 },
cd7509a4
KY
12462 [ALC262_HP_BPC_D7000_WL] = {
12463 .mixers = { alc262_HP_BPC_WildWest_mixer,
12464 alc262_HP_BPC_WildWest_option_mixer },
12465 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12466 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12467 .dac_nids = alc262_dac_nids,
12468 .hp_nid = 0x03,
12469 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12470 .channel_mode = alc262_modes,
accbe498 12471 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12472 .unsol_event = alc_sku_unsol_event,
12473 .setup = alc262_hp_wildwest_setup,
12474 .init_hook = alc_inithook,
f12ab1e0 12475 },
66d2a9d6
KY
12476 [ALC262_HP_TC_T5735] = {
12477 .mixers = { alc262_hp_t5735_mixer },
12478 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12479 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12480 .dac_nids = alc262_dac_nids,
12481 .hp_nid = 0x03,
12482 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12483 .channel_mode = alc262_modes,
12484 .input_mux = &alc262_capture_source,
dc99be47 12485 .unsol_event = alc_sku_unsol_event,
4f5d1706 12486 .setup = alc262_hp_t5735_setup,
dc99be47 12487 .init_hook = alc_inithook,
8c427226
KY
12488 },
12489 [ALC262_HP_RP5700] = {
12490 .mixers = { alc262_hp_rp5700_mixer },
12491 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12492 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12493 .dac_nids = alc262_dac_nids,
12494 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12495 .channel_mode = alc262_modes,
12496 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12497 },
304dcaac
TI
12498 [ALC262_BENQ_ED8] = {
12499 .mixers = { alc262_base_mixer },
12500 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12501 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12502 .dac_nids = alc262_dac_nids,
12503 .hp_nid = 0x03,
12504 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12505 .channel_mode = alc262_modes,
12506 .input_mux = &alc262_capture_source,
f12ab1e0 12507 },
272a527c
KY
12508 [ALC262_SONY_ASSAMD] = {
12509 .mixers = { alc262_sony_mixer },
12510 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12511 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12512 .dac_nids = alc262_dac_nids,
12513 .hp_nid = 0x02,
12514 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12515 .channel_mode = alc262_modes,
12516 .input_mux = &alc262_capture_source,
e9427969 12517 .unsol_event = alc_sku_unsol_event,
4f5d1706 12518 .setup = alc262_hippo_setup,
e9427969 12519 .init_hook = alc_inithook,
83c34218
KY
12520 },
12521 [ALC262_BENQ_T31] = {
12522 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12523 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12524 alc_hp15_unsol_verbs },
83c34218
KY
12525 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12526 .dac_nids = alc262_dac_nids,
12527 .hp_nid = 0x03,
12528 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12529 .channel_mode = alc262_modes,
12530 .input_mux = &alc262_capture_source,
e9427969 12531 .unsol_event = alc_sku_unsol_event,
4f5d1706 12532 .setup = alc262_hippo_setup,
e9427969 12533 .init_hook = alc_inithook,
ea1fb29a 12534 },
f651b50b 12535 [ALC262_ULTRA] = {
f9e336f6
TI
12536 .mixers = { alc262_ultra_mixer },
12537 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12538 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12539 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12540 .dac_nids = alc262_dac_nids,
f651b50b
TD
12541 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12542 .channel_mode = alc262_modes,
12543 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12544 .adc_nids = alc262_adc_nids, /* ADC0 */
12545 .capsrc_nids = alc262_capsrc_nids,
12546 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12547 .unsol_event = alc262_ultra_unsol_event,
12548 .init_hook = alc262_ultra_automute,
12549 },
0e31daf7
J
12550 [ALC262_LENOVO_3000] = {
12551 .mixers = { alc262_lenovo_3000_mixer },
12552 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12553 alc262_lenovo_3000_unsol_verbs,
12554 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12555 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12556 .dac_nids = alc262_dac_nids,
12557 .hp_nid = 0x03,
12558 .dig_out_nid = ALC262_DIGOUT_NID,
12559 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12560 .channel_mode = alc262_modes,
12561 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12562 .unsol_event = alc_sku_unsol_event,
12563 .setup = alc262_lenovo_3000_setup,
12564 .init_hook = alc_inithook,
0e31daf7 12565 },
e8f9ae2a
PT
12566 [ALC262_NEC] = {
12567 .mixers = { alc262_nec_mixer },
12568 .init_verbs = { alc262_nec_verbs },
12569 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12570 .dac_nids = alc262_dac_nids,
12571 .hp_nid = 0x03,
12572 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12573 .channel_mode = alc262_modes,
12574 .input_mux = &alc262_capture_source,
12575 },
4e555fe5
KY
12576 [ALC262_TOSHIBA_S06] = {
12577 .mixers = { alc262_toshiba_s06_mixer },
12578 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12579 alc262_eapd_verbs },
12580 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12581 .capsrc_nids = alc262_dmic_capsrc_nids,
12582 .dac_nids = alc262_dac_nids,
12583 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12584 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12585 .dig_out_nid = ALC262_DIGOUT_NID,
12586 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12587 .channel_mode = alc262_modes,
4f5d1706
TI
12588 .unsol_event = alc_sku_unsol_event,
12589 .setup = alc262_toshiba_s06_setup,
12590 .init_hook = alc_inithook,
4e555fe5 12591 },
9f99a638
HM
12592 [ALC262_TOSHIBA_RX1] = {
12593 .mixers = { alc262_toshiba_rx1_mixer },
12594 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12595 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12596 .dac_nids = alc262_dac_nids,
12597 .hp_nid = 0x03,
12598 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12599 .channel_mode = alc262_modes,
12600 .input_mux = &alc262_capture_source,
e9427969 12601 .unsol_event = alc_sku_unsol_event,
4f5d1706 12602 .setup = alc262_hippo_setup,
e9427969 12603 .init_hook = alc_inithook,
9f99a638 12604 },
ba340e82
TV
12605 [ALC262_TYAN] = {
12606 .mixers = { alc262_tyan_mixer },
12607 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12608 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12609 .dac_nids = alc262_dac_nids,
12610 .hp_nid = 0x02,
12611 .dig_out_nid = ALC262_DIGOUT_NID,
12612 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12613 .channel_mode = alc262_modes,
12614 .input_mux = &alc262_capture_source,
d922b51d 12615 .unsol_event = alc_sku_unsol_event,
4f5d1706 12616 .setup = alc262_tyan_setup,
d922b51d 12617 .init_hook = alc_hp_automute,
ba340e82 12618 },
df694daa
KY
12619};
12620
12621static int patch_alc262(struct hda_codec *codec)
12622{
12623 struct alc_spec *spec;
12624 int board_config;
12625 int err;
12626
dc041e0b 12627 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12628 if (spec == NULL)
12629 return -ENOMEM;
12630
12631 codec->spec = spec;
1f0f4b80
TI
12632
12633 spec->mixer_nid = 0x0b;
12634
df694daa 12635#if 0
f12ab1e0
TI
12636 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12637 * under-run
12638 */
df694daa
KY
12639 {
12640 int tmp;
12641 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12642 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12643 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12644 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12645 }
12646#endif
da00c244 12647 alc_auto_parse_customize_define(codec);
df694daa 12648
2c3bf9ab
TI
12649 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12650
f5fcc13c
TI
12651 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12652 alc262_models,
12653 alc262_cfg_tbl);
cd7509a4 12654
f5fcc13c 12655 if (board_config < 0) {
9a11f1aa
TI
12656 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12657 codec->chip_name);
df694daa
KY
12658 board_config = ALC262_AUTO;
12659 }
12660
b5bfbc67
TI
12661 if (board_config == ALC262_AUTO) {
12662 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12663 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12664 }
18675e42 12665
df694daa
KY
12666 if (board_config == ALC262_AUTO) {
12667 /* automatic parse from the BIOS config */
12668 err = alc262_parse_auto_config(codec);
12669 if (err < 0) {
12670 alc_free(codec);
12671 return err;
f12ab1e0 12672 } else if (!err) {
9c7f852e
TI
12673 printk(KERN_INFO
12674 "hda_codec: Cannot set up configuration "
12675 "from BIOS. Using base mode...\n");
df694daa
KY
12676 board_config = ALC262_BASIC;
12677 }
12678 }
12679
dc1eae25 12680 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12681 err = snd_hda_attach_beep_device(codec, 0x1);
12682 if (err < 0) {
12683 alc_free(codec);
12684 return err;
12685 }
680cd536
KK
12686 }
12687
df694daa 12688 if (board_config != ALC262_AUTO)
e9c364c0 12689 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12690
df694daa
KY
12691 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12692 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12693
df694daa
KY
12694 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12695 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12696
f12ab1e0 12697 if (!spec->adc_nids && spec->input_mux) {
d6cc9fab
TI
12698 alc_auto_fill_adc_caps(codec);
12699 alc_remove_invalid_adc_nids(codec);
df694daa 12700 }
e64f14f4 12701 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 12702 set_capture_mixer(codec);
dc1eae25 12703 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 12704 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 12705
b5bfbc67 12706 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 12707
2134ea4f
TI
12708 spec->vmaster_nid = 0x0c;
12709
df694daa
KY
12710 codec->patch_ops = alc_patch_ops;
12711 if (board_config == ALC262_AUTO)
ae6b813a 12712 spec->init_hook = alc262_auto_init;
1c716153 12713 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
12714
12715 alc_init_jacks(codec);
cb53c626
TI
12716#ifdef CONFIG_SND_HDA_POWER_SAVE
12717 if (!spec->loopback.amplist)
12718 spec->loopback.amplist = alc262_loopbacks;
12719#endif
ea1fb29a 12720
df694daa
KY
12721 return 0;
12722}
12723
a361d84b
KY
12724/*
12725 * ALC268 channel source setting (2 channel)
12726 */
12727#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12728#define alc268_modes alc260_modes
ea1fb29a 12729
4c6d72d1 12730static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
12731 /* front, hp */
12732 0x02, 0x03
12733};
12734
4c6d72d1 12735static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
12736 /* ADC0-1 */
12737 0x08, 0x07
12738};
12739
4c6d72d1 12740static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
12741 /* ADC0 */
12742 0x08
12743};
12744
4c6d72d1 12745static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 12746
a9111321 12747static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
12748 /* output mixer control */
12749 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12750 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12751 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
12753 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12754 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12755 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
12756 { }
12757};
12758
a9111321 12759static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
12760 /* output mixer control */
12761 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12762 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12763 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
12764 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12765 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12766 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
12767 { }
12768};
12769
aef9d318 12770/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 12771static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
12772 .ops = &snd_hda_bind_sw,
12773 .values = {
12774 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12775 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12776 0
12777 },
12778};
12779
a9111321 12780static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
12781 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12782 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12783 { }
12784};
12785
a9111321 12786static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
12787 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12788 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12789 { }
12790};
12791
d273809e 12792/* Toshiba specific */
a9111321 12793static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
12794 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12795 { } /* end */
12796};
12797
12798/* Acer specific */
889c4395 12799/* bind volumes of both NID 0x02 and 0x03 */
a9111321 12800static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
12801 .ops = &snd_hda_bind_vol,
12802 .values = {
12803 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12804 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12805 0
12806 },
12807};
12808
0f0f391c 12809static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
12810{
12811 struct alc_spec *spec = codec->spec;
889c4395 12812
0f0f391c
TI
12813 spec->autocfg.hp_pins[0] = 0x14;
12814 spec->autocfg.speaker_pins[0] = 0x15;
12815 spec->automute = 1;
12816 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
12817}
12818
0f0f391c
TI
12819#define alc268_acer_master_sw_get alc262_hp_master_sw_get
12820#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 12821
a9111321 12822static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
12823 /* output mixer control */
12824 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12825 {
12826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12827 .name = "Master Playback Switch",
0f0f391c
TI
12828 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12829 .info = snd_ctl_boolean_mono_info,
12830 .get = alc268_acer_master_sw_get,
8ef355da 12831 .put = alc268_acer_master_sw_put,
8ef355da
KY
12832 },
12833 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12834 { }
12835};
12836
a9111321 12837static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
12838 /* output mixer control */
12839 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12840 {
12841 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12842 .name = "Master Playback Switch",
0f0f391c
TI
12843 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12844 .info = snd_ctl_boolean_mono_info,
12845 .get = alc268_acer_master_sw_get,
d273809e 12846 .put = alc268_acer_master_sw_put,
d273809e 12847 },
5f99f86a
DH
12848 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12849 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12850 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
12851 { }
12852};
12853
a9111321 12854static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
12855 /* output mixer control */
12856 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12857 {
12858 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12859 .name = "Master Playback Switch",
0f0f391c
TI
12860 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12861 .info = snd_ctl_boolean_mono_info,
12862 .get = alc268_acer_master_sw_get,
c238b4f4 12863 .put = alc268_acer_master_sw_put,
c238b4f4 12864 },
5f99f86a
DH
12865 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12866 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
12867 { }
12868};
12869
a9111321 12870static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
12871 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12873 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12874 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12875 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12876 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12877 { }
12878};
12879
a9111321 12880static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
12881 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12882 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
12883 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
12885 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12886 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
12887 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12888 { }
12889};
12890
12891/* unsolicited event for HP jack sensing */
4f5d1706 12892#define alc268_toshiba_setup alc262_hippo_setup
d273809e 12893
4f5d1706
TI
12894static void alc268_acer_lc_setup(struct hda_codec *codec)
12895{
12896 struct alc_spec *spec = codec->spec;
3b8510ce
TI
12897 spec->autocfg.hp_pins[0] = 0x15;
12898 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce 12899 spec->automute = 1;
54463a66 12900 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
12901 spec->ext_mic.pin = 0x18;
12902 spec->ext_mic.mux_idx = 0;
12903 spec->int_mic.pin = 0x12;
12904 spec->int_mic.mux_idx = 6;
12905 spec->auto_mic = 1;
8ef355da
KY
12906}
12907
a9111321 12908static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
12909 /* output mixer control */
12910 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12911 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12912 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12913 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
12914 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12915 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
12916 { }
12917};
12918
a9111321 12919static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
12920 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12921 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12922 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 12923 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
12924 { }
12925};
12926
12927/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 12928static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 12929{
a9fd4f3f 12930 struct alc_spec *spec = codec->spec;
3866f0b0 12931
a9fd4f3f
TI
12932 spec->autocfg.hp_pins[0] = 0x15;
12933 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12934 spec->ext_mic.pin = 0x18;
12935 spec->ext_mic.mux_idx = 0;
12936 spec->int_mic.pin = 0x19;
12937 spec->int_mic.mux_idx = 1;
12938 spec->auto_mic = 1;
d922b51d
TI
12939 spec->automute = 1;
12940 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
12941}
12942
a9111321 12943static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
12944 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12945 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12946 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12948 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12949 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
12950 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12951 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
12952 { }
12953};
12954
a9111321 12955static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
12956 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12957 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12958 { }
12959};
12960
4f5d1706 12961static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 12962{
a9fd4f3f 12963 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
12964 spec->autocfg.hp_pins[0] = 0x15;
12965 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
12966 spec->ext_mic.pin = 0x18;
12967 spec->ext_mic.mux_idx = 0;
12968 spec->int_mic.pin = 0x19;
12969 spec->int_mic.mux_idx = 1;
12970 spec->auto_mic = 1;
d922b51d
TI
12971 spec->automute = 1;
12972 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
12973}
12974
a361d84b
KY
12975/*
12976 * generic initialization of ADC, input mixers and output mixers
12977 */
a9111321 12978static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
12979 /* Unmute DAC0-1 and set vol = 0 */
12980 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 12981 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
12982
12983 /*
12984 * Set up output mixers (0x0c - 0x0e)
12985 */
12986 /* set vol=0 to output mixers */
12987 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
12988 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12989
12990 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12991 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12992
12993 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12995 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12996 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12997 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12998 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12999 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13000 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13001
13002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13003 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13004 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13005 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13006 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13007
13008 /* set PCBEEP vol = 0, mute connections */
13009 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13011 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13012
a9b3aa8a 13013 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13014
a9b3aa8a
JZ
13015 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13016 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13017 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13018 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13019
a361d84b
KY
13020 { }
13021};
13022
1f0f4b80
TI
13023/* only for model=test */
13024#ifdef CONFIG_SND_DEBUG
a361d84b
KY
13025/*
13026 * generic initialization of ADC, input mixers and output mixers
13027 */
a9111321 13028static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13029 /* set output DAC */
4cfb91c6
TI
13030 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13031 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13032
13033 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13034 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13035 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13036 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13037 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13038
a361d84b 13039 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13040 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13041 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13042
13043 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13044 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1f0f4b80
TI
13045 { }
13046};
13047#endif /* CONFIG_SND_DEBUG */
a361d84b 13048
1f0f4b80
TI
13049/* set PCBEEP vol = 0, mute connections */
13050static const struct hda_verb alc268_beep_init_verbs[] = {
aef9d318
TI
13051 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13052 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13053 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13054 { }
13055};
13056
a9111321 13057static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13058 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13059 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13060 { } /* end */
13061};
13062
a9111321 13063static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13064 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13065 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13066 _DEFINE_CAPSRC(1),
a361d84b
KY
13067 { } /* end */
13068};
13069
a9111321 13070static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13071 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13072 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13073 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13074 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13075 _DEFINE_CAPSRC(2),
a361d84b
KY
13076 { } /* end */
13077};
13078
a9111321 13079static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13080 .num_items = 4,
13081 .items = {
13082 { "Mic", 0x0 },
13083 { "Front Mic", 0x1 },
13084 { "Line", 0x2 },
13085 { "CD", 0x3 },
13086 },
13087};
13088
a9111321 13089static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13090 .num_items = 3,
13091 .items = {
13092 { "Mic", 0x0 },
13093 { "Internal Mic", 0x1 },
13094 { "Line", 0x2 },
13095 },
13096};
13097
a9111321 13098static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13099 .num_items = 3,
13100 .items = {
13101 { "Mic", 0x0 },
13102 { "Internal Mic", 0x6 },
13103 { "Line", 0x2 },
13104 },
13105};
13106
86c53bd2 13107#ifdef CONFIG_SND_DEBUG
a9111321 13108static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13109 /* Volume widgets */
13110 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13111 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13112 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13113 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13114 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13115 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13116 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13117 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13118 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13119 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13120 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13121 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13122 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13123 /* The below appears problematic on some hardwares */
13124 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13125 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13126 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13127 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13128 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13129
13130 /* Modes for retasking pin widgets */
13131 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13132 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13133 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13134 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13135
13136 /* Controls for GPIO pins, assuming they are configured as outputs */
13137 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13138 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13139 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13140 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13141
13142 /* Switches to allow the digital SPDIF output pin to be enabled.
13143 * The ALC268 does not have an SPDIF input.
13144 */
13145 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13146
13147 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13148 * this output to turn on an external amplifier.
13149 */
13150 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13151 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13152
13153 { } /* end */
13154};
13155#endif
13156
a361d84b
KY
13157/* create input playback/capture controls for the given pin */
13158static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13159 const char *ctlname, int idx)
13160{
3f3b7c1a 13161 hda_nid_t dac;
a361d84b
KY
13162 int err;
13163
3f3b7c1a
TI
13164 switch (nid) {
13165 case 0x14:
13166 case 0x16:
13167 dac = 0x02;
13168 break;
13169 case 0x15:
b08b1637
TI
13170 case 0x1a: /* ALC259/269 only */
13171 case 0x1b: /* ALC259/269 only */
531d8791 13172 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13173 dac = 0x03;
13174 break;
13175 default:
c7a9434d
TI
13176 snd_printd(KERN_WARNING "hda_codec: "
13177 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13178 return 0;
13179 }
13180 if (spec->multiout.dac_nids[0] != dac &&
13181 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13182 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13183 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13184 HDA_OUTPUT));
13185 if (err < 0)
13186 return err;
dda14410 13187 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13188 }
13189
3f3b7c1a 13190 if (nid != 0x16)
0afe5f89 13191 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13192 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13193 else /* mono */
0afe5f89 13194 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13195 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13196 if (err < 0)
13197 return err;
13198 return 0;
13199}
13200
13201/* add playback controls from the parsed DAC table */
13202static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13203 const struct auto_pin_cfg *cfg)
13204{
13205 hda_nid_t nid;
13206 int err;
13207
a361d84b 13208 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13209
13210 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13211 if (nid) {
13212 const char *name;
2e925dde
TI
13213 int index;
13214 name = alc_get_line_out_pfx(spec, 0, true, &index);
3f3b7c1a
TI
13215 err = alc268_new_analog_output(spec, nid, name, 0);
13216 if (err < 0)
13217 return err;
13218 }
a361d84b
KY
13219
13220 nid = cfg->speaker_pins[0];
13221 if (nid == 0x1d) {
0afe5f89 13222 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13223 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13224 if (err < 0)
13225 return err;
7bfb9c03 13226 } else if (nid) {
3f3b7c1a
TI
13227 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13228 if (err < 0)
13229 return err;
a361d84b
KY
13230 }
13231 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13232 if (nid) {
13233 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13234 if (err < 0)
13235 return err;
13236 }
a361d84b
KY
13237
13238 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13239 if (nid == 0x16) {
0afe5f89 13240 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13241 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13242 if (err < 0)
13243 return err;
13244 }
ea1fb29a 13245 return 0;
a361d84b
KY
13246}
13247
e9af4f36
TI
13248static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13249 hda_nid_t nid, int pin_type)
13250{
13251 int idx;
13252
13253 alc_set_pin_output(codec, nid, pin_type);
4f574b7b
TI
13254 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
13255 return;
e9af4f36
TI
13256 if (nid == 0x14 || nid == 0x16)
13257 idx = 0;
13258 else
13259 idx = 1;
13260 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13261}
13262
1f0f4b80
TI
13263static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13264{
13265 if (!nid)
13266 return;
13267 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7ec9c6cc 13268 AMP_OUT_ZERO);
1f0f4b80
TI
13269}
13270
e9af4f36
TI
13271static void alc268_auto_init_multi_out(struct hda_codec *codec)
13272{
13273 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13274 int i;
13275
13276 for (i = 0; i < spec->autocfg.line_outs; i++) {
13277 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13278 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13279 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13280 }
1f0f4b80
TI
13281 /* mute DACs */
13282 for (i = 0; i < spec->multiout.num_dacs; i++)
13283 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9af4f36
TI
13284}
13285
13286static void alc268_auto_init_hp_out(struct hda_codec *codec)
13287{
13288 struct alc_spec *spec = codec->spec;
13289 hda_nid_t pin;
e1ca7b4e 13290 int i;
e9af4f36 13291
e1ca7b4e
TI
13292 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13293 pin = spec->autocfg.hp_pins[i];
e9af4f36 13294 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13295 }
13296 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13297 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13298 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13299 }
13300 if (spec->autocfg.mono_out_pin)
13301 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13302 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1f0f4b80
TI
13303 /* mute DACs */
13304 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13305 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13306 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9af4f36
TI
13307}
13308
a361d84b
KY
13309static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13310{
13311 struct alc_spec *spec = codec->spec;
13312 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13313 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13314 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13315 unsigned int dac_vol1, dac_vol2;
13316
e9af4f36 13317 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13318 snd_hda_codec_write(codec, speaker_nid, 0,
13319 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13320 /* mute mixer inputs from 0x1d */
a361d84b
KY
13321 snd_hda_codec_write(codec, 0x0f, 0,
13322 AC_VERB_SET_AMP_GAIN_MUTE,
13323 AMP_IN_UNMUTE(1));
13324 snd_hda_codec_write(codec, 0x10, 0,
13325 AC_VERB_SET_AMP_GAIN_MUTE,
13326 AMP_IN_UNMUTE(1));
13327 } else {
e9af4f36 13328 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13329 snd_hda_codec_write(codec, 0x0f, 0,
13330 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13331 snd_hda_codec_write(codec, 0x10, 0,
13332 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13333 }
13334
13335 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13336 if (line_nid == 0x14)
a361d84b
KY
13337 dac_vol2 = AMP_OUT_ZERO;
13338 else if (line_nid == 0x15)
13339 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13340 if (hp_nid == 0x14)
a361d84b
KY
13341 dac_vol2 = AMP_OUT_ZERO;
13342 else if (hp_nid == 0x15)
13343 dac_vol1 = AMP_OUT_ZERO;
13344 if (line_nid != 0x16 || hp_nid != 0x16 ||
13345 spec->autocfg.line_out_pins[1] != 0x16 ||
13346 spec->autocfg.line_out_pins[2] != 0x16)
13347 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13348
13349 snd_hda_codec_write(codec, 0x02, 0,
13350 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13351 snd_hda_codec_write(codec, 0x03, 0,
13352 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13353}
13354
def319f9 13355/* pcm configuration: identical with ALC880 */
a361d84b
KY
13356#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13357#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13358#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13359#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13360
13361/*
13362 * BIOS auto configuration
13363 */
13364static int alc268_parse_auto_config(struct hda_codec *codec)
13365{
13366 struct alc_spec *spec = codec->spec;
13367 int err;
4c6d72d1 13368 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13369
13370 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13371 alc268_ignore);
13372 if (err < 0)
13373 return err;
7e0e44d4
TI
13374 if (!spec->autocfg.line_outs) {
13375 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13376 spec->multiout.max_channels = 2;
13377 spec->no_analog = 1;
13378 goto dig_only;
13379 }
a361d84b 13380 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13381 }
a361d84b
KY
13382 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13383 if (err < 0)
13384 return err;
b7821709 13385 err = alc_auto_create_input_ctls(codec);
a361d84b
KY
13386 if (err < 0)
13387 return err;
13388
13389 spec->multiout.max_channels = 2;
13390
7e0e44d4 13391 dig_only:
a361d84b 13392 /* digital only support output */
757899ac 13393 alc_auto_parse_digital(codec);
603c4019 13394 if (spec->kctls.list)
d88897ea 13395 add_mixer(spec, spec->kctls.list);
a361d84b 13396
4f574b7b 13397 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
d88897ea 13398 add_mixer(spec, alc268_beep_mixer);
4f574b7b
TI
13399 add_verb(spec, alc268_beep_init_verbs);
13400 }
aef9d318 13401
f970de25 13402 spec->num_mux_defs = 1;
61b9b9b1 13403 spec->input_mux = &spec->private_imux[0];
a361d84b 13404
d6cc9fab
TI
13405 if (!spec->dual_adc_switch)
13406 alc_remove_invalid_adc_nids(codec);
13407
776e184e
TI
13408 err = alc_auto_add_mic_boost(codec);
13409 if (err < 0)
13410 return err;
13411
6227cdce 13412 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13413
a361d84b
KY
13414 return 1;
13415}
13416
a361d84b
KY
13417/* init callback for auto-configuration model -- overriding the default init */
13418static void alc268_auto_init(struct hda_codec *codec)
13419{
f6c7e546 13420 struct alc_spec *spec = codec->spec;
a361d84b
KY
13421 alc268_auto_init_multi_out(codec);
13422 alc268_auto_init_hp_out(codec);
13423 alc268_auto_init_mono_speaker_out(codec);
0a7f5320 13424 alc_auto_init_analog_input(codec);
f970de25 13425 alc_auto_init_input_src(codec);
757899ac 13426 alc_auto_init_digital(codec);
f6c7e546 13427 if (spec->unsol_event)
7fb0d78f 13428 alc_inithook(codec);
a361d84b
KY
13429}
13430
13431/*
13432 * configuration and preset
13433 */
ea734963 13434static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13435 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13436 [ALC268_3ST] = "3stack",
983f8ae4 13437 [ALC268_TOSHIBA] = "toshiba",
d273809e 13438 [ALC268_ACER] = "acer",
c238b4f4 13439 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13440 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13441 [ALC268_DELL] = "dell",
f12462c5 13442 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13443#ifdef CONFIG_SND_DEBUG
13444 [ALC268_TEST] = "test",
13445#endif
a361d84b
KY
13446 [ALC268_AUTO] = "auto",
13447};
13448
a9111321 13449static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13450 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13451 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13452 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13453 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13454 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13455 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13456 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13457 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
0a1896b2 13458 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
a1bf8088
DC
13459 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13460 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13461 /* almost compatible with toshiba but with optional digital outs;
13462 * auto-probing seems working fine
13463 */
8871e5b9 13464 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13465 ALC268_AUTO),
a361d84b 13466 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13467 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13468 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
eb5a6621 13469 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13470 {}
13471};
13472
3abf2f36 13473/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13474static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13475 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13476 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13477 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13478 ALC268_TOSHIBA),
13479 {}
13480};
13481
a9111321 13482static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13483 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13484 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13485 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13486 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13487 alc267_quanta_il1_verbs },
13488 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13489 .dac_nids = alc268_dac_nids,
13490 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13491 .adc_nids = alc268_adc_nids_alt,
13492 .hp_nid = 0x03,
13493 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13494 .channel_mode = alc268_modes,
4f5d1706
TI
13495 .unsol_event = alc_sku_unsol_event,
13496 .setup = alc267_quanta_il1_setup,
13497 .init_hook = alc_inithook,
eb5a6621 13498 },
a361d84b 13499 [ALC268_3ST] = {
aef9d318
TI
13500 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13501 alc268_beep_mixer },
a361d84b
KY
13502 .init_verbs = { alc268_base_init_verbs },
13503 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13504 .dac_nids = alc268_dac_nids,
13505 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13506 .adc_nids = alc268_adc_nids_alt,
e1406348 13507 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13508 .hp_nid = 0x03,
13509 .dig_out_nid = ALC268_DIGOUT_NID,
13510 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13511 .channel_mode = alc268_modes,
13512 .input_mux = &alc268_capture_source,
13513 },
d1a991a6 13514 [ALC268_TOSHIBA] = {
42171c17 13515 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13516 alc268_beep_mixer },
d273809e
TI
13517 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13518 alc268_toshiba_verbs },
d1a991a6
KY
13519 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13520 .dac_nids = alc268_dac_nids,
13521 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13522 .adc_nids = alc268_adc_nids_alt,
e1406348 13523 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13524 .hp_nid = 0x03,
13525 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13526 .channel_mode = alc268_modes,
13527 .input_mux = &alc268_capture_source,
e9427969 13528 .unsol_event = alc_sku_unsol_event,
4f5d1706 13529 .setup = alc268_toshiba_setup,
e9427969 13530 .init_hook = alc_inithook,
d273809e
TI
13531 },
13532 [ALC268_ACER] = {
432fd133 13533 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13534 alc268_beep_mixer },
d273809e
TI
13535 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13536 alc268_acer_verbs },
13537 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13538 .dac_nids = alc268_dac_nids,
13539 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13540 .adc_nids = alc268_adc_nids_alt,
e1406348 13541 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13542 .hp_nid = 0x02,
13543 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13544 .channel_mode = alc268_modes,
0ccb541c 13545 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13546 .unsol_event = alc_sku_unsol_event,
13547 .setup = alc268_acer_setup,
13548 .init_hook = alc_inithook,
d1a991a6 13549 },
c238b4f4
TI
13550 [ALC268_ACER_DMIC] = {
13551 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13552 alc268_beep_mixer },
13553 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13554 alc268_acer_verbs },
13555 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13556 .dac_nids = alc268_dac_nids,
13557 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13558 .adc_nids = alc268_adc_nids_alt,
13559 .capsrc_nids = alc268_capsrc_nids,
13560 .hp_nid = 0x02,
13561 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13562 .channel_mode = alc268_modes,
13563 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13564 .unsol_event = alc_sku_unsol_event,
13565 .setup = alc268_acer_setup,
13566 .init_hook = alc_inithook,
c238b4f4 13567 },
8ef355da
KY
13568 [ALC268_ACER_ASPIRE_ONE] = {
13569 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13570 alc268_beep_mixer,
fdbc6626 13571 alc268_capture_nosrc_mixer },
8ef355da
KY
13572 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13573 alc268_acer_aspire_one_verbs },
13574 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13575 .dac_nids = alc268_dac_nids,
13576 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13577 .adc_nids = alc268_adc_nids_alt,
13578 .capsrc_nids = alc268_capsrc_nids,
13579 .hp_nid = 0x03,
13580 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13581 .channel_mode = alc268_modes,
3b8510ce 13582 .unsol_event = alc_sku_unsol_event,
4f5d1706 13583 .setup = alc268_acer_lc_setup,
3b8510ce 13584 .init_hook = alc_inithook,
8ef355da 13585 },
3866f0b0 13586 [ALC268_DELL] = {
fdbc6626
TI
13587 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13588 alc268_capture_nosrc_mixer },
3866f0b0
TI
13589 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13590 alc268_dell_verbs },
13591 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13592 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13593 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13594 .adc_nids = alc268_adc_nids_alt,
13595 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13596 .hp_nid = 0x02,
13597 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13598 .channel_mode = alc268_modes,
a9fd4f3f 13599 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13600 .setup = alc268_dell_setup,
13601 .init_hook = alc_inithook,
3866f0b0 13602 },
f12462c5 13603 [ALC268_ZEPTO] = {
aef9d318
TI
13604 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13605 alc268_beep_mixer },
f12462c5
MT
13606 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13607 alc268_toshiba_verbs },
13608 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13609 .dac_nids = alc268_dac_nids,
13610 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13611 .adc_nids = alc268_adc_nids_alt,
e1406348 13612 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13613 .hp_nid = 0x03,
13614 .dig_out_nid = ALC268_DIGOUT_NID,
13615 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13616 .channel_mode = alc268_modes,
13617 .input_mux = &alc268_capture_source,
e9427969 13618 .unsol_event = alc_sku_unsol_event,
4f5d1706 13619 .setup = alc268_toshiba_setup,
e9427969 13620 .init_hook = alc_inithook,
f12462c5 13621 },
86c53bd2
JW
13622#ifdef CONFIG_SND_DEBUG
13623 [ALC268_TEST] = {
13624 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13625 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
1f0f4b80
TI
13626 alc268_volume_init_verbs,
13627 alc268_beep_init_verbs },
86c53bd2
JW
13628 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13629 .dac_nids = alc268_dac_nids,
13630 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13631 .adc_nids = alc268_adc_nids_alt,
e1406348 13632 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13633 .hp_nid = 0x03,
13634 .dig_out_nid = ALC268_DIGOUT_NID,
13635 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13636 .channel_mode = alc268_modes,
13637 .input_mux = &alc268_capture_source,
13638 },
13639#endif
a361d84b
KY
13640};
13641
13642static int patch_alc268(struct hda_codec *codec)
13643{
13644 struct alc_spec *spec;
13645 int board_config;
22971e3a 13646 int i, has_beep, err;
a361d84b 13647
ef86f581 13648 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13649 if (spec == NULL)
13650 return -ENOMEM;
13651
13652 codec->spec = spec;
13653
1f0f4b80
TI
13654 /* ALC268 has no aa-loopback mixer */
13655
a361d84b
KY
13656 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13657 alc268_models,
13658 alc268_cfg_tbl);
13659
3abf2f36
TI
13660 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13661 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13662 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13663
a361d84b 13664 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
13665 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13666 codec->chip_name);
a361d84b
KY
13667 board_config = ALC268_AUTO;
13668 }
13669
13670 if (board_config == ALC268_AUTO) {
13671 /* automatic parse from the BIOS config */
13672 err = alc268_parse_auto_config(codec);
13673 if (err < 0) {
13674 alc_free(codec);
13675 return err;
13676 } else if (!err) {
13677 printk(KERN_INFO
13678 "hda_codec: Cannot set up configuration "
13679 "from BIOS. Using base mode...\n");
13680 board_config = ALC268_3ST;
13681 }
13682 }
13683
13684 if (board_config != ALC268_AUTO)
e9c364c0 13685 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 13686
a361d84b
KY
13687 spec->stream_analog_playback = &alc268_pcm_analog_playback;
13688 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 13689 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 13690
a361d84b
KY
13691 spec->stream_digital_playback = &alc268_pcm_digital_playback;
13692
22971e3a
TI
13693 has_beep = 0;
13694 for (i = 0; i < spec->num_mixers; i++) {
13695 if (spec->mixers[i] == alc268_beep_mixer) {
13696 has_beep = 1;
13697 break;
13698 }
13699 }
13700
13701 if (has_beep) {
13702 err = snd_hda_attach_beep_device(codec, 0x1);
13703 if (err < 0) {
13704 alc_free(codec);
13705 return err;
13706 }
13707 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
13708 /* override the amp caps for beep generator */
13709 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
13710 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
13711 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
13712 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
13713 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 13714 }
aef9d318 13715
7e0e44d4 13716 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
d6cc9fab
TI
13717 alc_auto_fill_adc_caps(codec);
13718 alc_remove_invalid_adc_nids(codec);
a361d84b 13719 }
2134ea4f 13720
d6cc9fab
TI
13721 if (!spec->cap_mixer && !spec->no_analog)
13722 set_capture_mixer(codec);
13723
2134ea4f
TI
13724 spec->vmaster_nid = 0x02;
13725
a361d84b
KY
13726 codec->patch_ops = alc_patch_ops;
13727 if (board_config == ALC268_AUTO)
13728 spec->init_hook = alc268_auto_init;
1c716153 13729 spec->shutup = alc_eapd_shutup;
ea1fb29a 13730
bf1b0225
KY
13731 alc_init_jacks(codec);
13732
a361d84b
KY
13733 return 0;
13734}
13735
f6a92248
KY
13736/*
13737 * ALC269 channel source setting (2 channel)
13738 */
13739#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13740
13741#define alc269_dac_nids alc260_dac_nids
13742
4c6d72d1 13743static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 13744 /* ADC1 */
f53281e6
KY
13745 0x08,
13746};
13747
4c6d72d1 13748static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
13749 0x23,
13750};
13751
4c6d72d1 13752static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
13753 /* ADC1 */
13754 0x09,
13755};
13756
4c6d72d1 13757static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
13758 0x22,
13759};
13760
f6a92248
KY
13761#define alc269_modes alc260_modes
13762#define alc269_capture_source alc880_lg_lw_capture_source
13763
a9111321 13764static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
13765 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13766 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13767 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13768 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13770 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13771 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
13772 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13773 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13774 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
13775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13776 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13777 { } /* end */
13778};
13779
a9111321 13780static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
13781 /* output mixer control */
13782 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13783 {
13784 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13785 .name = "Master Playback Switch",
5e26dfd0 13786 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
13787 .info = snd_hda_mixer_amp_switch_info,
13788 .get = snd_hda_mixer_amp_switch_get,
13789 .put = alc268_acer_master_sw_put,
13790 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13791 },
13792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13793 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13794 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
13795 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13796 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13797 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
13798 { }
13799};
13800
a9111321 13801static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
13802 /* output mixer control */
13803 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13804 {
13805 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13806 .name = "Master Playback Switch",
5e26dfd0 13807 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
13808 .info = snd_hda_mixer_amp_switch_info,
13809 .get = snd_hda_mixer_amp_switch_get,
13810 .put = alc268_acer_master_sw_put,
13811 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13812 },
13813 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13814 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 13815 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
13816 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13817 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 13818 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
13819 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13820 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 13821 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
13822 { }
13823};
13824
a9111321 13825static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 13826 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 13827 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 13828 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 13829 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
13830 { } /* end */
13831};
13832
a9111321 13833static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
13834 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13835 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13836 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13837 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13838 { } /* end */
13839};
13840
a9111321 13841static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
13842 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13843 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13844 { } /* end */
13845};
13846
f53281e6 13847/* capture mixer elements */
a9111321 13848static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
13849 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13850 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
13851 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13852 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
13853 { } /* end */
13854};
13855
a9111321 13856static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
13857 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13858 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 13859 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
13860 { } /* end */
13861};
13862
a9111321 13863static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
13864 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13865 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
13866 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13867 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
13868 { } /* end */
13869};
13870
a9111321 13871static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
13872 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13873 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 13874 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
13875 { } /* end */
13876};
13877
26f5df26 13878/* FSC amilo */
84898e87 13879#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 13880
a9111321 13881static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
13882 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13883 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13884 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13885 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13887 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13888 { }
13889};
f6a92248 13890
a9111321 13891static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
13892 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13893 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13894 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13895 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13896 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13897 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13898 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13899 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13900 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13901 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13902 { }
13903};
13904
60db6b53
KY
13905/* toggle speaker-output according to the hp-jack state */
13906static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13907{
3b8510ce 13908 alc_hp_automute(codec);
f6a92248 13909
60db6b53
KY
13910 snd_hda_codec_write(codec, 0x20, 0,
13911 AC_VERB_SET_COEF_INDEX, 0x0c);
13912 snd_hda_codec_write(codec, 0x20, 0,
13913 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 13914
60db6b53
KY
13915 snd_hda_codec_write(codec, 0x20, 0,
13916 AC_VERB_SET_COEF_INDEX, 0x0c);
13917 snd_hda_codec_write(codec, 0x20, 0,
13918 AC_VERB_SET_PROC_COEF, 0x480);
13919}
f6a92248 13920
3b8510ce
TI
13921#define alc269_lifebook_speaker_automute \
13922 alc269_quanta_fl1_speaker_automute
64154835 13923
64154835
TV
13924static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13925{
13926 unsigned int present_laptop;
13927 unsigned int present_dock;
13928
864f92be
WF
13929 present_laptop = snd_hda_jack_detect(codec, 0x18);
13930 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
13931
13932 /* Laptop mic port overrides dock mic port, design decision */
13933 if (present_dock)
13934 snd_hda_codec_write(codec, 0x23, 0,
13935 AC_VERB_SET_CONNECT_SEL, 0x3);
13936 if (present_laptop)
13937 snd_hda_codec_write(codec, 0x23, 0,
13938 AC_VERB_SET_CONNECT_SEL, 0x0);
13939 if (!present_dock && !present_laptop)
13940 snd_hda_codec_write(codec, 0x23, 0,
13941 AC_VERB_SET_CONNECT_SEL, 0x1);
13942}
13943
60db6b53
KY
13944static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13945 unsigned int res)
13946{
4f5d1706
TI
13947 switch (res >> 26) {
13948 case ALC880_HP_EVENT:
60db6b53 13949 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
13950 break;
13951 case ALC880_MIC_EVENT:
13952 alc_mic_automute(codec);
13953 break;
13954 }
60db6b53 13955}
f6a92248 13956
64154835
TV
13957static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13958 unsigned int res)
13959{
13960 if ((res >> 26) == ALC880_HP_EVENT)
13961 alc269_lifebook_speaker_automute(codec);
13962 if ((res >> 26) == ALC880_MIC_EVENT)
13963 alc269_lifebook_mic_autoswitch(codec);
13964}
13965
4f5d1706
TI
13966static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13967{
13968 struct alc_spec *spec = codec->spec;
20645d70
TI
13969 spec->autocfg.hp_pins[0] = 0x15;
13970 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
13971 spec->automute_mixer_nid[0] = 0x0c;
13972 spec->automute = 1;
13973 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
13974 spec->ext_mic.pin = 0x18;
13975 spec->ext_mic.mux_idx = 0;
13976 spec->int_mic.pin = 0x19;
13977 spec->int_mic.mux_idx = 1;
13978 spec->auto_mic = 1;
13979}
13980
60db6b53
KY
13981static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13982{
13983 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 13984 alc_mic_automute(codec);
60db6b53 13985}
f6a92248 13986
3b8510ce
TI
13987static void alc269_lifebook_setup(struct hda_codec *codec)
13988{
13989 struct alc_spec *spec = codec->spec;
13990 spec->autocfg.hp_pins[0] = 0x15;
13991 spec->autocfg.hp_pins[1] = 0x1a;
13992 spec->autocfg.speaker_pins[0] = 0x14;
13993 spec->automute_mixer_nid[0] = 0x0c;
13994 spec->automute = 1;
13995 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13996}
13997
64154835
TV
13998static void alc269_lifebook_init_hook(struct hda_codec *codec)
13999{
14000 alc269_lifebook_speaker_automute(codec);
14001 alc269_lifebook_mic_autoswitch(codec);
14002}
14003
a9111321 14004static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14005 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14006 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14007 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14008 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14009 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14010 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14011 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14012 {}
14013};
14014
a9111321 14015static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14017 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14018 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14019 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14021 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14022 {}
14023};
14024
a9111321 14025static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14026 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14027 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14028 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14029 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14030 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14031 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14032 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14033 {}
14034};
14035
a9111321 14036static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14037 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14038 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14039 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14040 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14041 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14042 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14043 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14044 {}
14045};
14046
a9111321 14047static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14048 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14049 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14050 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14051 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14052 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14053 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14054 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14055 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14056 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14057 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14058 { }
14059};
14060
226b1ec8 14061static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14062{
4f5d1706 14063 struct alc_spec *spec = codec->spec;
20645d70
TI
14064 spec->autocfg.hp_pins[0] = 0x15;
14065 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14066 spec->automute_mixer_nid[0] = 0x0c;
14067 spec->automute = 1;
14068 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14069 spec->ext_mic.pin = 0x18;
14070 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14071 spec->int_mic.pin = 0x19;
14072 spec->int_mic.mux_idx = 1;
4f5d1706 14073 spec->auto_mic = 1;
f53281e6
KY
14074}
14075
226b1ec8 14076static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14077{
14078 struct alc_spec *spec = codec->spec;
20645d70
TI
14079 spec->autocfg.hp_pins[0] = 0x15;
14080 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14081 spec->automute_mixer_nid[0] = 0x0c;
14082 spec->automute = 1;
14083 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14084 spec->ext_mic.pin = 0x18;
14085 spec->ext_mic.mux_idx = 0;
14086 spec->int_mic.pin = 0x12;
226b1ec8 14087 spec->int_mic.mux_idx = 5;
84898e87
KY
14088 spec->auto_mic = 1;
14089}
14090
226b1ec8 14091static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14092{
4f5d1706 14093 struct alc_spec *spec = codec->spec;
226b1ec8 14094 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14095 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14096 spec->automute_mixer_nid[0] = 0x0c;
14097 spec->automute = 1;
14098 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14099 spec->ext_mic.pin = 0x18;
14100 spec->ext_mic.mux_idx = 0;
14101 spec->int_mic.pin = 0x19;
14102 spec->int_mic.mux_idx = 1;
14103 spec->auto_mic = 1;
f53281e6
KY
14104}
14105
226b1ec8
KY
14106static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14107{
14108 struct alc_spec *spec = codec->spec;
14109 spec->autocfg.hp_pins[0] = 0x21;
14110 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14111 spec->automute_mixer_nid[0] = 0x0c;
14112 spec->automute = 1;
14113 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14114 spec->ext_mic.pin = 0x18;
14115 spec->ext_mic.mux_idx = 0;
14116 spec->int_mic.pin = 0x12;
14117 spec->int_mic.mux_idx = 6;
14118 spec->auto_mic = 1;
14119}
14120
60db6b53
KY
14121/*
14122 * generic initialization of ADC, input mixers and output mixers
14123 */
a9111321 14124static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14125 /*
14126 * Unmute ADC0 and set the default input to mic-in
14127 */
84898e87 14128 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14129
14130 /*
84898e87 14131 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14132 */
14133 /* set vol=0 to output mixers */
14134 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14135 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14136
14137 /* set up input amps for analog loopback */
14138 /* Amp Indices: DAC = 0, mixer = 1 */
14139 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14140 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14141 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14142 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14143 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14144 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14145
14146 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14147 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14148 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14149 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14150 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14151 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14153
14154 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14155 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14156
84898e87
KY
14157 /* FIXME: use Mux-type input source selection */
14158 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14159 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14160 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14161
84898e87
KY
14162 /* set EAPD */
14163 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14164 { }
14165};
14166
a9111321 14167static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14168 /*
14169 * Unmute ADC0 and set the default input to mic-in
14170 */
14171 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14172
14173 /*
14174 * Set up output mixers (0x02 - 0x03)
14175 */
14176 /* set vol=0 to output mixers */
14177 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14178 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14179
14180 /* set up input amps for analog loopback */
14181 /* Amp Indices: DAC = 0, mixer = 1 */
14182 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14183 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14184 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14185 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14186 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14187 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14188
14189 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14190 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14191 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14192 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14193 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14194 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14195 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14196
14197 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14198 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14199
14200 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14201 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14202 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14203 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14204
14205 /* set EAPD */
14206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14207 { }
14208};
14209
9d0b71b1
TI
14210#define alc269_auto_create_multi_out_ctls \
14211 alc268_auto_create_multi_out_ctls
f6a92248
KY
14212
14213#ifdef CONFIG_SND_HDA_POWER_SAVE
14214#define alc269_loopbacks alc880_loopbacks
14215#endif
14216
def319f9 14217/* pcm configuration: identical with ALC880 */
f6a92248
KY
14218#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14219#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14220#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14221#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14222
a9111321 14223static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14224 .substreams = 1,
14225 .channels_min = 2,
14226 .channels_max = 8,
14227 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14228 /* NID is set in alc_build_pcms */
14229 .ops = {
14230 .open = alc880_playback_pcm_open,
14231 .prepare = alc880_playback_pcm_prepare,
14232 .cleanup = alc880_playback_pcm_cleanup
14233 },
14234};
14235
a9111321 14236static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14237 .substreams = 1,
14238 .channels_min = 2,
14239 .channels_max = 2,
14240 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14241 /* NID is set in alc_build_pcms */
14242};
14243
ad35879a
TI
14244#ifdef CONFIG_SND_HDA_POWER_SAVE
14245static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14246{
14247 switch (codec->subsystem_id) {
14248 case 0x103c1586:
14249 return 1;
14250 }
14251 return 0;
14252}
14253
14254static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14255{
14256 /* update mute-LED according to the speaker mute state */
14257 if (nid == 0x01 || nid == 0x14) {
14258 int pinval;
14259 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14260 HDA_AMP_MUTE)
14261 pinval = 0x24;
14262 else
14263 pinval = 0x20;
14264 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14265 snd_hda_codec_update_cache(codec, 0x19, 0,
14266 AC_VERB_SET_PIN_WIDGET_CONTROL,
14267 pinval);
ad35879a
TI
14268 }
14269 return alc_check_power_status(codec, nid);
14270}
14271#endif /* CONFIG_SND_HDA_POWER_SAVE */
14272
840b64c0
TI
14273static int alc275_setup_dual_adc(struct hda_codec *codec)
14274{
14275 struct alc_spec *spec = codec->spec;
14276
14277 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14278 return 0;
14279 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14280 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14281 if (spec->ext_mic.pin <= 0x12) {
14282 spec->private_adc_nids[0] = 0x08;
14283 spec->private_adc_nids[1] = 0x11;
14284 spec->private_capsrc_nids[0] = 0x23;
14285 spec->private_capsrc_nids[1] = 0x22;
14286 } else {
14287 spec->private_adc_nids[0] = 0x11;
14288 spec->private_adc_nids[1] = 0x08;
14289 spec->private_capsrc_nids[0] = 0x22;
14290 spec->private_capsrc_nids[1] = 0x23;
14291 }
14292 spec->adc_nids = spec->private_adc_nids;
14293 spec->capsrc_nids = spec->private_capsrc_nids;
14294 spec->num_adc_nids = 2;
14295 spec->dual_adc_switch = 1;
14296 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14297 spec->adc_nids[0], spec->adc_nids[1]);
14298 return 1;
14299 }
14300 return 0;
14301}
14302
d433a678
TI
14303/* different alc269-variants */
14304enum {
b6878571 14305 ALC269_TYPE_ALC269VA,
48c88e82 14306 ALC269_TYPE_ALC269VB,
b6878571 14307 ALC269_TYPE_ALC269VC,
d433a678
TI
14308};
14309
f6a92248
KY
14310/*
14311 * BIOS auto configuration
14312 */
14313static int alc269_parse_auto_config(struct hda_codec *codec)
14314{
14315 struct alc_spec *spec = codec->spec;
cfb9fb55 14316 int err;
4c6d72d1 14317 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14318
14319 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14320 alc269_ignore);
14321 if (err < 0)
14322 return err;
14323
14324 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14325 if (err < 0)
14326 return err;
b7821709 14327 err = alc_auto_create_input_ctls(codec);
f6a92248
KY
14328 if (err < 0)
14329 return err;
14330
14331 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14332
757899ac 14333 alc_auto_parse_digital(codec);
f6a92248 14334
603c4019 14335 if (spec->kctls.list)
d88897ea 14336 add_mixer(spec, spec->kctls.list);
f6a92248 14337
b6878571 14338 if (spec->codec_variant != ALC269_TYPE_ALC269VA)
6227cdce 14339 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
1f0f4b80 14340 else
6227cdce 14341 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87 14342
f6a92248 14343 spec->num_mux_defs = 1;
61b9b9b1 14344 spec->input_mux = &spec->private_imux[0];
840b64c0 14345
d6cc9fab
TI
14346 alc275_setup_dual_adc(codec);
14347 if (!spec->dual_adc_switch)
14348 alc_remove_invalid_adc_nids(codec);
6694635d 14349
f6a92248
KY
14350 err = alc_auto_add_mic_boost(codec);
14351 if (err < 0)
14352 return err;
14353
7e0e44d4 14354 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14355 set_capture_mixer(codec);
f53281e6 14356
f6a92248
KY
14357 return 1;
14358}
14359
e9af4f36
TI
14360#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14361#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248
KY
14362
14363
14364/* init callback for auto-configuration model -- overriding the default init */
14365static void alc269_auto_init(struct hda_codec *codec)
14366{
f6c7e546 14367 struct alc_spec *spec = codec->spec;
f6a92248
KY
14368 alc269_auto_init_multi_out(codec);
14369 alc269_auto_init_hp_out(codec);
0a7f5320 14370 alc_auto_init_analog_input(codec);
f970de25 14371 alc_auto_init_input_src(codec);
757899ac 14372 alc_auto_init_digital(codec);
f6c7e546 14373 if (spec->unsol_event)
7fb0d78f 14374 alc_inithook(codec);
f6a92248
KY
14375}
14376
0ec33d1f
TI
14377static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14378{
14379 int val = alc_read_coef_idx(codec, 0x04);
14380 if (power_up)
14381 val |= 1 << 11;
14382 else
14383 val &= ~(1 << 11);
14384 alc_write_coef_idx(codec, 0x04, val);
14385}
14386
5402e4cb 14387static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14388{
0ec33d1f
TI
14389 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14390 alc269_toggle_power_output(codec, 0);
977ddd6b 14391 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14392 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14393 msleep(150);
14394 }
977ddd6b 14395}
0ec33d1f 14396
5402e4cb 14397#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14398static int alc269_resume(struct hda_codec *codec)
14399{
977ddd6b 14400 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14401 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14402 msleep(150);
14403 }
14404
14405 codec->patch_ops.init(codec);
14406
14407 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14408 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14409 msleep(200);
14410 }
14411
0ec33d1f
TI
14412 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14413 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14414
14415 snd_hda_codec_resume_amp(codec);
14416 snd_hda_codec_resume_cache(codec);
9e5341b9 14417 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14418 return 0;
14419}
0ec33d1f 14420#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14421
1a99d4a4 14422static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14423 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14424{
14425 int coef;
14426
58701120 14427 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14428 return;
1a99d4a4
KY
14429 coef = alc_read_coef_idx(codec, 0x1e);
14430 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14431}
14432
6981d184
TI
14433static void alc271_fixup_dmic(struct hda_codec *codec,
14434 const struct alc_fixup *fix, int action)
14435{
a9111321 14436 static const struct hda_verb verbs[] = {
6981d184
TI
14437 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14438 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14439 {}
14440 };
14441 unsigned int cfg;
14442
14443 if (strcmp(codec->chip_name, "ALC271X"))
14444 return;
14445 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14446 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14447 snd_hda_sequence_write(codec, verbs);
14448}
14449
ff818c24
TI
14450enum {
14451 ALC269_FIXUP_SONY_VAIO,
74dc8909 14452 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14453 ALC269_FIXUP_DELL_M101Z,
022c92be 14454 ALC269_FIXUP_SKU_IGNORE,
ac612407 14455 ALC269_FIXUP_ASUS_G73JW,
357f915e 14456 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14457 ALC275_FIXUP_SONY_HWEQ,
6981d184 14458 ALC271_FIXUP_DMIC,
ff818c24
TI
14459};
14460
ff818c24
TI
14461static const struct alc_fixup alc269_fixups[] = {
14462 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14463 .type = ALC_FIXUP_VERBS,
14464 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14465 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14466 {}
14467 }
ff818c24 14468 },
74dc8909 14469 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14470 .type = ALC_FIXUP_VERBS,
14471 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14472 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14473 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14474 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14475 { }
b5bfbc67
TI
14476 },
14477 .chained = true,
14478 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14479 },
145a902b 14480 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14481 .type = ALC_FIXUP_VERBS,
14482 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14483 /* Enables internal speaker */
14484 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14485 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14486 {}
14487 }
14488 },
022c92be 14489 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14490 .type = ALC_FIXUP_SKU,
14491 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14492 },
ac612407 14493 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14494 .type = ALC_FIXUP_PINS,
14495 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14496 { 0x17, 0x99130111 }, /* subwoofer */
14497 { }
14498 }
14499 },
357f915e 14500 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14501 .type = ALC_FIXUP_VERBS,
14502 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14503 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14504 {}
14505 }
14506 },
1a99d4a4 14507 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14508 .type = ALC_FIXUP_FUNC,
14509 .v.func = alc269_fixup_hweq,
14510 .chained = true,
14511 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14512 },
14513 [ALC271_FIXUP_DMIC] = {
14514 .type = ALC_FIXUP_FUNC,
14515 .v.func = alc271_fixup_dmic,
14516 },
ff818c24
TI
14517};
14518
a9111321 14519static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14520 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14521 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14522 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14523 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14524 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14525 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14526 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14527 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14528 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14529 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14530 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14531 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14532 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14533 {}
14534};
14535
14536
f6a92248
KY
14537/*
14538 * configuration and preset
14539 */
ea734963 14540static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14541 [ALC269_BASIC] = "basic",
2922c9af 14542 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14543 [ALC269_AMIC] = "laptop-amic",
14544 [ALC269_DMIC] = "laptop-dmic",
64154835 14545 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14546 [ALC269_LIFEBOOK] = "lifebook",
14547 [ALC269_AUTO] = "auto",
f6a92248
KY
14548};
14549
a9111321 14550static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14551 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14552 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14553 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14554 ALC269_AMIC),
14555 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14556 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14557 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14558 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14559 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14560 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14561 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14562 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14563 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14564 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14565 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14566 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14567 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14568 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14569 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14570 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14571 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14572 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14573 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14574 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14575 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14576 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14577 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14578 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14579 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14580 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14581 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14582 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14583 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14584 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14585 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14586 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14587 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14588 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14589 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14590 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14591 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14592 ALC269_DMIC),
60db6b53 14593 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14594 ALC269_DMIC),
14595 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14596 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14597 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14598 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14599 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14600 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14601 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14602 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14603 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14604 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14605 {}
14606};
14607
a9111321 14608static const struct alc_config_preset alc269_presets[] = {
f6a92248 14609 [ALC269_BASIC] = {
f9e336f6 14610 .mixers = { alc269_base_mixer },
f6a92248
KY
14611 .init_verbs = { alc269_init_verbs },
14612 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14613 .dac_nids = alc269_dac_nids,
14614 .hp_nid = 0x03,
14615 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14616 .channel_mode = alc269_modes,
14617 .input_mux = &alc269_capture_source,
14618 },
60db6b53
KY
14619 [ALC269_QUANTA_FL1] = {
14620 .mixers = { alc269_quanta_fl1_mixer },
14621 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14622 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14623 .dac_nids = alc269_dac_nids,
14624 .hp_nid = 0x03,
14625 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14626 .channel_mode = alc269_modes,
14627 .input_mux = &alc269_capture_source,
14628 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14629 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14630 .init_hook = alc269_quanta_fl1_init_hook,
14631 },
84898e87
KY
14632 [ALC269_AMIC] = {
14633 .mixers = { alc269_laptop_mixer },
14634 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 14635 .init_verbs = { alc269_init_verbs,
84898e87 14636 alc269_laptop_amic_init_verbs },
f53281e6
KY
14637 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14638 .dac_nids = alc269_dac_nids,
14639 .hp_nid = 0x03,
14640 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14641 .channel_mode = alc269_modes,
3b8510ce 14642 .unsol_event = alc_sku_unsol_event,
84898e87 14643 .setup = alc269_laptop_amic_setup,
3b8510ce 14644 .init_hook = alc_inithook,
f53281e6 14645 },
84898e87
KY
14646 [ALC269_DMIC] = {
14647 .mixers = { alc269_laptop_mixer },
14648 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 14649 .init_verbs = { alc269_init_verbs,
84898e87
KY
14650 alc269_laptop_dmic_init_verbs },
14651 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14652 .dac_nids = alc269_dac_nids,
14653 .hp_nid = 0x03,
14654 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14655 .channel_mode = alc269_modes,
3b8510ce 14656 .unsol_event = alc_sku_unsol_event,
84898e87 14657 .setup = alc269_laptop_dmic_setup,
3b8510ce 14658 .init_hook = alc_inithook,
84898e87
KY
14659 },
14660 [ALC269VB_AMIC] = {
14661 .mixers = { alc269vb_laptop_mixer },
14662 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14663 .init_verbs = { alc269vb_init_verbs,
14664 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
14665 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14666 .dac_nids = alc269_dac_nids,
14667 .hp_nid = 0x03,
14668 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14669 .channel_mode = alc269_modes,
3b8510ce 14670 .unsol_event = alc_sku_unsol_event,
226b1ec8 14671 .setup = alc269vb_laptop_amic_setup,
3b8510ce 14672 .init_hook = alc_inithook,
84898e87
KY
14673 },
14674 [ALC269VB_DMIC] = {
14675 .mixers = { alc269vb_laptop_mixer },
14676 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14677 .init_verbs = { alc269vb_init_verbs,
14678 alc269vb_laptop_dmic_init_verbs },
14679 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14680 .dac_nids = alc269_dac_nids,
14681 .hp_nid = 0x03,
14682 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14683 .channel_mode = alc269_modes,
3b8510ce 14684 .unsol_event = alc_sku_unsol_event,
84898e87 14685 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 14686 .init_hook = alc_inithook,
f53281e6 14687 },
26f5df26 14688 [ALC269_FUJITSU] = {
45bdd1c1 14689 .mixers = { alc269_fujitsu_mixer },
84898e87 14690 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 14691 .init_verbs = { alc269_init_verbs,
84898e87 14692 alc269_laptop_dmic_init_verbs },
26f5df26
TI
14693 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14694 .dac_nids = alc269_dac_nids,
14695 .hp_nid = 0x03,
14696 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14697 .channel_mode = alc269_modes,
3b8510ce 14698 .unsol_event = alc_sku_unsol_event,
84898e87 14699 .setup = alc269_laptop_dmic_setup,
3b8510ce 14700 .init_hook = alc_inithook,
26f5df26 14701 },
64154835
TV
14702 [ALC269_LIFEBOOK] = {
14703 .mixers = { alc269_lifebook_mixer },
14704 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14705 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14706 .dac_nids = alc269_dac_nids,
14707 .hp_nid = 0x03,
14708 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14709 .channel_mode = alc269_modes,
14710 .input_mux = &alc269_capture_source,
14711 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 14712 .setup = alc269_lifebook_setup,
64154835
TV
14713 .init_hook = alc269_lifebook_init_hook,
14714 },
fe3eb0a7
KY
14715 [ALC271_ACER] = {
14716 .mixers = { alc269_asus_mixer },
14717 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14718 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14719 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14720 .dac_nids = alc269_dac_nids,
14721 .adc_nids = alc262_dmic_adc_nids,
14722 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14723 .capsrc_nids = alc262_dmic_capsrc_nids,
14724 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14725 .channel_mode = alc269_modes,
14726 .input_mux = &alc269_capture_source,
14727 .dig_out_nid = ALC880_DIGOUT_NID,
14728 .unsol_event = alc_sku_unsol_event,
14729 .setup = alc269vb_laptop_dmic_setup,
14730 .init_hook = alc_inithook,
14731 },
f6a92248
KY
14732};
14733
977ddd6b
KY
14734static int alc269_fill_coef(struct hda_codec *codec)
14735{
14736 int val;
14737
14738 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
14739 alc_write_coef_idx(codec, 0xf, 0x960b);
14740 alc_write_coef_idx(codec, 0xe, 0x8817);
14741 }
14742
14743 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
14744 alc_write_coef_idx(codec, 0xf, 0x960b);
14745 alc_write_coef_idx(codec, 0xe, 0x8814);
14746 }
14747
14748 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14749 val = alc_read_coef_idx(codec, 0x04);
14750 /* Power up output pin */
14751 alc_write_coef_idx(codec, 0x04, val | (1<<11));
14752 }
14753
14754 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14755 val = alc_read_coef_idx(codec, 0xd);
14756 if ((val & 0x0c00) >> 10 != 0x1) {
14757 /* Capless ramp up clock control */
b896b4eb 14758 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
14759 }
14760 val = alc_read_coef_idx(codec, 0x17);
14761 if ((val & 0x01c0) >> 6 != 0x4) {
14762 /* Class D power on reset */
b896b4eb 14763 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
14764 }
14765 }
b896b4eb
KY
14766
14767 val = alc_read_coef_idx(codec, 0xd); /* Class D */
14768 alc_write_coef_idx(codec, 0xd, val | (1<<14));
14769
14770 val = alc_read_coef_idx(codec, 0x4); /* HP */
14771 alc_write_coef_idx(codec, 0x4, val | (1<<11));
14772
977ddd6b
KY
14773 return 0;
14774}
14775
f6a92248
KY
14776static int patch_alc269(struct hda_codec *codec)
14777{
14778 struct alc_spec *spec;
48c88e82 14779 int board_config, coef;
f6a92248
KY
14780 int err;
14781
14782 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14783 if (spec == NULL)
14784 return -ENOMEM;
14785
14786 codec->spec = spec;
14787
1f0f4b80
TI
14788 spec->mixer_nid = 0x0b;
14789
da00c244
KY
14790 alc_auto_parse_customize_define(codec);
14791
c793bec5 14792 if (codec->vendor_id == 0x10ec0269) {
b6878571 14793 spec->codec_variant = ALC269_TYPE_ALC269VA;
c793bec5
KY
14794 coef = alc_read_coef_idx(codec, 0);
14795 if ((coef & 0x00f0) == 0x0010) {
14796 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
14797 spec->cdefine.platform_type == 1) {
14798 alc_codec_rename(codec, "ALC271X");
c793bec5
KY
14799 } else if ((coef & 0xf000) == 0x2000) {
14800 alc_codec_rename(codec, "ALC259");
c793bec5
KY
14801 } else if ((coef & 0xf000) == 0x3000) {
14802 alc_codec_rename(codec, "ALC258");
b6878571
KY
14803 } else if ((coef & 0xfff0) == 0x3010) {
14804 alc_codec_rename(codec, "ALC277");
c793bec5
KY
14805 } else {
14806 alc_codec_rename(codec, "ALC269VB");
c793bec5 14807 }
b6878571
KY
14808 spec->codec_variant = ALC269_TYPE_ALC269VB;
14809 } else if ((coef & 0x00f0) == 0x0020) {
14810 if (coef == 0xa023)
14811 alc_codec_rename(codec, "ALC259");
14812 else if (coef == 0x6023)
14813 alc_codec_rename(codec, "ALC281X");
14814 else if (codec->bus->pci->subsystem_vendor == 0x17aa &&
14815 codec->bus->pci->subsystem_device == 0x21f3)
14816 alc_codec_rename(codec, "ALC3202");
14817 else
14818 alc_codec_rename(codec, "ALC269VC");
14819 spec->codec_variant = ALC269_TYPE_ALC269VC;
c793bec5
KY
14820 } else
14821 alc_fix_pll_init(codec, 0x20, 0x04, 15);
14822 alc269_fill_coef(codec);
14823 }
977ddd6b 14824
f6a92248
KY
14825 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
14826 alc269_models,
14827 alc269_cfg_tbl);
14828
14829 if (board_config < 0) {
9a11f1aa
TI
14830 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14831 codec->chip_name);
f6a92248
KY
14832 board_config = ALC269_AUTO;
14833 }
14834
b5bfbc67
TI
14835 if (board_config == ALC269_AUTO) {
14836 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14837 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14838 }
ff818c24 14839
f6a92248
KY
14840 if (board_config == ALC269_AUTO) {
14841 /* automatic parse from the BIOS config */
14842 err = alc269_parse_auto_config(codec);
14843 if (err < 0) {
14844 alc_free(codec);
14845 return err;
14846 } else if (!err) {
14847 printk(KERN_INFO
14848 "hda_codec: Cannot set up configuration "
14849 "from BIOS. Using base mode...\n");
14850 board_config = ALC269_BASIC;
14851 }
14852 }
14853
dc1eae25 14854 if (has_cdefine_beep(codec)) {
8af2591d
TI
14855 err = snd_hda_attach_beep_device(codec, 0x1);
14856 if (err < 0) {
14857 alc_free(codec);
14858 return err;
14859 }
680cd536
KK
14860 }
14861
f6a92248 14862 if (board_config != ALC269_AUTO)
e9c364c0 14863 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 14864
84898e87 14865 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
14866 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14867 * fix the sample rate of analog I/O to 44.1kHz
14868 */
14869 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14870 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
14871 } else if (spec->dual_adc_switch) {
14872 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14873 /* switch ADC dynamically */
14874 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
14875 } else {
14876 spec->stream_analog_playback = &alc269_pcm_analog_playback;
14877 spec->stream_analog_capture = &alc269_pcm_analog_capture;
14878 }
f6a92248
KY
14879 spec->stream_digital_playback = &alc269_pcm_digital_playback;
14880 spec->stream_digital_capture = &alc269_pcm_digital_capture;
14881
6694635d 14882 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
d6cc9fab
TI
14883 alc_auto_fill_adc_caps(codec);
14884 alc_remove_invalid_adc_nids(codec);
84898e87
KY
14885 }
14886
f9e336f6 14887 if (!spec->cap_mixer)
b59bdf3b 14888 set_capture_mixer(codec);
dc1eae25 14889 if (has_cdefine_beep(codec))
da00c244 14890 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 14891
b5bfbc67 14892 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 14893
100d5eb3
TI
14894 spec->vmaster_nid = 0x02;
14895
f6a92248 14896 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
14897#ifdef SND_HDA_NEEDS_RESUME
14898 codec->patch_ops.resume = alc269_resume;
14899#endif
f6a92248
KY
14900 if (board_config == ALC269_AUTO)
14901 spec->init_hook = alc269_auto_init;
5402e4cb 14902 spec->shutup = alc269_shutup;
bf1b0225
KY
14903
14904 alc_init_jacks(codec);
f6a92248
KY
14905#ifdef CONFIG_SND_HDA_POWER_SAVE
14906 if (!spec->loopback.amplist)
14907 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
14908 if (alc269_mic2_for_mute_led(codec))
14909 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
14910#endif
14911
14912 return 0;
14913}
14914
df694daa
KY
14915/*
14916 * ALC861 channel source setting (2/6 channel selection for 3-stack)
14917 */
14918
14919/*
14920 * set the path ways for 2 channel output
14921 * need to set the codec line out and mic 1 pin widgets to inputs
14922 */
a9111321 14923static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
14924 /* set pin widget 1Ah (line in) for input */
14925 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14926 /* set pin widget 18h (mic1/2) for input, for mic also enable
14927 * the vref
14928 */
df694daa
KY
14929 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14930
9c7f852e
TI
14931 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14932#if 0
14933 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14934 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14935#endif
df694daa
KY
14936 { } /* end */
14937};
14938/*
14939 * 6ch mode
14940 * need to set the codec line out and mic 1 pin widgets to outputs
14941 */
a9111321 14942static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
14943 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14944 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14945 /* set pin widget 18h (mic1) for output (CLFE)*/
14946 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14947
14948 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 14949 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 14950
9c7f852e
TI
14951 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14952#if 0
14953 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14954 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14955#endif
df694daa
KY
14956 { } /* end */
14957};
14958
a9111321 14959static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
14960 { 2, alc861_threestack_ch2_init },
14961 { 6, alc861_threestack_ch6_init },
14962};
22309c3e 14963/* Set mic1 as input and unmute the mixer */
a9111321 14964static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
14965 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14966 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14967 { } /* end */
14968};
14969/* Set mic1 as output and mute mixer */
a9111321 14970static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
14971 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14972 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14973 { } /* end */
14974};
14975
a9111321 14976static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
14977 { 2, alc861_uniwill_m31_ch2_init },
14978 { 4, alc861_uniwill_m31_ch4_init },
14979};
df694daa 14980
7cdbff94 14981/* Set mic1 and line-in as input and unmute the mixer */
a9111321 14982static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
14983 /* set pin widget 1Ah (line in) for input */
14984 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
14985 /* set pin widget 18h (mic1/2) for input, for mic also enable
14986 * the vref
14987 */
7cdbff94
MD
14988 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14989
14990 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14991#if 0
14992 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14993 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14994#endif
14995 { } /* end */
14996};
14997/* Set mic1 nad line-in as output and mute mixer */
a9111321 14998static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
14999 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15000 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15001 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15002 /* set pin widget 18h (mic1) for output (CLFE)*/
15003 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15004 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15005 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15006 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15007
15008 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15009#if 0
15010 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15011 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15012#endif
15013 { } /* end */
15014};
15015
a9111321 15016static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15017 { 2, alc861_asus_ch2_init },
15018 { 6, alc861_asus_ch6_init },
15019};
15020
df694daa
KY
15021/* patch-ALC861 */
15022
a9111321 15023static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15024 /* output mixer control */
15025 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15026 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15027 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15028 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15029 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15030
15031 /*Input mixer control */
15032 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15033 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15034 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15035 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15036 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15037 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15039 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15040 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15041 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15042
df694daa
KY
15043 { } /* end */
15044};
15045
a9111321 15046static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15047 /* output mixer control */
15048 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15049 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15050 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15051 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15052 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15053
15054 /* Input mixer control */
15055 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15056 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15057 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15058 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15059 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15060 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15062 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15063 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15064 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15065
df694daa
KY
15066 {
15067 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15068 .name = "Channel Mode",
15069 .info = alc_ch_mode_info,
15070 .get = alc_ch_mode_get,
15071 .put = alc_ch_mode_put,
15072 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15073 },
15074 { } /* end */
a53d1aec
TD
15075};
15076
a9111321 15077static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15078 /* output mixer control */
15079 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15080 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15081 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15082
a53d1aec 15083 { } /* end */
f12ab1e0 15084};
a53d1aec 15085
a9111321 15086static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15087 /* output mixer control */
15088 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15089 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15090 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15091 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15092 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15093
15094 /* Input mixer control */
15095 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15096 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15097 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15098 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15099 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15100 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15102 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15103 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15104 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15105
22309c3e
TI
15106 {
15107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15108 .name = "Channel Mode",
15109 .info = alc_ch_mode_info,
15110 .get = alc_ch_mode_get,
15111 .put = alc_ch_mode_put,
15112 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15113 },
15114 { } /* end */
f12ab1e0 15115};
7cdbff94 15116
a9111321 15117static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15118 /* output mixer control */
15119 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15120 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15121 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15122 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15123 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15124
15125 /* Input mixer control */
15126 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15127 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15128 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15129 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15130 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15131 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15132 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15133 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15134 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15136
7cdbff94
MD
15137 {
15138 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15139 .name = "Channel Mode",
15140 .info = alc_ch_mode_info,
15141 .get = alc_ch_mode_get,
15142 .put = alc_ch_mode_put,
15143 .private_value = ARRAY_SIZE(alc861_asus_modes),
15144 },
15145 { }
56bb0cab
TI
15146};
15147
15148/* additional mixer */
a9111321 15149static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15150 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15151 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15152 { }
15153};
7cdbff94 15154
df694daa
KY
15155/*
15156 * generic initialization of ADC, input mixers and output mixers
15157 */
a9111321 15158static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15159 /*
15160 * Unmute ADC0 and set the default input to mic-in
15161 */
15162 /* port-A for surround (rear panel) */
15163 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15164 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15165 /* port-B for mic-in (rear panel) with vref */
15166 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15167 /* port-C for line-in (rear panel) */
15168 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15169 /* port-D for Front */
15170 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15171 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15172 /* port-E for HP out (front panel) */
15173 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15174 /* route front PCM to HP */
9dece1d7 15175 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15176 /* port-F for mic-in (front panel) with vref */
15177 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15178 /* port-G for CLFE (rear panel) */
15179 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15180 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15181 /* port-H for side (rear panel) */
15182 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15183 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15184 /* CD-in */
15185 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15186 /* route front mic to ADC1*/
15187 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15188 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15189
df694daa
KY
15190 /* Unmute DAC0~3 & spdif out*/
15191 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15192 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15193 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15194 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15195 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15196
df694daa
KY
15197 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15198 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15199 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15200 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15201 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15202
df694daa
KY
15203 /* Unmute Stereo Mixer 15 */
15204 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15205 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15206 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15207 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15208
15209 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15211 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15212 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15213 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15214 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15215 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15216 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15217 /* hp used DAC 3 (Front) */
15218 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15219 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15220
15221 { }
15222};
15223
a9111321 15224static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15225 /*
15226 * Unmute ADC0 and set the default input to mic-in
15227 */
15228 /* port-A for surround (rear panel) */
15229 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15230 /* port-B for mic-in (rear panel) with vref */
15231 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15232 /* port-C for line-in (rear panel) */
15233 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15234 /* port-D for Front */
15235 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15236 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15237 /* port-E for HP out (front panel) */
15238 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15239 /* route front PCM to HP */
9dece1d7 15240 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15241 /* port-F for mic-in (front panel) with vref */
15242 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15243 /* port-G for CLFE (rear panel) */
15244 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15245 /* port-H for side (rear panel) */
15246 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15247 /* CD-in */
15248 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15249 /* route front mic to ADC1*/
15250 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15251 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15252 /* Unmute DAC0~3 & spdif out*/
15253 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15254 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15255 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15256 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15257 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15258
df694daa
KY
15259 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15260 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15261 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15262 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15263 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15264
df694daa
KY
15265 /* Unmute Stereo Mixer 15 */
15266 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15267 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15268 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15270
15271 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15272 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15273 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15274 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15275 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15277 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15278 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15279 /* hp used DAC 3 (Front) */
15280 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15281 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15282 { }
15283};
22309c3e 15284
a9111321 15285static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15286 /*
15287 * Unmute ADC0 and set the default input to mic-in
15288 */
15289 /* port-A for surround (rear panel) */
15290 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15291 /* port-B for mic-in (rear panel) with vref */
15292 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15293 /* port-C for line-in (rear panel) */
15294 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15295 /* port-D for Front */
15296 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15297 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15298 /* port-E for HP out (front panel) */
f12ab1e0
TI
15299 /* this has to be set to VREF80 */
15300 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15301 /* route front PCM to HP */
9dece1d7 15302 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15303 /* port-F for mic-in (front panel) with vref */
15304 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15305 /* port-G for CLFE (rear panel) */
15306 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15307 /* port-H for side (rear panel) */
15308 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15309 /* CD-in */
15310 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15311 /* route front mic to ADC1*/
15312 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15313 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15314 /* Unmute DAC0~3 & spdif out*/
15315 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15316 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15317 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15318 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15319 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15320
22309c3e
TI
15321 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15322 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15323 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15324 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15325 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15326
22309c3e
TI
15327 /* Unmute Stereo Mixer 15 */
15328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15329 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15332
15333 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15334 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15335 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15336 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15337 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15338 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15339 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15340 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15341 /* hp used DAC 3 (Front) */
15342 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15343 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15344 { }
15345};
15346
a9111321 15347static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15348 /*
15349 * Unmute ADC0 and set the default input to mic-in
15350 */
f12ab1e0
TI
15351 /* port-A for surround (rear panel)
15352 * according to codec#0 this is the HP jack
15353 */
7cdbff94
MD
15354 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15355 /* route front PCM to HP */
15356 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15357 /* port-B for mic-in (rear panel) with vref */
15358 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15359 /* port-C for line-in (rear panel) */
15360 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15361 /* port-D for Front */
15362 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15363 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15364 /* port-E for HP out (front panel) */
f12ab1e0
TI
15365 /* this has to be set to VREF80 */
15366 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15367 /* route front PCM to HP */
9dece1d7 15368 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15369 /* port-F for mic-in (front panel) with vref */
15370 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15371 /* port-G for CLFE (rear panel) */
15372 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15373 /* port-H for side (rear panel) */
15374 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15375 /* CD-in */
15376 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15377 /* route front mic to ADC1*/
15378 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15379 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15380 /* Unmute DAC0~3 & spdif out*/
15381 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15382 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15383 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15384 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15386 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15387 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15388 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15389 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15390 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15391
7cdbff94
MD
15392 /* Unmute Stereo Mixer 15 */
15393 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15394 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15395 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15396 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15397
15398 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15399 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15400 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15401 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15402 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15403 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15404 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15405 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15406 /* hp used DAC 3 (Front) */
15407 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15408 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15409 { }
15410};
15411
56bb0cab 15412/* additional init verbs for ASUS laptops */
a9111321 15413static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15414 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15415 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15416 { }
15417};
7cdbff94 15418
a9111321 15419static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15420 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15421
a53d1aec
TD
15422 { }
15423};
15424
15425/* toggle speaker-output according to the hp-jack state */
15426static void alc861_toshiba_automute(struct hda_codec *codec)
15427{
864f92be 15428 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15429
47fd830a
TI
15430 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15431 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15432 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15433 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15434}
15435
15436static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15437 unsigned int res)
15438{
a53d1aec
TD
15439 if ((res >> 26) == ALC880_HP_EVENT)
15440 alc861_toshiba_automute(codec);
15441}
15442
def319f9 15443/* pcm configuration: identical with ALC880 */
df694daa
KY
15444#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15445#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15446#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15447#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15448
15449
15450#define ALC861_DIGOUT_NID 0x07
15451
a9111321 15452static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15453 { 8, NULL }
15454};
15455
4c6d72d1 15456static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15457 /* front, surround, clfe, side */
15458 0x03, 0x06, 0x05, 0x04
15459};
15460
4c6d72d1 15461static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15462 /* front, clfe, surround */
15463 0x03, 0x05, 0x06
15464};
15465
4c6d72d1 15466static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15467 /* ADC0-2 */
15468 0x08,
15469};
15470
a9111321 15471static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15472 .num_items = 5,
15473 .items = {
15474 { "Mic", 0x0 },
15475 { "Front Mic", 0x3 },
15476 { "Line", 0x1 },
15477 { "CD", 0x4 },
15478 { "Mixer", 0x5 },
15479 },
15480};
15481
1c20930a
TI
15482static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15483{
15484 struct alc_spec *spec = codec->spec;
15485 hda_nid_t mix, srcs[5];
3af9ee6b 15486 int i, num;
1c20930a
TI
15487
15488 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15489 return 0;
15490 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15491 if (num < 0)
15492 return 0;
15493 for (i = 0; i < num; i++) {
15494 unsigned int type;
a22d543a 15495 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15496 if (type != AC_WID_AUD_OUT)
15497 continue;
3af9ee6b
TI
15498 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15499 spec->multiout.num_dacs))
1c20930a
TI
15500 return srcs[i];
15501 }
15502 return 0;
15503}
15504
df694daa 15505/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 15506static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
df694daa 15507{
1c20930a 15508 struct alc_spec *spec = codec->spec;
cb053a82 15509 const struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa 15510 int i;
1c20930a 15511 hda_nid_t nid, dac;
df694daa
KY
15512
15513 spec->multiout.dac_nids = spec->private_dac_nids;
15514 for (i = 0; i < cfg->line_outs; i++) {
15515 nid = cfg->line_out_pins[i];
1c20930a
TI
15516 dac = alc861_look_for_dac(codec, nid);
15517 if (!dac)
15518 continue;
dda14410 15519 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15520 }
df694daa
KY
15521 return 0;
15522}
15523
bcb2f0f5
TI
15524static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15525 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15526{
bcb2f0f5 15527 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15528 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15529}
15530
bcb2f0f5
TI
15531#define alc861_create_out_sw(codec, pfx, nid, chs) \
15532 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15533
df694daa 15534/* add playback controls from the parsed DAC table */
1c20930a 15535static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15536 const struct auto_pin_cfg *cfg)
15537{
1c20930a 15538 struct alc_spec *spec = codec->spec;
df694daa 15539 hda_nid_t nid;
ce764ab2 15540 int i, err, noutputs;
1c20930a 15541
ce764ab2
TI
15542 noutputs = cfg->line_outs;
15543 if (spec->multi_ios > 0)
15544 noutputs += spec->multi_ios;
15545
15546 for (i = 0; i < noutputs; i++) {
6843ca16
TI
15547 const char *name;
15548 int index;
df694daa 15549 nid = spec->multiout.dac_nids[i];
f12ab1e0 15550 if (!nid)
df694daa 15551 continue;
6843ca16
TI
15552 name = alc_get_line_out_pfx(spec, i, true, &index);
15553 if (!name) {
df694daa 15554 /* Center/LFE */
1c20930a 15555 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15556 if (err < 0)
df694daa 15557 return err;
1c20930a 15558 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15559 if (err < 0)
df694daa
KY
15560 return err;
15561 } else {
5a882646 15562 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 15563 if (err < 0)
df694daa
KY
15564 return err;
15565 }
15566 }
15567 return 0;
15568}
15569
1c20930a 15570static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15571{
1c20930a 15572 struct alc_spec *spec = codec->spec;
df694daa
KY
15573 int err;
15574 hda_nid_t nid;
15575
f12ab1e0 15576 if (!pin)
df694daa
KY
15577 return 0;
15578
15579 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15580 nid = alc861_look_for_dac(codec, pin);
15581 if (nid) {
15582 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15583 if (err < 0)
15584 return err;
15585 spec->multiout.hp_nid = nid;
15586 }
df694daa
KY
15587 }
15588 return 0;
15589}
15590
f12ab1e0
TI
15591static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15592 hda_nid_t nid,
1c20930a 15593 int pin_type, hda_nid_t dac)
df694daa 15594{
1c20930a
TI
15595 hda_nid_t mix, srcs[5];
15596 int i, num;
15597
564c5bea
JL
15598 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15599 pin_type);
1c20930a 15600 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15601 AMP_OUT_UNMUTE);
1c20930a
TI
15602 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15603 return;
15604 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15605 if (num < 0)
15606 return;
15607 for (i = 0; i < num; i++) {
15608 unsigned int mute;
15609 if (srcs[i] == dac || srcs[i] == 0x15)
15610 mute = AMP_IN_UNMUTE(i);
15611 else
15612 mute = AMP_IN_MUTE(i);
15613 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15614 mute);
15615 }
df694daa
KY
15616}
15617
15618static void alc861_auto_init_multi_out(struct hda_codec *codec)
15619{
15620 struct alc_spec *spec = codec->spec;
15621 int i;
15622
1f0f4b80 15623 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
df694daa 15624 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15625 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15626 if (nid)
baba8ee9 15627 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 15628 spec->multiout.dac_nids[i]);
df694daa
KY
15629 }
15630}
15631
15632static void alc861_auto_init_hp_out(struct hda_codec *codec)
15633{
15634 struct alc_spec *spec = codec->spec;
df694daa 15635
15870f05
TI
15636 if (spec->autocfg.hp_outs)
15637 alc861_auto_set_output_and_unmute(codec,
15638 spec->autocfg.hp_pins[0],
15639 PIN_HP,
1c20930a 15640 spec->multiout.hp_nid);
15870f05
TI
15641 if (spec->autocfg.speaker_outs)
15642 alc861_auto_set_output_and_unmute(codec,
15643 spec->autocfg.speaker_pins[0],
15644 PIN_OUT,
1c20930a 15645 spec->multiout.dac_nids[0]);
df694daa
KY
15646}
15647
df694daa 15648/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
15649/* return 1 if successful, 0 if the proper config is not found,
15650 * or a negative error code
15651 */
df694daa
KY
15652static int alc861_parse_auto_config(struct hda_codec *codec)
15653{
15654 struct alc_spec *spec = codec->spec;
15655 int err;
4c6d72d1 15656 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 15657
f12ab1e0
TI
15658 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
15659 alc861_ignore);
15660 if (err < 0)
df694daa 15661 return err;
f12ab1e0 15662 if (!spec->autocfg.line_outs)
df694daa
KY
15663 return 0; /* can't find valid BIOS pin config */
15664
cb053a82 15665 err = alc861_auto_fill_dac_nids(codec);
ce764ab2
TI
15666 if (err < 0)
15667 return err;
cb053a82 15668 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
f12ab1e0
TI
15669 if (err < 0)
15670 return err;
1c20930a 15671 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
15672 if (err < 0)
15673 return err;
1c20930a 15674 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
15675 if (err < 0)
15676 return err;
b7821709 15677 err = alc_auto_create_input_ctls(codec);
f12ab1e0 15678 if (err < 0)
df694daa
KY
15679 return err;
15680
15681 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
15682
757899ac 15683 alc_auto_parse_digital(codec);
df694daa 15684
603c4019 15685 if (spec->kctls.list)
d88897ea 15686 add_mixer(spec, spec->kctls.list);
df694daa 15687
a1e8d2da 15688 spec->num_mux_defs = 1;
61b9b9b1 15689 spec->input_mux = &spec->private_imux[0];
df694daa 15690
d6cc9fab
TI
15691 if (!spec->dual_adc_switch)
15692 alc_remove_invalid_adc_nids(codec);
df694daa 15693
6227cdce 15694 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 15695
d6cc9fab
TI
15696 set_capture_mixer(codec);
15697
df694daa
KY
15698 return 1;
15699}
15700
ae6b813a
TI
15701/* additional initialization for auto-configuration model */
15702static void alc861_auto_init(struct hda_codec *codec)
df694daa 15703{
f6c7e546 15704 struct alc_spec *spec = codec->spec;
df694daa
KY
15705 alc861_auto_init_multi_out(codec);
15706 alc861_auto_init_hp_out(codec);
0a7f5320 15707 alc_auto_init_analog_input(codec);
757899ac 15708 alc_auto_init_digital(codec);
f6c7e546 15709 if (spec->unsol_event)
7fb0d78f 15710 alc_inithook(codec);
df694daa
KY
15711}
15712
cb53c626 15713#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 15714static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
15715 { 0x15, HDA_INPUT, 0 },
15716 { 0x15, HDA_INPUT, 1 },
15717 { 0x15, HDA_INPUT, 2 },
15718 { 0x15, HDA_INPUT, 3 },
15719 { } /* end */
15720};
15721#endif
15722
df694daa
KY
15723
15724/*
15725 * configuration and preset
15726 */
ea734963 15727static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
15728 [ALC861_3ST] = "3stack",
15729 [ALC660_3ST] = "3stack-660",
15730 [ALC861_3ST_DIG] = "3stack-dig",
15731 [ALC861_6ST_DIG] = "6stack-dig",
15732 [ALC861_UNIWILL_M31] = "uniwill-m31",
15733 [ALC861_TOSHIBA] = "toshiba",
15734 [ALC861_ASUS] = "asus",
15735 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15736 [ALC861_AUTO] = "auto",
15737};
15738
a9111321 15739static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 15740 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
15741 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15742 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15743 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 15744 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 15745 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 15746 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
15747 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15748 * Any other models that need this preset?
15749 */
15750 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
15751 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15752 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 15753 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
15754 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15755 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15756 /* FIXME: the below seems conflict */
15757 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 15758 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 15759 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
15760 {}
15761};
15762
a9111321 15763static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
15764 [ALC861_3ST] = {
15765 .mixers = { alc861_3ST_mixer },
15766 .init_verbs = { alc861_threestack_init_verbs },
15767 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15768 .dac_nids = alc861_dac_nids,
15769 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15770 .channel_mode = alc861_threestack_modes,
4e195a7b 15771 .need_dac_fix = 1,
df694daa
KY
15772 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15773 .adc_nids = alc861_adc_nids,
15774 .input_mux = &alc861_capture_source,
15775 },
15776 [ALC861_3ST_DIG] = {
15777 .mixers = { alc861_base_mixer },
15778 .init_verbs = { alc861_threestack_init_verbs },
15779 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15780 .dac_nids = alc861_dac_nids,
15781 .dig_out_nid = ALC861_DIGOUT_NID,
15782 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15783 .channel_mode = alc861_threestack_modes,
4e195a7b 15784 .need_dac_fix = 1,
df694daa
KY
15785 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15786 .adc_nids = alc861_adc_nids,
15787 .input_mux = &alc861_capture_source,
15788 },
15789 [ALC861_6ST_DIG] = {
15790 .mixers = { alc861_base_mixer },
15791 .init_verbs = { alc861_base_init_verbs },
15792 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15793 .dac_nids = alc861_dac_nids,
15794 .dig_out_nid = ALC861_DIGOUT_NID,
15795 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15796 .channel_mode = alc861_8ch_modes,
15797 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15798 .adc_nids = alc861_adc_nids,
15799 .input_mux = &alc861_capture_source,
15800 },
9c7f852e
TI
15801 [ALC660_3ST] = {
15802 .mixers = { alc861_3ST_mixer },
15803 .init_verbs = { alc861_threestack_init_verbs },
15804 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15805 .dac_nids = alc660_dac_nids,
15806 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15807 .channel_mode = alc861_threestack_modes,
4e195a7b 15808 .need_dac_fix = 1,
9c7f852e
TI
15809 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15810 .adc_nids = alc861_adc_nids,
15811 .input_mux = &alc861_capture_source,
15812 },
22309c3e
TI
15813 [ALC861_UNIWILL_M31] = {
15814 .mixers = { alc861_uniwill_m31_mixer },
15815 .init_verbs = { alc861_uniwill_m31_init_verbs },
15816 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15817 .dac_nids = alc861_dac_nids,
15818 .dig_out_nid = ALC861_DIGOUT_NID,
15819 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15820 .channel_mode = alc861_uniwill_m31_modes,
15821 .need_dac_fix = 1,
15822 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15823 .adc_nids = alc861_adc_nids,
15824 .input_mux = &alc861_capture_source,
15825 },
a53d1aec
TD
15826 [ALC861_TOSHIBA] = {
15827 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
15828 .init_verbs = { alc861_base_init_verbs,
15829 alc861_toshiba_init_verbs },
a53d1aec
TD
15830 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15831 .dac_nids = alc861_dac_nids,
15832 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15833 .channel_mode = alc883_3ST_2ch_modes,
15834 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15835 .adc_nids = alc861_adc_nids,
15836 .input_mux = &alc861_capture_source,
15837 .unsol_event = alc861_toshiba_unsol_event,
15838 .init_hook = alc861_toshiba_automute,
15839 },
7cdbff94
MD
15840 [ALC861_ASUS] = {
15841 .mixers = { alc861_asus_mixer },
15842 .init_verbs = { alc861_asus_init_verbs },
15843 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15844 .dac_nids = alc861_dac_nids,
15845 .dig_out_nid = ALC861_DIGOUT_NID,
15846 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15847 .channel_mode = alc861_asus_modes,
15848 .need_dac_fix = 1,
15849 .hp_nid = 0x06,
15850 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15851 .adc_nids = alc861_adc_nids,
15852 .input_mux = &alc861_capture_source,
15853 },
56bb0cab
TI
15854 [ALC861_ASUS_LAPTOP] = {
15855 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15856 .init_verbs = { alc861_asus_init_verbs,
15857 alc861_asus_laptop_init_verbs },
15858 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15859 .dac_nids = alc861_dac_nids,
15860 .dig_out_nid = ALC861_DIGOUT_NID,
15861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15862 .channel_mode = alc883_3ST_2ch_modes,
15863 .need_dac_fix = 1,
15864 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15865 .adc_nids = alc861_adc_nids,
15866 .input_mux = &alc861_capture_source,
15867 },
15868};
df694daa 15869
cfc9b06f
TI
15870/* Pin config fixes */
15871enum {
15872 PINFIX_FSC_AMILO_PI1505,
15873};
15874
cfc9b06f
TI
15875static const struct alc_fixup alc861_fixups[] = {
15876 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
15877 .type = ALC_FIXUP_PINS,
15878 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
15879 { 0x0b, 0x0221101f }, /* HP */
15880 { 0x0f, 0x90170310 }, /* speaker */
15881 { }
15882 }
cfc9b06f
TI
15883 },
15884};
15885
a9111321 15886static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
15887 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
15888 {}
15889};
df694daa
KY
15890
15891static int patch_alc861(struct hda_codec *codec)
15892{
15893 struct alc_spec *spec;
15894 int board_config;
15895 int err;
15896
dc041e0b 15897 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
15898 if (spec == NULL)
15899 return -ENOMEM;
15900
f12ab1e0 15901 codec->spec = spec;
df694daa 15902
1f0f4b80
TI
15903 spec->mixer_nid = 0x15;
15904
f5fcc13c
TI
15905 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
15906 alc861_models,
15907 alc861_cfg_tbl);
9c7f852e 15908
f5fcc13c 15909 if (board_config < 0) {
9a11f1aa
TI
15910 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15911 codec->chip_name);
df694daa
KY
15912 board_config = ALC861_AUTO;
15913 }
15914
b5bfbc67
TI
15915 if (board_config == ALC861_AUTO) {
15916 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15917 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15918 }
cfc9b06f 15919
df694daa
KY
15920 if (board_config == ALC861_AUTO) {
15921 /* automatic parse from the BIOS config */
15922 err = alc861_parse_auto_config(codec);
15923 if (err < 0) {
15924 alc_free(codec);
15925 return err;
f12ab1e0 15926 } else if (!err) {
9c7f852e
TI
15927 printk(KERN_INFO
15928 "hda_codec: Cannot set up configuration "
15929 "from BIOS. Using base mode...\n");
df694daa
KY
15930 board_config = ALC861_3ST_DIG;
15931 }
15932 }
15933
680cd536
KK
15934 err = snd_hda_attach_beep_device(codec, 0x23);
15935 if (err < 0) {
15936 alc_free(codec);
15937 return err;
15938 }
15939
df694daa 15940 if (board_config != ALC861_AUTO)
e9c364c0 15941 setup_preset(codec, &alc861_presets[board_config]);
df694daa 15942
df694daa
KY
15943 spec->stream_analog_playback = &alc861_pcm_analog_playback;
15944 spec->stream_analog_capture = &alc861_pcm_analog_capture;
15945
df694daa
KY
15946 spec->stream_digital_playback = &alc861_pcm_digital_playback;
15947 spec->stream_digital_capture = &alc861_pcm_digital_capture;
15948
c7a8eb10
TI
15949 if (!spec->cap_mixer)
15950 set_capture_mixer(codec);
45bdd1c1
TI
15951 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
15952
2134ea4f
TI
15953 spec->vmaster_nid = 0x03;
15954
b5bfbc67 15955 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 15956
df694daa 15957 codec->patch_ops = alc_patch_ops;
c97259df 15958 if (board_config == ALC861_AUTO) {
ae6b813a 15959 spec->init_hook = alc861_auto_init;
c97259df
DC
15960#ifdef CONFIG_SND_HDA_POWER_SAVE
15961 spec->power_hook = alc_power_eapd;
15962#endif
15963 }
cb53c626
TI
15964#ifdef CONFIG_SND_HDA_POWER_SAVE
15965 if (!spec->loopback.amplist)
15966 spec->loopback.amplist = alc861_loopbacks;
15967#endif
ea1fb29a 15968
1da177e4
LT
15969 return 0;
15970}
15971
f32610ed
JS
15972/*
15973 * ALC861-VD support
15974 *
15975 * Based on ALC882
15976 *
15977 * In addition, an independent DAC
15978 */
15979#define ALC861VD_DIGOUT_NID 0x06
15980
4c6d72d1 15981static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
15982 /* front, surr, clfe, side surr */
15983 0x02, 0x03, 0x04, 0x05
15984};
15985
15986/* dac_nids for ALC660vd are in a different order - according to
15987 * Realtek's driver.
def319f9 15988 * This should probably result in a different mixer for 6stack models
f32610ed
JS
15989 * of ALC660vd codecs, but for now there is only 3stack mixer
15990 * - and it is the same as in 861vd.
15991 * adc_nids in ALC660vd are (is) the same as in 861vd
15992 */
4c6d72d1 15993static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
15994 /* front, rear, clfe, rear_surr */
15995 0x02, 0x04, 0x03
15996};
15997
4c6d72d1 15998static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
15999 /* ADC0 */
16000 0x09,
16001};
16002
4c6d72d1 16003static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16004
f32610ed
JS
16005/* input MUX */
16006/* FIXME: should be a matrix-type input source selection */
a9111321 16007static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16008 .num_items = 4,
16009 .items = {
16010 { "Mic", 0x0 },
16011 { "Front Mic", 0x1 },
16012 { "Line", 0x2 },
16013 { "CD", 0x4 },
16014 },
16015};
16016
a9111321 16017static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16018 .num_items = 2,
272a527c 16019 .items = {
8607f7c4 16020 { "Mic", 0x0 },
28c4edb7 16021 { "Internal Mic", 0x1 },
272a527c
KY
16022 },
16023};
16024
a9111321 16025static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16026 .num_items = 2,
16027 .items = {
16028 { "Front Mic", 0x0 },
16029 { "ATAPI Mic", 0x1 },
16030 },
16031};
16032
f32610ed
JS
16033/*
16034 * 2ch mode
16035 */
a9111321 16036static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16037 { 2, NULL }
16038};
16039
16040/*
16041 * 6ch mode
16042 */
a9111321 16043static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16044 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16045 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16046 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16047 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16048 { } /* end */
16049};
16050
16051/*
16052 * 8ch mode
16053 */
a9111321 16054static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16055 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16056 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16057 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16058 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16059 { } /* end */
16060};
16061
a9111321 16062static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16063 { 6, alc861vd_6stack_ch6_init },
16064 { 8, alc861vd_6stack_ch8_init },
16065};
16066
a9111321 16067static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16068 {
16069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16070 .name = "Channel Mode",
16071 .info = alc_ch_mode_info,
16072 .get = alc_ch_mode_get,
16073 .put = alc_ch_mode_put,
16074 },
16075 { } /* end */
16076};
16077
f32610ed
JS
16078/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16079 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16080 */
a9111321 16081static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16082 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16083 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16084
16085 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16086 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16087
16088 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16089 HDA_OUTPUT),
16090 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16091 HDA_OUTPUT),
16092 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16093 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16094
16095 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16096 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16097
16098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16099
5f99f86a 16100 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16103
5f99f86a 16104 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16105 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16106 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16107
16108 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16109 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16110
16111 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16112 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16113
f32610ed
JS
16114 { } /* end */
16115};
16116
a9111321 16117static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16118 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16120
16121 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16122
5f99f86a 16123 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16126
5f99f86a 16127 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16128 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16129 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16130
16131 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16132 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16133
16134 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16135 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16136
f32610ed
JS
16137 { } /* end */
16138};
16139
a9111321 16140static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16141 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16142 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16143 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16144
16145 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16146
5f99f86a 16147 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16150
5f99f86a 16151 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16152 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16153 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16154
16155 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16156 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16157
16158 { } /* end */
16159};
16160
b419f346 16161/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16162 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16163 */
a9111321 16164static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16165 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16166 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16167 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16168 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16171 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16172 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16173 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16174 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16175 { } /* end */
16176};
16177
d1a991a6
KY
16178/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16179 * Front Mic=0x18, ATAPI Mic = 0x19,
16180 */
a9111321 16181static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16182 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16183 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16184 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16185 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16186 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16187 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16188 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16189 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16190
d1a991a6
KY
16191 { } /* end */
16192};
16193
f32610ed
JS
16194/*
16195 * generic initialization of ADC, input mixers and output mixers
16196 */
a9111321 16197static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16198 /*
16199 * Unmute ADC0 and set the default input to mic-in
16200 */
16201 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16202 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16203
16204 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16205 * the analog-loopback mixer widget
16206 */
16207 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16208 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16209 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16210 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16211 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16212 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16213
16214 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16215 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16216 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16217 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16218 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16219
16220 /*
16221 * Set up output mixers (0x02 - 0x05)
16222 */
16223 /* set vol=0 to output mixers */
16224 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16225 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16226 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16227 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16228
16229 /* set up input amps for analog loopback */
16230 /* Amp Indices: DAC = 0, mixer = 1 */
16231 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16232 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16233 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16234 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16235 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16236 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16239
16240 { }
16241};
16242
16243/*
16244 * 3-stack pin configuration:
16245 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16246 */
a9111321 16247static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16248 /*
16249 * Set pin mode and muting
16250 */
16251 /* set front pin widgets 0x14 for output */
16252 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16253 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16254 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16255
16256 /* Mic (rear) pin: input vref at 80% */
16257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16258 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16259 /* Front Mic pin: input vref at 80% */
16260 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16261 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16262 /* Line In pin: input */
16263 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16264 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16265 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16267 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16268 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16269 /* CD pin widget for input */
16270 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16271
16272 { }
16273};
16274
16275/*
16276 * 6-stack pin configuration:
16277 */
a9111321 16278static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16279 /*
16280 * Set pin mode and muting
16281 */
16282 /* set front pin widgets 0x14 for output */
16283 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16284 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16285 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16286
16287 /* Rear Pin: output 1 (0x0d) */
16288 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16290 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16291 /* CLFE Pin: output 2 (0x0e) */
16292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16293 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16294 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16295 /* Side Pin: output 3 (0x0f) */
16296 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16298 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16299
16300 /* Mic (rear) pin: input vref at 80% */
16301 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16302 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16303 /* Front Mic pin: input vref at 80% */
16304 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16305 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16306 /* Line In pin: input */
16307 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16308 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16309 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16310 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16311 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16312 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16313 /* CD pin widget for input */
16314 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16315
16316 { }
16317};
16318
a9111321 16319static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16320 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16321 { }
16322};
16323
a9111321 16324static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16325 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16326 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16327 { }
16328};
16329
a9111321 16330static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16333 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16334 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16335 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16336 {}
16337};
16338
4f5d1706 16339static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16340{
a9fd4f3f 16341 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16342 spec->autocfg.hp_pins[0] = 0x1b;
16343 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16344 spec->automute = 1;
16345 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16346}
16347
16348static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16349{
d922b51d 16350 alc_hp_automute(codec);
eeb43387 16351 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16352}
16353
16354static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16355 unsigned int res)
16356{
16357 switch (res >> 26) {
bdd148a3 16358 case ALC880_MIC_EVENT:
eeb43387 16359 alc88x_simple_mic_automute(codec);
bdd148a3 16360 break;
a9fd4f3f 16361 default:
d922b51d 16362 alc_sku_unsol_event(codec, res);
a9fd4f3f 16363 break;
bdd148a3
KY
16364 }
16365}
16366
a9111321 16367static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16368 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16369 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16370 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16371 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16372
16373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16375 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16376 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16378 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16381
272a527c
KY
16382 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16383 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16384 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16385 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16387 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16388 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16389 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16390
16391 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16392 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16393 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16394 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16395 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16396 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16397 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16398 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16399
16400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16401 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16402 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16403 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16404
16405 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16406 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16407 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16408
16409 { } /* end */
16410};
16411
16412/* toggle speaker-output according to the hp-jack state */
4f5d1706 16413static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16414{
a9fd4f3f 16415 struct alc_spec *spec = codec->spec;
272a527c 16416
a9fd4f3f
TI
16417 spec->autocfg.hp_pins[0] = 0x15;
16418 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16419 spec->automute = 1;
16420 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16421}
16422
cb53c626
TI
16423#ifdef CONFIG_SND_HDA_POWER_SAVE
16424#define alc861vd_loopbacks alc880_loopbacks
16425#endif
16426
def319f9 16427/* pcm configuration: identical with ALC880 */
f32610ed
JS
16428#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16429#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16430#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16431#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16432
16433/*
16434 * configuration and preset
16435 */
ea734963 16436static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16437 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16438 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16439 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16440 [ALC861VD_3ST] = "3stack",
16441 [ALC861VD_3ST_DIG] = "3stack-digout",
16442 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16443 [ALC861VD_LENOVO] = "lenovo",
272a527c 16444 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16445 [ALC861VD_HP] = "hp",
f32610ed
JS
16446 [ALC861VD_AUTO] = "auto",
16447};
16448
a9111321 16449static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16450 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16451 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16452 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16453 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16454 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16455 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16456 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16457 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16458 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16459 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16460 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16461 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16462 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16463 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16464 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16465 {}
16466};
16467
a9111321 16468static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16469 [ALC660VD_3ST] = {
16470 .mixers = { alc861vd_3st_mixer },
16471 .init_verbs = { alc861vd_volume_init_verbs,
16472 alc861vd_3stack_init_verbs },
16473 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16474 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16475 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16476 .channel_mode = alc861vd_3stack_2ch_modes,
16477 .input_mux = &alc861vd_capture_source,
16478 },
6963f84c
MC
16479 [ALC660VD_3ST_DIG] = {
16480 .mixers = { alc861vd_3st_mixer },
16481 .init_verbs = { alc861vd_volume_init_verbs,
16482 alc861vd_3stack_init_verbs },
16483 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16484 .dac_nids = alc660vd_dac_nids,
16485 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16486 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16487 .channel_mode = alc861vd_3stack_2ch_modes,
16488 .input_mux = &alc861vd_capture_source,
16489 },
f32610ed
JS
16490 [ALC861VD_3ST] = {
16491 .mixers = { alc861vd_3st_mixer },
16492 .init_verbs = { alc861vd_volume_init_verbs,
16493 alc861vd_3stack_init_verbs },
16494 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16495 .dac_nids = alc861vd_dac_nids,
16496 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16497 .channel_mode = alc861vd_3stack_2ch_modes,
16498 .input_mux = &alc861vd_capture_source,
16499 },
16500 [ALC861VD_3ST_DIG] = {
16501 .mixers = { alc861vd_3st_mixer },
16502 .init_verbs = { alc861vd_volume_init_verbs,
16503 alc861vd_3stack_init_verbs },
16504 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16505 .dac_nids = alc861vd_dac_nids,
16506 .dig_out_nid = ALC861VD_DIGOUT_NID,
16507 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16508 .channel_mode = alc861vd_3stack_2ch_modes,
16509 .input_mux = &alc861vd_capture_source,
16510 },
16511 [ALC861VD_6ST_DIG] = {
16512 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16513 .init_verbs = { alc861vd_volume_init_verbs,
16514 alc861vd_6stack_init_verbs },
16515 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16516 .dac_nids = alc861vd_dac_nids,
16517 .dig_out_nid = ALC861VD_DIGOUT_NID,
16518 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16519 .channel_mode = alc861vd_6stack_modes,
16520 .input_mux = &alc861vd_capture_source,
16521 },
bdd148a3
KY
16522 [ALC861VD_LENOVO] = {
16523 .mixers = { alc861vd_lenovo_mixer },
16524 .init_verbs = { alc861vd_volume_init_verbs,
16525 alc861vd_3stack_init_verbs,
16526 alc861vd_eapd_verbs,
16527 alc861vd_lenovo_unsol_verbs },
16528 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16529 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16530 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16531 .channel_mode = alc861vd_3stack_2ch_modes,
16532 .input_mux = &alc861vd_capture_source,
16533 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16534 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16535 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16536 },
272a527c
KY
16537 [ALC861VD_DALLAS] = {
16538 .mixers = { alc861vd_dallas_mixer },
16539 .init_verbs = { alc861vd_dallas_verbs },
16540 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16541 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16542 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16543 .channel_mode = alc861vd_3stack_2ch_modes,
16544 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 16545 .unsol_event = alc_sku_unsol_event,
4f5d1706 16546 .setup = alc861vd_dallas_setup,
d922b51d 16547 .init_hook = alc_hp_automute,
d1a991a6
KY
16548 },
16549 [ALC861VD_HP] = {
16550 .mixers = { alc861vd_hp_mixer },
16551 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16552 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16553 .dac_nids = alc861vd_dac_nids,
d1a991a6 16554 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16555 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16556 .channel_mode = alc861vd_3stack_2ch_modes,
16557 .input_mux = &alc861vd_hp_capture_source,
d922b51d 16558 .unsol_event = alc_sku_unsol_event,
4f5d1706 16559 .setup = alc861vd_dallas_setup,
d922b51d 16560 .init_hook = alc_hp_automute,
ea1fb29a 16561 },
13c94744
TI
16562 [ALC660VD_ASUS_V1S] = {
16563 .mixers = { alc861vd_lenovo_mixer },
16564 .init_verbs = { alc861vd_volume_init_verbs,
16565 alc861vd_3stack_init_verbs,
16566 alc861vd_eapd_verbs,
16567 alc861vd_lenovo_unsol_verbs },
16568 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16569 .dac_nids = alc660vd_dac_nids,
16570 .dig_out_nid = ALC861VD_DIGOUT_NID,
16571 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16572 .channel_mode = alc861vd_3stack_2ch_modes,
16573 .input_mux = &alc861vd_capture_source,
16574 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16575 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16576 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16577 },
f32610ed
JS
16578};
16579
16580/*
16581 * BIOS auto configuration
16582 */
f32610ed
JS
16583#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16584#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16585
16586/* add playback controls from the parsed DAC table */
569ed348 16587/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
16588 * different NIDs for mute/unmute switch and volume control */
16589static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16590 const struct auto_pin_cfg *cfg)
16591{
f32610ed 16592 hda_nid_t nid_v, nid_s;
ce764ab2 16593 int i, err, noutputs;
f32610ed 16594
ce764ab2
TI
16595 noutputs = cfg->line_outs;
16596 if (spec->multi_ios > 0)
16597 noutputs += spec->multi_ios;
16598
16599 for (i = 0; i < noutputs; i++) {
6843ca16
TI
16600 const char *name;
16601 int index;
f12ab1e0 16602 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16603 continue;
16604 nid_v = alc861vd_idx_to_mixer_vol(
16605 alc880_dac_to_idx(
16606 spec->multiout.dac_nids[i]));
16607 nid_s = alc861vd_idx_to_mixer_switch(
16608 alc880_dac_to_idx(
16609 spec->multiout.dac_nids[i]));
16610
6843ca16
TI
16611 name = alc_get_line_out_pfx(spec, i, true, &index);
16612 if (!name) {
f32610ed 16613 /* Center/LFE */
0afe5f89
TI
16614 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16615 "Center",
f12ab1e0
TI
16616 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
16617 HDA_OUTPUT));
16618 if (err < 0)
f32610ed 16619 return err;
0afe5f89
TI
16620 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
16621 "LFE",
f12ab1e0
TI
16622 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
16623 HDA_OUTPUT));
16624 if (err < 0)
f32610ed 16625 return err;
0afe5f89
TI
16626 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16627 "Center",
f12ab1e0
TI
16628 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
16629 HDA_INPUT));
16630 if (err < 0)
f32610ed 16631 return err;
0afe5f89
TI
16632 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
16633 "LFE",
f12ab1e0
TI
16634 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
16635 HDA_INPUT));
16636 if (err < 0)
f32610ed
JS
16637 return err;
16638 } else {
bcb2f0f5 16639 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 16640 name, index,
f12ab1e0
TI
16641 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
16642 HDA_OUTPUT));
16643 if (err < 0)
f32610ed 16644 return err;
bcb2f0f5 16645 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 16646 name, index,
bdd148a3 16647 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
16648 HDA_INPUT));
16649 if (err < 0)
f32610ed
JS
16650 return err;
16651 }
16652 }
16653 return 0;
16654}
16655
16656/* add playback controls for speaker and HP outputs */
16657/* Based on ALC880 version. But ALC861VD has separate,
16658 * different NIDs for mute/unmute switch and volume control */
16659static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16660 hda_nid_t pin, const char *pfx)
16661{
16662 hda_nid_t nid_v, nid_s;
16663 int err;
f32610ed 16664
f12ab1e0 16665 if (!pin)
f32610ed
JS
16666 return 0;
16667
16668 if (alc880_is_fixed_pin(pin)) {
16669 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
16670 /* specify the DAC as the extra output */
f12ab1e0 16671 if (!spec->multiout.hp_nid)
f32610ed
JS
16672 spec->multiout.hp_nid = nid_v;
16673 else
16674 spec->multiout.extra_out_nid[0] = nid_v;
16675 /* control HP volume/switch on the output mixer amp */
16676 nid_v = alc861vd_idx_to_mixer_vol(
16677 alc880_fixed_pin_idx(pin));
16678 nid_s = alc861vd_idx_to_mixer_switch(
16679 alc880_fixed_pin_idx(pin));
16680
0afe5f89 16681 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
16682 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
16683 if (err < 0)
f32610ed 16684 return err;
0afe5f89 16685 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
16686 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16687 if (err < 0)
f32610ed
JS
16688 return err;
16689 } else if (alc880_is_multi_pin(pin)) {
16690 /* set manual connection */
16691 /* we have only a switch on HP-out PIN */
0afe5f89 16692 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
16693 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
16694 if (err < 0)
f32610ed
JS
16695 return err;
16696 }
16697 return 0;
16698}
16699
16700/* parse the BIOS configuration and set up the alc_spec
16701 * return 1 if successful, 0 if the proper config is not found,
16702 * or a negative error code
16703 * Based on ALC880 version - had to change it to override
16704 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
16705static int alc861vd_parse_auto_config(struct hda_codec *codec)
16706{
16707 struct alc_spec *spec = codec->spec;
16708 int err;
4c6d72d1 16709 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 16710
f12ab1e0
TI
16711 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16712 alc861vd_ignore);
16713 if (err < 0)
f32610ed 16714 return err;
f12ab1e0 16715 if (!spec->autocfg.line_outs)
f32610ed
JS
16716 return 0; /* can't find valid BIOS pin config */
16717
343a04be 16718 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
16719 if (err < 0)
16720 return err;
343a04be 16721 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
16722 if (err < 0)
16723 return err;
16724 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
16725 if (err < 0)
16726 return err;
16727 err = alc861vd_auto_create_extra_out(spec,
16728 spec->autocfg.speaker_pins[0],
16729 "Speaker");
16730 if (err < 0)
16731 return err;
16732 err = alc861vd_auto_create_extra_out(spec,
16733 spec->autocfg.hp_pins[0],
16734 "Headphone");
16735 if (err < 0)
16736 return err;
b7821709 16737 err = alc_auto_create_input_ctls(codec);
f12ab1e0 16738 if (err < 0)
f32610ed
JS
16739 return err;
16740
16741 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16742
757899ac 16743 alc_auto_parse_digital(codec);
f32610ed 16744
603c4019 16745 if (spec->kctls.list)
d88897ea 16746 add_mixer(spec, spec->kctls.list);
f32610ed 16747
f32610ed 16748 spec->num_mux_defs = 1;
61b9b9b1 16749 spec->input_mux = &spec->private_imux[0];
f32610ed 16750
d6cc9fab
TI
16751 if (!spec->dual_adc_switch)
16752 alc_remove_invalid_adc_nids(codec);
16753
776e184e
TI
16754 err = alc_auto_add_mic_boost(codec);
16755 if (err < 0)
16756 return err;
16757
6227cdce 16758 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 16759
f32610ed
JS
16760 return 1;
16761}
16762
16763/* additional initialization for auto-configuration model */
16764static void alc861vd_auto_init(struct hda_codec *codec)
16765{
f6c7e546 16766 struct alc_spec *spec = codec->spec;
343a04be
TI
16767 alc_auto_init_multi_out(codec);
16768 alc_auto_init_extra_out(codec);
0a7f5320 16769 alc_auto_init_analog_input(codec);
f970de25 16770 alc_auto_init_input_src(codec);
757899ac 16771 alc_auto_init_digital(codec);
f6c7e546 16772 if (spec->unsol_event)
7fb0d78f 16773 alc_inithook(codec);
f32610ed
JS
16774}
16775
f8f25ba3
TI
16776enum {
16777 ALC660VD_FIX_ASUS_GPIO1
16778};
16779
16780/* reset GPIO1 */
f8f25ba3
TI
16781static const struct alc_fixup alc861vd_fixups[] = {
16782 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
16783 .type = ALC_FIXUP_VERBS,
16784 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
16785 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
16786 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
16787 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
16788 { }
16789 }
f8f25ba3
TI
16790 },
16791};
16792
a9111321 16793static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
16794 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
16795 {}
16796};
16797
f32610ed
JS
16798static int patch_alc861vd(struct hda_codec *codec)
16799{
16800 struct alc_spec *spec;
16801 int err, board_config;
16802
16803 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16804 if (spec == NULL)
16805 return -ENOMEM;
16806
16807 codec->spec = spec;
16808
1f0f4b80
TI
16809 spec->mixer_nid = 0x0b;
16810
f32610ed
JS
16811 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
16812 alc861vd_models,
16813 alc861vd_cfg_tbl);
16814
16815 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
16816 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16817 codec->chip_name);
f32610ed
JS
16818 board_config = ALC861VD_AUTO;
16819 }
16820
b5bfbc67
TI
16821 if (board_config == ALC861VD_AUTO) {
16822 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16823 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16824 }
f8f25ba3 16825
f32610ed
JS
16826 if (board_config == ALC861VD_AUTO) {
16827 /* automatic parse from the BIOS config */
16828 err = alc861vd_parse_auto_config(codec);
16829 if (err < 0) {
16830 alc_free(codec);
16831 return err;
f12ab1e0 16832 } else if (!err) {
f32610ed
JS
16833 printk(KERN_INFO
16834 "hda_codec: Cannot set up configuration "
16835 "from BIOS. Using base mode...\n");
16836 board_config = ALC861VD_3ST;
16837 }
16838 }
16839
680cd536
KK
16840 err = snd_hda_attach_beep_device(codec, 0x23);
16841 if (err < 0) {
16842 alc_free(codec);
16843 return err;
16844 }
16845
f32610ed 16846 if (board_config != ALC861VD_AUTO)
e9c364c0 16847 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 16848
2f893286 16849 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 16850 /* always turn on EAPD */
d88897ea 16851 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
16852 }
16853
f32610ed
JS
16854 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
16855 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
16856
f32610ed
JS
16857 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
16858 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
16859
dd704698 16860 if (!spec->adc_nids) {
d6cc9fab
TI
16861 alc_auto_fill_adc_caps(codec);
16862 alc_remove_invalid_adc_nids(codec);
dd704698 16863 }
f32610ed 16864
b59bdf3b 16865 set_capture_mixer(codec);
45bdd1c1 16866 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 16867
2134ea4f
TI
16868 spec->vmaster_nid = 0x02;
16869
b5bfbc67 16870 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16871
f32610ed
JS
16872 codec->patch_ops = alc_patch_ops;
16873
16874 if (board_config == ALC861VD_AUTO)
16875 spec->init_hook = alc861vd_auto_init;
1c716153 16876 spec->shutup = alc_eapd_shutup;
cb53c626
TI
16877#ifdef CONFIG_SND_HDA_POWER_SAVE
16878 if (!spec->loopback.amplist)
16879 spec->loopback.amplist = alc861vd_loopbacks;
16880#endif
f32610ed
JS
16881
16882 return 0;
16883}
16884
bc9f98a9
KY
16885/*
16886 * ALC662 support
16887 *
16888 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
16889 * configuration. Each pin widget can choose any input DACs and a mixer.
16890 * Each ADC is connected from a mixer of all inputs. This makes possible
16891 * 6-channel independent captures.
16892 *
16893 * In addition, an independent DAC for the multi-playback (not used in this
16894 * driver yet).
16895 */
16896#define ALC662_DIGOUT_NID 0x06
16897#define ALC662_DIGIN_NID 0x0a
16898
4c6d72d1 16899static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 16900 /* front, rear, clfe */
bc9f98a9
KY
16901 0x02, 0x03, 0x04
16902};
16903
4c6d72d1 16904static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
16905 0x02, 0x03
16906};
16907
4c6d72d1 16908static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 16909 /* ADC1-2 */
b59bdf3b 16910 0x09, 0x08
bc9f98a9 16911};
e1406348 16912
4c6d72d1 16913static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
16914 /* ADC1-2 */
16915 0x08,
16916};
16917
4c6d72d1
TI
16918static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16919static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 16920
e1406348 16921
bc9f98a9
KY
16922/* input MUX */
16923/* FIXME: should be a matrix-type input source selection */
a9111321 16924static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
16925 .num_items = 4,
16926 .items = {
16927 { "Mic", 0x0 },
16928 { "Front Mic", 0x1 },
16929 { "Line", 0x2 },
16930 { "CD", 0x4 },
16931 },
16932};
16933
a9111321 16934static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
16935 .num_items = 2,
16936 .items = {
16937 { "Mic", 0x1 },
16938 { "Line", 0x2 },
16939 },
16940};
291702f0 16941
a9111321 16942static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
16943 .num_items = 3,
16944 .items = {
16945 { "Mic", 0x0 },
16946 { "Front Mic", 0x1 },
16947 { "Line", 0x2 },
16948 },
16949};
16950
4f5d1706 16951#if 0 /* set to 1 for testing other input sources below */
a9111321 16952static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
16953 .num_items = 16,
16954 .items = {
16955 { "Autoselect Mic", 0x0 },
16956 { "Internal Mic", 0x1 },
16957 { "In-0x02", 0x2 },
16958 { "In-0x03", 0x3 },
16959 { "In-0x04", 0x4 },
16960 { "In-0x05", 0x5 },
16961 { "In-0x06", 0x6 },
16962 { "In-0x07", 0x7 },
16963 { "In-0x08", 0x8 },
16964 { "In-0x09", 0x9 },
16965 { "In-0x0a", 0x0a },
16966 { "In-0x0b", 0x0b },
16967 { "In-0x0c", 0x0c },
16968 { "In-0x0d", 0x0d },
16969 { "In-0x0e", 0x0e },
16970 { "In-0x0f", 0x0f },
16971 },
16972};
16973#endif
16974
bc9f98a9
KY
16975/*
16976 * 2ch mode
16977 */
a9111321 16978static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
16979 { 2, NULL }
16980};
16981
16982/*
16983 * 2ch mode
16984 */
a9111321 16985static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
16986 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16987 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16988 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16989 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16990 { } /* end */
16991};
16992
16993/*
16994 * 6ch mode
16995 */
a9111321 16996static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
16997 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16998 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16999 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17000 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17001 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17002 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17003 { } /* end */
17004};
17005
a9111321 17006static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17007 { 2, alc662_3ST_ch2_init },
17008 { 6, alc662_3ST_ch6_init },
17009};
17010
17011/*
17012 * 2ch mode
17013 */
a9111321 17014static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17015 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17016 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17017 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17018 { } /* end */
17019};
17020
17021/*
17022 * 6ch mode
17023 */
a9111321 17024static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17025 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17026 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17027 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17028 { } /* end */
17029};
17030
a9111321 17031static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17032 { 2, alc662_sixstack_ch6_init },
17033 { 6, alc662_sixstack_ch8_init },
17034};
17035
17036/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17037 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17038 */
17039
a9111321 17040static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17041 /* output mixer control */
17042 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17043 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17044 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17045 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17046 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17047 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17048 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17049 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17050 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17051
17052 /*Input mixer control */
17053 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17054 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17055 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17056 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17057 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17058 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17059 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17060 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17061 { } /* end */
17062};
17063
a9111321 17064static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17065 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17066 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17068 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17069 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17070 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17071 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17072 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17073 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17075 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17076 { } /* end */
17077};
17078
a9111321 17079static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17080 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17081 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17082 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17083 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17084 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17085 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17086 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17087 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17090 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17095 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17096 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17097 { } /* end */
17098};
17099
a9111321 17100static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17101 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17102 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17103 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17104 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17105 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17106 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17107 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17108 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17110 { } /* end */
17111};
17112
a9111321 17113static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17114 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17115 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17116
5f99f86a 17117 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17118 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17119 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17120
5f99f86a 17121 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17122 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17123 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17124 { } /* end */
17125};
17126
a9111321 17127static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17128 ALC262_HIPPO_MASTER_SWITCH,
17129 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17130 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17131 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17132 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17133 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17134 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17135 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17136 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17137 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17138 { } /* end */
17139};
17140
a9111321 17141static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17142 .ops = &snd_hda_bind_vol,
17143 .values = {
17144 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17145 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17146 0
17147 },
17148};
17149
a9111321 17150static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17151 .ops = &snd_hda_bind_sw,
17152 .values = {
17153 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17154 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17155 0
17156 },
17157};
17158
a9111321 17159static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17160 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17161 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17164 { } /* end */
17165};
17166
a9111321 17167static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17168 .ops = &snd_hda_bind_sw,
17169 .values = {
17170 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17171 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17172 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17173 0
17174 },
17175};
17176
a9111321 17177static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17178 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17179 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17180 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17181 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17182 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17183 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17184
17185 { } /* end */
17186};
17187
a9111321 17188static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17189 .ops = &snd_hda_bind_sw,
17190 .values = {
17191 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17192 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17193 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17194 0
17195 },
17196};
17197
a9111321 17198static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17199 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17200 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17201 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17202 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17203 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17204 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17205 { } /* end */
17206};
17207
a9111321 17208static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17209 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17210 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17214 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17215 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17216 { } /* end */
17217};
17218
a9111321 17219static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17220 .ops = &snd_hda_bind_vol,
17221 .values = {
17222 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17223 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17224 0
17225 },
17226};
17227
a9111321 17228static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17229 .ops = &snd_hda_bind_sw,
17230 .values = {
17231 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17232 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17233 0
17234 },
17235};
17236
a9111321 17237static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17238 HDA_BIND_VOL("Master Playback Volume",
17239 &alc663_asus_two_bind_master_vol),
17240 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17245 { } /* end */
17246};
17247
a9111321 17248static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17249 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17250 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17252 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17254 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17255 { } /* end */
17256};
17257
a9111321 17258static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17259 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17260 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17261 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17262 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17264
17265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17266 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17267 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17268 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17269 { } /* end */
17270};
17271
a9111321 17272static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17273 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17274 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17276
17277 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17279 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17280 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17281 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17282 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17283 { } /* end */
17284};
17285
a9111321 17286static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17287 .ops = &snd_hda_bind_sw,
17288 .values = {
17289 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17290 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17291 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17292 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17293 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17294 0
17295 },
17296};
17297
a9111321 17298static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17299 .ops = &snd_hda_bind_sw,
17300 .values = {
17301 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17302 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17303 0
17304 },
17305};
17306
a9111321 17307static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17308 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17309 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17310 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17311 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17312 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17313 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17314 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17316 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17317 { } /* end */
17318};
17319
a9111321 17320static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17321 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17322 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17323 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17324 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17325 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17326 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17327 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17328 { } /* end */
17329};
17330
17331
a9111321 17332static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17333 {
17334 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17335 .name = "Channel Mode",
17336 .info = alc_ch_mode_info,
17337 .get = alc_ch_mode_get,
17338 .put = alc_ch_mode_put,
17339 },
17340 { } /* end */
17341};
17342
a9111321 17343static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17344 /* ADC: mute amp left and right */
17345 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17346 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17347
b60dd394
KY
17348 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17349 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17350 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17351 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17352 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17353 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17354
17355 /* Front Pin: output 0 (0x0c) */
17356 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17357 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17358
17359 /* Rear Pin: output 1 (0x0d) */
17360 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17361 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17362
17363 /* CLFE Pin: output 2 (0x0e) */
17364 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17365 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17366
17367 /* Mic (rear) pin: input vref at 80% */
17368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17369 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17370 /* Front Mic pin: input vref at 80% */
17371 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17372 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17373 /* Line In pin: input */
17374 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17375 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17376 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17377 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17378 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17379 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17380 /* CD pin widget for input */
17381 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17382
17383 /* FIXME: use matrix-type input source selection */
17384 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17385 /* Input mixer */
17386 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17387 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17388
a7f2371f
TI
17389 { }
17390};
17391
a9111321 17392static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17393 /* always trun on EAPD */
17394 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17395 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17396 { }
17397};
17398
a9111321 17399static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17400 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17401 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17402 {}
17403};
17404
a9111321 17405static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17406 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17407 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17408 {}
bc9f98a9
KY
17409};
17410
8c427226 17411/* Set Unsolicited Event*/
a9111321 17412static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17413 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17415 {}
17416};
17417
a9111321 17418static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17419 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17420 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17421 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17422 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17423 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17426 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17427 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17428 {}
17429};
17430
a9111321 17431static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17432 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17433 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17434 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17437 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17438 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17439 {}
17440};
17441
a9111321 17442static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17444 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17445 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17446 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17447 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17448 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17449 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17450 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17451 {}
17452};
6dda9f4a 17453
a9111321 17454static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17455 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17456 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17457 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17458 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17459 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17460 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17461 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17462 {}
17463};
6dda9f4a 17464
a9111321 17465static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17466 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17467 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17468 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17469 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17470 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17472 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17475 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17476 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17477 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17478 {}
17479};
17480
a9111321 17481static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
17482 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17483 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17484 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17485 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17486 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17487 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17488 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17489 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17490 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17491 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17492 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17493 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17494 {}
17495};
17496
a9111321 17497static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
17498 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17499 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17500 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17501
17502 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17503 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17504 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17505
17506 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17507 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17508 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17509 {}
17510};
17511
a9111321 17512static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
17513 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17514 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17515 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17516
17517 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17518 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17519 {}
17520};
17521
a9111321 17522static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
17523 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17525 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17526 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17527 {}
17528};
17529
a9111321 17530static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
17531 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17532 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17533 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17534 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17535 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17536 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17537 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17538 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17539 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17540 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17541 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17542 {}
17543};
17544
a9111321 17545static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
17546 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17547 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17548 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17549 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17550 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17551 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17552 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17553 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17554 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17555 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17556 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17557 {}
17558};
17559
a9111321 17560static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
17561 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17562 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17563 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17564 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17565 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17566 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17567 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17568 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17569 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17570 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17572 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17573 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17574 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17575 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17576 {}
17577};
17578
a9111321 17579static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
17580 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17584 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17585 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17586 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17588 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17589 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17590 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17592 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17593 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17594 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17595 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17596 {}
17597};
17598
a9111321 17599static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
17600 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17601 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17602 { } /* end */
17603};
17604
a9111321 17605static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
17606 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17607 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17608 { } /* end */
17609};
17610
e6a5e1b7 17611static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 17612{
e6a5e1b7 17613 struct alc_spec *spec = codec->spec;
bc9f98a9 17614
e6a5e1b7
TI
17615 spec->autocfg.hp_pins[0] = 0x1b;
17616 spec->autocfg.line_out_pins[0] = 0x14;
17617 spec->autocfg.speaker_pins[0] = 0x15;
17618 spec->automute = 1;
17619 spec->detect_line = 1;
17620 spec->automute_lines = 1;
17621 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
17622}
17623
4f5d1706
TI
17624static void alc662_eeepc_setup(struct hda_codec *codec)
17625{
17626 struct alc_spec *spec = codec->spec;
17627
17628 alc262_hippo1_setup(codec);
17629 spec->ext_mic.pin = 0x18;
17630 spec->ext_mic.mux_idx = 0;
17631 spec->int_mic.pin = 0x19;
17632 spec->int_mic.mux_idx = 1;
17633 spec->auto_mic = 1;
17634}
17635
4f5d1706 17636static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 17637{
42171c17
TI
17638 struct alc_spec *spec = codec->spec;
17639
17640 spec->autocfg.hp_pins[0] = 0x14;
17641 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
17642 spec->automute = 1;
17643 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
17644}
17645
4f5d1706
TI
17646static void alc663_m51va_setup(struct hda_codec *codec)
17647{
17648 struct alc_spec *spec = codec->spec;
3b8510ce
TI
17649 spec->autocfg.hp_pins[0] = 0x21;
17650 spec->autocfg.speaker_pins[0] = 0x14;
17651 spec->automute_mixer_nid[0] = 0x0c;
17652 spec->automute = 1;
17653 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
17654 spec->ext_mic.pin = 0x18;
17655 spec->ext_mic.mux_idx = 0;
17656 spec->int_mic.pin = 0x12;
ebb83eeb 17657 spec->int_mic.mux_idx = 9;
4f5d1706
TI
17658 spec->auto_mic = 1;
17659}
17660
f1d4e28b 17661/* ***************** Mode1 ******************************/
ebb83eeb
KY
17662static void alc663_mode1_setup(struct hda_codec *codec)
17663{
17664 struct alc_spec *spec = codec->spec;
3b8510ce
TI
17665 spec->autocfg.hp_pins[0] = 0x21;
17666 spec->autocfg.speaker_pins[0] = 0x14;
17667 spec->automute_mixer_nid[0] = 0x0c;
17668 spec->automute = 1;
17669 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
17670 spec->ext_mic.pin = 0x18;
17671 spec->ext_mic.mux_idx = 0;
17672 spec->int_mic.pin = 0x19;
17673 spec->int_mic.mux_idx = 1;
17674 spec->auto_mic = 1;
17675}
17676
f1d4e28b 17677/* ***************** Mode2 ******************************/
3b8510ce 17678static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 17679{
3b8510ce
TI
17680 struct alc_spec *spec = codec->spec;
17681 spec->autocfg.hp_pins[0] = 0x1b;
17682 spec->autocfg.speaker_pins[0] = 0x14;
17683 spec->automute = 1;
17684 spec->automute_mode = ALC_AUTOMUTE_PIN;
17685 spec->ext_mic.pin = 0x18;
17686 spec->ext_mic.mux_idx = 0;
17687 spec->int_mic.pin = 0x19;
17688 spec->int_mic.mux_idx = 1;
17689 spec->auto_mic = 1;
f1d4e28b
KY
17690}
17691
f1d4e28b 17692/* ***************** Mode3 ******************************/
3b8510ce 17693static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 17694{
3b8510ce
TI
17695 struct alc_spec *spec = codec->spec;
17696 spec->autocfg.hp_pins[0] = 0x21;
17697 spec->autocfg.hp_pins[0] = 0x15;
17698 spec->autocfg.speaker_pins[0] = 0x14;
17699 spec->automute = 1;
17700 spec->automute_mode = ALC_AUTOMUTE_PIN;
17701 spec->ext_mic.pin = 0x18;
17702 spec->ext_mic.mux_idx = 0;
17703 spec->int_mic.pin = 0x19;
17704 spec->int_mic.mux_idx = 1;
17705 spec->auto_mic = 1;
f1d4e28b
KY
17706}
17707
f1d4e28b 17708/* ***************** Mode4 ******************************/
3b8510ce 17709static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 17710{
3b8510ce
TI
17711 struct alc_spec *spec = codec->spec;
17712 spec->autocfg.hp_pins[0] = 0x21;
17713 spec->autocfg.speaker_pins[0] = 0x14;
17714 spec->autocfg.speaker_pins[1] = 0x16;
17715 spec->automute_mixer_nid[0] = 0x0c;
17716 spec->automute_mixer_nid[1] = 0x0e;
17717 spec->automute = 1;
17718 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17719 spec->ext_mic.pin = 0x18;
17720 spec->ext_mic.mux_idx = 0;
17721 spec->int_mic.pin = 0x19;
17722 spec->int_mic.mux_idx = 1;
17723 spec->auto_mic = 1;
f1d4e28b
KY
17724}
17725
f1d4e28b 17726/* ***************** Mode5 ******************************/
3b8510ce 17727static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 17728{
3b8510ce
TI
17729 struct alc_spec *spec = codec->spec;
17730 spec->autocfg.hp_pins[0] = 0x15;
17731 spec->autocfg.speaker_pins[0] = 0x14;
17732 spec->autocfg.speaker_pins[1] = 0x16;
17733 spec->automute_mixer_nid[0] = 0x0c;
17734 spec->automute_mixer_nid[1] = 0x0e;
17735 spec->automute = 1;
17736 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17737 spec->ext_mic.pin = 0x18;
17738 spec->ext_mic.mux_idx = 0;
17739 spec->int_mic.pin = 0x19;
17740 spec->int_mic.mux_idx = 1;
17741 spec->auto_mic = 1;
f1d4e28b
KY
17742}
17743
f1d4e28b 17744/* ***************** Mode6 ******************************/
3b8510ce 17745static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 17746{
3b8510ce
TI
17747 struct alc_spec *spec = codec->spec;
17748 spec->autocfg.hp_pins[0] = 0x1b;
17749 spec->autocfg.hp_pins[0] = 0x15;
17750 spec->autocfg.speaker_pins[0] = 0x14;
17751 spec->automute_mixer_nid[0] = 0x0c;
17752 spec->automute = 1;
17753 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17754 spec->ext_mic.pin = 0x18;
17755 spec->ext_mic.mux_idx = 0;
17756 spec->int_mic.pin = 0x19;
17757 spec->int_mic.mux_idx = 1;
17758 spec->auto_mic = 1;
f1d4e28b
KY
17759}
17760
ebb83eeb 17761/* ***************** Mode7 ******************************/
3b8510ce 17762static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 17763{
3b8510ce
TI
17764 struct alc_spec *spec = codec->spec;
17765 spec->autocfg.hp_pins[0] = 0x1b;
17766 spec->autocfg.hp_pins[0] = 0x21;
17767 spec->autocfg.speaker_pins[0] = 0x14;
17768 spec->autocfg.speaker_pins[0] = 0x17;
17769 spec->automute = 1;
17770 spec->automute_mode = ALC_AUTOMUTE_PIN;
17771 spec->ext_mic.pin = 0x18;
17772 spec->ext_mic.mux_idx = 0;
17773 spec->int_mic.pin = 0x19;
17774 spec->int_mic.mux_idx = 1;
17775 spec->auto_mic = 1;
ebb83eeb
KY
17776}
17777
17778/* ***************** Mode8 ******************************/
3b8510ce 17779static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 17780{
3b8510ce
TI
17781 struct alc_spec *spec = codec->spec;
17782 spec->autocfg.hp_pins[0] = 0x21;
17783 spec->autocfg.hp_pins[1] = 0x15;
17784 spec->autocfg.speaker_pins[0] = 0x14;
17785 spec->autocfg.speaker_pins[0] = 0x17;
17786 spec->automute = 1;
17787 spec->automute_mode = ALC_AUTOMUTE_PIN;
17788 spec->ext_mic.pin = 0x18;
17789 spec->ext_mic.mux_idx = 0;
17790 spec->int_mic.pin = 0x12;
17791 spec->int_mic.mux_idx = 9;
17792 spec->auto_mic = 1;
ebb83eeb
KY
17793}
17794
e6a5e1b7 17795static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 17796{
e6a5e1b7
TI
17797 struct alc_spec *spec = codec->spec;
17798 spec->autocfg.hp_pins[0] = 0x21;
17799 spec->autocfg.line_out_pins[0] = 0x15;
17800 spec->autocfg.speaker_pins[0] = 0x14;
17801 spec->automute = 1;
17802 spec->automute_mode = ALC_AUTOMUTE_AMP;
17803 spec->detect_line = 1;
17804 spec->automute_lines = 1;
17805 spec->ext_mic.pin = 0x18;
17806 spec->ext_mic.mux_idx = 0;
17807 spec->int_mic.pin = 0x12;
17808 spec->int_mic.mux_idx = 9;
17809 spec->auto_mic = 1;
6dda9f4a
KY
17810}
17811
4f5d1706
TI
17812#define alc663_g50v_setup alc663_m51va_setup
17813
a9111321 17814static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 17815 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 17816 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 17817
5f99f86a 17818 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17819 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17820 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 17821
5f99f86a 17822 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17823 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17824 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
17825 { } /* end */
17826};
17827
a9111321 17828static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
17829 /* Master Playback automatically created from Speaker and Headphone */
17830 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17831 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17832 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17833 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17834
8607f7c4
DH
17835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 17837 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 17838
28c4edb7
DH
17839 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17840 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 17841 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
17842 { } /* end */
17843};
17844
cb53c626
TI
17845#ifdef CONFIG_SND_HDA_POWER_SAVE
17846#define alc662_loopbacks alc880_loopbacks
17847#endif
17848
bc9f98a9 17849
def319f9 17850/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
17851#define alc662_pcm_analog_playback alc880_pcm_analog_playback
17852#define alc662_pcm_analog_capture alc880_pcm_analog_capture
17853#define alc662_pcm_digital_playback alc880_pcm_digital_playback
17854#define alc662_pcm_digital_capture alc880_pcm_digital_capture
17855
17856/*
17857 * configuration and preset
17858 */
ea734963 17859static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
17860 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17861 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17862 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 17863 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 17864 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 17865 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 17866 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 17867 [ALC662_ECS] = "ecs",
6dda9f4a
KY
17868 [ALC663_ASUS_M51VA] = "m51va",
17869 [ALC663_ASUS_G71V] = "g71v",
17870 [ALC663_ASUS_H13] = "h13",
17871 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
17872 [ALC663_ASUS_MODE1] = "asus-mode1",
17873 [ALC662_ASUS_MODE2] = "asus-mode2",
17874 [ALC663_ASUS_MODE3] = "asus-mode3",
17875 [ALC663_ASUS_MODE4] = "asus-mode4",
17876 [ALC663_ASUS_MODE5] = "asus-mode5",
17877 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
17878 [ALC663_ASUS_MODE7] = "asus-mode7",
17879 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
17880 [ALC272_DELL] = "dell",
17881 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 17882 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
17883 [ALC662_AUTO] = "auto",
17884};
17885
a9111321 17886static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 17887 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
17888 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17889 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 17890 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 17891 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 17892 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 17893 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 17894 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 17895 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 17896 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
17897 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17898 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 17899 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17900 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17901 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17902 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17903 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17904 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 17905 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
17906 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17907 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
17908 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17909 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17910 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17911 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 17912 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
17913 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17914 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17915 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 17916 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17917 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17918 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17919 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 17920 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 17921 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
17922 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17923 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17924 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 17925 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 17926 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 17927 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 17928 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
17929 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17930 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
17931 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17932 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17933 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 17934 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
17935 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17936 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 17937 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
17938 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17939 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17940 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17941 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17942 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 17943 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 17944 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 17945 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
17946 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17947 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17948 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17949 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
17950 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17951 ALC662_3ST_6ch_DIG),
4dee8baa 17952 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 17953 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
17954 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17955 ALC662_3ST_6ch_DIG),
6227cdce 17956 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 17957 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 17958 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 17959 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 17960 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 17961 ALC662_3ST_6ch_DIG),
dea0a509
TI
17962 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17963 ALC663_ASUS_H13),
965b76d2 17964 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
17965 {}
17966};
17967
a9111321 17968static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 17969 [ALC662_3ST_2ch_DIG] = {
f9e336f6 17970 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 17971 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17972 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17973 .dac_nids = alc662_dac_nids,
17974 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17975 .dig_in_nid = ALC662_DIGIN_NID,
17976 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17977 .channel_mode = alc662_3ST_2ch_modes,
17978 .input_mux = &alc662_capture_source,
17979 },
17980 [ALC662_3ST_6ch_DIG] = {
f9e336f6 17981 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 17982 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17983 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17984 .dac_nids = alc662_dac_nids,
17985 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
17986 .dig_in_nid = ALC662_DIGIN_NID,
17987 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17988 .channel_mode = alc662_3ST_6ch_modes,
17989 .need_dac_fix = 1,
17990 .input_mux = &alc662_capture_source,
f12ab1e0 17991 },
bc9f98a9 17992 [ALC662_3ST_6ch] = {
f9e336f6 17993 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 17994 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
17995 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17996 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
17997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17998 .channel_mode = alc662_3ST_6ch_modes,
17999 .need_dac_fix = 1,
18000 .input_mux = &alc662_capture_source,
f12ab1e0 18001 },
bc9f98a9 18002 [ALC662_5ST_DIG] = {
f9e336f6 18003 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18004 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18005 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18006 .dac_nids = alc662_dac_nids,
18007 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18008 .dig_in_nid = ALC662_DIGIN_NID,
18009 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18010 .channel_mode = alc662_5stack_modes,
18011 .input_mux = &alc662_capture_source,
18012 },
18013 [ALC662_LENOVO_101E] = {
f9e336f6 18014 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18015 .init_verbs = { alc662_init_verbs,
18016 alc662_eapd_init_verbs,
18017 alc662_sue_init_verbs },
bc9f98a9
KY
18018 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18019 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18020 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18021 .channel_mode = alc662_3ST_2ch_modes,
18022 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18023 .unsol_event = alc_sku_unsol_event,
18024 .setup = alc662_lenovo_101e_setup,
18025 .init_hook = alc_inithook,
bc9f98a9 18026 },
291702f0 18027 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18028 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18029 .init_verbs = { alc662_init_verbs,
a7f2371f 18030 alc662_eapd_init_verbs,
291702f0
KY
18031 alc662_eeepc_sue_init_verbs },
18032 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18033 .dac_nids = alc662_dac_nids,
291702f0
KY
18034 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18035 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18036 .unsol_event = alc_sku_unsol_event,
4f5d1706 18037 .setup = alc662_eeepc_setup,
e9427969 18038 .init_hook = alc_inithook,
291702f0 18039 },
8c427226 18040 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18041 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18042 alc662_chmode_mixer },
18043 .init_verbs = { alc662_init_verbs,
a7f2371f 18044 alc662_eapd_init_verbs,
8c427226
KY
18045 alc662_eeepc_ep20_sue_init_verbs },
18046 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18047 .dac_nids = alc662_dac_nids,
8c427226
KY
18048 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18049 .channel_mode = alc662_3ST_6ch_modes,
18050 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18051 .unsol_event = alc_sku_unsol_event,
4f5d1706 18052 .setup = alc662_eeepc_ep20_setup,
e9427969 18053 .init_hook = alc_inithook,
8c427226 18054 },
f1d4e28b 18055 [ALC662_ECS] = {
f9e336f6 18056 .mixers = { alc662_ecs_mixer },
f1d4e28b 18057 .init_verbs = { alc662_init_verbs,
a7f2371f 18058 alc662_eapd_init_verbs,
f1d4e28b
KY
18059 alc662_ecs_init_verbs },
18060 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18061 .dac_nids = alc662_dac_nids,
18062 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18063 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18064 .unsol_event = alc_sku_unsol_event,
4f5d1706 18065 .setup = alc662_eeepc_setup,
e9427969 18066 .init_hook = alc_inithook,
f1d4e28b 18067 },
6dda9f4a 18068 [ALC663_ASUS_M51VA] = {
f9e336f6 18069 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18070 .init_verbs = { alc662_init_verbs,
18071 alc662_eapd_init_verbs,
18072 alc663_m51va_init_verbs },
6dda9f4a
KY
18073 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18074 .dac_nids = alc662_dac_nids,
18075 .dig_out_nid = ALC662_DIGOUT_NID,
18076 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18077 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18078 .unsol_event = alc_sku_unsol_event,
4f5d1706 18079 .setup = alc663_m51va_setup,
3b8510ce 18080 .init_hook = alc_inithook,
6dda9f4a
KY
18081 },
18082 [ALC663_ASUS_G71V] = {
f9e336f6 18083 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18084 .init_verbs = { alc662_init_verbs,
18085 alc662_eapd_init_verbs,
18086 alc663_g71v_init_verbs },
6dda9f4a
KY
18087 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18088 .dac_nids = alc662_dac_nids,
18089 .dig_out_nid = ALC662_DIGOUT_NID,
18090 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18091 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18092 .unsol_event = alc_sku_unsol_event,
4f5d1706 18093 .setup = alc663_g71v_setup,
e6a5e1b7 18094 .init_hook = alc_inithook,
6dda9f4a
KY
18095 },
18096 [ALC663_ASUS_H13] = {
f9e336f6 18097 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18098 .init_verbs = { alc662_init_verbs,
18099 alc662_eapd_init_verbs,
18100 alc663_m51va_init_verbs },
6dda9f4a
KY
18101 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18102 .dac_nids = alc662_dac_nids,
18103 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18104 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18105 .setup = alc663_m51va_setup,
18106 .unsol_event = alc_sku_unsol_event,
18107 .init_hook = alc_inithook,
6dda9f4a
KY
18108 },
18109 [ALC663_ASUS_G50V] = {
f9e336f6 18110 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18111 .init_verbs = { alc662_init_verbs,
18112 alc662_eapd_init_verbs,
18113 alc663_g50v_init_verbs },
6dda9f4a
KY
18114 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18115 .dac_nids = alc662_dac_nids,
18116 .dig_out_nid = ALC662_DIGOUT_NID,
18117 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18118 .channel_mode = alc662_3ST_6ch_modes,
18119 .input_mux = &alc663_capture_source,
3b8510ce 18120 .unsol_event = alc_sku_unsol_event,
4f5d1706 18121 .setup = alc663_g50v_setup,
3b8510ce 18122 .init_hook = alc_inithook,
6dda9f4a 18123 },
f1d4e28b 18124 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18125 .mixers = { alc663_m51va_mixer },
18126 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18127 .init_verbs = { alc662_init_verbs,
a7f2371f 18128 alc662_eapd_init_verbs,
f1d4e28b
KY
18129 alc663_21jd_amic_init_verbs },
18130 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18131 .hp_nid = 0x03,
18132 .dac_nids = alc662_dac_nids,
18133 .dig_out_nid = ALC662_DIGOUT_NID,
18134 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18135 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18136 .unsol_event = alc_sku_unsol_event,
4f5d1706 18137 .setup = alc663_mode1_setup,
3b8510ce 18138 .init_hook = alc_inithook,
f1d4e28b
KY
18139 },
18140 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18141 .mixers = { alc662_1bjd_mixer },
18142 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18143 .init_verbs = { alc662_init_verbs,
a7f2371f 18144 alc662_eapd_init_verbs,
f1d4e28b
KY
18145 alc662_1bjd_amic_init_verbs },
18146 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18147 .dac_nids = alc662_dac_nids,
18148 .dig_out_nid = ALC662_DIGOUT_NID,
18149 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18150 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18151 .unsol_event = alc_sku_unsol_event,
4f5d1706 18152 .setup = alc662_mode2_setup,
3b8510ce 18153 .init_hook = alc_inithook,
f1d4e28b
KY
18154 },
18155 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18156 .mixers = { alc663_two_hp_m1_mixer },
18157 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18158 .init_verbs = { alc662_init_verbs,
a7f2371f 18159 alc662_eapd_init_verbs,
f1d4e28b
KY
18160 alc663_two_hp_amic_m1_init_verbs },
18161 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18162 .hp_nid = 0x03,
18163 .dac_nids = alc662_dac_nids,
18164 .dig_out_nid = ALC662_DIGOUT_NID,
18165 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18166 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18167 .unsol_event = alc_sku_unsol_event,
4f5d1706 18168 .setup = alc663_mode3_setup,
3b8510ce 18169 .init_hook = alc_inithook,
f1d4e28b
KY
18170 },
18171 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18172 .mixers = { alc663_asus_21jd_clfe_mixer },
18173 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18174 .init_verbs = { alc662_init_verbs,
a7f2371f 18175 alc662_eapd_init_verbs,
f1d4e28b
KY
18176 alc663_21jd_amic_init_verbs},
18177 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18178 .hp_nid = 0x03,
18179 .dac_nids = alc662_dac_nids,
18180 .dig_out_nid = ALC662_DIGOUT_NID,
18181 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18182 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18183 .unsol_event = alc_sku_unsol_event,
4f5d1706 18184 .setup = alc663_mode4_setup,
3b8510ce 18185 .init_hook = alc_inithook,
f1d4e28b
KY
18186 },
18187 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18188 .mixers = { alc663_asus_15jd_clfe_mixer },
18189 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18190 .init_verbs = { alc662_init_verbs,
a7f2371f 18191 alc662_eapd_init_verbs,
f1d4e28b
KY
18192 alc663_15jd_amic_init_verbs },
18193 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18194 .hp_nid = 0x03,
18195 .dac_nids = alc662_dac_nids,
18196 .dig_out_nid = ALC662_DIGOUT_NID,
18197 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18198 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18199 .unsol_event = alc_sku_unsol_event,
4f5d1706 18200 .setup = alc663_mode5_setup,
3b8510ce 18201 .init_hook = alc_inithook,
f1d4e28b
KY
18202 },
18203 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18204 .mixers = { alc663_two_hp_m2_mixer },
18205 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18206 .init_verbs = { alc662_init_verbs,
a7f2371f 18207 alc662_eapd_init_verbs,
f1d4e28b
KY
18208 alc663_two_hp_amic_m2_init_verbs },
18209 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18210 .hp_nid = 0x03,
18211 .dac_nids = alc662_dac_nids,
18212 .dig_out_nid = ALC662_DIGOUT_NID,
18213 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18214 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18215 .unsol_event = alc_sku_unsol_event,
4f5d1706 18216 .setup = alc663_mode6_setup,
3b8510ce 18217 .init_hook = alc_inithook,
f1d4e28b 18218 },
ebb83eeb
KY
18219 [ALC663_ASUS_MODE7] = {
18220 .mixers = { alc663_mode7_mixer },
18221 .cap_mixer = alc662_auto_capture_mixer,
18222 .init_verbs = { alc662_init_verbs,
a7f2371f 18223 alc662_eapd_init_verbs,
ebb83eeb
KY
18224 alc663_mode7_init_verbs },
18225 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18226 .hp_nid = 0x03,
18227 .dac_nids = alc662_dac_nids,
18228 .dig_out_nid = ALC662_DIGOUT_NID,
18229 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18230 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18231 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18232 .setup = alc663_mode7_setup,
3b8510ce 18233 .init_hook = alc_inithook,
ebb83eeb
KY
18234 },
18235 [ALC663_ASUS_MODE8] = {
18236 .mixers = { alc663_mode8_mixer },
18237 .cap_mixer = alc662_auto_capture_mixer,
18238 .init_verbs = { alc662_init_verbs,
a7f2371f 18239 alc662_eapd_init_verbs,
ebb83eeb
KY
18240 alc663_mode8_init_verbs },
18241 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18242 .hp_nid = 0x03,
18243 .dac_nids = alc662_dac_nids,
18244 .dig_out_nid = ALC662_DIGOUT_NID,
18245 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18246 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18247 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18248 .setup = alc663_mode8_setup,
3b8510ce 18249 .init_hook = alc_inithook,
ebb83eeb 18250 },
622e84cd
KY
18251 [ALC272_DELL] = {
18252 .mixers = { alc663_m51va_mixer },
18253 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18254 .init_verbs = { alc662_init_verbs,
18255 alc662_eapd_init_verbs,
18256 alc272_dell_init_verbs },
622e84cd 18257 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18258 .dac_nids = alc272_dac_nids,
622e84cd
KY
18259 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18260 .adc_nids = alc272_adc_nids,
18261 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18262 .capsrc_nids = alc272_capsrc_nids,
18263 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18264 .unsol_event = alc_sku_unsol_event,
4f5d1706 18265 .setup = alc663_m51va_setup,
3b8510ce 18266 .init_hook = alc_inithook,
622e84cd
KY
18267 },
18268 [ALC272_DELL_ZM1] = {
18269 .mixers = { alc663_m51va_mixer },
18270 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18271 .init_verbs = { alc662_init_verbs,
18272 alc662_eapd_init_verbs,
18273 alc272_dell_zm1_init_verbs },
622e84cd 18274 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18275 .dac_nids = alc272_dac_nids,
622e84cd
KY
18276 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18277 .adc_nids = alc662_adc_nids,
b59bdf3b 18278 .num_adc_nids = 1,
622e84cd
KY
18279 .capsrc_nids = alc662_capsrc_nids,
18280 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18281 .unsol_event = alc_sku_unsol_event,
4f5d1706 18282 .setup = alc663_m51va_setup,
3b8510ce 18283 .init_hook = alc_inithook,
622e84cd 18284 },
9541ba1d
CP
18285 [ALC272_SAMSUNG_NC10] = {
18286 .mixers = { alc272_nc10_mixer },
18287 .init_verbs = { alc662_init_verbs,
a7f2371f 18288 alc662_eapd_init_verbs,
9541ba1d
CP
18289 alc663_21jd_amic_init_verbs },
18290 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18291 .dac_nids = alc272_dac_nids,
18292 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18293 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18294 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18295 .unsol_event = alc_sku_unsol_event,
4f5d1706 18296 .setup = alc663_mode4_setup,
3b8510ce 18297 .init_hook = alc_inithook,
9541ba1d 18298 },
bc9f98a9
KY
18299};
18300
18301
18302/*
18303 * BIOS auto configuration
18304 */
18305
7085ec12 18306/* convert from MIX nid to DAC */
604401a9 18307static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18308{
604401a9 18309 hda_nid_t list[5];
1304ac89
TI
18310 int i, num;
18311
18312 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18313 for (i = 0; i < num; i++) {
18314 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18315 return list[i];
18316 }
18317 return 0;
7085ec12
TI
18318}
18319
604401a9
TI
18320/* go down to the selector widget before the mixer */
18321static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18322{
18323 hda_nid_t srcs[5];
18324 int num = snd_hda_get_connections(codec, pin, srcs,
18325 ARRAY_SIZE(srcs));
18326 if (num != 1 ||
18327 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18328 return pin;
18329 return srcs[0];
18330}
18331
7085ec12 18332/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18333static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18334 hda_nid_t dac)
18335{
cc1c452e 18336 hda_nid_t mix[5];
7085ec12
TI
18337 int i, num;
18338
604401a9 18339 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18340 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18341 for (i = 0; i < num; i++) {
604401a9 18342 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18343 return mix[i];
18344 }
18345 return 0;
18346}
18347
ce764ab2
TI
18348/* select the connection from pin to DAC if needed */
18349static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18350 hda_nid_t dac)
18351{
18352 hda_nid_t mix[5];
18353 int i, num;
18354
18355 pin = alc_go_down_to_selector(codec, pin);
18356 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18357 if (num < 2)
18358 return 0;
18359 for (i = 0; i < num; i++) {
18360 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18361 snd_hda_codec_update_cache(codec, pin, 0,
18362 AC_VERB_SET_CONNECT_SEL, i);
18363 return 0;
18364 }
18365 }
18366 return 0;
18367}
18368
7085ec12 18369/* look for an empty DAC slot */
604401a9 18370static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18371{
18372 struct alc_spec *spec = codec->spec;
18373 hda_nid_t srcs[5];
3af9ee6b 18374 int i, num;
7085ec12 18375
604401a9 18376 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18377 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18378 for (i = 0; i < num; i++) {
604401a9 18379 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18380 if (!nid)
18381 continue;
3af9ee6b
TI
18382 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18383 spec->multiout.num_dacs))
18384 continue;
18385 if (spec->multiout.hp_nid == nid)
18386 continue;
18387 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18388 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18389 continue;
18390 return nid;
7085ec12
TI
18391 }
18392 return 0;
18393}
18394
3af9ee6b
TI
18395static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18396{
18397 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18398 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18399 return alc_auto_look_for_dac(codec, pin);
18400 return 0;
18401}
18402
7085ec12 18403/* fill in the dac_nids table from the parsed pin configuration */
343a04be 18404static int alc_auto_fill_dac_nids(struct hda_codec *codec)
7085ec12
TI
18405{
18406 struct alc_spec *spec = codec->spec;
cb053a82 18407 const struct auto_pin_cfg *cfg = &spec->autocfg;
350434ee 18408 bool redone = false;
7085ec12 18409 int i;
7085ec12 18410
3af9ee6b 18411 again:
3fccdfd8 18412 spec->multiout.num_dacs = 0;
3af9ee6b
TI
18413 spec->multiout.hp_nid = 0;
18414 spec->multiout.extra_out_nid[0] = 0;
18415 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18416 spec->multiout.dac_nids = spec->private_dac_nids;
18417
18418 /* fill hard-wired DACs first */
18419 if (!redone) {
18420 for (i = 0; i < cfg->line_outs; i++)
18421 spec->private_dac_nids[i] =
18422 get_dac_if_single(codec, cfg->line_out_pins[i]);
18423 if (cfg->hp_outs)
18424 spec->multiout.hp_nid =
18425 get_dac_if_single(codec, cfg->hp_pins[0]);
18426 if (cfg->speaker_outs)
18427 spec->multiout.extra_out_nid[0] =
18428 get_dac_if_single(codec, cfg->speaker_pins[0]);
18429 }
18430
7085ec12 18431 for (i = 0; i < cfg->line_outs; i++) {
3af9ee6b
TI
18432 hda_nid_t pin = cfg->line_out_pins[i];
18433 if (spec->private_dac_nids[i])
7085ec12 18434 continue;
3af9ee6b
TI
18435 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18436 if (!spec->private_dac_nids[i] && !redone) {
18437 /* if we can't find primary DACs, re-probe without
18438 * checking the hard-wired DACs
18439 */
18440 redone = true;
18441 goto again;
18442 }
18443 }
18444
18445 for (i = 0; i < cfg->line_outs; i++) {
18446 if (spec->private_dac_nids[i])
18447 spec->multiout.num_dacs++;
18448 else
18449 memmove(spec->private_dac_nids + i,
18450 spec->private_dac_nids + i + 1,
18451 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
7085ec12 18452 }
3af9ee6b 18453
bb8bf4d4
TI
18454 if (cfg->hp_outs && !spec->multiout.hp_nid)
18455 spec->multiout.hp_nid =
18456 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18457 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18458 spec->multiout.extra_out_nid[0] =
18459 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18460
7085ec12
TI
18461 return 0;
18462}
18463
343a04be 18464static int alc_auto_add_vol_ctl(struct hda_codec *codec,
97aaab7b
TI
18465 const char *pfx, int cidx,
18466 hda_nid_t nid, unsigned int chs)
7085ec12 18467{
97aaab7b
TI
18468 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18469 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
7085ec12
TI
18470}
18471
343a04be
TI
18472#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18473 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
97aaab7b
TI
18474
18475/* create a mute-switch for the given mixer widget;
18476 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18477 */
343a04be 18478static int alc_auto_add_sw_ctl(struct hda_codec *codec,
97aaab7b
TI
18479 const char *pfx, int cidx,
18480 hda_nid_t nid, unsigned int chs)
7085ec12 18481{
97aaab7b
TI
18482 int type;
18483 unsigned long val;
18484 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18485 type = ALC_CTL_WIDGET_MUTE;
18486 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18487 } else {
18488 type = ALC_CTL_BIND_MUTE;
18489 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18490 }
18491 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
7085ec12
TI
18492}
18493
343a04be
TI
18494#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18495 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
7085ec12 18496
bc9f98a9 18497/* add playback controls from the parsed DAC table */
343a04be 18498static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18499 const struct auto_pin_cfg *cfg)
18500{
7085ec12 18501 struct alc_spec *spec = codec->spec;
ce764ab2
TI
18502 hda_nid_t nid, mix, pin;
18503 int i, err, noutputs;
bc9f98a9 18504
ce764ab2
TI
18505 noutputs = cfg->line_outs;
18506 if (spec->multi_ios > 0)
18507 noutputs += spec->multi_ios;
18508
18509 for (i = 0; i < noutputs; i++) {
6843ca16
TI
18510 const char *name;
18511 int index;
7085ec12
TI
18512 nid = spec->multiout.dac_nids[i];
18513 if (!nid)
18514 continue;
ce764ab2
TI
18515 if (i >= cfg->line_outs)
18516 pin = spec->multi_io[i - 1].pin;
18517 else
18518 pin = cfg->line_out_pins[i];
18519 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18520 if (!mix)
bc9f98a9 18521 continue;
6843ca16
TI
18522 name = alc_get_line_out_pfx(spec, i, true, &index);
18523 if (!name) {
bc9f98a9 18524 /* Center/LFE */
343a04be 18525 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
bc9f98a9
KY
18526 if (err < 0)
18527 return err;
343a04be 18528 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
bc9f98a9
KY
18529 if (err < 0)
18530 return err;
343a04be 18531 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
bc9f98a9
KY
18532 if (err < 0)
18533 return err;
343a04be 18534 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
bc9f98a9
KY
18535 if (err < 0)
18536 return err;
18537 } else {
343a04be 18538 err = alc_auto_add_stereo_vol(codec, name, index, nid);
bc9f98a9
KY
18539 if (err < 0)
18540 return err;
343a04be 18541 err = alc_auto_add_stereo_sw(codec, name, index, mix);
bc9f98a9
KY
18542 if (err < 0)
18543 return err;
18544 }
18545 }
18546 return 0;
18547}
18548
18549/* add playback controls for speaker and HP outputs */
343a04be 18550static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3af9ee6b 18551 hda_nid_t dac, const char *pfx)
bc9f98a9 18552{
7085ec12 18553 struct alc_spec *spec = codec->spec;
3af9ee6b 18554 hda_nid_t mix;
bc9f98a9 18555 int err;
bc9f98a9
KY
18556
18557 if (!pin)
18558 return 0;
3af9ee6b 18559 if (!dac) {
7085ec12
TI
18560 /* the corresponding DAC is already occupied */
18561 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18562 return 0; /* no way */
18563 /* create a switch only */
0afe5f89 18564 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18565 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18566 }
18567
3af9ee6b 18568 mix = alc_auto_dac_to_mix(codec, pin, dac);
7085ec12
TI
18569 if (!mix)
18570 return 0;
343a04be 18571 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
7085ec12
TI
18572 if (err < 0)
18573 return err;
343a04be 18574 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
7085ec12
TI
18575 if (err < 0)
18576 return err;
3af9ee6b 18577 return 0;
bc9f98a9
KY
18578}
18579
343a04be
TI
18580static int alc_auto_create_hp_out(struct hda_codec *codec)
18581{
18582 struct alc_spec *spec = codec->spec;
18583 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18584 spec->multiout.hp_nid,
18585 "Headphone");
18586}
18587
18588static int alc_auto_create_speaker_out(struct hda_codec *codec)
18589{
18590 struct alc_spec *spec = codec->spec;
18591 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18592 spec->multiout.extra_out_nid[0],
18593 "Speaker");
18594}
18595
343a04be 18596static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
bc9f98a9 18597 hda_nid_t nid, int pin_type,
7085ec12 18598 hda_nid_t dac)
bc9f98a9 18599{
7085ec12 18600 int i, num;
343a04be 18601 hda_nid_t mix = 0;
ce503f38 18602 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18603
f6c7e546 18604 alc_set_pin_output(codec, nid, pin_type);
cd511556 18605 nid = alc_go_down_to_selector(codec, nid);
7085ec12 18606 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 18607 for (i = 0; i < num; i++) {
604401a9 18608 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 18609 continue;
cd511556
TI
18610 mix = srcs[i];
18611 break;
bc9f98a9 18612 }
cd511556
TI
18613 if (!mix)
18614 return;
18615
18616 /* need the manual connection? */
18617 if (num > 1)
18618 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18619 /* unmute mixer widget inputs */
18620 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18621 AMP_IN_UNMUTE(0));
18622 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18623 AMP_IN_UNMUTE(1));
18624 /* initialize volume */
18625 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18626 nid = dac;
18627 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18628 nid = mix;
18629 else
18630 return;
18631 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18632 AMP_OUT_ZERO);
bc9f98a9
KY
18633}
18634
343a04be 18635static void alc_auto_init_multi_out(struct hda_codec *codec)
bc9f98a9
KY
18636{
18637 struct alc_spec *spec = codec->spec;
7085ec12 18638 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18639 int i;
18640
18641 for (i = 0; i <= HDA_SIDE; i++) {
18642 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18643 if (nid)
343a04be 18644 alc_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18645 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18646 }
18647}
18648
343a04be 18649static void alc_auto_init_extra_out(struct hda_codec *codec)
bc9f98a9
KY
18650{
18651 struct alc_spec *spec = codec->spec;
18652 hda_nid_t pin;
18653
18654 pin = spec->autocfg.hp_pins[0];
7085ec12 18655 if (pin)
343a04be 18656 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
7085ec12 18657 spec->multiout.hp_nid);
f6c7e546
TI
18658 pin = spec->autocfg.speaker_pins[0];
18659 if (pin)
343a04be 18660 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
7085ec12 18661 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
18662}
18663
ce764ab2
TI
18664/*
18665 * multi-io helper
18666 */
18667static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18668 unsigned int location)
18669{
18670 struct alc_spec *spec = codec->spec;
18671 struct auto_pin_cfg *cfg = &spec->autocfg;
18672 int type, i, num_pins = 0;
18673
18674 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18675 for (i = 0; i < cfg->num_inputs; i++) {
18676 hda_nid_t nid = cfg->inputs[i].pin;
18677 hda_nid_t dac;
18678 unsigned int defcfg, caps;
18679 if (cfg->inputs[i].type != type)
18680 continue;
18681 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18682 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18683 continue;
18684 if (location && get_defcfg_location(defcfg) != location)
18685 continue;
18686 caps = snd_hda_query_pin_caps(codec, nid);
18687 if (!(caps & AC_PINCAP_OUT))
18688 continue;
18689 dac = alc_auto_look_for_dac(codec, nid);
18690 if (!dac)
18691 continue;
18692 spec->multi_io[num_pins].pin = nid;
18693 spec->multi_io[num_pins].dac = dac;
18694 num_pins++;
dda14410 18695 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
18696 }
18697 }
18698 spec->multiout.num_dacs = 1;
18699 if (num_pins < 2)
18700 return 0;
18701 return num_pins;
18702}
18703
18704static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18705 struct snd_ctl_elem_info *uinfo)
18706{
18707 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18708 struct alc_spec *spec = codec->spec;
18709
18710 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18711 uinfo->count = 1;
18712 uinfo->value.enumerated.items = spec->multi_ios + 1;
18713 if (uinfo->value.enumerated.item > spec->multi_ios)
18714 uinfo->value.enumerated.item = spec->multi_ios;
18715 sprintf(uinfo->value.enumerated.name, "%dch",
18716 (uinfo->value.enumerated.item + 1) * 2);
18717 return 0;
18718}
18719
18720static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18721 struct snd_ctl_elem_value *ucontrol)
18722{
18723 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18724 struct alc_spec *spec = codec->spec;
18725 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18726 return 0;
18727}
18728
18729static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18730{
18731 struct alc_spec *spec = codec->spec;
18732 hda_nid_t nid = spec->multi_io[idx].pin;
18733
18734 if (!spec->multi_io[idx].ctl_in)
18735 spec->multi_io[idx].ctl_in =
18736 snd_hda_codec_read(codec, nid, 0,
18737 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18738 if (output) {
18739 snd_hda_codec_update_cache(codec, nid, 0,
18740 AC_VERB_SET_PIN_WIDGET_CONTROL,
18741 PIN_OUT);
18742 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18743 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18744 HDA_AMP_MUTE, 0);
18745 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18746 } else {
18747 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18748 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18749 HDA_AMP_MUTE, HDA_AMP_MUTE);
18750 snd_hda_codec_update_cache(codec, nid, 0,
18751 AC_VERB_SET_PIN_WIDGET_CONTROL,
18752 spec->multi_io[idx].ctl_in);
18753 }
18754 return 0;
18755}
18756
18757static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18758 struct snd_ctl_elem_value *ucontrol)
18759{
18760 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18761 struct alc_spec *spec = codec->spec;
18762 int i, ch;
18763
18764 ch = ucontrol->value.enumerated.item[0];
18765 if (ch < 0 || ch > spec->multi_ios)
18766 return -EINVAL;
18767 if (ch == (spec->ext_channel_count - 1) / 2)
18768 return 0;
18769 spec->ext_channel_count = (ch + 1) * 2;
18770 for (i = 0; i < spec->multi_ios; i++)
18771 alc_set_multi_io(codec, i, i < ch);
18772 spec->multiout.max_channels = spec->ext_channel_count;
18773 return 1;
18774}
18775
a9111321 18776static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
18777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18778 .name = "Channel Mode",
18779 .info = alc_auto_ch_mode_info,
18780 .get = alc_auto_ch_mode_get,
18781 .put = alc_auto_ch_mode_put,
18782};
18783
cb053a82
TI
18784static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18785 int (*fill_dac)(struct hda_codec *))
ce764ab2
TI
18786{
18787 struct alc_spec *spec = codec->spec;
18788 struct auto_pin_cfg *cfg = &spec->autocfg;
18789 unsigned int location, defcfg;
18790 int num_pins;
18791
3fccdfd8
TI
18792 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18793 /* use HP as primary out */
18794 cfg->speaker_outs = cfg->line_outs;
18795 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18796 sizeof(cfg->speaker_pins));
18797 cfg->line_outs = cfg->hp_outs;
18798 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18799 cfg->hp_outs = 0;
18800 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18801 cfg->line_out_type = AUTO_PIN_HP_OUT;
cb053a82
TI
18802 if (fill_dac)
18803 fill_dac(codec);
3fccdfd8 18804 }
ce764ab2 18805 if (cfg->line_outs != 1 ||
3fccdfd8 18806 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
ce764ab2
TI
18807 return 0;
18808
18809 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18810 location = get_defcfg_location(defcfg);
18811
18812 num_pins = alc_auto_fill_multi_ios(codec, location);
18813 if (num_pins > 0) {
18814 struct snd_kcontrol_new *knew;
18815
18816 knew = alc_kcontrol_new(spec);
18817 if (!knew)
18818 return -ENOMEM;
18819 *knew = alc_auto_channel_mode_enum;
18820 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18821 if (!knew->name)
18822 return -ENOMEM;
18823
18824 spec->multi_ios = num_pins;
18825 spec->ext_channel_count = 2;
18826 spec->multiout.num_dacs = num_pins + 1;
18827 }
18828 return 0;
18829}
18830
bc9f98a9
KY
18831static int alc662_parse_auto_config(struct hda_codec *codec)
18832{
18833 struct alc_spec *spec = codec->spec;
18834 int err;
4c6d72d1 18835 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
18836
18837 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
18838 alc662_ignore);
18839 if (err < 0)
18840 return err;
18841 if (!spec->autocfg.line_outs)
18842 return 0; /* can't find valid BIOS pin config */
18843
343a04be 18844 err = alc_auto_fill_dac_nids(codec);
ce764ab2
TI
18845 if (err < 0)
18846 return err;
343a04be 18847 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
f12ab1e0
TI
18848 if (err < 0)
18849 return err;
343a04be 18850 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
18851 if (err < 0)
18852 return err;
343a04be 18853 err = alc_auto_create_extra_out(codec,
f12ab1e0 18854 spec->autocfg.speaker_pins[0],
3af9ee6b 18855 spec->multiout.extra_out_nid[0],
f12ab1e0
TI
18856 "Speaker");
18857 if (err < 0)
18858 return err;
343a04be 18859 err = alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3af9ee6b 18860 spec->multiout.hp_nid,
f12ab1e0
TI
18861 "Headphone");
18862 if (err < 0)
18863 return err;
b7821709 18864 err = alc_auto_create_input_ctls(codec);
f12ab1e0 18865 if (err < 0)
bc9f98a9
KY
18866 return err;
18867
18868 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
18869
757899ac 18870 alc_auto_parse_digital(codec);
bc9f98a9 18871
603c4019 18872 if (spec->kctls.list)
d88897ea 18873 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
18874
18875 spec->num_mux_defs = 1;
61b9b9b1 18876 spec->input_mux = &spec->private_imux[0];
ea1fb29a 18877
d6cc9fab
TI
18878 if (!spec->dual_adc_switch)
18879 alc_remove_invalid_adc_nids(codec);
18880
ee979a14
TI
18881 err = alc_auto_add_mic_boost(codec);
18882 if (err < 0)
18883 return err;
18884
6227cdce
KY
18885 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18886 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18887 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18888 else
18889 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 18890
8c87286f 18891 return 1;
bc9f98a9
KY
18892}
18893
18894/* additional initialization for auto-configuration model */
18895static void alc662_auto_init(struct hda_codec *codec)
18896{
f6c7e546 18897 struct alc_spec *spec = codec->spec;
343a04be
TI
18898 alc_auto_init_multi_out(codec);
18899 alc_auto_init_extra_out(codec);
0a7f5320 18900 alc_auto_init_analog_input(codec);
f970de25 18901 alc_auto_init_input_src(codec);
757899ac 18902 alc_auto_init_digital(codec);
f6c7e546 18903 if (spec->unsol_event)
7fb0d78f 18904 alc_inithook(codec);
bc9f98a9
KY
18905}
18906
6be7948f 18907static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 18908 const struct alc_fixup *fix, int action)
6fc398cb 18909{
b5bfbc67 18910 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 18911 return;
6be7948f
TB
18912 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
18913 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
18914 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
18915 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
18916 (0 << AC_AMPCAP_MUTE_SHIFT)))
18917 printk(KERN_WARNING
18918 "hda_codec: failed to override amp caps for NID 0x2\n");
18919}
18920
6cb3b707 18921enum {
2df03514 18922 ALC662_FIXUP_ASPIRE,
6cb3b707 18923 ALC662_FIXUP_IDEAPAD,
6be7948f 18924 ALC272_FIXUP_MARIO,
d2ebd479 18925 ALC662_FIXUP_CZC_P10T,
94024cd1 18926 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
18927};
18928
18929static const struct alc_fixup alc662_fixups[] = {
2df03514 18930 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
18931 .type = ALC_FIXUP_PINS,
18932 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
18933 { 0x15, 0x99130112 }, /* subwoofer */
18934 { }
18935 }
18936 },
6cb3b707 18937 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
18938 .type = ALC_FIXUP_PINS,
18939 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
18940 { 0x17, 0x99130112 }, /* subwoofer */
18941 { }
18942 }
18943 },
6be7948f 18944 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
18945 .type = ALC_FIXUP_FUNC,
18946 .v.func = alc272_fixup_mario,
d2ebd479
AA
18947 },
18948 [ALC662_FIXUP_CZC_P10T] = {
18949 .type = ALC_FIXUP_VERBS,
18950 .v.verbs = (const struct hda_verb[]) {
18951 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
18952 {}
18953 }
18954 },
94024cd1
DH
18955 [ALC662_FIXUP_SKU_IGNORE] = {
18956 .type = ALC_FIXUP_SKU,
18957 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 18958 },
6cb3b707
DH
18959};
18960
a9111321 18961static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 18962 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 18963 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 18964 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 18965 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 18966 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 18967 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 18968 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
18969 {}
18970};
18971
6be7948f
TB
18972static const struct alc_model_fixup alc662_fixup_models[] = {
18973 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
18974 {}
18975};
6cb3b707
DH
18976
18977
bc9f98a9
KY
18978static int patch_alc662(struct hda_codec *codec)
18979{
18980 struct alc_spec *spec;
18981 int err, board_config;
693194f3 18982 int coef;
bc9f98a9
KY
18983
18984 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
18985 if (!spec)
18986 return -ENOMEM;
18987
18988 codec->spec = spec;
18989
1f0f4b80
TI
18990 spec->mixer_nid = 0x0b;
18991
da00c244
KY
18992 alc_auto_parse_customize_define(codec);
18993
2c3bf9ab
TI
18994 alc_fix_pll_init(codec, 0x20, 0x04, 15);
18995
693194f3
KY
18996 coef = alc_read_coef_idx(codec, 0);
18997 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 18998 alc_codec_rename(codec, "ALC661");
693194f3
KY
18999 else if (coef & (1 << 14) &&
19000 codec->bus->pci->subsystem_vendor == 0x1025 &&
19001 spec->cdefine.platform_type == 1)
c027ddcd 19002 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19003 else if (coef == 0x4011)
19004 alc_codec_rename(codec, "ALC656");
274693f3 19005
bc9f98a9
KY
19006 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19007 alc662_models,
19008 alc662_cfg_tbl);
19009 if (board_config < 0) {
9a11f1aa
TI
19010 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19011 codec->chip_name);
bc9f98a9
KY
19012 board_config = ALC662_AUTO;
19013 }
19014
19015 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19016 alc_pick_fixup(codec, alc662_fixup_models,
19017 alc662_fixup_tbl, alc662_fixups);
19018 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19019 /* automatic parse from the BIOS config */
19020 err = alc662_parse_auto_config(codec);
19021 if (err < 0) {
19022 alc_free(codec);
19023 return err;
8c87286f 19024 } else if (!err) {
bc9f98a9
KY
19025 printk(KERN_INFO
19026 "hda_codec: Cannot set up configuration "
19027 "from BIOS. Using base mode...\n");
19028 board_config = ALC662_3ST_2ch_DIG;
19029 }
19030 }
19031
dc1eae25 19032 if (has_cdefine_beep(codec)) {
8af2591d
TI
19033 err = snd_hda_attach_beep_device(codec, 0x1);
19034 if (err < 0) {
19035 alc_free(codec);
19036 return err;
19037 }
680cd536
KK
19038 }
19039
bc9f98a9 19040 if (board_config != ALC662_AUTO)
e9c364c0 19041 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19042
bc9f98a9
KY
19043 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19044 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19045
bc9f98a9
KY
19046 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19047 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19048
dd704698 19049 if (!spec->adc_nids) {
d6cc9fab
TI
19050 alc_auto_fill_adc_caps(codec);
19051 alc_remove_invalid_adc_nids(codec);
dd704698 19052 }
bc9f98a9 19053
f9e336f6 19054 if (!spec->cap_mixer)
b59bdf3b 19055 set_capture_mixer(codec);
cec27c89 19056
dc1eae25 19057 if (has_cdefine_beep(codec)) {
da00c244
KY
19058 switch (codec->vendor_id) {
19059 case 0x10ec0662:
19060 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19061 break;
19062 case 0x10ec0272:
19063 case 0x10ec0663:
19064 case 0x10ec0665:
19065 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19066 break;
19067 case 0x10ec0273:
19068 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19069 break;
19070 }
cec27c89 19071 }
2134ea4f
TI
19072 spec->vmaster_nid = 0x02;
19073
b5bfbc67
TI
19074 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19075
bc9f98a9 19076 codec->patch_ops = alc_patch_ops;
b5bfbc67 19077 if (board_config == ALC662_AUTO)
bc9f98a9 19078 spec->init_hook = alc662_auto_init;
1c716153 19079 spec->shutup = alc_eapd_shutup;
6cb3b707 19080
bf1b0225
KY
19081 alc_init_jacks(codec);
19082
cb53c626
TI
19083#ifdef CONFIG_SND_HDA_POWER_SAVE
19084 if (!spec->loopback.amplist)
19085 spec->loopback.amplist = alc662_loopbacks;
19086#endif
bc9f98a9
KY
19087
19088 return 0;
19089}
19090
274693f3
KY
19091static int patch_alc888(struct hda_codec *codec)
19092{
19093 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19094 kfree(codec->chip_name);
01e0f137
KY
19095 if (codec->vendor_id == 0x10ec0887)
19096 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19097 else
19098 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19099 if (!codec->chip_name) {
19100 alc_free(codec);
274693f3 19101 return -ENOMEM;
ac2c92e0
TI
19102 }
19103 return patch_alc662(codec);
274693f3 19104 }
ac2c92e0 19105 return patch_alc882(codec);
274693f3
KY
19106}
19107
b478b998
KY
19108static int patch_alc899(struct hda_codec *codec)
19109{
19110 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19111 kfree(codec->chip_name);
19112 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19113 }
19114 return patch_alc882(codec);
19115}
19116
d1eb57f4
KY
19117/*
19118 * ALC680 support
19119 */
c69aefab 19120#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19121#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19122#define alc680_modes alc260_modes
19123
4c6d72d1 19124static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19125 /* Lout1, Lout2, hp */
19126 0x02, 0x03, 0x04
19127};
19128
4c6d72d1 19129static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19130 /* ADC0-2 */
19131 /* DMIC, MIC, Line-in*/
19132 0x07, 0x08, 0x09
19133};
19134
c69aefab
KY
19135/*
19136 * Analog capture ADC cgange
19137 */
66ceeb6b
TI
19138static void alc680_rec_autoswitch(struct hda_codec *codec)
19139{
19140 struct alc_spec *spec = codec->spec;
19141 struct auto_pin_cfg *cfg = &spec->autocfg;
19142 int pin_found = 0;
19143 int type_found = AUTO_PIN_LAST;
19144 hda_nid_t nid;
19145 int i;
19146
19147 for (i = 0; i < cfg->num_inputs; i++) {
19148 nid = cfg->inputs[i].pin;
06dec228 19149 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19150 continue;
19151 if (snd_hda_jack_detect(codec, nid)) {
19152 if (cfg->inputs[i].type < type_found) {
19153 type_found = cfg->inputs[i].type;
19154 pin_found = nid;
19155 }
19156 }
19157 }
19158
19159 nid = 0x07;
19160 if (pin_found)
19161 snd_hda_get_connections(codec, pin_found, &nid, 1);
19162
19163 if (nid != spec->cur_adc)
19164 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19165 spec->cur_adc = nid;
19166 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19167 spec->cur_adc_format);
19168}
19169
c69aefab
KY
19170static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19171 struct hda_codec *codec,
19172 unsigned int stream_tag,
19173 unsigned int format,
19174 struct snd_pcm_substream *substream)
19175{
19176 struct alc_spec *spec = codec->spec;
c69aefab 19177
66ceeb6b 19178 spec->cur_adc = 0x07;
c69aefab
KY
19179 spec->cur_adc_stream_tag = stream_tag;
19180 spec->cur_adc_format = format;
19181
66ceeb6b 19182 alc680_rec_autoswitch(codec);
c69aefab
KY
19183 return 0;
19184}
19185
19186static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19187 struct hda_codec *codec,
19188 struct snd_pcm_substream *substream)
19189{
19190 snd_hda_codec_cleanup_stream(codec, 0x07);
19191 snd_hda_codec_cleanup_stream(codec, 0x08);
19192 snd_hda_codec_cleanup_stream(codec, 0x09);
19193 return 0;
19194}
19195
a9111321 19196static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19197 .substreams = 1, /* can be overridden */
19198 .channels_min = 2,
19199 .channels_max = 2,
19200 /* NID is set in alc_build_pcms */
19201 .ops = {
19202 .prepare = alc680_capture_pcm_prepare,
19203 .cleanup = alc680_capture_pcm_cleanup
19204 },
19205};
19206
a9111321 19207static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19208 /* output mixer control */
19209 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19210 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19211 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19212 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19213 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19215 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19216 { }
19217};
19218
a9111321 19219static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19220 .ops = &snd_hda_bind_vol,
19221 .values = {
19222 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19223 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19224 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19225 0
19226 },
19227};
19228
a9111321 19229static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19230 .ops = &snd_hda_bind_sw,
19231 .values = {
19232 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19233 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19234 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19235 0
19236 },
19237};
19238
a9111321 19239static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19240 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19241 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19242 { } /* end */
19243};
19244
19245/*
19246 * generic initialization of ADC, input mixers and output mixers
19247 */
a9111321 19248static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19249 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19250 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19251 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19252
c69aefab
KY
19253 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19254 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19255 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19256 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19257 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19258 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19259
19260 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19261 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19263 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19264 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19265
19266 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19267 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19268 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19269
d1eb57f4
KY
19270 { }
19271};
19272
c69aefab
KY
19273/* toggle speaker-output according to the hp-jack state */
19274static void alc680_base_setup(struct hda_codec *codec)
19275{
19276 struct alc_spec *spec = codec->spec;
19277
19278 spec->autocfg.hp_pins[0] = 0x16;
19279 spec->autocfg.speaker_pins[0] = 0x14;
19280 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19281 spec->autocfg.num_inputs = 2;
19282 spec->autocfg.inputs[0].pin = 0x18;
19283 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19284 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19285 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19286 spec->automute = 1;
19287 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19288}
19289
19290static void alc680_unsol_event(struct hda_codec *codec,
19291 unsigned int res)
19292{
19293 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19294 alc_hp_automute(codec);
c69aefab
KY
19295 if ((res >> 26) == ALC880_MIC_EVENT)
19296 alc680_rec_autoswitch(codec);
19297}
19298
19299static void alc680_inithook(struct hda_codec *codec)
19300{
d922b51d 19301 alc_hp_automute(codec);
c69aefab
KY
19302 alc680_rec_autoswitch(codec);
19303}
19304
d1eb57f4
KY
19305/* create input playback/capture controls for the given pin */
19306static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19307 const char *ctlname, int idx)
19308{
19309 hda_nid_t dac;
19310 int err;
19311
19312 switch (nid) {
19313 case 0x14:
19314 dac = 0x02;
19315 break;
19316 case 0x15:
19317 dac = 0x03;
19318 break;
19319 case 0x16:
19320 dac = 0x04;
19321 break;
19322 default:
19323 return 0;
19324 }
19325 if (spec->multiout.dac_nids[0] != dac &&
19326 spec->multiout.dac_nids[1] != dac) {
19327 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19328 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19329 HDA_OUTPUT));
19330 if (err < 0)
19331 return err;
19332
19333 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19334 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19335
19336 if (err < 0)
19337 return err;
dda14410 19338 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19339 }
19340
19341 return 0;
19342}
19343
19344/* add playback controls from the parsed DAC table */
19345static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19346 const struct auto_pin_cfg *cfg)
19347{
19348 hda_nid_t nid;
19349 int err;
19350
19351 spec->multiout.dac_nids = spec->private_dac_nids;
19352
19353 nid = cfg->line_out_pins[0];
19354 if (nid) {
19355 const char *name;
2e925dde
TI
19356 int index;
19357 name = alc_get_line_out_pfx(spec, 0, true, &index);
d1eb57f4
KY
19358 err = alc680_new_analog_output(spec, nid, name, 0);
19359 if (err < 0)
19360 return err;
19361 }
19362
19363 nid = cfg->speaker_pins[0];
19364 if (nid) {
19365 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19366 if (err < 0)
19367 return err;
19368 }
19369 nid = cfg->hp_pins[0];
19370 if (nid) {
19371 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19372 if (err < 0)
19373 return err;
19374 }
19375
19376 return 0;
19377}
19378
19379static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19380 hda_nid_t nid, int pin_type)
19381{
19382 alc_set_pin_output(codec, nid, pin_type);
19383}
19384
19385static void alc680_auto_init_multi_out(struct hda_codec *codec)
19386{
19387 struct alc_spec *spec = codec->spec;
19388 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19389 if (nid) {
19390 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19391 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19392 }
19393}
19394
19395static void alc680_auto_init_hp_out(struct hda_codec *codec)
19396{
19397 struct alc_spec *spec = codec->spec;
19398 hda_nid_t pin;
19399
19400 pin = spec->autocfg.hp_pins[0];
19401 if (pin)
19402 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19403 pin = spec->autocfg.speaker_pins[0];
19404 if (pin)
19405 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19406}
19407
19408/* pcm configuration: identical with ALC880 */
19409#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19410#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19411#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19412#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19413#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19414
19415/*
19416 * BIOS auto configuration
19417 */
19418static int alc680_parse_auto_config(struct hda_codec *codec)
19419{
19420 struct alc_spec *spec = codec->spec;
19421 int err;
4c6d72d1 19422 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19423
19424 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19425 alc680_ignore);
19426 if (err < 0)
19427 return err;
c69aefab 19428
d1eb57f4
KY
19429 if (!spec->autocfg.line_outs) {
19430 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19431 spec->multiout.max_channels = 2;
19432 spec->no_analog = 1;
19433 goto dig_only;
19434 }
19435 return 0; /* can't find valid BIOS pin config */
19436 }
19437 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19438 if (err < 0)
19439 return err;
19440
19441 spec->multiout.max_channels = 2;
19442
19443 dig_only:
19444 /* digital only support output */
757899ac 19445 alc_auto_parse_digital(codec);
d1eb57f4
KY
19446 if (spec->kctls.list)
19447 add_mixer(spec, spec->kctls.list);
19448
d1eb57f4
KY
19449 err = alc_auto_add_mic_boost(codec);
19450 if (err < 0)
19451 return err;
19452
19453 return 1;
19454}
19455
d1eb57f4
KY
19456/* init callback for auto-configuration model -- overriding the default init */
19457static void alc680_auto_init(struct hda_codec *codec)
19458{
19459 struct alc_spec *spec = codec->spec;
19460 alc680_auto_init_multi_out(codec);
19461 alc680_auto_init_hp_out(codec);
0a7f5320 19462 alc_auto_init_analog_input(codec);
757899ac 19463 alc_auto_init_digital(codec);
d1eb57f4
KY
19464 if (spec->unsol_event)
19465 alc_inithook(codec);
19466}
19467
19468/*
19469 * configuration and preset
19470 */
ea734963 19471static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19472 [ALC680_BASE] = "base",
19473 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19474};
19475
a9111321 19476static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19477 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19478 {}
19479};
19480
a9111321 19481static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19482 [ALC680_BASE] = {
19483 .mixers = { alc680_base_mixer },
c69aefab 19484 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19485 .init_verbs = { alc680_init_verbs },
19486 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19487 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19488 .dig_out_nid = ALC680_DIGOUT_NID,
19489 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19490 .channel_mode = alc680_modes,
c69aefab
KY
19491 .unsol_event = alc680_unsol_event,
19492 .setup = alc680_base_setup,
19493 .init_hook = alc680_inithook,
19494
d1eb57f4
KY
19495 },
19496};
19497
19498static int patch_alc680(struct hda_codec *codec)
19499{
19500 struct alc_spec *spec;
19501 int board_config;
19502 int err;
19503
19504 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19505 if (spec == NULL)
19506 return -ENOMEM;
19507
19508 codec->spec = spec;
19509
1f0f4b80
TI
19510 /* ALC680 has no aa-loopback mixer */
19511
d1eb57f4
KY
19512 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19513 alc680_models,
19514 alc680_cfg_tbl);
19515
19516 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19517 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19518 codec->chip_name);
19519 board_config = ALC680_AUTO;
19520 }
19521
19522 if (board_config == ALC680_AUTO) {
19523 /* automatic parse from the BIOS config */
19524 err = alc680_parse_auto_config(codec);
19525 if (err < 0) {
19526 alc_free(codec);
19527 return err;
19528 } else if (!err) {
19529 printk(KERN_INFO
19530 "hda_codec: Cannot set up configuration "
19531 "from BIOS. Using base mode...\n");
19532 board_config = ALC680_BASE;
19533 }
19534 }
19535
19536 if (board_config != ALC680_AUTO)
19537 setup_preset(codec, &alc680_presets[board_config]);
19538
19539 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19540 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19541 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19542 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19543
19544 if (!spec->adc_nids) {
d6cc9fab
TI
19545 alc_auto_fill_adc_caps(codec);
19546 alc_remove_invalid_adc_nids(codec);
d1eb57f4
KY
19547 }
19548
19549 if (!spec->cap_mixer)
19550 set_capture_mixer(codec);
19551
19552 spec->vmaster_nid = 0x02;
19553
19554 codec->patch_ops = alc_patch_ops;
19555 if (board_config == ALC680_AUTO)
19556 spec->init_hook = alc680_auto_init;
19557
19558 return 0;
19559}
19560
1da177e4
LT
19561/*
19562 * patch entries
19563 */
a9111321 19564static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 19565 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 19566 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19567 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19568 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19569 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19570 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19571 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19572 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19573 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 19574 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 19575 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19576 .patch = patch_alc861 },
f32610ed
JS
19577 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19578 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19579 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19580 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19581 .patch = patch_alc882 },
bc9f98a9
KY
19582 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19583 .patch = patch_alc662 },
6dda9f4a 19584 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19585 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19586 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19587 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19588 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19589 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19590 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19591 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19592 .patch = patch_alc882 },
cb308f97 19593 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19594 .patch = patch_alc882 },
df694daa 19595 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 19596 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 19597 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19598 .patch = patch_alc882 },
274693f3 19599 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19600 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19601 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 19602 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
19603 {} /* terminator */
19604};
1289e9e8
TI
19605
19606MODULE_ALIAS("snd-hda-codec-id:10ec*");
19607
19608MODULE_LICENSE("GPL");
19609MODULE_DESCRIPTION("Realtek HD-audio codec");
19610
19611static struct hda_codec_preset_list realtek_list = {
19612 .preset = snd_hda_preset_realtek,
19613 .owner = THIS_MODULE,
19614};
19615
19616static int __init patch_realtek_init(void)
19617{
19618 return snd_hda_add_codec_preset(&realtek_list);
19619}
19620
19621static void __exit patch_realtek_exit(void)
19622{
19623 snd_hda_delete_codec_preset(&realtek_list);
19624}
19625
19626module_init(patch_realtek_init)
19627module_exit(patch_realtek_exit)