]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Fix unsol event initializations for VIA codecs
[mirror_ubuntu-bionic-kernel.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
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;
d922b51d
TI
408
409 /* auto-mute control */
410 int automute_mode;
3b8510ce 411 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 412
4a79ba34 413 int init_amp;
d433a678 414 int codec_variant; /* flag for other variants */
e64f14f4 415
2134ea4f
TI
416 /* for virtual master */
417 hda_nid_t vmaster_nid;
cb53c626
TI
418#ifdef CONFIG_SND_HDA_POWER_SAVE
419 struct hda_loopback_check loopback;
420#endif
2c3bf9ab
TI
421
422 /* for PLL fix */
423 hda_nid_t pll_nid;
424 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
425
426 /* fix-up list */
427 int fixup_id;
428 const struct alc_fixup *fixup_list;
429 const char *fixup_name;
ce764ab2
TI
430
431 /* multi-io */
432 int multi_ios;
433 struct alc_multi_io multi_io[4];
df694daa
KY
434};
435
436/*
437 * configuration template - to be copied to the spec instance
438 */
439struct alc_config_preset {
a9111321 440 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
441 * with spec
442 */
a9111321 443 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
444 const struct hda_verb *init_verbs[5];
445 unsigned int num_dacs;
4c6d72d1 446 const hda_nid_t *dac_nids;
df694daa
KY
447 hda_nid_t dig_out_nid; /* optional */
448 hda_nid_t hp_nid; /* optional */
4c6d72d1 449 const hda_nid_t *slave_dig_outs;
df694daa 450 unsigned int num_adc_nids;
4c6d72d1
TI
451 const hda_nid_t *adc_nids;
452 const hda_nid_t *capsrc_nids;
df694daa
KY
453 hda_nid_t dig_in_nid;
454 unsigned int num_channel_mode;
455 const struct hda_channel_mode *channel_mode;
4e195a7b 456 int need_dac_fix;
3b315d70 457 int const_channel_count;
a1e8d2da 458 unsigned int num_mux_defs;
df694daa 459 const struct hda_input_mux *input_mux;
ae6b813a 460 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 461 void (*setup)(struct hda_codec *);
ae6b813a 462 void (*init_hook)(struct hda_codec *);
cb53c626 463#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 464 const struct hda_amp_list *loopbacks;
c97259df 465 void (*power_hook)(struct hda_codec *codec);
cb53c626 466#endif
1da177e4
LT
467};
468
1da177e4
LT
469
470/*
471 * input MUX handling
472 */
9c7f852e
TI
473static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
474 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
475{
476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
477 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
478 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
479 if (mux_idx >= spec->num_mux_defs)
480 mux_idx = 0;
5311114d
TI
481 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
482 mux_idx = 0;
a1e8d2da 483 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
484}
485
9c7f852e
TI
486static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
487 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
488{
489 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
490 struct alc_spec *spec = codec->spec;
491 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
492
493 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
494 return 0;
495}
496
9c7f852e
TI
497static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
498 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
499{
500 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
501 struct alc_spec *spec = codec->spec;
cd896c33 502 const struct hda_input_mux *imux;
1da177e4 503 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 504 unsigned int mux_idx;
e1406348
TI
505 hda_nid_t nid = spec->capsrc_nids ?
506 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 507 unsigned int type;
1da177e4 508
cd896c33
TI
509 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
510 imux = &spec->input_mux[mux_idx];
5311114d
TI
511 if (!imux->num_items && mux_idx > 0)
512 imux = &spec->input_mux[0];
cd896c33 513
a22d543a 514 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 515 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
516 /* Matrix-mixer style (e.g. ALC882) */
517 unsigned int *cur_val = &spec->cur_mux[adc_idx];
518 unsigned int i, idx;
519
520 idx = ucontrol->value.enumerated.item[0];
521 if (idx >= imux->num_items)
522 idx = imux->num_items - 1;
523 if (*cur_val == idx)
524 return 0;
525 for (i = 0; i < imux->num_items; i++) {
526 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
527 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
528 imux->items[i].index,
529 HDA_AMP_MUTE, v);
530 }
531 *cur_val = idx;
532 return 1;
533 } else {
534 /* MUX style (e.g. ALC880) */
cd896c33 535 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
536 &spec->cur_mux[adc_idx]);
537 }
538}
e9edcee0 539
1da177e4
LT
540/*
541 * channel mode setting
542 */
9c7f852e
TI
543static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
545{
546 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
547 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
548 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
549 spec->num_channel_mode);
1da177e4
LT
550}
551
9c7f852e
TI
552static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
554{
555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
556 struct alc_spec *spec = codec->spec;
d2a6d7dc 557 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 558 spec->num_channel_mode,
3b315d70 559 spec->ext_channel_count);
1da177e4
LT
560}
561
9c7f852e
TI
562static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
564{
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct alc_spec *spec = codec->spec;
4e195a7b
TI
567 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
568 spec->num_channel_mode,
3b315d70
HM
569 &spec->ext_channel_count);
570 if (err >= 0 && !spec->const_channel_count) {
571 spec->multiout.max_channels = spec->ext_channel_count;
572 if (spec->need_dac_fix)
573 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
574 }
4e195a7b 575 return err;
1da177e4
LT
576}
577
a9430dd8 578/*
4c5186ed 579 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 580 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
581 * being part of a format specifier. Maximum allowed length of a value is
582 * 63 characters plus NULL terminator.
7cf51e48
JW
583 *
584 * Note: some retasking pin complexes seem to ignore requests for input
585 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
586 * are requested. Therefore order this list so that this behaviour will not
587 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
588 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
589 * March 2006.
4c5186ed 590 */
a9111321 591static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
592 "Mic 50pc bias", "Mic 80pc bias",
593 "Line in", "Line out", "Headphone out",
4c5186ed 594};
a9111321 595static const unsigned char alc_pin_mode_values[] = {
7cf51e48 596 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
597};
598/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
599 * in the pin being assumed to be exclusively an input or an output pin. In
600 * addition, "input" pins may or may not process the mic bias option
601 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
602 * accept requests for bias as of chip versions up to March 2006) and/or
603 * wiring in the computer.
a9430dd8 604 */
a1e8d2da
JW
605#define ALC_PIN_DIR_IN 0x00
606#define ALC_PIN_DIR_OUT 0x01
607#define ALC_PIN_DIR_INOUT 0x02
608#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
609#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 610
ea1fb29a 611/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
612 * For each direction the minimum and maximum values are given.
613 */
a9111321 614static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
615 { 0, 2 }, /* ALC_PIN_DIR_IN */
616 { 3, 4 }, /* ALC_PIN_DIR_OUT */
617 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
618 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
619 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
620};
621#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
622#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
623#define alc_pin_mode_n_items(_dir) \
624 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
625
9c7f852e
TI
626static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_info *uinfo)
a9430dd8 628{
4c5186ed
JW
629 unsigned int item_num = uinfo->value.enumerated.item;
630 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
631
632 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 633 uinfo->count = 1;
4c5186ed
JW
634 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
635
636 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
637 item_num = alc_pin_mode_min(dir);
638 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
639 return 0;
640}
641
9c7f852e
TI
642static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
643 struct snd_ctl_elem_value *ucontrol)
a9430dd8 644{
4c5186ed 645 unsigned int i;
a9430dd8
JW
646 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
647 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 648 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 649 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
650 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
651 AC_VERB_GET_PIN_WIDGET_CONTROL,
652 0x00);
a9430dd8 653
4c5186ed
JW
654 /* Find enumerated value for current pinctl setting */
655 i = alc_pin_mode_min(dir);
4b35d2ca 656 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 657 i++;
9c7f852e 658 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
659 return 0;
660}
661
9c7f852e
TI
662static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
663 struct snd_ctl_elem_value *ucontrol)
a9430dd8 664{
4c5186ed 665 signed int change;
a9430dd8
JW
666 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
667 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
668 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
669 long val = *ucontrol->value.integer.value;
9c7f852e
TI
670 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
671 AC_VERB_GET_PIN_WIDGET_CONTROL,
672 0x00);
a9430dd8 673
f12ab1e0 674 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
675 val = alc_pin_mode_min(dir);
676
677 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
678 if (change) {
679 /* Set pin mode to that requested */
82beb8fd
TI
680 snd_hda_codec_write_cache(codec, nid, 0,
681 AC_VERB_SET_PIN_WIDGET_CONTROL,
682 alc_pin_mode_values[val]);
cdcd9268 683
ea1fb29a 684 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
685 * for the requested pin mode. Enum values of 2 or less are
686 * input modes.
687 *
688 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
689 * reduces noise slightly (particularly on input) so we'll
690 * do it. However, having both input and output buffers
691 * enabled simultaneously doesn't seem to be problematic if
692 * this turns out to be necessary in the future.
cdcd9268
JW
693 */
694 if (val <= 2) {
47fd830a
TI
695 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
696 HDA_AMP_MUTE, HDA_AMP_MUTE);
697 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
698 HDA_AMP_MUTE, 0);
cdcd9268 699 } else {
47fd830a
TI
700 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
701 HDA_AMP_MUTE, HDA_AMP_MUTE);
702 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
703 HDA_AMP_MUTE, 0);
cdcd9268
JW
704 }
705 }
a9430dd8
JW
706 return change;
707}
708
4c5186ed 709#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 710 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 711 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
712 .info = alc_pin_mode_info, \
713 .get = alc_pin_mode_get, \
714 .put = alc_pin_mode_put, \
715 .private_value = nid | (dir<<16) }
df694daa 716
5c8f858d
JW
717/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
718 * together using a mask with more than one bit set. This control is
719 * currently used only by the ALC260 test model. At this stage they are not
720 * needed for any "production" models.
721 */
722#ifdef CONFIG_SND_DEBUG
a5ce8890 723#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 724
9c7f852e
TI
725static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
726 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
727{
728 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
729 hda_nid_t nid = kcontrol->private_value & 0xffff;
730 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
731 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
732 unsigned int val = snd_hda_codec_read(codec, nid, 0,
733 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
734
735 *valp = (val & mask) != 0;
736 return 0;
737}
9c7f852e
TI
738static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
739 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
740{
741 signed int change;
742 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
743 hda_nid_t nid = kcontrol->private_value & 0xffff;
744 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
745 long val = *ucontrol->value.integer.value;
9c7f852e
TI
746 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
747 AC_VERB_GET_GPIO_DATA,
748 0x00);
5c8f858d
JW
749
750 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
751 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
752 if (val == 0)
5c8f858d
JW
753 gpio_data &= ~mask;
754 else
755 gpio_data |= mask;
82beb8fd
TI
756 snd_hda_codec_write_cache(codec, nid, 0,
757 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
758
759 return change;
760}
761#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
762 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 763 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
764 .info = alc_gpio_data_info, \
765 .get = alc_gpio_data_get, \
766 .put = alc_gpio_data_put, \
767 .private_value = nid | (mask<<16) }
768#endif /* CONFIG_SND_DEBUG */
769
92621f13
JW
770/* A switch control to allow the enabling of the digital IO pins on the
771 * ALC260. This is incredibly simplistic; the intention of this control is
772 * to provide something in the test model allowing digital outputs to be
773 * identified if present. If models are found which can utilise these
774 * outputs a more complete mixer control can be devised for those models if
775 * necessary.
776 */
777#ifdef CONFIG_SND_DEBUG
a5ce8890 778#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 779
9c7f852e
TI
780static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
782{
783 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
784 hda_nid_t nid = kcontrol->private_value & 0xffff;
785 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
786 long *valp = ucontrol->value.integer.value;
9c7f852e 787 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 788 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
789
790 *valp = (val & mask) != 0;
791 return 0;
792}
9c7f852e
TI
793static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
794 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
795{
796 signed int change;
797 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
798 hda_nid_t nid = kcontrol->private_value & 0xffff;
799 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
800 long val = *ucontrol->value.integer.value;
9c7f852e 801 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 802 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 803 0x00);
92621f13
JW
804
805 /* Set/unset the masked control bit(s) as needed */
9c7f852e 806 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
807 if (val==0)
808 ctrl_data &= ~mask;
809 else
810 ctrl_data |= mask;
82beb8fd
TI
811 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
812 ctrl_data);
92621f13
JW
813
814 return change;
815}
816#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
817 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 818 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
819 .info = alc_spdif_ctrl_info, \
820 .get = alc_spdif_ctrl_get, \
821 .put = alc_spdif_ctrl_put, \
822 .private_value = nid | (mask<<16) }
823#endif /* CONFIG_SND_DEBUG */
824
f8225f6d
JW
825/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
826 * Again, this is only used in the ALC26x test models to help identify when
827 * the EAPD line must be asserted for features to work.
828 */
829#ifdef CONFIG_SND_DEBUG
830#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
831
832static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
833 struct snd_ctl_elem_value *ucontrol)
834{
835 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
836 hda_nid_t nid = kcontrol->private_value & 0xffff;
837 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
838 long *valp = ucontrol->value.integer.value;
839 unsigned int val = snd_hda_codec_read(codec, nid, 0,
840 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
841
842 *valp = (val & mask) != 0;
843 return 0;
844}
845
846static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
847 struct snd_ctl_elem_value *ucontrol)
848{
849 int change;
850 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
851 hda_nid_t nid = kcontrol->private_value & 0xffff;
852 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
853 long val = *ucontrol->value.integer.value;
854 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
855 AC_VERB_GET_EAPD_BTLENABLE,
856 0x00);
857
858 /* Set/unset the masked control bit(s) as needed */
859 change = (!val ? 0 : mask) != (ctrl_data & mask);
860 if (!val)
861 ctrl_data &= ~mask;
862 else
863 ctrl_data |= mask;
864 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
865 ctrl_data);
866
867 return change;
868}
869
870#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
871 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 872 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
873 .info = alc_eapd_ctrl_info, \
874 .get = alc_eapd_ctrl_get, \
875 .put = alc_eapd_ctrl_put, \
876 .private_value = nid | (mask<<16) }
877#endif /* CONFIG_SND_DEBUG */
878
23f0c048
TI
879/*
880 * set up the input pin config (depending on the given auto-pin type)
881 */
882static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
883 int auto_pin_type)
884{
885 unsigned int val = PIN_IN;
886
86e2959a 887 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 888 unsigned int pincap;
954a29c8
TI
889 unsigned int oldval;
890 oldval = snd_hda_codec_read(codec, nid, 0,
891 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 892 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 893 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
894 /* if the default pin setup is vref50, we give it priority */
895 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 896 val = PIN_VREF80;
461c6c3a
TI
897 else if (pincap & AC_PINCAP_VREF_50)
898 val = PIN_VREF50;
899 else if (pincap & AC_PINCAP_VREF_100)
900 val = PIN_VREF100;
901 else if (pincap & AC_PINCAP_VREF_GRD)
902 val = PIN_VREFGRD;
23f0c048
TI
903 }
904 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
905}
906
f6837bbd
TI
907static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
908{
909 struct alc_spec *spec = codec->spec;
910 struct auto_pin_cfg *cfg = &spec->autocfg;
911
912 if (!cfg->line_outs) {
913 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
914 cfg->line_out_pins[cfg->line_outs])
915 cfg->line_outs++;
916 }
917 if (!cfg->speaker_outs) {
918 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
919 cfg->speaker_pins[cfg->speaker_outs])
920 cfg->speaker_outs++;
921 }
922 if (!cfg->hp_outs) {
923 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
924 cfg->hp_pins[cfg->hp_outs])
925 cfg->hp_outs++;
926 }
927}
928
d88897ea
TI
929/*
930 */
a9111321 931static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
932{
933 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
934 return;
935 spec->mixers[spec->num_mixers++] = mix;
936}
937
938static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
939{
940 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
941 return;
942 spec->init_verbs[spec->num_init_verbs++] = verb;
943}
944
df694daa
KY
945/*
946 * set up from the preset table
947 */
e9c364c0 948static void setup_preset(struct hda_codec *codec,
9c7f852e 949 const struct alc_config_preset *preset)
df694daa 950{
e9c364c0 951 struct alc_spec *spec = codec->spec;
df694daa
KY
952 int i;
953
954 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 955 add_mixer(spec, preset->mixers[i]);
f9e336f6 956 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
957 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
958 i++)
d88897ea 959 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 960
df694daa
KY
961 spec->channel_mode = preset->channel_mode;
962 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 963 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 964 spec->const_channel_count = preset->const_channel_count;
df694daa 965
3b315d70
HM
966 if (preset->const_channel_count)
967 spec->multiout.max_channels = preset->const_channel_count;
968 else
969 spec->multiout.max_channels = spec->channel_mode[0].channels;
970 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
971
972 spec->multiout.num_dacs = preset->num_dacs;
973 spec->multiout.dac_nids = preset->dac_nids;
974 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 975 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 976 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 977
a1e8d2da 978 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 979 if (!spec->num_mux_defs)
a1e8d2da 980 spec->num_mux_defs = 1;
df694daa
KY
981 spec->input_mux = preset->input_mux;
982
983 spec->num_adc_nids = preset->num_adc_nids;
984 spec->adc_nids = preset->adc_nids;
e1406348 985 spec->capsrc_nids = preset->capsrc_nids;
df694daa 986 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
987
988 spec->unsol_event = preset->unsol_event;
989 spec->init_hook = preset->init_hook;
cb53c626 990#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 991 spec->power_hook = preset->power_hook;
cb53c626
TI
992 spec->loopback.amplist = preset->loopbacks;
993#endif
e9c364c0
TI
994
995 if (preset->setup)
996 preset->setup(codec);
f6837bbd
TI
997
998 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
999}
1000
bc9f98a9 1001/* Enable GPIO mask and set output */
a9111321 1002static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1003 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1005 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1006 { }
1007};
1008
a9111321 1009static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1010 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1012 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1013 { }
1014};
1015
a9111321 1016static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1017 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1019 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1020 { }
1021};
1022
2c3bf9ab
TI
1023/*
1024 * Fix hardware PLL issue
1025 * On some codecs, the analog PLL gating control must be off while
1026 * the default value is 1.
1027 */
1028static void alc_fix_pll(struct hda_codec *codec)
1029{
1030 struct alc_spec *spec = codec->spec;
1031 unsigned int val;
1032
1033 if (!spec->pll_nid)
1034 return;
1035 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1036 spec->pll_coef_idx);
1037 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1038 AC_VERB_GET_PROC_COEF, 0);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1040 spec->pll_coef_idx);
1041 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1042 val & ~(1 << spec->pll_coef_bit));
1043}
1044
1045static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1046 unsigned int coef_idx, unsigned int coef_bit)
1047{
1048 struct alc_spec *spec = codec->spec;
1049 spec->pll_nid = nid;
1050 spec->pll_coef_idx = coef_idx;
1051 spec->pll_coef_bit = coef_bit;
1052 alc_fix_pll(codec);
1053}
1054
9ad0e496
KY
1055static int alc_init_jacks(struct hda_codec *codec)
1056{
cd372fb3 1057#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1058 struct alc_spec *spec = codec->spec;
1059 int err;
1060 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1061 unsigned int mic_nid = spec->ext_mic.pin;
8ed99d97 1062 unsigned int dock_nid = spec->dock_mic.pin;
9ad0e496 1063
265a0247 1064 if (hp_nid) {
cd372fb3
TI
1065 err = snd_hda_input_jack_add(codec, hp_nid,
1066 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1067 if (err < 0)
1068 return err;
cd372fb3 1069 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1070 }
9ad0e496 1071
265a0247 1072 if (mic_nid) {
cd372fb3
TI
1073 err = snd_hda_input_jack_add(codec, mic_nid,
1074 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1075 if (err < 0)
1076 return err;
cd372fb3 1077 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1078 }
8ed99d97
TI
1079 if (dock_nid) {
1080 err = snd_hda_input_jack_add(codec, dock_nid,
1081 SND_JACK_MICROPHONE, NULL);
1082 if (err < 0)
1083 return err;
1084 snd_hda_input_jack_report(codec, dock_nid);
1085 }
cd372fb3 1086#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1087 return 0;
1088}
9ad0e496 1089
e6a5e1b7 1090static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1091{
e6a5e1b7 1092 int i, present = 0;
c9b58006 1093
e6a5e1b7
TI
1094 for (i = 0; i < num_pins; i++) {
1095 hda_nid_t nid = pins[i];
bb35febd
TI
1096 if (!nid)
1097 break;
cd372fb3 1098 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1099 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1100 }
e6a5e1b7
TI
1101 return present;
1102}
bb35febd 1103
e6a5e1b7 1104static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1105 bool mute, bool hp_out)
e6a5e1b7
TI
1106{
1107 struct alc_spec *spec = codec->spec;
1108 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1109 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1110 int i;
1111
1112 for (i = 0; i < num_pins; i++) {
1113 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1114 if (!nid)
1115 break;
3b8510ce
TI
1116 switch (spec->automute_mode) {
1117 case ALC_AUTOMUTE_PIN:
bb35febd 1118 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1119 AC_VERB_SET_PIN_WIDGET_CONTROL,
1120 pin_bits);
3b8510ce
TI
1121 break;
1122 case ALC_AUTOMUTE_AMP:
bb35febd 1123 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1124 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1125 break;
1126 case ALC_AUTOMUTE_MIXER:
1127 nid = spec->automute_mixer_nid[i];
1128 if (!nid)
1129 break;
1130 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1131 HDA_AMP_MUTE, mute_bits);
3b8510ce 1132 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1133 HDA_AMP_MUTE, mute_bits);
3b8510ce 1134 break;
bb35febd 1135 }
a9fd4f3f 1136 }
c9b58006
KY
1137}
1138
e6a5e1b7
TI
1139/* Toggle internal speakers muting */
1140static void update_speakers(struct hda_codec *codec)
1141{
1142 struct alc_spec *spec = codec->spec;
1a1455de 1143 int on;
e6a5e1b7 1144
c0a20263
TI
1145 /* Control HP pins/amps depending on master_mute state;
1146 * in general, HP pins/amps control should be enabled in all cases,
1147 * but currently set only for master_mute, just to be safe
1148 */
1149 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1150 spec->autocfg.hp_pins, spec->master_mute, true);
1151
1a1455de
TI
1152 if (!spec->automute)
1153 on = 0;
1154 else
1155 on = spec->jack_present | spec->line_jack_present;
1156 on |= spec->master_mute;
e6a5e1b7 1157 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1158 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1159
1160 /* toggle line-out mutes if needed, too */
1a1455de
TI
1161 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1162 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1163 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1164 return;
1a1455de
TI
1165 if (!spec->automute_lines || !spec->automute)
1166 on = 0;
1167 else
1168 on = spec->jack_present;
1169 on |= spec->master_mute;
e6a5e1b7 1170 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1171 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1172}
1173
1174static void alc_hp_automute(struct hda_codec *codec)
1175{
1176 struct alc_spec *spec = codec->spec;
1177
1178 if (!spec->automute)
1179 return;
1180 spec->jack_present =
1181 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1182 spec->autocfg.hp_pins);
1183 update_speakers(codec);
1184}
1185
1186static void alc_line_automute(struct hda_codec *codec)
1187{
1188 struct alc_spec *spec = codec->spec;
1189
1190 if (!spec->automute || !spec->detect_line)
1191 return;
1192 spec->line_jack_present =
1193 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1194 spec->autocfg.line_out_pins);
1195 update_speakers(codec);
1196}
1197
6c819492
TI
1198static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1199 hda_nid_t nid)
1200{
1201 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1202 int i, nums;
1203
1204 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1205 for (i = 0; i < nums; i++)
1206 if (conn[i] == nid)
1207 return i;
1208 return -1;
1209}
1210
840b64c0
TI
1211/* switch the current ADC according to the jack state */
1212static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1213{
1214 struct alc_spec *spec = codec->spec;
1215 unsigned int present;
1216 hda_nid_t new_adc;
1217
1218 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1219 if (present)
1220 spec->cur_adc_idx = 1;
1221 else
1222 spec->cur_adc_idx = 0;
1223 new_adc = spec->adc_nids[spec->cur_adc_idx];
1224 if (spec->cur_adc && spec->cur_adc != new_adc) {
1225 /* stream is running, let's swap the current ADC */
f0cea797 1226 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1227 spec->cur_adc = new_adc;
1228 snd_hda_codec_setup_stream(codec, new_adc,
1229 spec->cur_adc_stream_tag, 0,
1230 spec->cur_adc_format);
1231 }
1232}
1233
7fb0d78f
KY
1234static void alc_mic_automute(struct hda_codec *codec)
1235{
1236 struct alc_spec *spec = codec->spec;
8ed99d97 1237 struct alc_mic_route *dead1, *dead2, *alive;
6c819492
TI
1238 unsigned int present, type;
1239 hda_nid_t cap_nid;
1240
b59bdf3b
TI
1241 if (!spec->auto_mic)
1242 return;
6c819492
TI
1243 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1244 return;
1245 if (snd_BUG_ON(!spec->adc_nids))
1246 return;
1247
840b64c0
TI
1248 if (spec->dual_adc_switch) {
1249 alc_dual_mic_adc_auto_switch(codec);
1250 return;
1251 }
1252
6c819492
TI
1253 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1254
8ed99d97
TI
1255 alive = &spec->int_mic;
1256 dead1 = &spec->ext_mic;
1257 dead2 = &spec->dock_mic;
1258
864f92be 1259 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1260 if (present) {
1261 alive = &spec->ext_mic;
8ed99d97
TI
1262 dead1 = &spec->int_mic;
1263 dead2 = &spec->dock_mic;
1264 }
1265 if (!present && spec->dock_mic.pin > 0) {
1266 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1267 if (present) {
1268 alive = &spec->dock_mic;
1269 dead1 = &spec->int_mic;
1270 dead2 = &spec->ext_mic;
1271 }
1272 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
6c819492
TI
1273 }
1274
6c819492
TI
1275 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1276 if (type == AC_WID_AUD_MIX) {
1277 /* Matrix-mixer style (e.g. ALC882) */
1278 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1279 alive->mux_idx,
1280 HDA_AMP_MUTE, 0);
8ed99d97
TI
1281 if (dead1->pin > 0)
1282 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1283 dead1->mux_idx,
1284 HDA_AMP_MUTE, HDA_AMP_MUTE);
1285 if (dead2->pin > 0)
1286 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1287 dead2->mux_idx,
1288 HDA_AMP_MUTE, HDA_AMP_MUTE);
6c819492
TI
1289 } else {
1290 /* MUX style (e.g. ALC880) */
1291 snd_hda_codec_write_cache(codec, cap_nid, 0,
1292 AC_VERB_SET_CONNECT_SEL,
1293 alive->mux_idx);
1294 }
cd372fb3 1295 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1296
1297 /* FIXME: analog mixer */
7fb0d78f
KY
1298}
1299
c9b58006
KY
1300/* unsolicited event for HP jack sensing */
1301static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1302{
1303 if (codec->vendor_id == 0x10ec0880)
1304 res >>= 28;
1305 else
1306 res >>= 26;
a9fd4f3f
TI
1307 switch (res) {
1308 case ALC880_HP_EVENT:
d922b51d 1309 alc_hp_automute(codec);
a9fd4f3f 1310 break;
e6a5e1b7
TI
1311 case ALC880_FRONT_EVENT:
1312 alc_line_automute(codec);
1313 break;
a9fd4f3f 1314 case ALC880_MIC_EVENT:
7fb0d78f 1315 alc_mic_automute(codec);
a9fd4f3f
TI
1316 break;
1317 }
7fb0d78f
KY
1318}
1319
1320static void alc_inithook(struct hda_codec *codec)
1321{
d922b51d 1322 alc_hp_automute(codec);
e6a5e1b7 1323 alc_line_automute(codec);
7fb0d78f 1324 alc_mic_automute(codec);
c9b58006
KY
1325}
1326
f9423e7a
KY
1327/* additional initialization for ALC888 variants */
1328static void alc888_coef_init(struct hda_codec *codec)
1329{
1330 unsigned int tmp;
1331
1332 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1333 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1334 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1335 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1336 /* alc888S-VC */
1337 snd_hda_codec_read(codec, 0x20, 0,
1338 AC_VERB_SET_PROC_COEF, 0x830);
1339 else
1340 /* alc888-VB */
1341 snd_hda_codec_read(codec, 0x20, 0,
1342 AC_VERB_SET_PROC_COEF, 0x3030);
1343}
1344
87a8c370
JK
1345static void alc889_coef_init(struct hda_codec *codec)
1346{
1347 unsigned int tmp;
1348
1349 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1350 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1352 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1353}
1354
3fb4a508
TI
1355/* turn on/off EAPD control (only if available) */
1356static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1357{
1358 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1359 return;
1360 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1361 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1362 on ? 2 : 0);
1363}
1364
691f1fcc
TI
1365/* turn on/off EAPD controls of the codec */
1366static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1367{
1368 /* We currently only handle front, HP */
39fa84e9
TI
1369 static hda_nid_t pins[] = {
1370 0x0f, 0x10, 0x14, 0x15, 0
1371 };
1372 hda_nid_t *p;
1373 for (p = pins; *p; p++)
1374 set_eapd(codec, *p, on);
691f1fcc
TI
1375}
1376
1c716153
TI
1377/* generic shutup callback;
1378 * just turning off EPAD and a little pause for avoiding pop-noise
1379 */
1380static void alc_eapd_shutup(struct hda_codec *codec)
1381{
1382 alc_auto_setup_eapd(codec, false);
1383 msleep(200);
1384}
1385
4a79ba34 1386static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1387{
4a79ba34 1388 unsigned int tmp;
bc9f98a9 1389
39fa84e9 1390 alc_auto_setup_eapd(codec, true);
4a79ba34
TI
1391 switch (type) {
1392 case ALC_INIT_GPIO1:
bc9f98a9
KY
1393 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1394 break;
4a79ba34 1395 case ALC_INIT_GPIO2:
bc9f98a9
KY
1396 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1397 break;
4a79ba34 1398 case ALC_INIT_GPIO3:
bdd148a3
KY
1399 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1400 break;
4a79ba34 1401 case ALC_INIT_DEFAULT:
c9b58006
KY
1402 switch (codec->vendor_id) {
1403 case 0x10ec0260:
1404 snd_hda_codec_write(codec, 0x1a, 0,
1405 AC_VERB_SET_COEF_INDEX, 7);
1406 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1407 AC_VERB_GET_PROC_COEF, 0);
1408 snd_hda_codec_write(codec, 0x1a, 0,
1409 AC_VERB_SET_COEF_INDEX, 7);
1410 snd_hda_codec_write(codec, 0x1a, 0,
1411 AC_VERB_SET_PROC_COEF,
1412 tmp | 0x2010);
1413 break;
1414 case 0x10ec0262:
1415 case 0x10ec0880:
1416 case 0x10ec0882:
1417 case 0x10ec0883:
1418 case 0x10ec0885:
4a5a4c56 1419 case 0x10ec0887:
20b67ddd 1420 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1421 alc889_coef_init(codec);
c9b58006 1422 break;
f9423e7a 1423 case 0x10ec0888:
4a79ba34 1424 alc888_coef_init(codec);
f9423e7a 1425 break;
0aea778e 1426#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1427 case 0x10ec0267:
1428 case 0x10ec0268:
1429 snd_hda_codec_write(codec, 0x20, 0,
1430 AC_VERB_SET_COEF_INDEX, 7);
1431 tmp = snd_hda_codec_read(codec, 0x20, 0,
1432 AC_VERB_GET_PROC_COEF, 0);
1433 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1434 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1435 snd_hda_codec_write(codec, 0x20, 0,
1436 AC_VERB_SET_PROC_COEF,
1437 tmp | 0x3000);
1438 break;
0aea778e 1439#endif /* XXX */
bc9f98a9 1440 }
4a79ba34
TI
1441 break;
1442 }
1443}
1444
1a1455de
TI
1445static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1446 struct snd_ctl_elem_info *uinfo)
1447{
ae8a60a5
TI
1448 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1449 struct alc_spec *spec = codec->spec;
1450 static const char * const texts2[] = {
1451 "Disabled", "Enabled"
1452 };
1453 static const char * const texts3[] = {
1a1455de
TI
1454 "Disabled", "Speaker Only", "Line-Out+Speaker"
1455 };
ae8a60a5 1456 const char * const *texts;
1a1455de
TI
1457
1458 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1459 uinfo->count = 1;
ae8a60a5
TI
1460 if (spec->automute_hp_lo) {
1461 uinfo->value.enumerated.items = 3;
1462 texts = texts3;
1463 } else {
1464 uinfo->value.enumerated.items = 2;
1465 texts = texts2;
1466 }
1467 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1468 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1469 strcpy(uinfo->value.enumerated.name,
1470 texts[uinfo->value.enumerated.item]);
1471 return 0;
1472}
1473
1474static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1475 struct snd_ctl_elem_value *ucontrol)
1476{
1477 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1478 struct alc_spec *spec = codec->spec;
1479 unsigned int val;
1480 if (!spec->automute)
1481 val = 0;
1482 else if (!spec->automute_lines)
1483 val = 1;
1484 else
1485 val = 2;
1486 ucontrol->value.enumerated.item[0] = val;
1487 return 0;
1488}
1489
1490static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1491 struct snd_ctl_elem_value *ucontrol)
1492{
1493 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1494 struct alc_spec *spec = codec->spec;
1495
1496 switch (ucontrol->value.enumerated.item[0]) {
1497 case 0:
1498 if (!spec->automute)
1499 return 0;
1500 spec->automute = 0;
1501 break;
1502 case 1:
1503 if (spec->automute && !spec->automute_lines)
1504 return 0;
1505 spec->automute = 1;
1506 spec->automute_lines = 0;
1507 break;
1508 case 2:
ae8a60a5
TI
1509 if (!spec->automute_hp_lo)
1510 return -EINVAL;
1a1455de
TI
1511 if (spec->automute && spec->automute_lines)
1512 return 0;
1513 spec->automute = 1;
1514 spec->automute_lines = 1;
1515 break;
1516 default:
1517 return -EINVAL;
1518 }
1519 update_speakers(codec);
1520 return 1;
1521}
1522
a9111321 1523static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1524 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1525 .name = "Auto-Mute Mode",
1526 .info = alc_automute_mode_info,
1527 .get = alc_automute_mode_get,
1528 .put = alc_automute_mode_put,
1529};
1530
1531static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1532
1533static int alc_add_automute_mode_enum(struct hda_codec *codec)
1534{
1535 struct alc_spec *spec = codec->spec;
1536 struct snd_kcontrol_new *knew;
1537
1538 knew = alc_kcontrol_new(spec);
1539 if (!knew)
1540 return -ENOMEM;
1541 *knew = alc_automute_mode_enum;
1542 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1543 if (!knew->name)
1544 return -ENOMEM;
1545 return 0;
1546}
1547
4a79ba34
TI
1548static void alc_init_auto_hp(struct hda_codec *codec)
1549{
1550 struct alc_spec *spec = codec->spec;
bb35febd 1551 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1552 int present = 0;
bb35febd 1553 int i;
4a79ba34 1554
1daf5f46
TI
1555 if (cfg->hp_pins[0])
1556 present++;
1557 if (cfg->line_out_pins[0])
1558 present++;
1559 if (cfg->speaker_pins[0])
1560 present++;
1561 if (present < 2) /* need two different output types */
1562 return;
ae8a60a5
TI
1563 if (present == 3)
1564 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1565
bb35febd 1566 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1567 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1568 sizeof(cfg->speaker_pins));
1569 cfg->speaker_outs = cfg->line_outs;
1570 }
1571
1572 if (!cfg->hp_pins[0]) {
1573 memcpy(cfg->hp_pins, cfg->line_out_pins,
1574 sizeof(cfg->hp_pins));
1575 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1576 }
1577
bb35febd 1578 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de 1579 hda_nid_t nid = cfg->hp_pins[i];
06dec228 1580 if (!is_jack_detectable(codec, nid))
1a1455de 1581 continue;
bb35febd 1582 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1583 nid);
1584 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1585 AC_VERB_SET_UNSOLICITED_ENABLE,
1586 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1587 spec->automute = 1;
1588 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1589 }
1a1455de
TI
1590 if (spec->automute && cfg->line_out_pins[0] &&
1591 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1592 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1593 for (i = 0; i < cfg->line_outs; i++) {
1594 hda_nid_t nid = cfg->line_out_pins[i];
06dec228 1595 if (!is_jack_detectable(codec, nid))
1a1455de
TI
1596 continue;
1597 snd_printdd("realtek: Enable Line-Out auto-muting "
1598 "on NID 0x%x\n", nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_FRONT_EVENT);
1602 spec->detect_line = 1;
1603 }
52d3cb88 1604 spec->automute_lines = spec->detect_line;
ae8a60a5
TI
1605 }
1606
1607 if (spec->automute) {
1a1455de
TI
1608 /* create a control for automute mode */
1609 alc_add_automute_mode_enum(codec);
ae8a60a5 1610 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1611 }
4a79ba34
TI
1612}
1613
6c819492
TI
1614static void alc_init_auto_mic(struct hda_codec *codec)
1615{
1616 struct alc_spec *spec = codec->spec;
1617 struct auto_pin_cfg *cfg = &spec->autocfg;
8ed99d97 1618 hda_nid_t fixed, ext, dock;
6c819492
TI
1619 int i;
1620
8ed99d97 1621 fixed = ext = dock = 0;
66ceeb6b
TI
1622 for (i = 0; i < cfg->num_inputs; i++) {
1623 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1624 unsigned int defcfg;
6c819492 1625 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1626 switch (snd_hda_get_input_pin_attr(defcfg)) {
1627 case INPUT_PIN_ATTR_INT:
6c819492
TI
1628 if (fixed)
1629 return; /* already occupied */
8ed99d97
TI
1630 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1631 return; /* invalid type */
6c819492
TI
1632 fixed = nid;
1633 break;
99ae28be
TI
1634 case INPUT_PIN_ATTR_UNUSED:
1635 return; /* invalid entry */
8ed99d97
TI
1636 case INPUT_PIN_ATTR_DOCK:
1637 if (dock)
1638 return; /* already occupied */
1639 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1640 return; /* invalid type */
1641 dock = nid;
1642 break;
99ae28be 1643 default:
6c819492
TI
1644 if (ext)
1645 return; /* already occupied */
8ed99d97
TI
1646 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1647 return; /* invalid type */
6c819492
TI
1648 ext = nid;
1649 break;
6c819492
TI
1650 }
1651 }
8ed99d97
TI
1652 if (!ext && dock) {
1653 ext = dock;
1654 dock = 0;
1655 }
eaa9b3a7
TI
1656 if (!ext || !fixed)
1657 return;
e35d9d6a 1658 if (!is_jack_detectable(codec, ext))
6c819492 1659 return; /* no unsol support */
8ed99d97
TI
1660 if (dock && !is_jack_detectable(codec, dock))
1661 return; /* no unsol support */
1662 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1663 ext, fixed, dock);
6c819492 1664 spec->ext_mic.pin = ext;
8ed99d97 1665 spec->dock_mic.pin = dock;
6c819492
TI
1666 spec->int_mic.pin = fixed;
1667 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
8ed99d97 1668 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
6c819492
TI
1669 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1670 spec->auto_mic = 1;
1671 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1672 AC_VERB_SET_UNSOLICITED_ENABLE,
1673 AC_USRSP_EN | ALC880_MIC_EVENT);
1674 spec->unsol_event = alc_sku_unsol_event;
1675}
1676
90622917
DH
1677/* Could be any non-zero and even value. When used as fixup, tells
1678 * the driver to ignore any present sku defines.
1679 */
1680#define ALC_FIXUP_SKU_IGNORE (2)
1681
da00c244
KY
1682static int alc_auto_parse_customize_define(struct hda_codec *codec)
1683{
1684 unsigned int ass, tmp, i;
7fb56223 1685 unsigned nid = 0;
da00c244
KY
1686 struct alc_spec *spec = codec->spec;
1687
b6cbe517
TI
1688 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1689
90622917
DH
1690 if (spec->cdefine.fixup) {
1691 ass = spec->cdefine.sku_cfg;
1692 if (ass == ALC_FIXUP_SKU_IGNORE)
1693 return -1;
1694 goto do_sku;
1695 }
1696
da00c244 1697 ass = codec->subsystem_id & 0xffff;
b6cbe517 1698 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1699 goto do_sku;
1700
1701 nid = 0x1d;
1702 if (codec->vendor_id == 0x10ec0260)
1703 nid = 0x17;
1704 ass = snd_hda_codec_get_pincfg(codec, nid);
1705
1706 if (!(ass & 1)) {
1707 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1708 codec->chip_name, ass);
1709 return -1;
1710 }
1711
1712 /* check sum */
1713 tmp = 0;
1714 for (i = 1; i < 16; i++) {
1715 if ((ass >> i) & 1)
1716 tmp++;
1717 }
1718 if (((ass >> 16) & 0xf) != tmp)
1719 return -1;
1720
1721 spec->cdefine.port_connectivity = ass >> 30;
1722 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1723 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1724 spec->cdefine.customization = ass >> 8;
1725do_sku:
1726 spec->cdefine.sku_cfg = ass;
1727 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1728 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1729 spec->cdefine.swap = (ass & 0x2) >> 1;
1730 spec->cdefine.override = ass & 0x1;
1731
1732 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1733 nid, spec->cdefine.sku_cfg);
1734 snd_printd("SKU: port_connectivity=0x%x\n",
1735 spec->cdefine.port_connectivity);
1736 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1737 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1738 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1739 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1740 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1741 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1742 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1743
1744 return 0;
1745}
1746
3af9ee6b
TI
1747static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1748{
1749 int i;
1750 for (i = 0; i < nums; i++)
1751 if (list[i] == nid)
1752 return true;
1753 return false;
1754}
1755
4a79ba34
TI
1756/* check subsystem ID and set up device-specific initialization;
1757 * return 1 if initialized, 0 if invalid SSID
1758 */
1759/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1760 * 31 ~ 16 : Manufacture ID
1761 * 15 ~ 8 : SKU ID
1762 * 7 ~ 0 : Assembly ID
1763 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1764 */
1765static int alc_subsystem_id(struct hda_codec *codec,
1766 hda_nid_t porta, hda_nid_t porte,
6227cdce 1767 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1768{
1769 unsigned int ass, tmp, i;
1770 unsigned nid;
1771 struct alc_spec *spec = codec->spec;
1772
90622917
DH
1773 if (spec->cdefine.fixup) {
1774 ass = spec->cdefine.sku_cfg;
1775 if (ass == ALC_FIXUP_SKU_IGNORE)
1776 return 0;
1777 goto do_sku;
1778 }
1779
4a79ba34
TI
1780 ass = codec->subsystem_id & 0xffff;
1781 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1782 goto do_sku;
1783
1784 /* invalid SSID, check the special NID pin defcfg instead */
1785 /*
def319f9 1786 * 31~30 : port connectivity
4a79ba34
TI
1787 * 29~21 : reserve
1788 * 20 : PCBEEP input
1789 * 19~16 : Check sum (15:1)
1790 * 15~1 : Custom
1791 * 0 : override
1792 */
1793 nid = 0x1d;
1794 if (codec->vendor_id == 0x10ec0260)
1795 nid = 0x17;
1796 ass = snd_hda_codec_get_pincfg(codec, nid);
1797 snd_printd("realtek: No valid SSID, "
1798 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1799 ass, nid);
6227cdce 1800 if (!(ass & 1))
4a79ba34
TI
1801 return 0;
1802 if ((ass >> 30) != 1) /* no physical connection */
1803 return 0;
1804
1805 /* check sum */
1806 tmp = 0;
1807 for (i = 1; i < 16; i++) {
1808 if ((ass >> i) & 1)
1809 tmp++;
1810 }
1811 if (((ass >> 16) & 0xf) != tmp)
1812 return 0;
1813do_sku:
1814 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1815 ass & 0xffff, codec->vendor_id);
1816 /*
1817 * 0 : override
1818 * 1 : Swap Jack
1819 * 2 : 0 --> Desktop, 1 --> Laptop
1820 * 3~5 : External Amplifier control
1821 * 7~6 : Reserved
1822 */
1823 tmp = (ass & 0x38) >> 3; /* external Amp control */
1824 switch (tmp) {
1825 case 1:
1826 spec->init_amp = ALC_INIT_GPIO1;
1827 break;
1828 case 3:
1829 spec->init_amp = ALC_INIT_GPIO2;
1830 break;
1831 case 7:
1832 spec->init_amp = ALC_INIT_GPIO3;
1833 break;
1834 case 5:
5a8cfb4e 1835 default:
4a79ba34 1836 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1837 break;
1838 }
ea1fb29a 1839
8c427226 1840 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1841 * when the external headphone out jack is plugged"
1842 */
8c427226 1843 if (!(ass & 0x8000))
4a79ba34 1844 return 1;
c9b58006
KY
1845 /*
1846 * 10~8 : Jack location
1847 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1848 * 14~13: Resvered
1849 * 15 : 1 --> enable the function "Mute internal speaker
1850 * when the external headphone out jack is plugged"
1851 */
c9b58006 1852 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1853 hda_nid_t nid;
c9b58006
KY
1854 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1855 if (tmp == 0)
01d4825d 1856 nid = porta;
c9b58006 1857 else if (tmp == 1)
01d4825d 1858 nid = porte;
c9b58006 1859 else if (tmp == 2)
01d4825d 1860 nid = portd;
6227cdce
KY
1861 else if (tmp == 3)
1862 nid = porti;
c9b58006 1863 else
4a79ba34 1864 return 1;
3af9ee6b
TI
1865 if (found_in_nid_list(nid, spec->autocfg.line_out_pins,
1866 spec->autocfg.line_outs))
1867 return 1;
01d4825d 1868 spec->autocfg.hp_pins[0] = nid;
c9b58006 1869 }
4a79ba34
TI
1870 return 1;
1871}
ea1fb29a 1872
4a79ba34 1873static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1874 hda_nid_t porta, hda_nid_t porte,
1875 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1876{
6227cdce 1877 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1878 struct alc_spec *spec = codec->spec;
1879 snd_printd("realtek: "
1880 "Enable default setup for auto mode as fallback\n");
1881 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1882 }
1a1455de
TI
1883
1884 alc_init_auto_hp(codec);
1885 alc_init_auto_mic(codec);
bc9f98a9
KY
1886}
1887
f95474ec 1888/*
f8f25ba3 1889 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1890 */
1891
1892struct alc_pincfg {
1893 hda_nid_t nid;
1894 u32 val;
1895};
1896
e1eb5f10
TB
1897struct alc_model_fixup {
1898 const int id;
1899 const char *name;
1900};
1901
f8f25ba3 1902struct alc_fixup {
b5bfbc67 1903 int type;
361fe6e9
TI
1904 bool chained;
1905 int chain_id;
b5bfbc67
TI
1906 union {
1907 unsigned int sku;
1908 const struct alc_pincfg *pins;
1909 const struct hda_verb *verbs;
1910 void (*func)(struct hda_codec *codec,
1911 const struct alc_fixup *fix,
1912 int action);
1913 } v;
f8f25ba3
TI
1914};
1915
b5bfbc67
TI
1916enum {
1917 ALC_FIXUP_INVALID,
1918 ALC_FIXUP_SKU,
1919 ALC_FIXUP_PINS,
1920 ALC_FIXUP_VERBS,
1921 ALC_FIXUP_FUNC,
1922};
1923
1924enum {
1925 ALC_FIXUP_ACT_PRE_PROBE,
1926 ALC_FIXUP_ACT_PROBE,
58701120 1927 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1928};
1929
1930static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1931{
b5bfbc67
TI
1932 struct alc_spec *spec = codec->spec;
1933 int id = spec->fixup_id;
aa1d0c52 1934#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1935 const char *modelname = spec->fixup_name;
aa1d0c52 1936#endif
b5bfbc67 1937 int depth = 0;
f95474ec 1938
b5bfbc67
TI
1939 if (!spec->fixup_list)
1940 return;
1941
1942 while (id >= 0) {
1943 const struct alc_fixup *fix = spec->fixup_list + id;
1944 const struct alc_pincfg *cfg;
1945
1946 switch (fix->type) {
1947 case ALC_FIXUP_SKU:
1948 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1949 break;;
1950 snd_printdd(KERN_INFO "hda_codec: %s: "
1951 "Apply sku override for %s\n",
1952 codec->chip_name, modelname);
1953 spec->cdefine.sku_cfg = fix->v.sku;
1954 spec->cdefine.fixup = 1;
1955 break;
1956 case ALC_FIXUP_PINS:
1957 cfg = fix->v.pins;
1958 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1959 break;
1960 snd_printdd(KERN_INFO "hda_codec: %s: "
1961 "Apply pincfg for %s\n",
1962 codec->chip_name, modelname);
1963 for (; cfg->nid; cfg++)
1964 snd_hda_codec_set_pincfg(codec, cfg->nid,
1965 cfg->val);
1966 break;
1967 case ALC_FIXUP_VERBS:
1968 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1969 break;
1970 snd_printdd(KERN_INFO "hda_codec: %s: "
1971 "Apply fix-verbs for %s\n",
1972 codec->chip_name, modelname);
1973 add_verb(codec->spec, fix->v.verbs);
1974 break;
1975 case ALC_FIXUP_FUNC:
1976 if (!fix->v.func)
1977 break;
1978 snd_printdd(KERN_INFO "hda_codec: %s: "
1979 "Apply fix-func for %s\n",
1980 codec->chip_name, modelname);
1981 fix->v.func(codec, fix, action);
1982 break;
1983 default:
1984 snd_printk(KERN_ERR "hda_codec: %s: "
1985 "Invalid fixup type %d\n",
1986 codec->chip_name, fix->type);
1987 break;
1988 }
24af2b1c 1989 if (!fix->chained)
b5bfbc67
TI
1990 break;
1991 if (++depth > 10)
1992 break;
24af2b1c 1993 id = fix->chain_id;
9d57883f 1994 }
f95474ec
TI
1995}
1996
e1eb5f10 1997static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1998 const struct alc_model_fixup *models,
1999 const struct snd_pci_quirk *quirk,
2000 const struct alc_fixup *fixlist)
e1eb5f10 2001{
b5bfbc67
TI
2002 struct alc_spec *spec = codec->spec;
2003 int id = -1;
2004 const char *name = NULL;
e1eb5f10 2005
e1eb5f10
TB
2006 if (codec->modelname && models) {
2007 while (models->name) {
2008 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
2009 id = models->id;
2010 name = models->name;
e1eb5f10
TB
2011 break;
2012 }
2013 models++;
2014 }
b5bfbc67
TI
2015 }
2016 if (id < 0) {
2017 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2018 if (quirk) {
2019 id = quirk->value;
2020#ifdef CONFIG_SND_DEBUG_VERBOSE
2021 name = quirk->name;
2022#endif
2023 }
2024 }
2025
2026 spec->fixup_id = id;
2027 if (id >= 0) {
2028 spec->fixup_list = fixlist;
2029 spec->fixup_name = name;
e1eb5f10 2030 }
f95474ec
TI
2031}
2032
274693f3
KY
2033static int alc_read_coef_idx(struct hda_codec *codec,
2034 unsigned int coef_idx)
2035{
2036 unsigned int val;
2037 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2038 coef_idx);
2039 val = snd_hda_codec_read(codec, 0x20, 0,
2040 AC_VERB_GET_PROC_COEF, 0);
2041 return val;
2042}
2043
977ddd6b
KY
2044static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2045 unsigned int coef_val)
2046{
2047 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2048 coef_idx);
2049 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2050 coef_val);
2051}
2052
757899ac
TI
2053/* set right pin controls for digital I/O */
2054static void alc_auto_init_digital(struct hda_codec *codec)
2055{
2056 struct alc_spec *spec = codec->spec;
2057 int i;
1f0f4b80 2058 hda_nid_t pin, dac;
757899ac
TI
2059
2060 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2061 pin = spec->autocfg.dig_out_pins[i];
1f0f4b80
TI
2062 if (!pin)
2063 continue;
2064 snd_hda_codec_write(codec, pin, 0,
2065 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2066 if (!i)
2067 dac = spec->multiout.dig_out_nid;
2068 else
2069 dac = spec->slave_dig_outs[i - 1];
2070 if (!dac || !(get_wcaps(codec, dac) & AC_WCAP_OUT_AMP))
2071 continue;
2072 snd_hda_codec_write(codec, dac, 0,
2073 AC_VERB_SET_AMP_GAIN_MUTE,
2074 AMP_OUT_UNMUTE);
757899ac
TI
2075 }
2076 pin = spec->autocfg.dig_in_pin;
2077 if (pin)
2078 snd_hda_codec_write(codec, pin, 0,
2079 AC_VERB_SET_PIN_WIDGET_CONTROL,
2080 PIN_IN);
2081}
2082
2083/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2084static void alc_auto_parse_digital(struct hda_codec *codec)
2085{
2086 struct alc_spec *spec = codec->spec;
2087 int i, err;
2088 hda_nid_t dig_nid;
2089
2090 /* support multiple SPDIFs; the secondary is set up as a slave */
2091 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2092 err = snd_hda_get_connections(codec,
2093 spec->autocfg.dig_out_pins[i],
2094 &dig_nid, 1);
2095 if (err < 0)
2096 continue;
2097 if (!i) {
2098 spec->multiout.dig_out_nid = dig_nid;
2099 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2100 } else {
2101 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2102 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2103 break;
2104 spec->slave_dig_outs[i - 1] = dig_nid;
2105 }
2106 }
2107
2108 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2109 dig_nid = codec->start_nid;
2110 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2111 unsigned int wcaps = get_wcaps(codec, dig_nid);
2112 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2113 continue;
2114 if (!(wcaps & AC_WCAP_DIGITAL))
2115 continue;
2116 if (!(wcaps & AC_WCAP_CONN_LIST))
2117 continue;
2118 err = get_connection_index(codec, dig_nid,
2119 spec->autocfg.dig_in_pin);
2120 if (err >= 0) {
2121 spec->dig_in_nid = dig_nid;
2122 break;
2123 }
2124 }
757899ac
TI
2125 }
2126}
2127
ef8ef5fb
VP
2128/*
2129 * ALC888
2130 */
2131
2132/*
2133 * 2ch mode
2134 */
a9111321 2135static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2136/* Mic-in jack as mic in */
2137 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2138 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2139/* Line-in jack as Line in */
2140 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2141 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2142/* Line-Out as Front */
2143 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2144 { } /* end */
2145};
2146
2147/*
2148 * 4ch mode
2149 */
a9111321 2150static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2151/* Mic-in jack as mic in */
2152 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2153 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2154/* Line-in jack as Surround */
2155 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2156 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2157/* Line-Out as Front */
2158 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2159 { } /* end */
2160};
2161
2162/*
2163 * 6ch mode
2164 */
a9111321 2165static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2166/* Mic-in jack as CLFE */
2167 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2168 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2169/* Line-in jack as Surround */
2170 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2171 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2172/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2173 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2174 { } /* end */
2175};
2176
2177/*
2178 * 8ch mode
2179 */
a9111321 2180static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2181/* Mic-in jack as CLFE */
2182 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2183 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2184/* Line-in jack as Surround */
2185 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2186 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2187/* Line-Out as Side */
2188 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2189 { } /* end */
2190};
2191
a9111321 2192static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2193 { 2, alc888_4ST_ch2_intel_init },
2194 { 4, alc888_4ST_ch4_intel_init },
2195 { 6, alc888_4ST_ch6_intel_init },
2196 { 8, alc888_4ST_ch8_intel_init },
2197};
2198
2199/*
2200 * ALC888 Fujitsu Siemens Amillo xa3530
2201 */
2202
a9111321 2203static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2204/* Front Mic: set to PIN_IN (empty by default) */
2205 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2206/* Connect Internal HP to Front */
2207 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2208 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2209 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2210/* Connect Bass HP to Front */
2211 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2212 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2213 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2214/* Connect Line-Out side jack (SPDIF) to Side */
2215 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2216 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2217 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2218/* Connect Mic jack to CLFE */
2219 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2220 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2221 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2222/* Connect Line-in jack to Surround */
2223 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2224 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2225 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2226/* Connect HP out jack to Front */
2227 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2228 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2229 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2230/* Enable unsolicited event for HP jack and Line-out jack */
2231 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2232 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2233 {}
2234};
2235
4f5d1706 2236static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2237{
2238 struct alc_spec *spec = codec->spec;
2239
2240 spec->autocfg.hp_pins[0] = 0x15;
2241 spec->autocfg.speaker_pins[0] = 0x14;
2242 spec->autocfg.speaker_pins[1] = 0x16;
2243 spec->autocfg.speaker_pins[2] = 0x17;
2244 spec->autocfg.speaker_pins[3] = 0x19;
2245 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2246 spec->automute = 1;
2247 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2248}
2249
2250static void alc889_intel_init_hook(struct hda_codec *codec)
2251{
2252 alc889_coef_init(codec);
d922b51d 2253 alc_hp_automute(codec);
6732bd0d
WF
2254}
2255
4f5d1706 2256static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2257{
2258 struct alc_spec *spec = codec->spec;
2259
2260 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2261 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2262 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2263 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2264 spec->automute = 1;
2265 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2266}
ef8ef5fb 2267
5b2d1eca
VP
2268/*
2269 * ALC888 Acer Aspire 4930G model
2270 */
2271
a9111321 2272static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2273/* Front Mic: set to PIN_IN (empty by default) */
2274 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2275/* Unselect Front Mic by default in input mixer 3 */
2276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2277/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2278 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2279/* Connect Internal HP to front */
2280 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2281 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2282 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2283/* Connect HP out to front */
2284 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2286 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2287 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2288 { }
2289};
2290
d2fd4b09
TV
2291/*
2292 * ALC888 Acer Aspire 6530G model
2293 */
2294
a9111321 2295static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2296/* Route to built-in subwoofer as well as speakers */
2297 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2300 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2301/* Bias voltage on for external mic port */
2302 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2303/* Front Mic: set to PIN_IN (empty by default) */
2304 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2305/* Unselect Front Mic by default in input mixer 3 */
2306 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2307/* Enable unsolicited event for HP jack */
2308 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2309/* Enable speaker output */
2310 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2311 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2312 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2313/* Enable headphone output */
2314 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2315 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2316 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2317 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2318 { }
2319};
2320
d9477207
DK
2321/*
2322 *ALC888 Acer Aspire 7730G model
2323 */
2324
a9111321 2325static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2326/* Bias voltage on for external mic port */
2327 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2328/* Front Mic: set to PIN_IN (empty by default) */
2329 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2330/* Unselect Front Mic by default in input mixer 3 */
2331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2332/* Enable unsolicited event for HP jack */
2333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2334/* Enable speaker output */
2335 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2336 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2337 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2338/* Enable headphone output */
2339 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2340 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2341 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2342 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2343/*Enable internal subwoofer */
2344 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2345 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2346 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2347 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2348 { }
2349};
2350
3b315d70 2351/*
018df418 2352 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2353 */
2354
a9111321 2355static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2356/* Front Mic: set to PIN_IN (empty by default) */
2357 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2358/* Unselect Front Mic by default in input mixer 3 */
2359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2360/* Enable unsolicited event for HP jack */
2361 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2362/* Connect Internal Front to Front */
2363 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2364 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2365 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2366/* Connect Internal Rear to Rear */
2367 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2368 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2369 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2370/* Connect Internal CLFE to CLFE */
2371 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2372 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2373 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2374/* Connect HP out to Front */
018df418 2375 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2376 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2378/* Enable all DACs */
2379/* DAC DISABLE/MUTE 1? */
2380/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2381 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2382 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2383/* DAC DISABLE/MUTE 2? */
2384/* some bit here disables the other DACs. Init=0x4900 */
2385 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2386 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2387/* DMIC fix
2388 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2389 * which makes the stereo useless. However, either the mic or the ALC889
2390 * makes the signal become a difference/sum signal instead of standard
2391 * stereo, which is annoying. So instead we flip this bit which makes the
2392 * codec replicate the sum signal to both channels, turning it into a
2393 * normal mono mic.
2394 */
2395/* DMIC_CONTROL? Init value = 0x0001 */
2396 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2397 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2398 { }
2399};
2400
a9111321 2401static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2402 /* Front mic only available on one ADC */
2403 {
2404 .num_items = 4,
2405 .items = {
2406 { "Mic", 0x0 },
2407 { "Line", 0x2 },
2408 { "CD", 0x4 },
2409 { "Front Mic", 0xb },
2410 },
2411 },
2412 {
2413 .num_items = 3,
2414 .items = {
2415 { "Mic", 0x0 },
2416 { "Line", 0x2 },
2417 { "CD", 0x4 },
2418 },
2419 }
2420};
2421
a9111321 2422static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2423 /* Interal mic only available on one ADC */
2424 {
684a8842 2425 .num_items = 5,
d2fd4b09 2426 .items = {
8607f7c4 2427 { "Mic", 0x0 },
684a8842 2428 { "Line In", 0x2 },
d2fd4b09 2429 { "CD", 0x4 },
684a8842 2430 { "Input Mix", 0xa },
28c4edb7 2431 { "Internal Mic", 0xb },
d2fd4b09
TV
2432 },
2433 },
2434 {
684a8842 2435 .num_items = 4,
d2fd4b09 2436 .items = {
8607f7c4 2437 { "Mic", 0x0 },
684a8842 2438 { "Line In", 0x2 },
d2fd4b09 2439 { "CD", 0x4 },
684a8842 2440 { "Input Mix", 0xa },
d2fd4b09
TV
2441 },
2442 }
2443};
2444
a9111321 2445static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2446 /* Digital mic only available on first "ADC" */
2447 {
2448 .num_items = 5,
2449 .items = {
2450 { "Mic", 0x0 },
2451 { "Line", 0x2 },
2452 { "CD", 0x4 },
2453 { "Front Mic", 0xb },
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 .num_items = 4,
2468 .items = {
2469 { "Mic", 0x0 },
2470 { "Line", 0x2 },
2471 { "CD", 0x4 },
2472 { "Input Mix", 0xa },
2473 },
2474 }
2475};
2476
a9111321 2477static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2478 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2481 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2482 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2483 HDA_OUTPUT),
2484 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2485 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2486 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2488 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2489 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2490 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2494 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2495 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2496 { } /* end */
2497};
2498
a9111321 2499static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2503 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2504 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2505 HDA_OUTPUT),
786c51f9
ŁW
2506 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2510 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2511 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2512 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2514 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2515 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2516 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2517 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2518 { } /* end */
2519};
2520
a9111321 2521static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2522 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2525 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2527 HDA_OUTPUT),
2528 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2530 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2532 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2534 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2535 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2536 { } /* end */
2537};
2538
2539
4f5d1706 2540static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2541{
a9fd4f3f 2542 struct alc_spec *spec = codec->spec;
5b2d1eca 2543
a9fd4f3f
TI
2544 spec->autocfg.hp_pins[0] = 0x15;
2545 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2546 spec->autocfg.speaker_pins[1] = 0x16;
2547 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2548 spec->automute = 1;
2549 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2550}
2551
4f5d1706 2552static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2553{
2554 struct alc_spec *spec = codec->spec;
2555
2556 spec->autocfg.hp_pins[0] = 0x15;
2557 spec->autocfg.speaker_pins[0] = 0x14;
2558 spec->autocfg.speaker_pins[1] = 0x16;
2559 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2560 spec->automute = 1;
2561 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2562}
2563
d9477207
DK
2564static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2565{
2566 struct alc_spec *spec = codec->spec;
2567
2568 spec->autocfg.hp_pins[0] = 0x15;
2569 spec->autocfg.speaker_pins[0] = 0x14;
2570 spec->autocfg.speaker_pins[1] = 0x16;
2571 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2572 spec->automute = 1;
2573 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2574}
2575
4f5d1706 2576static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2577{
2578 struct alc_spec *spec = codec->spec;
2579
2580 spec->autocfg.hp_pins[0] = 0x15;
2581 spec->autocfg.speaker_pins[0] = 0x14;
2582 spec->autocfg.speaker_pins[1] = 0x16;
2583 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2584 spec->automute = 1;
2585 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2586}
2587
1da177e4 2588/*
e9edcee0
TI
2589 * ALC880 3-stack model
2590 *
2591 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2592 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2593 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2594 */
2595
4c6d72d1 2596static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2597 /* front, rear, clfe, rear_surr */
2598 0x02, 0x05, 0x04, 0x03
2599};
2600
4c6d72d1 2601static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2602 /* ADC0-2 */
2603 0x07, 0x08, 0x09,
2604};
2605
2606/* The datasheet says the node 0x07 is connected from inputs,
2607 * but it shows zero connection in the real implementation on some devices.
df694daa 2608 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2609 */
4c6d72d1 2610static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2611 /* ADC1-2 */
2612 0x08, 0x09,
2613};
2614
2615#define ALC880_DIGOUT_NID 0x06
2616#define ALC880_DIGIN_NID 0x0a
2617
a9111321 2618static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2619 .num_items = 4,
2620 .items = {
2621 { "Mic", 0x0 },
2622 { "Front Mic", 0x3 },
2623 { "Line", 0x2 },
2624 { "CD", 0x4 },
2625 },
2626};
2627
2628/* channel source setting (2/6 channel selection for 3-stack) */
2629/* 2ch mode */
a9111321 2630static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2631 /* set line-in to input, mute it */
2632 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2633 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2634 /* set mic-in to input vref 80%, mute it */
2635 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2636 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2637 { } /* end */
2638};
2639
2640/* 6ch mode */
a9111321 2641static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2642 /* set line-in to output, unmute it */
2643 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2644 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2645 /* set mic-in to output, unmute it */
2646 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2647 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2648 { } /* end */
2649};
2650
a9111321 2651static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2652 { 2, alc880_threestack_ch2_init },
2653 { 6, alc880_threestack_ch6_init },
2654};
2655
a9111321 2656static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2657 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2658 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2659 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2660 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2661 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2662 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2663 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2664 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2665 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2666 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2668 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2669 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2670 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2671 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2672 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2673 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2674 {
2675 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2676 .name = "Channel Mode",
df694daa
KY
2677 .info = alc_ch_mode_info,
2678 .get = alc_ch_mode_get,
2679 .put = alc_ch_mode_put,
e9edcee0
TI
2680 },
2681 { } /* end */
2682};
2683
2684/* capture mixer elements */
f9e336f6
TI
2685static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2686 struct snd_ctl_elem_info *uinfo)
2687{
2688 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2689 struct alc_spec *spec = codec->spec;
2690 int err;
1da177e4 2691
5a9e02e9 2692 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2693 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2694 HDA_INPUT);
2695 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2696 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2697 return err;
2698}
2699
2700static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2701 unsigned int size, unsigned int __user *tlv)
2702{
2703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2704 struct alc_spec *spec = codec->spec;
2705 int err;
1da177e4 2706
5a9e02e9 2707 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2708 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2709 HDA_INPUT);
2710 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2711 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2712 return err;
2713}
2714
2715typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2716 struct snd_ctl_elem_value *ucontrol);
2717
2718static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2719 struct snd_ctl_elem_value *ucontrol,
2720 getput_call_t func)
2721{
2722 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2723 struct alc_spec *spec = codec->spec;
2724 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2725 int err;
2726
5a9e02e9 2727 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2728 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2729 3, 0, HDA_INPUT);
2730 err = func(kcontrol, ucontrol);
5a9e02e9 2731 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2732 return err;
2733}
2734
2735static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2736 struct snd_ctl_elem_value *ucontrol)
2737{
2738 return alc_cap_getput_caller(kcontrol, ucontrol,
2739 snd_hda_mixer_amp_volume_get);
2740}
2741
2742static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2743 struct snd_ctl_elem_value *ucontrol)
2744{
2745 return alc_cap_getput_caller(kcontrol, ucontrol,
2746 snd_hda_mixer_amp_volume_put);
2747}
2748
2749/* capture mixer elements */
2750#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2751
2752static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2753 struct snd_ctl_elem_value *ucontrol)
2754{
2755 return alc_cap_getput_caller(kcontrol, ucontrol,
2756 snd_hda_mixer_amp_switch_get);
2757}
2758
2759static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2760 struct snd_ctl_elem_value *ucontrol)
2761{
2762 return alc_cap_getput_caller(kcontrol, ucontrol,
2763 snd_hda_mixer_amp_switch_put);
2764}
2765
a23b688f 2766#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2767 { \
2768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2769 .name = "Capture Switch", \
2770 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2771 .count = num, \
2772 .info = alc_cap_sw_info, \
2773 .get = alc_cap_sw_get, \
2774 .put = alc_cap_sw_put, \
2775 }, \
2776 { \
2777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2778 .name = "Capture Volume", \
2779 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2780 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2781 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2782 .count = num, \
2783 .info = alc_cap_vol_info, \
2784 .get = alc_cap_vol_get, \
2785 .put = alc_cap_vol_put, \
2786 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2787 }
2788
2789#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2790 { \
2791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2792 /* .name = "Capture Source", */ \
2793 .name = "Input Source", \
2794 .count = num, \
2795 .info = alc_mux_enum_info, \
2796 .get = alc_mux_enum_get, \
2797 .put = alc_mux_enum_put, \
a23b688f
TI
2798 }
2799
2800#define DEFINE_CAPMIX(num) \
a9111321 2801static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2802 _DEFINE_CAPMIX(num), \
2803 _DEFINE_CAPSRC(num), \
2804 { } /* end */ \
2805}
2806
2807#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2808static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2809 _DEFINE_CAPMIX(num), \
2810 { } /* end */ \
f9e336f6
TI
2811}
2812
2813/* up to three ADCs */
2814DEFINE_CAPMIX(1);
2815DEFINE_CAPMIX(2);
2816DEFINE_CAPMIX(3);
a23b688f
TI
2817DEFINE_CAPMIX_NOSRC(1);
2818DEFINE_CAPMIX_NOSRC(2);
2819DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2820
2821/*
2822 * ALC880 5-stack model
2823 *
9c7f852e
TI
2824 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2825 * Side = 0x02 (0xd)
e9edcee0
TI
2826 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2827 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2828 */
2829
2830/* additional mixers to alc880_three_stack_mixer */
a9111321 2831static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2832 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2833 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2834 { } /* end */
2835};
2836
e9edcee0
TI
2837/* channel source setting (6/8 channel selection for 5-stack) */
2838/* 6ch mode */
a9111321 2839static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2840 /* set line-in to input, mute it */
2841 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2842 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2843 { } /* end */
2844};
2845
e9edcee0 2846/* 8ch mode */
a9111321 2847static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2848 /* set line-in to output, unmute it */
2849 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2850 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2851 { } /* end */
2852};
2853
a9111321 2854static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2855 { 6, alc880_fivestack_ch6_init },
2856 { 8, alc880_fivestack_ch8_init },
2857};
2858
2859
2860/*
2861 * ALC880 6-stack model
2862 *
9c7f852e
TI
2863 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2864 * Side = 0x05 (0x0f)
e9edcee0
TI
2865 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2866 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2867 */
2868
4c6d72d1 2869static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2870 /* front, rear, clfe, rear_surr */
2871 0x02, 0x03, 0x04, 0x05
f12ab1e0 2872};
e9edcee0 2873
a9111321 2874static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2875 .num_items = 4,
2876 .items = {
2877 { "Mic", 0x0 },
2878 { "Front Mic", 0x1 },
2879 { "Line", 0x2 },
2880 { "CD", 0x4 },
2881 },
2882};
2883
2884/* fixed 8-channels */
a9111321 2885static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2886 { 8, NULL },
2887};
2888
a9111321 2889static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2890 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2891 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2892 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2893 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2894 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2895 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2896 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2897 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2898 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2899 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2900 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2901 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2907 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2908 {
2909 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2910 .name = "Channel Mode",
df694daa
KY
2911 .info = alc_ch_mode_info,
2912 .get = alc_ch_mode_get,
2913 .put = alc_ch_mode_put,
16ded525
TI
2914 },
2915 { } /* end */
2916};
2917
e9edcee0
TI
2918
2919/*
2920 * ALC880 W810 model
2921 *
2922 * W810 has rear IO for:
2923 * Front (DAC 02)
2924 * Surround (DAC 03)
2925 * Center/LFE (DAC 04)
2926 * Digital out (06)
2927 *
2928 * The system also has a pair of internal speakers, and a headphone jack.
2929 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2930 *
e9edcee0
TI
2931 * There is a variable resistor to control the speaker or headphone
2932 * volume. This is a hardware-only device without a software API.
2933 *
2934 * Plugging headphones in will disable the internal speakers. This is
2935 * implemented in hardware, not via the driver using jack sense. In
2936 * a similar fashion, plugging into the rear socket marked "front" will
2937 * disable both the speakers and headphones.
2938 *
2939 * For input, there's a microphone jack, and an "audio in" jack.
2940 * These may not do anything useful with this driver yet, because I
2941 * haven't setup any initialization verbs for these yet...
2942 */
2943
4c6d72d1 2944static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2945 /* front, rear/surround, clfe */
2946 0x02, 0x03, 0x04
16ded525
TI
2947};
2948
e9edcee0 2949/* fixed 6 channels */
a9111321 2950static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2951 { 6, NULL }
2952};
2953
2954/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2955static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2956 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2957 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2958 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2959 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2960 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2961 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2962 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2963 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2965 { } /* end */
2966};
2967
2968
2969/*
2970 * Z710V model
2971 *
2972 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2973 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2974 * Line = 0x1a
e9edcee0
TI
2975 */
2976
4c6d72d1 2977static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2978 0x02
2979};
2980#define ALC880_Z71V_HP_DAC 0x03
2981
2982/* fixed 2 channels */
a9111321 2983static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2984 { 2, NULL }
2985};
2986
a9111321 2987static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2988 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2989 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2990 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2991 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2992 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2993 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2994 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2996 { } /* end */
2997};
2998
e9edcee0 2999
e9edcee0
TI
3000/*
3001 * ALC880 F1734 model
3002 *
3003 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3004 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3005 */
3006
4c6d72d1 3007static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
3008 0x03
3009};
3010#define ALC880_F1734_HP_DAC 0x02
3011
a9111321 3012static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 3013 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3014 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
3015 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3016 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
3017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
3019 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3020 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
3021 { } /* end */
3022};
3023
a9111321 3024static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
3025 .num_items = 2,
3026 .items = {
3027 { "Mic", 0x1 },
3028 { "CD", 0x4 },
3029 },
3030};
3031
e9edcee0 3032
e9edcee0
TI
3033/*
3034 * ALC880 ASUS model
3035 *
3036 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3037 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3038 * Mic = 0x18, Line = 0x1a
3039 */
3040
3041#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3042#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3043
a9111321 3044static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 3045 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3046 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3047 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3048 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3049 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3050 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3051 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3052 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3053 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3054 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3055 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3056 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3057 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3059 {
3060 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3061 .name = "Channel Mode",
df694daa
KY
3062 .info = alc_ch_mode_info,
3063 .get = alc_ch_mode_get,
3064 .put = alc_ch_mode_put,
16ded525
TI
3065 },
3066 { } /* end */
3067};
e9edcee0 3068
e9edcee0
TI
3069/*
3070 * ALC880 ASUS W1V model
3071 *
3072 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3073 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3074 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3075 */
3076
3077/* additional mixers to alc880_asus_mixer */
a9111321 3078static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3079 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3080 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3081 { } /* end */
3082};
3083
df694daa 3084/* TCL S700 */
a9111321 3085static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3086 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3087 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3088 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3089 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3090 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3093 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3094 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3095 { } /* end */
3096};
3097
ccc656ce 3098/* Uniwill */
a9111321 3099static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3100 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3101 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3102 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3103 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3104 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3105 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3106 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3107 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3108 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3109 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3111 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3114 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3116 {
3117 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3118 .name = "Channel Mode",
3119 .info = alc_ch_mode_info,
3120 .get = alc_ch_mode_get,
3121 .put = alc_ch_mode_put,
3122 },
3123 { } /* end */
3124};
3125
a9111321 3126static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3127 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3130 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3131 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3132 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3133 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3134 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3135 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3136 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3137 { } /* end */
3138};
3139
a9111321 3140static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3141 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3143 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3144 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3146 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3147 { } /* end */
3148};
3149
2134ea4f
TI
3150/*
3151 * virtual master controls
3152 */
3153
3154/*
3155 * slave controls for virtual master
3156 */
ea734963 3157static const char * const alc_slave_vols[] = {
2134ea4f
TI
3158 "Front Playback Volume",
3159 "Surround Playback Volume",
3160 "Center Playback Volume",
3161 "LFE Playback Volume",
3162 "Side Playback Volume",
3163 "Headphone Playback Volume",
3164 "Speaker Playback Volume",
3165 "Mono Playback Volume",
2134ea4f
TI
3166 "Line-Out Playback Volume",
3167 NULL,
3168};
3169
ea734963 3170static const char * const alc_slave_sws[] = {
2134ea4f
TI
3171 "Front Playback Switch",
3172 "Surround Playback Switch",
3173 "Center Playback Switch",
3174 "LFE Playback Switch",
3175 "Side Playback Switch",
3176 "Headphone Playback Switch",
3177 "Speaker Playback Switch",
3178 "Mono Playback Switch",
edb54a55 3179 "IEC958 Playback Switch",
23033b2b 3180 "Line-Out Playback Switch",
2134ea4f
TI
3181 NULL,
3182};
3183
1da177e4 3184/*
e9edcee0 3185 * build control elements
1da177e4 3186 */
603c4019 3187
5b0cb1d8
JK
3188#define NID_MAPPING (-1)
3189
3190#define SUBDEV_SPEAKER_ (0 << 6)
3191#define SUBDEV_HP_ (1 << 6)
3192#define SUBDEV_LINE_ (2 << 6)
3193#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3194#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3195#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3196
603c4019
TI
3197static void alc_free_kctls(struct hda_codec *codec);
3198
67d634c0 3199#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3200/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3201static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3202 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3203 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3204 { } /* end */
3205};
67d634c0 3206#endif
45bdd1c1 3207
1da177e4
LT
3208static int alc_build_controls(struct hda_codec *codec)
3209{
3210 struct alc_spec *spec = codec->spec;
2f44f847 3211 struct snd_kcontrol *kctl = NULL;
a9111321 3212 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3213 int i, j, err;
3214 unsigned int u;
3215 hda_nid_t nid;
1da177e4
LT
3216
3217 for (i = 0; i < spec->num_mixers; i++) {
3218 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3219 if (err < 0)
3220 return err;
3221 }
f9e336f6
TI
3222 if (spec->cap_mixer) {
3223 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3224 if (err < 0)
3225 return err;
3226 }
1da177e4 3227 if (spec->multiout.dig_out_nid) {
9c7f852e 3228 err = snd_hda_create_spdif_out_ctls(codec,
74b654c9 3229 spec->multiout.dig_out_nid,
9c7f852e 3230 spec->multiout.dig_out_nid);
1da177e4
LT
3231 if (err < 0)
3232 return err;
e64f14f4
TI
3233 if (!spec->no_analog) {
3234 err = snd_hda_create_spdif_share_sw(codec,
3235 &spec->multiout);
3236 if (err < 0)
3237 return err;
3238 spec->multiout.share_spdif = 1;
3239 }
1da177e4
LT
3240 }
3241 if (spec->dig_in_nid) {
3242 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3243 if (err < 0)
3244 return err;
3245 }
2134ea4f 3246
67d634c0 3247#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3248 /* create beep controls if needed */
3249 if (spec->beep_amp) {
a9111321 3250 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3251 for (knew = alc_beep_mixer; knew->name; knew++) {
3252 struct snd_kcontrol *kctl;
3253 kctl = snd_ctl_new1(knew, codec);
3254 if (!kctl)
3255 return -ENOMEM;
3256 kctl->private_value = spec->beep_amp;
5e26dfd0 3257 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3258 if (err < 0)
3259 return err;
3260 }
3261 }
67d634c0 3262#endif
45bdd1c1 3263
2134ea4f 3264 /* if we have no master control, let's create it */
e64f14f4
TI
3265 if (!spec->no_analog &&
3266 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3267 unsigned int vmaster_tlv[4];
2134ea4f 3268 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3269 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3270 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3271 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3272 if (err < 0)
3273 return err;
3274 }
e64f14f4
TI
3275 if (!spec->no_analog &&
3276 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3277 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3278 NULL, alc_slave_sws);
3279 if (err < 0)
3280 return err;
3281 }
3282
5b0cb1d8 3283 /* assign Capture Source enums to NID */
fbe618f2
TI
3284 if (spec->capsrc_nids || spec->adc_nids) {
3285 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3286 if (!kctl)
3287 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3288 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3289 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3290 if (!nids)
3291 nids = spec->adc_nids;
3292 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3293 if (err < 0)
3294 return err;
3295 }
5b0cb1d8
JK
3296 }
3297 if (spec->cap_mixer) {
3298 const char *kname = kctl ? kctl->id.name : NULL;
3299 for (knew = spec->cap_mixer; knew->name; knew++) {
3300 if (kname && strcmp(knew->name, kname) == 0)
3301 continue;
3302 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3303 for (i = 0; kctl && i < kctl->count; i++) {
3304 err = snd_hda_add_nid(codec, kctl, i,
3305 spec->adc_nids[i]);
3306 if (err < 0)
3307 return err;
3308 }
3309 }
3310 }
3311
3312 /* other nid->control mapping */
3313 for (i = 0; i < spec->num_mixers; i++) {
3314 for (knew = spec->mixers[i]; knew->name; knew++) {
3315 if (knew->iface != NID_MAPPING)
3316 continue;
3317 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3318 if (kctl == NULL)
3319 continue;
3320 u = knew->subdevice;
3321 for (j = 0; j < 4; j++, u >>= 8) {
3322 nid = u & 0x3f;
3323 if (nid == 0)
3324 continue;
3325 switch (u & 0xc0) {
3326 case SUBDEV_SPEAKER_:
3327 nid = spec->autocfg.speaker_pins[nid];
3328 break;
3329 case SUBDEV_LINE_:
3330 nid = spec->autocfg.line_out_pins[nid];
3331 break;
3332 case SUBDEV_HP_:
3333 nid = spec->autocfg.hp_pins[nid];
3334 break;
3335 default:
3336 continue;
3337 }
3338 err = snd_hda_add_nid(codec, kctl, 0, nid);
3339 if (err < 0)
3340 return err;
3341 }
3342 u = knew->private_value;
3343 for (j = 0; j < 4; j++, u >>= 8) {
3344 nid = u & 0xff;
3345 if (nid == 0)
3346 continue;
3347 err = snd_hda_add_nid(codec, kctl, 0, nid);
3348 if (err < 0)
3349 return err;
3350 }
3351 }
3352 }
bae84e70
TI
3353
3354 alc_free_kctls(codec); /* no longer needed */
3355
1da177e4
LT
3356 return 0;
3357}
3358
e9edcee0 3359
1da177e4
LT
3360/*
3361 * initialize the codec volumes, etc
3362 */
3363
e9edcee0
TI
3364/*
3365 * generic initialization of ADC, input mixers and output mixers
3366 */
a9111321 3367static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3368 /*
3369 * Unmute ADC0-2 and set the default input to mic-in
3370 */
71fe7b82 3371 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3372 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3373 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3374 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3375 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3376 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3377
e9edcee0
TI
3378 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3379 * mixer widget
9c7f852e
TI
3380 * Note: PASD motherboards uses the Line In 2 as the input for front
3381 * panel mic (mic 2)
1da177e4 3382 */
e9edcee0 3383 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3388 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3389 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3390 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3391
e9edcee0
TI
3392 /*
3393 * Set up output mixers (0x0c - 0x0f)
1da177e4 3394 */
e9edcee0
TI
3395 /* set vol=0 to output mixers */
3396 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3397 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3398 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3399 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3400 /* set up input amps for analog loopback */
3401 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3404 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3405 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3407 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3408 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3410
3411 { }
3412};
3413
e9edcee0
TI
3414/*
3415 * 3-stack pin configuration:
3416 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3417 */
a9111321 3418static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3419 /*
3420 * preset connection lists of input pins
3421 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3422 */
3423 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3424 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3425 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3426
3427 /*
3428 * Set pin mode and muting
3429 */
3430 /* set front pin widgets 0x14 for output */
05acb863 3431 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3432 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3433 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3434 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3435 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3436 /* Mic2 (as headphone out) for HP output */
3437 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3438 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3439 /* Line In pin widget for input */
05acb863 3440 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3442 /* Line2 (as front mic) pin widget for input and vref at 80% */
3443 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3444 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3445 /* CD pin widget for input */
05acb863 3446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3447
e9edcee0
TI
3448 { }
3449};
1da177e4 3450
e9edcee0
TI
3451/*
3452 * 5-stack pin configuration:
3453 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3454 * line-in/side = 0x1a, f-mic = 0x1b
3455 */
a9111321 3456static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3457 /*
3458 * preset connection lists of input pins
3459 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3460 */
e9edcee0
TI
3461 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3462 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3463
e9edcee0
TI
3464 /*
3465 * Set pin mode and muting
1da177e4 3466 */
e9edcee0
TI
3467 /* set pin widgets 0x14-0x17 for output */
3468 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3469 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3470 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3471 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3472 /* unmute pins for output (no gain on this amp) */
3473 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3475 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3476 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3477
3478 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3479 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3480 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3481 /* Mic2 (as headphone out) for HP output */
3482 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3483 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3484 /* Line In pin widget for input */
3485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3486 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 /* Line2 (as front mic) pin widget for input and vref at 80% */
3488 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3489 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3490 /* CD pin widget for input */
3491 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3492
3493 { }
3494};
3495
e9edcee0
TI
3496/*
3497 * W810 pin configuration:
3498 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3499 */
a9111321 3500static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3501 /* hphone/speaker input selector: front DAC */
3502 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3503
05acb863 3504 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3505 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3506 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3507 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3508 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3509 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3510
e9edcee0 3511 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3512 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3513
1da177e4
LT
3514 { }
3515};
3516
e9edcee0
TI
3517/*
3518 * Z71V pin configuration:
3519 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3520 */
a9111321 3521static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3522 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3523 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3525 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3526
16ded525 3527 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3530 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3531
3532 { }
3533};
3534
e9edcee0
TI
3535/*
3536 * 6-stack pin configuration:
9c7f852e
TI
3537 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3538 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3539 */
a9111321 3540static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3541 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3542
16ded525 3543 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3544 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3546 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3548 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3549 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3550 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551
16ded525 3552 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3553 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3554 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3555 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3556 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3557 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3558 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3559 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3560 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3561
e9edcee0
TI
3562 { }
3563};
3564
ccc656ce
KY
3565/*
3566 * Uniwill pin configuration:
3567 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3568 * line = 0x1a
3569 */
a9111321 3570static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3571 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3572
3573 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3575 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3578 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3581 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3582 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3583 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3584 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3585 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3586 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3587
3588 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3589 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3590 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3591 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3592 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3593 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3594 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3595 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3596 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3597
3598 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3599 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3600
3601 { }
3602};
3603
3604/*
3605* Uniwill P53
ea1fb29a 3606* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3607 */
a9111321 3608static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3609 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3610
3611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3612 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3613 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3614 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3615 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3616 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3618 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3619 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3623
3624 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3625 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3626 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3627 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3628 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3629 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3630
3631 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3632 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3633
3634 { }
3635};
3636
a9111321 3637static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3638 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3639 { }
3640};
3641
458a4fab 3642/* auto-toggle front mic */
eeb43387 3643static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3644{
3645 unsigned int present;
3646 unsigned char bits;
ccc656ce 3647
864f92be 3648 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3649 bits = present ? HDA_AMP_MUTE : 0;
3650 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3651}
3652
4f5d1706 3653static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3654{
a9fd4f3f
TI
3655 struct alc_spec *spec = codec->spec;
3656
3657 spec->autocfg.hp_pins[0] = 0x14;
3658 spec->autocfg.speaker_pins[0] = 0x15;
3659 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3660 spec->automute = 1;
3661 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3662}
3663
3664static void alc880_uniwill_init_hook(struct hda_codec *codec)
3665{
d922b51d 3666 alc_hp_automute(codec);
eeb43387 3667 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3668}
3669
3670static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3671 unsigned int res)
3672{
3673 /* Looks like the unsol event is incompatible with the standard
3674 * definition. 4bit tag is placed at 28 bit!
3675 */
458a4fab 3676 switch (res >> 28) {
458a4fab 3677 case ALC880_MIC_EVENT:
eeb43387 3678 alc88x_simple_mic_automute(codec);
458a4fab 3679 break;
a9fd4f3f 3680 default:
d922b51d 3681 alc_sku_unsol_event(codec, res);
a9fd4f3f 3682 break;
458a4fab 3683 }
ccc656ce
KY
3684}
3685
4f5d1706 3686static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3687{
a9fd4f3f 3688 struct alc_spec *spec = codec->spec;
ccc656ce 3689
a9fd4f3f
TI
3690 spec->autocfg.hp_pins[0] = 0x14;
3691 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3692 spec->automute = 1;
3693 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3694}
3695
3696static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3697{
3698 unsigned int present;
ea1fb29a 3699
ccc656ce 3700 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3701 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3702 present &= HDA_AMP_VOLMASK;
3703 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3704 HDA_AMP_VOLMASK, present);
3705 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3706 HDA_AMP_VOLMASK, present);
ccc656ce 3707}
47fd830a 3708
ccc656ce
KY
3709static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3710 unsigned int res)
3711{
3712 /* Looks like the unsol event is incompatible with the standard
3713 * definition. 4bit tag is placed at 28 bit!
3714 */
f12ab1e0 3715 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3716 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3717 else
d922b51d 3718 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3719}
3720
e9edcee0
TI
3721/*
3722 * F1734 pin configuration:
3723 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3724 */
a9111321 3725static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3726 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3727 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3728 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3729 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3730 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3731
e9edcee0 3732 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3734 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3735 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3736
e9edcee0
TI
3737 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3738 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3739 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3740 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3741 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3742 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3743 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3744 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3745 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3746
937b4160
TI
3747 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3748 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3749
dfc0ff62
TI
3750 { }
3751};
3752
e9edcee0
TI
3753/*
3754 * ASUS pin configuration:
3755 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3756 */
a9111321 3757static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3758 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3759 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3760 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3761 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3762
3763 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3764 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3765 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3768 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3769 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3771
3772 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3773 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3774 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3775 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3777 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3779 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3780 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3781
e9edcee0
TI
3782 { }
3783};
16ded525 3784
e9edcee0 3785/* Enable GPIO mask and set output */
bc9f98a9
KY
3786#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3787#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3788#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3789
3790/* Clevo m520g init */
a9111321 3791static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3792 /* headphone output */
3793 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3794 /* line-out */
3795 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3796 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3797 /* Line-in */
3798 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3800 /* CD */
3801 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3802 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803 /* Mic1 (rear panel) */
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* Mic2 (front panel) */
3807 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3808 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809 /* headphone */
3810 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3811 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 /* change to EAPD mode */
3813 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3814 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3815
3816 { }
16ded525
TI
3817};
3818
a9111321 3819static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3820 /* change to EAPD mode */
3821 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3822 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3823
df694daa
KY
3824 /* Headphone output */
3825 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3826 /* Front output*/
3827 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3828 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830 /* Line In pin widget for input */
3831 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3832 /* CD pin widget for input */
3833 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3834 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3835 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3836
3837 /* change to EAPD mode */
3838 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3839 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3840
3841 { }
3842};
16ded525 3843
e9edcee0 3844/*
ae6b813a
TI
3845 * LG m1 express dual
3846 *
3847 * Pin assignment:
3848 * Rear Line-In/Out (blue): 0x14
3849 * Build-in Mic-In: 0x15
3850 * Speaker-out: 0x17
3851 * HP-Out (green): 0x1b
3852 * Mic-In/Out (red): 0x19
3853 * SPDIF-Out: 0x1e
3854 */
3855
3856/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3857static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3858 0x05, 0x02, 0x03
3859};
3860
3861/* seems analog CD is not working */
a9111321 3862static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3863 .num_items = 3,
3864 .items = {
3865 { "Mic", 0x1 },
3866 { "Line", 0x5 },
3867 { "Internal Mic", 0x6 },
3868 },
3869};
3870
3871/* 2,4,6 channel modes */
a9111321 3872static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3873 /* set line-in and mic-in to input */
3874 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3875 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3876 { }
3877};
3878
a9111321 3879static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3880 /* set line-in to out and mic-in to input */
3881 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3882 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3883 { }
3884};
3885
a9111321 3886static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3887 /* set line-in and mic-in to output */
3888 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3889 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3890 { }
3891};
3892
a9111321 3893static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3894 { 2, alc880_lg_ch2_init },
3895 { 4, alc880_lg_ch4_init },
3896 { 6, alc880_lg_ch6_init },
3897};
3898
a9111321 3899static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3900 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3901 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3902 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3903 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3904 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3905 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3906 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3907 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3908 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3909 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3910 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3911 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3912 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3913 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3914 {
3915 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3916 .name = "Channel Mode",
3917 .info = alc_ch_mode_info,
3918 .get = alc_ch_mode_get,
3919 .put = alc_ch_mode_put,
3920 },
3921 { } /* end */
3922};
3923
a9111321 3924static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3925 /* set capture source to mic-in */
3926 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3927 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3929 /* mute all amp mixer inputs */
3930 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3931 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3932 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3933 /* line-in to input */
3934 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3935 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* built-in mic */
3937 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3938 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* speaker-out */
3940 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3941 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3942 /* mic-in to input */
3943 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3944 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3945 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3946 /* HP-out */
3947 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3948 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3949 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3950 /* jack sense */
a9fd4f3f 3951 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3952 { }
3953};
3954
3955/* toggle speaker-output according to the hp-jack state */
4f5d1706 3956static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3957{
a9fd4f3f 3958 struct alc_spec *spec = codec->spec;
ae6b813a 3959
a9fd4f3f
TI
3960 spec->autocfg.hp_pins[0] = 0x1b;
3961 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3962 spec->automute = 1;
3963 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3964}
3965
d681518a
TI
3966/*
3967 * LG LW20
3968 *
3969 * Pin assignment:
3970 * Speaker-out: 0x14
3971 * Mic-In: 0x18
e4f41da9
CM
3972 * Built-in Mic-In: 0x19
3973 * Line-In: 0x1b
3974 * HP-Out: 0x1a
d681518a
TI
3975 * SPDIF-Out: 0x1e
3976 */
3977
a9111321 3978static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3979 .num_items = 3,
d681518a
TI
3980 .items = {
3981 { "Mic", 0x0 },
3982 { "Internal Mic", 0x1 },
e4f41da9 3983 { "Line In", 0x2 },
d681518a
TI
3984 },
3985};
3986
0a8c5da3
CM
3987#define alc880_lg_lw_modes alc880_threestack_modes
3988
a9111321 3989static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3990 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3991 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3992 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3993 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3994 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3995 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3996 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3997 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
4000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4001 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4002 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4003 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
4004 {
4005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4006 .name = "Channel Mode",
4007 .info = alc_ch_mode_info,
4008 .get = alc_ch_mode_get,
4009 .put = alc_ch_mode_put,
4010 },
d681518a
TI
4011 { } /* end */
4012};
4013
a9111321 4014static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
4015 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4016 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4017 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4018
d681518a
TI
4019 /* set capture source to mic-in */
4020 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4021 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4022 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 4023 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
4024 /* speaker-out */
4025 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4027 /* HP-out */
d681518a
TI
4028 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4029 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030 /* mic-in to input */
4031 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4033 /* built-in mic */
4034 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4035 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4036 /* jack sense */
a9fd4f3f 4037 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
4038 { }
4039};
4040
4041/* toggle speaker-output according to the hp-jack state */
4f5d1706 4042static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 4043{
a9fd4f3f 4044 struct alc_spec *spec = codec->spec;
d681518a 4045
a9fd4f3f
TI
4046 spec->autocfg.hp_pins[0] = 0x1b;
4047 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4048 spec->automute = 1;
4049 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4050}
4051
a9111321 4052static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4053 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4057 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4058 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4059 { } /* end */
4060};
4061
a9111321 4062static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4063 .num_items = 2,
4064 .items = {
4065 { "Mic", 0x0 },
4066 { "Internal Mic", 0x1 },
4067 },
4068};
4069
a9111321 4070static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4071 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4072
4073 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4074 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4075
4076 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4077 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4078 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079 /* Mic2 (as headphone out) for HP output */
4080 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4081 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4082 /* Internal Speaker */
4083 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4084 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4085
4086 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4087 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4088
4089 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4090 { }
4091};
4092
4093/* toggle speaker-output according to the hp-jack state */
4094static void alc880_medion_rim_automute(struct hda_codec *codec)
4095{
a9fd4f3f 4096 struct alc_spec *spec = codec->spec;
d922b51d 4097 alc_hp_automute(codec);
a9fd4f3f
TI
4098 /* toggle EAPD */
4099 if (spec->jack_present)
df99cd33
TI
4100 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4101 else
4102 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4103}
4104
4105static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4106 unsigned int res)
4107{
4108 /* Looks like the unsol event is incompatible with the standard
4109 * definition. 4bit tag is placed at 28 bit!
4110 */
4111 if ((res >> 28) == ALC880_HP_EVENT)
4112 alc880_medion_rim_automute(codec);
4113}
4114
4f5d1706 4115static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4116{
4117 struct alc_spec *spec = codec->spec;
4118
4119 spec->autocfg.hp_pins[0] = 0x14;
4120 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4121 spec->automute = 1;
4122 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4123}
4124
cb53c626 4125#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4126static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4127 { 0x0b, HDA_INPUT, 0 },
4128 { 0x0b, HDA_INPUT, 1 },
4129 { 0x0b, HDA_INPUT, 2 },
4130 { 0x0b, HDA_INPUT, 3 },
4131 { 0x0b, HDA_INPUT, 4 },
4132 { } /* end */
4133};
4134
a9111321 4135static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4136 { 0x0b, HDA_INPUT, 1 },
4137 { 0x0b, HDA_INPUT, 6 },
4138 { 0x0b, HDA_INPUT, 7 },
4139 { } /* end */
4140};
4141#endif
4142
ae6b813a
TI
4143/*
4144 * Common callbacks
e9edcee0
TI
4145 */
4146
584c0c4c
TI
4147static void alc_init_special_input_src(struct hda_codec *codec);
4148
1da177e4
LT
4149static int alc_init(struct hda_codec *codec)
4150{
4151 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4152 unsigned int i;
4153
2c3bf9ab 4154 alc_fix_pll(codec);
4a79ba34 4155 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4156
e9edcee0
TI
4157 for (i = 0; i < spec->num_init_verbs; i++)
4158 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4159 alc_init_special_input_src(codec);
ae6b813a
TI
4160
4161 if (spec->init_hook)
4162 spec->init_hook(codec);
4163
58701120
TI
4164 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4165
9e5341b9 4166 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4167 return 0;
4168}
4169
ae6b813a
TI
4170static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4171{
4172 struct alc_spec *spec = codec->spec;
4173
4174 if (spec->unsol_event)
4175 spec->unsol_event(codec, res);
4176}
4177
cb53c626
TI
4178#ifdef CONFIG_SND_HDA_POWER_SAVE
4179static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4180{
4181 struct alc_spec *spec = codec->spec;
4182 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4183}
4184#endif
4185
1da177e4
LT
4186/*
4187 * Analog playback callbacks
4188 */
4189static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4190 struct hda_codec *codec,
c8b6bf9b 4191 struct snd_pcm_substream *substream)
1da177e4
LT
4192{
4193 struct alc_spec *spec = codec->spec;
9a08160b
TI
4194 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4195 hinfo);
1da177e4
LT
4196}
4197
4198static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4199 struct hda_codec *codec,
4200 unsigned int stream_tag,
4201 unsigned int format,
c8b6bf9b 4202 struct snd_pcm_substream *substream)
1da177e4
LT
4203{
4204 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4205 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4206 stream_tag, format, substream);
1da177e4
LT
4207}
4208
4209static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4210 struct hda_codec *codec,
c8b6bf9b 4211 struct snd_pcm_substream *substream)
1da177e4
LT
4212{
4213 struct alc_spec *spec = codec->spec;
4214 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4215}
4216
4217/*
4218 * Digital out
4219 */
4220static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4221 struct hda_codec *codec,
c8b6bf9b 4222 struct snd_pcm_substream *substream)
1da177e4
LT
4223{
4224 struct alc_spec *spec = codec->spec;
4225 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4226}
4227
6b97eb45
TI
4228static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4229 struct hda_codec *codec,
4230 unsigned int stream_tag,
4231 unsigned int format,
4232 struct snd_pcm_substream *substream)
4233{
4234 struct alc_spec *spec = codec->spec;
4235 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4236 stream_tag, format, substream);
4237}
4238
9b5f12e5
TI
4239static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4240 struct hda_codec *codec,
4241 struct snd_pcm_substream *substream)
4242{
4243 struct alc_spec *spec = codec->spec;
4244 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4245}
4246
1da177e4
LT
4247static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4248 struct hda_codec *codec,
c8b6bf9b 4249 struct snd_pcm_substream *substream)
1da177e4
LT
4250{
4251 struct alc_spec *spec = codec->spec;
4252 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4253}
4254
4255/*
4256 * Analog capture
4257 */
6330079f 4258static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4259 struct hda_codec *codec,
4260 unsigned int stream_tag,
4261 unsigned int format,
c8b6bf9b 4262 struct snd_pcm_substream *substream)
1da177e4
LT
4263{
4264 struct alc_spec *spec = codec->spec;
4265
6330079f 4266 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4267 stream_tag, 0, format);
4268 return 0;
4269}
4270
6330079f 4271static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4272 struct hda_codec *codec,
c8b6bf9b 4273 struct snd_pcm_substream *substream)
1da177e4
LT
4274{
4275 struct alc_spec *spec = codec->spec;
4276
888afa15
TI
4277 snd_hda_codec_cleanup_stream(codec,
4278 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4279 return 0;
4280}
4281
840b64c0
TI
4282/* analog capture with dynamic dual-adc changes */
4283static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4284 struct hda_codec *codec,
4285 unsigned int stream_tag,
4286 unsigned int format,
4287 struct snd_pcm_substream *substream)
4288{
4289 struct alc_spec *spec = codec->spec;
4290 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4291 spec->cur_adc_stream_tag = stream_tag;
4292 spec->cur_adc_format = format;
4293 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4294 return 0;
4295}
4296
4297static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4298 struct hda_codec *codec,
4299 struct snd_pcm_substream *substream)
4300{
4301 struct alc_spec *spec = codec->spec;
4302 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4303 spec->cur_adc = 0;
4304 return 0;
4305}
4306
a9111321 4307static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4308 .substreams = 1,
4309 .channels_min = 2,
4310 .channels_max = 2,
4311 .nid = 0, /* fill later */
4312 .ops = {
4313 .prepare = dualmic_capture_pcm_prepare,
4314 .cleanup = dualmic_capture_pcm_cleanup
4315 },
4316};
1da177e4
LT
4317
4318/*
4319 */
a9111321 4320static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4321 .substreams = 1,
4322 .channels_min = 2,
4323 .channels_max = 8,
e9edcee0 4324 /* NID is set in alc_build_pcms */
1da177e4
LT
4325 .ops = {
4326 .open = alc880_playback_pcm_open,
4327 .prepare = alc880_playback_pcm_prepare,
4328 .cleanup = alc880_playback_pcm_cleanup
4329 },
4330};
4331
a9111321 4332static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4333 .substreams = 1,
4334 .channels_min = 2,
4335 .channels_max = 2,
4336 /* NID is set in alc_build_pcms */
4337};
4338
a9111321 4339static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4340 .substreams = 1,
4341 .channels_min = 2,
4342 .channels_max = 2,
4343 /* NID is set in alc_build_pcms */
4344};
4345
a9111321 4346static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4347 .substreams = 2, /* can be overridden */
1da177e4
LT
4348 .channels_min = 2,
4349 .channels_max = 2,
e9edcee0 4350 /* NID is set in alc_build_pcms */
1da177e4 4351 .ops = {
6330079f
TI
4352 .prepare = alc880_alt_capture_pcm_prepare,
4353 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4354 },
4355};
4356
a9111321 4357static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4358 .substreams = 1,
4359 .channels_min = 2,
4360 .channels_max = 2,
4361 /* NID is set in alc_build_pcms */
4362 .ops = {
4363 .open = alc880_dig_playback_pcm_open,
6b97eb45 4364 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4365 .prepare = alc880_dig_playback_pcm_prepare,
4366 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4367 },
4368};
4369
a9111321 4370static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4371 .substreams = 1,
4372 .channels_min = 2,
4373 .channels_max = 2,
4374 /* NID is set in alc_build_pcms */
4375};
4376
4c5186ed 4377/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4378static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4379 .substreams = 0,
4380 .channels_min = 0,
4381 .channels_max = 0,
4382};
4383
1da177e4
LT
4384static int alc_build_pcms(struct hda_codec *codec)
4385{
4386 struct alc_spec *spec = codec->spec;
4387 struct hda_pcm *info = spec->pcm_rec;
4388 int i;
4389
4390 codec->num_pcms = 1;
4391 codec->pcm_info = info;
4392
e64f14f4
TI
4393 if (spec->no_analog)
4394 goto skip_analog;
4395
812a2cca
TI
4396 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4397 "%s Analog", codec->chip_name);
1da177e4 4398 info->name = spec->stream_name_analog;
274693f3 4399
4a471b7d 4400 if (spec->stream_analog_playback) {
da3cec35
TI
4401 if (snd_BUG_ON(!spec->multiout.dac_nids))
4402 return -EINVAL;
4a471b7d
TI
4403 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4404 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4405 }
4406 if (spec->stream_analog_capture) {
da3cec35
TI
4407 if (snd_BUG_ON(!spec->adc_nids))
4408 return -EINVAL;
4a471b7d
TI
4409 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4410 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4411 }
4412
4413 if (spec->channel_mode) {
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4415 for (i = 0; i < spec->num_channel_mode; i++) {
4416 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4417 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4418 }
1da177e4
LT
4419 }
4420 }
4421
e64f14f4 4422 skip_analog:
e08a007d 4423 /* SPDIF for stream index #1 */
1da177e4 4424 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4425 snprintf(spec->stream_name_digital,
4426 sizeof(spec->stream_name_digital),
4427 "%s Digital", codec->chip_name);
e08a007d 4428 codec->num_pcms = 2;
b25c9da1 4429 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4430 info = spec->pcm_rec + 1;
1da177e4 4431 info->name = spec->stream_name_digital;
8c441982
TI
4432 if (spec->dig_out_type)
4433 info->pcm_type = spec->dig_out_type;
4434 else
4435 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4436 if (spec->multiout.dig_out_nid &&
4437 spec->stream_digital_playback) {
1da177e4
LT
4438 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4439 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4440 }
4a471b7d
TI
4441 if (spec->dig_in_nid &&
4442 spec->stream_digital_capture) {
1da177e4
LT
4443 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4444 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4445 }
963f803f
TI
4446 /* FIXME: do we need this for all Realtek codec models? */
4447 codec->spdif_status_reset = 1;
1da177e4
LT
4448 }
4449
e64f14f4
TI
4450 if (spec->no_analog)
4451 return 0;
4452
e08a007d
TI
4453 /* If the use of more than one ADC is requested for the current
4454 * model, configure a second analog capture-only PCM.
4455 */
4456 /* Additional Analaog capture for index #2 */
6330079f
TI
4457 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4458 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4459 codec->num_pcms = 3;
c06134d7 4460 info = spec->pcm_rec + 2;
e08a007d 4461 info->name = spec->stream_name_analog;
6330079f
TI
4462 if (spec->alt_dac_nid) {
4463 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4464 *spec->stream_analog_alt_playback;
4465 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4466 spec->alt_dac_nid;
4467 } else {
4468 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4469 alc_pcm_null_stream;
4470 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4471 }
ce85c9ac 4472 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4473 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4474 *spec->stream_analog_alt_capture;
4475 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4476 spec->adc_nids[1];
4477 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4478 spec->num_adc_nids - 1;
4479 } else {
4480 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4481 alc_pcm_null_stream;
4482 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4483 }
4484 }
4485
1da177e4
LT
4486 return 0;
4487}
4488
a4e09aa3
TI
4489static inline void alc_shutup(struct hda_codec *codec)
4490{
1c716153
TI
4491 struct alc_spec *spec = codec->spec;
4492
4493 if (spec && spec->shutup)
4494 spec->shutup(codec);
a4e09aa3
TI
4495 snd_hda_shutup_pins(codec);
4496}
4497
603c4019
TI
4498static void alc_free_kctls(struct hda_codec *codec)
4499{
4500 struct alc_spec *spec = codec->spec;
4501
4502 if (spec->kctls.list) {
4503 struct snd_kcontrol_new *kctl = spec->kctls.list;
4504 int i;
4505 for (i = 0; i < spec->kctls.used; i++)
4506 kfree(kctl[i].name);
4507 }
4508 snd_array_free(&spec->kctls);
4509}
4510
1da177e4
LT
4511static void alc_free(struct hda_codec *codec)
4512{
e9edcee0 4513 struct alc_spec *spec = codec->spec;
e9edcee0 4514
f12ab1e0 4515 if (!spec)
e9edcee0
TI
4516 return;
4517
a4e09aa3 4518 alc_shutup(codec);
cd372fb3 4519 snd_hda_input_jack_free(codec);
603c4019 4520 alc_free_kctls(codec);
e9edcee0 4521 kfree(spec);
680cd536 4522 snd_hda_detach_beep_device(codec);
1da177e4
LT
4523}
4524
f5de24b0 4525#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4526static void alc_power_eapd(struct hda_codec *codec)
4527{
691f1fcc 4528 alc_auto_setup_eapd(codec, false);
c97259df
DC
4529}
4530
f5de24b0
HM
4531static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4532{
4533 struct alc_spec *spec = codec->spec;
a4e09aa3 4534 alc_shutup(codec);
f5de24b0 4535 if (spec && spec->power_hook)
c97259df 4536 spec->power_hook(codec);
f5de24b0
HM
4537 return 0;
4538}
4539#endif
4540
e044c39a 4541#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4542static int alc_resume(struct hda_codec *codec)
4543{
1c716153 4544 msleep(150); /* to avoid pop noise */
e044c39a
TI
4545 codec->patch_ops.init(codec);
4546 snd_hda_codec_resume_amp(codec);
4547 snd_hda_codec_resume_cache(codec);
9e5341b9 4548 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4549 return 0;
4550}
e044c39a
TI
4551#endif
4552
1da177e4
LT
4553/*
4554 */
a9111321 4555static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4556 .build_controls = alc_build_controls,
4557 .build_pcms = alc_build_pcms,
4558 .init = alc_init,
4559 .free = alc_free,
ae6b813a 4560 .unsol_event = alc_unsol_event,
e044c39a
TI
4561#ifdef SND_HDA_NEEDS_RESUME
4562 .resume = alc_resume,
4563#endif
cb53c626 4564#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4565 .suspend = alc_suspend,
cb53c626
TI
4566 .check_power_status = alc_check_power_status,
4567#endif
c97259df 4568 .reboot_notify = alc_shutup,
1da177e4
LT
4569};
4570
c027ddcd
KY
4571/* replace the codec chip_name with the given string */
4572static int alc_codec_rename(struct hda_codec *codec, const char *name)
4573{
4574 kfree(codec->chip_name);
4575 codec->chip_name = kstrdup(name, GFP_KERNEL);
4576 if (!codec->chip_name) {
4577 alc_free(codec);
4578 return -ENOMEM;
4579 }
4580 return 0;
4581}
4582
2fa522be
TI
4583/*
4584 * Test configuration for debugging
4585 *
4586 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4587 * enum controls.
4588 */
4589#ifdef CONFIG_SND_DEBUG
4c6d72d1 4590static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4591 0x02, 0x03, 0x04, 0x05
4592};
4593
a9111321 4594static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4595 .num_items = 7,
2fa522be
TI
4596 .items = {
4597 { "In-1", 0x0 },
4598 { "In-2", 0x1 },
4599 { "In-3", 0x2 },
4600 { "In-4", 0x3 },
4601 { "CD", 0x4 },
ae6b813a
TI
4602 { "Front", 0x5 },
4603 { "Surround", 0x6 },
2fa522be
TI
4604 },
4605};
4606
a9111321 4607static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4608 { 2, NULL },
fd2c326d 4609 { 4, NULL },
2fa522be 4610 { 6, NULL },
fd2c326d 4611 { 8, NULL },
2fa522be
TI
4612};
4613
9c7f852e
TI
4614static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4615 struct snd_ctl_elem_info *uinfo)
2fa522be 4616{
4c6d72d1 4617 static const char * const texts[] = {
2fa522be
TI
4618 "N/A", "Line Out", "HP Out",
4619 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4620 };
4621 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4622 uinfo->count = 1;
4623 uinfo->value.enumerated.items = 8;
4624 if (uinfo->value.enumerated.item >= 8)
4625 uinfo->value.enumerated.item = 7;
4626 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4627 return 0;
4628}
4629
9c7f852e
TI
4630static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4631 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4632{
4633 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4634 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4635 unsigned int pin_ctl, item = 0;
4636
4637 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4638 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4639 if (pin_ctl & AC_PINCTL_OUT_EN) {
4640 if (pin_ctl & AC_PINCTL_HP_EN)
4641 item = 2;
4642 else
4643 item = 1;
4644 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4645 switch (pin_ctl & AC_PINCTL_VREFEN) {
4646 case AC_PINCTL_VREF_HIZ: item = 3; break;
4647 case AC_PINCTL_VREF_50: item = 4; break;
4648 case AC_PINCTL_VREF_GRD: item = 5; break;
4649 case AC_PINCTL_VREF_80: item = 6; break;
4650 case AC_PINCTL_VREF_100: item = 7; break;
4651 }
4652 }
4653 ucontrol->value.enumerated.item[0] = item;
4654 return 0;
4655}
4656
9c7f852e
TI
4657static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4658 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4659{
4660 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4661 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4662 static const unsigned int ctls[] = {
2fa522be
TI
4663 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4666 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4667 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4668 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4669 };
4670 unsigned int old_ctl, new_ctl;
4671
4672 old_ctl = snd_hda_codec_read(codec, nid, 0,
4673 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4674 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4675 if (old_ctl != new_ctl) {
82beb8fd
TI
4676 int val;
4677 snd_hda_codec_write_cache(codec, nid, 0,
4678 AC_VERB_SET_PIN_WIDGET_CONTROL,
4679 new_ctl);
47fd830a
TI
4680 val = ucontrol->value.enumerated.item[0] >= 3 ?
4681 HDA_AMP_MUTE : 0;
4682 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4683 HDA_AMP_MUTE, val);
2fa522be
TI
4684 return 1;
4685 }
4686 return 0;
4687}
4688
9c7f852e
TI
4689static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4690 struct snd_ctl_elem_info *uinfo)
2fa522be 4691{
4c6d72d1 4692 static const char * const texts[] = {
2fa522be
TI
4693 "Front", "Surround", "CLFE", "Side"
4694 };
4695 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4696 uinfo->count = 1;
4697 uinfo->value.enumerated.items = 4;
4698 if (uinfo->value.enumerated.item >= 4)
4699 uinfo->value.enumerated.item = 3;
4700 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4701 return 0;
4702}
4703
9c7f852e
TI
4704static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4705 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4706{
4707 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4708 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4709 unsigned int sel;
4710
4711 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4712 ucontrol->value.enumerated.item[0] = sel & 3;
4713 return 0;
4714}
4715
9c7f852e
TI
4716static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4717 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4718{
4719 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4720 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4721 unsigned int sel;
4722
4723 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4724 if (ucontrol->value.enumerated.item[0] != sel) {
4725 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4726 snd_hda_codec_write_cache(codec, nid, 0,
4727 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4728 return 1;
4729 }
4730 return 0;
4731}
4732
4733#define PIN_CTL_TEST(xname,nid) { \
4734 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4735 .name = xname, \
5b0cb1d8 4736 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4737 .info = alc_test_pin_ctl_info, \
4738 .get = alc_test_pin_ctl_get, \
4739 .put = alc_test_pin_ctl_put, \
4740 .private_value = nid \
4741 }
4742
4743#define PIN_SRC_TEST(xname,nid) { \
4744 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4745 .name = xname, \
5b0cb1d8 4746 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4747 .info = alc_test_pin_src_info, \
4748 .get = alc_test_pin_src_get, \
4749 .put = alc_test_pin_src_put, \
4750 .private_value = nid \
4751 }
4752
a9111321 4753static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4754 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4755 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4756 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4757 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4758 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4759 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4760 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4761 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4762 PIN_CTL_TEST("Front Pin Mode", 0x14),
4763 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4764 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4765 PIN_CTL_TEST("Side Pin Mode", 0x17),
4766 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4767 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4768 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4769 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4770 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4771 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4772 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4773 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4774 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4775 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4776 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4777 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4778 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4779 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4780 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4781 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4782 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4783 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4784 {
4785 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4786 .name = "Channel Mode",
df694daa
KY
4787 .info = alc_ch_mode_info,
4788 .get = alc_ch_mode_get,
4789 .put = alc_ch_mode_put,
2fa522be
TI
4790 },
4791 { } /* end */
4792};
4793
a9111321 4794static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4795 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4796 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4797 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4798 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4799 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4800 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4801 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4802 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4803 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4804 /* Vol output for 0x0c-0x0f */
05acb863
TI
4805 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4806 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4807 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4809 /* Set output pins 0x14-0x17 */
05acb863
TI
4810 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4811 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4813 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4814 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4815 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4816 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4817 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4818 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4819 /* Set input pins 0x18-0x1c */
16ded525
TI
4820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4821 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4822 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4824 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4825 /* Mute input pins 0x18-0x1b */
05acb863
TI
4826 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4827 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4828 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4829 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4830 /* ADC set up */
05acb863 4831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4832 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4835 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4836 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4837 /* Analog input/passthru */
4838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4840 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4841 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4842 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4843 { }
4844};
4845#endif
4846
1da177e4
LT
4847/*
4848 */
4849
ea734963 4850static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4851 [ALC880_3ST] = "3stack",
4852 [ALC880_TCL_S700] = "tcl",
4853 [ALC880_3ST_DIG] = "3stack-digout",
4854 [ALC880_CLEVO] = "clevo",
4855 [ALC880_5ST] = "5stack",
4856 [ALC880_5ST_DIG] = "5stack-digout",
4857 [ALC880_W810] = "w810",
4858 [ALC880_Z71V] = "z71v",
4859 [ALC880_6ST] = "6stack",
4860 [ALC880_6ST_DIG] = "6stack-digout",
4861 [ALC880_ASUS] = "asus",
4862 [ALC880_ASUS_W1V] = "asus-w1v",
4863 [ALC880_ASUS_DIG] = "asus-dig",
4864 [ALC880_ASUS_DIG2] = "asus-dig2",
4865 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4866 [ALC880_UNIWILL_P53] = "uniwill-p53",
4867 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4868 [ALC880_F1734] = "F1734",
4869 [ALC880_LG] = "lg",
4870 [ALC880_LG_LW] = "lg-lw",
df99cd33 4871 [ALC880_MEDION_RIM] = "medion",
2fa522be 4872#ifdef CONFIG_SND_DEBUG
f5fcc13c 4873 [ALC880_TEST] = "test",
2fa522be 4874#endif
f5fcc13c
TI
4875 [ALC880_AUTO] = "auto",
4876};
4877
a9111321 4878static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4879 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4880 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4881 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4882 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4883 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4884 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4885 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4886 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4887 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c 4888 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
f5fcc13c
TI
4889 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4890 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4893 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4894 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4895 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4896 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4897 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4899 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4900 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4901 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4902 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4903 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4904 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4905 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4906 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4907 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4908 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4909 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4910 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4911 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4912 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4913 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4914 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4915 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4916 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4917 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4918 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4919 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4920 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4921 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4922 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4923 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4924 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4925 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4926 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4927 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4928 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4929 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4930 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4931 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4932 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4933 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4934 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4935 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4936 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4938 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4939 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4940 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4941 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4942 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4943 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4944 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4945 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4946 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4947 /* default Intel */
4948 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4949 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4950 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4951 {}
4952};
4953
16ded525 4954/*
df694daa 4955 * ALC880 codec presets
16ded525 4956 */
a9111321 4957static const struct alc_config_preset alc880_presets[] = {
16ded525 4958 [ALC880_3ST] = {
e9edcee0 4959 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4960 .init_verbs = { alc880_volume_init_verbs,
4961 alc880_pin_3stack_init_verbs },
16ded525 4962 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4963 .dac_nids = alc880_dac_nids,
16ded525
TI
4964 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4965 .channel_mode = alc880_threestack_modes,
4e195a7b 4966 .need_dac_fix = 1,
16ded525
TI
4967 .input_mux = &alc880_capture_source,
4968 },
4969 [ALC880_3ST_DIG] = {
e9edcee0 4970 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4971 .init_verbs = { alc880_volume_init_verbs,
4972 alc880_pin_3stack_init_verbs },
16ded525 4973 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4974 .dac_nids = alc880_dac_nids,
4975 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4976 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4977 .channel_mode = alc880_threestack_modes,
4e195a7b 4978 .need_dac_fix = 1,
16ded525
TI
4979 .input_mux = &alc880_capture_source,
4980 },
df694daa
KY
4981 [ALC880_TCL_S700] = {
4982 .mixers = { alc880_tcl_s700_mixer },
4983 .init_verbs = { alc880_volume_init_verbs,
4984 alc880_pin_tcl_S700_init_verbs,
4985 alc880_gpio2_init_verbs },
4986 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4987 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4988 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4989 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4990 .hp_nid = 0x03,
4991 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4992 .channel_mode = alc880_2_jack_modes,
4993 .input_mux = &alc880_capture_source,
4994 },
16ded525 4995 [ALC880_5ST] = {
f12ab1e0
TI
4996 .mixers = { alc880_three_stack_mixer,
4997 alc880_five_stack_mixer},
4998 .init_verbs = { alc880_volume_init_verbs,
4999 alc880_pin_5stack_init_verbs },
16ded525
TI
5000 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5001 .dac_nids = alc880_dac_nids,
16ded525
TI
5002 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5003 .channel_mode = alc880_fivestack_modes,
5004 .input_mux = &alc880_capture_source,
5005 },
5006 [ALC880_5ST_DIG] = {
f12ab1e0
TI
5007 .mixers = { alc880_three_stack_mixer,
5008 alc880_five_stack_mixer },
5009 .init_verbs = { alc880_volume_init_verbs,
5010 alc880_pin_5stack_init_verbs },
16ded525
TI
5011 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5012 .dac_nids = alc880_dac_nids,
5013 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5014 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5015 .channel_mode = alc880_fivestack_modes,
5016 .input_mux = &alc880_capture_source,
5017 },
b6482d48
TI
5018 [ALC880_6ST] = {
5019 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5020 .init_verbs = { alc880_volume_init_verbs,
5021 alc880_pin_6stack_init_verbs },
b6482d48
TI
5022 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5023 .dac_nids = alc880_6st_dac_nids,
5024 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5025 .channel_mode = alc880_sixstack_modes,
5026 .input_mux = &alc880_6stack_capture_source,
5027 },
16ded525 5028 [ALC880_6ST_DIG] = {
e9edcee0 5029 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
5030 .init_verbs = { alc880_volume_init_verbs,
5031 alc880_pin_6stack_init_verbs },
16ded525
TI
5032 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5033 .dac_nids = alc880_6st_dac_nids,
5034 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5035 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5036 .channel_mode = alc880_sixstack_modes,
5037 .input_mux = &alc880_6stack_capture_source,
5038 },
5039 [ALC880_W810] = {
e9edcee0 5040 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_w810_init_verbs,
b0af0de5 5043 alc880_gpio2_init_verbs },
16ded525
TI
5044 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5045 .dac_nids = alc880_w810_dac_nids,
5046 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5047 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5048 .channel_mode = alc880_w810_modes,
5049 .input_mux = &alc880_capture_source,
5050 },
5051 [ALC880_Z71V] = {
e9edcee0 5052 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5053 .init_verbs = { alc880_volume_init_verbs,
5054 alc880_pin_z71v_init_verbs },
16ded525
TI
5055 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5056 .dac_nids = alc880_z71v_dac_nids,
5057 .dig_out_nid = ALC880_DIGOUT_NID,
5058 .hp_nid = 0x03,
e9edcee0
TI
5059 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5060 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5061 .input_mux = &alc880_capture_source,
5062 },
5063 [ALC880_F1734] = {
e9edcee0 5064 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5065 .init_verbs = { alc880_volume_init_verbs,
5066 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5067 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5068 .dac_nids = alc880_f1734_dac_nids,
5069 .hp_nid = 0x02,
5070 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5071 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5072 .input_mux = &alc880_f1734_capture_source,
5073 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5074 .setup = alc880_uniwill_p53_setup,
d922b51d 5075 .init_hook = alc_hp_automute,
16ded525
TI
5076 },
5077 [ALC880_ASUS] = {
e9edcee0 5078 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_asus_init_verbs,
e9edcee0
TI
5081 alc880_gpio1_init_verbs },
5082 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5083 .dac_nids = alc880_asus_dac_nids,
5084 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5085 .channel_mode = alc880_asus_modes,
4e195a7b 5086 .need_dac_fix = 1,
16ded525
TI
5087 .input_mux = &alc880_capture_source,
5088 },
5089 [ALC880_ASUS_DIG] = {
e9edcee0 5090 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5091 .init_verbs = { alc880_volume_init_verbs,
5092 alc880_pin_asus_init_verbs,
e9edcee0
TI
5093 alc880_gpio1_init_verbs },
5094 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5095 .dac_nids = alc880_asus_dac_nids,
16ded525 5096 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5097 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5098 .channel_mode = alc880_asus_modes,
4e195a7b 5099 .need_dac_fix = 1,
16ded525
TI
5100 .input_mux = &alc880_capture_source,
5101 },
df694daa
KY
5102 [ALC880_ASUS_DIG2] = {
5103 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5104 .init_verbs = { alc880_volume_init_verbs,
5105 alc880_pin_asus_init_verbs,
df694daa
KY
5106 alc880_gpio2_init_verbs }, /* use GPIO2 */
5107 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5108 .dac_nids = alc880_asus_dac_nids,
5109 .dig_out_nid = ALC880_DIGOUT_NID,
5110 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5111 .channel_mode = alc880_asus_modes,
4e195a7b 5112 .need_dac_fix = 1,
df694daa
KY
5113 .input_mux = &alc880_capture_source,
5114 },
16ded525 5115 [ALC880_ASUS_W1V] = {
e9edcee0 5116 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5117 .init_verbs = { alc880_volume_init_verbs,
5118 alc880_pin_asus_init_verbs,
e9edcee0
TI
5119 alc880_gpio1_init_verbs },
5120 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5121 .dac_nids = alc880_asus_dac_nids,
16ded525 5122 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5123 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5124 .channel_mode = alc880_asus_modes,
4e195a7b 5125 .need_dac_fix = 1,
16ded525
TI
5126 .input_mux = &alc880_capture_source,
5127 },
5128 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5129 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5130 .init_verbs = { alc880_volume_init_verbs,
5131 alc880_pin_asus_init_verbs },
e9edcee0
TI
5132 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5133 .dac_nids = alc880_asus_dac_nids,
16ded525 5134 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5135 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5136 .channel_mode = alc880_asus_modes,
4e195a7b 5137 .need_dac_fix = 1,
16ded525
TI
5138 .input_mux = &alc880_capture_source,
5139 },
ccc656ce
KY
5140 [ALC880_UNIWILL] = {
5141 .mixers = { alc880_uniwill_mixer },
5142 .init_verbs = { alc880_volume_init_verbs,
5143 alc880_uniwill_init_verbs },
5144 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5145 .dac_nids = alc880_asus_dac_nids,
5146 .dig_out_nid = ALC880_DIGOUT_NID,
5147 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5148 .channel_mode = alc880_threestack_modes,
5149 .need_dac_fix = 1,
5150 .input_mux = &alc880_capture_source,
5151 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5152 .setup = alc880_uniwill_setup,
a9fd4f3f 5153 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5154 },
5155 [ALC880_UNIWILL_P53] = {
5156 .mixers = { alc880_uniwill_p53_mixer },
5157 .init_verbs = { alc880_volume_init_verbs,
5158 alc880_uniwill_p53_init_verbs },
5159 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5160 .dac_nids = alc880_asus_dac_nids,
5161 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5162 .channel_mode = alc880_threestack_modes,
5163 .input_mux = &alc880_capture_source,
5164 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5165 .setup = alc880_uniwill_p53_setup,
d922b51d 5166 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5167 },
5168 [ALC880_FUJITSU] = {
45bdd1c1 5169 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5170 .init_verbs = { alc880_volume_init_verbs,
5171 alc880_uniwill_p53_init_verbs,
5172 alc880_beep_init_verbs },
5173 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5174 .dac_nids = alc880_dac_nids,
d53d7d9e 5175 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5176 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5177 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5178 .input_mux = &alc880_capture_source,
5179 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5180 .setup = alc880_uniwill_p53_setup,
d922b51d 5181 .init_hook = alc_hp_automute,
ccc656ce 5182 },
df694daa
KY
5183 [ALC880_CLEVO] = {
5184 .mixers = { alc880_three_stack_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_clevo_init_verbs },
5187 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5188 .dac_nids = alc880_dac_nids,
5189 .hp_nid = 0x03,
5190 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5191 .channel_mode = alc880_threestack_modes,
4e195a7b 5192 .need_dac_fix = 1,
df694daa
KY
5193 .input_mux = &alc880_capture_source,
5194 },
ae6b813a
TI
5195 [ALC880_LG] = {
5196 .mixers = { alc880_lg_mixer },
5197 .init_verbs = { alc880_volume_init_verbs,
5198 alc880_lg_init_verbs },
5199 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5200 .dac_nids = alc880_lg_dac_nids,
5201 .dig_out_nid = ALC880_DIGOUT_NID,
5202 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5203 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5204 .need_dac_fix = 1,
ae6b813a 5205 .input_mux = &alc880_lg_capture_source,
d922b51d 5206 .unsol_event = alc_sku_unsol_event,
4f5d1706 5207 .setup = alc880_lg_setup,
d922b51d 5208 .init_hook = alc_hp_automute,
cb53c626
TI
5209#ifdef CONFIG_SND_HDA_POWER_SAVE
5210 .loopbacks = alc880_lg_loopbacks,
5211#endif
ae6b813a 5212 },
d681518a
TI
5213 [ALC880_LG_LW] = {
5214 .mixers = { alc880_lg_lw_mixer },
5215 .init_verbs = { alc880_volume_init_verbs,
5216 alc880_lg_lw_init_verbs },
0a8c5da3 5217 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5218 .dac_nids = alc880_dac_nids,
5219 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5220 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5221 .channel_mode = alc880_lg_lw_modes,
d681518a 5222 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5223 .unsol_event = alc_sku_unsol_event,
4f5d1706 5224 .setup = alc880_lg_lw_setup,
d922b51d 5225 .init_hook = alc_hp_automute,
d681518a 5226 },
df99cd33
TI
5227 [ALC880_MEDION_RIM] = {
5228 .mixers = { alc880_medion_rim_mixer },
5229 .init_verbs = { alc880_volume_init_verbs,
5230 alc880_medion_rim_init_verbs,
5231 alc_gpio2_init_verbs },
5232 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5233 .dac_nids = alc880_dac_nids,
5234 .dig_out_nid = ALC880_DIGOUT_NID,
5235 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5236 .channel_mode = alc880_2_jack_modes,
5237 .input_mux = &alc880_medion_rim_capture_source,
5238 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5239 .setup = alc880_medion_rim_setup,
5240 .init_hook = alc880_medion_rim_automute,
df99cd33 5241 },
16ded525
TI
5242#ifdef CONFIG_SND_DEBUG
5243 [ALC880_TEST] = {
e9edcee0
TI
5244 .mixers = { alc880_test_mixer },
5245 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5246 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5247 .dac_nids = alc880_test_dac_nids,
5248 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5249 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5250 .channel_mode = alc880_test_modes,
5251 .input_mux = &alc880_test_capture_source,
5252 },
5253#endif
5254};
5255
e9edcee0
TI
5256/*
5257 * Automatic parse of I/O pins from the BIOS configuration
5258 */
5259
e9edcee0
TI
5260enum {
5261 ALC_CTL_WIDGET_VOL,
5262 ALC_CTL_WIDGET_MUTE,
5263 ALC_CTL_BIND_MUTE,
5264};
a9111321 5265static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5266 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5267 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5268 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5269};
5270
ce764ab2
TI
5271static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5272{
5273 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5274 return snd_array_new(&spec->kctls);
5275}
5276
e9edcee0 5277/* add dynamic controls */
f12ab1e0 5278static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5279 int cidx, unsigned long val)
e9edcee0 5280{
c8b6bf9b 5281 struct snd_kcontrol_new *knew;
e9edcee0 5282
ce764ab2 5283 knew = alc_kcontrol_new(spec);
603c4019
TI
5284 if (!knew)
5285 return -ENOMEM;
e9edcee0 5286 *knew = alc880_control_templates[type];
543537bd 5287 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5288 if (!knew->name)
e9edcee0 5289 return -ENOMEM;
66ceeb6b 5290 knew->index = cidx;
4d02d1b6 5291 if (get_amp_nid_(val))
5e26dfd0 5292 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5293 knew->private_value = val;
e9edcee0
TI
5294 return 0;
5295}
5296
0afe5f89
TI
5297static int add_control_with_pfx(struct alc_spec *spec, int type,
5298 const char *pfx, const char *dir,
66ceeb6b 5299 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5300{
5301 char name[32];
5302 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5303 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5304}
5305
66ceeb6b
TI
5306#define add_pb_vol_ctrl(spec, type, pfx, val) \
5307 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5308#define add_pb_sw_ctrl(spec, type, pfx, val) \
5309 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5310#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5311 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5312#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5313 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5314
e9edcee0
TI
5315#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5316#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5317#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5318#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5319#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5320#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5321#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5322#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5323#define ALC880_PIN_CD_NID 0x1c
5324
5325/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 5326static int alc880_auto_fill_dac_nids(struct hda_codec *codec)
e9edcee0 5327{
cb053a82
TI
5328 struct alc_spec *spec = codec->spec;
5329 const struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5330 hda_nid_t nid;
5331 int assigned[4];
5332 int i, j;
5333
5334 memset(assigned, 0, sizeof(assigned));
b0af0de5 5335 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5336
5337 /* check the pins hardwired to audio widget */
5338 for (i = 0; i < cfg->line_outs; i++) {
5339 nid = cfg->line_out_pins[i];
5340 if (alc880_is_fixed_pin(nid)) {
5341 int idx = alc880_fixed_pin_idx(nid);
dda14410 5342 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5343 assigned[idx] = 1;
5344 }
5345 }
5346 /* left pins can be connect to any audio widget */
5347 for (i = 0; i < cfg->line_outs; i++) {
5348 nid = cfg->line_out_pins[i];
5349 if (alc880_is_fixed_pin(nid))
5350 continue;
5351 /* search for an empty channel */
5352 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5353 if (!assigned[j]) {
dda14410 5354 spec->private_dac_nids[i] =
f12ab1e0 5355 alc880_idx_to_dac(j);
e9edcee0
TI
5356 assigned[j] = 1;
5357 break;
5358 }
5359 }
5360 }
5361 spec->multiout.num_dacs = cfg->line_outs;
5362 return 0;
5363}
5364
6843ca16
TI
5365static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5366 bool can_be_master, int *index)
bcb2f0f5 5367{
ce764ab2 5368 struct auto_pin_cfg *cfg = &spec->autocfg;
6843ca16
TI
5369 static const char * const chname[4] = {
5370 "Front", "Surround", NULL /*CLFE*/, "Side"
5371 };
ce764ab2 5372
6843ca16 5373 *index = 0;
ce764ab2
TI
5374 if (cfg->line_outs == 1 && !spec->multi_ios &&
5375 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5376 return "Master";
5377
5378 switch (cfg->line_out_type) {
5379 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5380 if (cfg->line_outs == 1)
5381 return "Speaker";
5382 break;
bcb2f0f5 5383 case AUTO_PIN_HP_OUT:
6843ca16
TI
5384 /* for multi-io case, only the primary out */
5385 if (ch && spec->multi_ios)
5386 break;
5387 *index = ch;
bcb2f0f5
TI
5388 return "Headphone";
5389 default:
ce764ab2 5390 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5391 return "PCM";
5392 break;
5393 }
6843ca16 5394 return chname[ch];
bcb2f0f5
TI
5395}
5396
e9edcee0 5397/* add playback controls from the parsed DAC table */
df694daa
KY
5398static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5399 const struct auto_pin_cfg *cfg)
e9edcee0 5400{
e9edcee0 5401 hda_nid_t nid;
ce764ab2 5402 int i, err, noutputs;
e9edcee0 5403
ce764ab2
TI
5404 noutputs = cfg->line_outs;
5405 if (spec->multi_ios > 0)
5406 noutputs += spec->multi_ios;
5407
5408 for (i = 0; i < noutputs; i++) {
6843ca16
TI
5409 const char *name;
5410 int index;
f12ab1e0 5411 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5412 continue;
5413 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
6843ca16
TI
5414 name = alc_get_line_out_pfx(spec, i, false, &index);
5415 if (!name) {
e9edcee0 5416 /* Center/LFE */
0afe5f89
TI
5417 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5418 "Center",
f12ab1e0
TI
5419 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5420 HDA_OUTPUT));
5421 if (err < 0)
e9edcee0 5422 return err;
0afe5f89
TI
5423 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5424 "LFE",
f12ab1e0
TI
5425 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5426 HDA_OUTPUT));
5427 if (err < 0)
e9edcee0 5428 return err;
0afe5f89
TI
5429 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5430 "Center",
f12ab1e0
TI
5431 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5432 HDA_INPUT));
5433 if (err < 0)
e9edcee0 5434 return err;
0afe5f89
TI
5435 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5436 "LFE",
f12ab1e0
TI
5437 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5438 HDA_INPUT));
5439 if (err < 0)
e9edcee0
TI
5440 return err;
5441 } else {
bcb2f0f5 5442 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5443 name, index,
f12ab1e0
TI
5444 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5445 HDA_OUTPUT));
5446 if (err < 0)
e9edcee0 5447 return err;
bcb2f0f5 5448 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5449 name, index,
f12ab1e0
TI
5450 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5451 HDA_INPUT));
5452 if (err < 0)
e9edcee0
TI
5453 return err;
5454 }
5455 }
e9edcee0
TI
5456 return 0;
5457}
5458
8d88bc3d
TI
5459/* add playback controls for speaker and HP outputs */
5460static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5461 const char *pfx)
e9edcee0
TI
5462{
5463 hda_nid_t nid;
5464 int err;
5465
f12ab1e0 5466 if (!pin)
e9edcee0
TI
5467 return 0;
5468
5469 if (alc880_is_fixed_pin(pin)) {
5470 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5471 /* specify the DAC as the extra output */
f12ab1e0 5472 if (!spec->multiout.hp_nid)
e9edcee0 5473 spec->multiout.hp_nid = nid;
82bc955f
TI
5474 else
5475 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5476 /* control HP volume/switch on the output mixer amp */
5477 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5478 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5479 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5480 if (err < 0)
e9edcee0 5481 return err;
0afe5f89 5482 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5483 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5484 if (err < 0)
e9edcee0
TI
5485 return err;
5486 } else if (alc880_is_multi_pin(pin)) {
5487 /* set manual connection */
e9edcee0 5488 /* we have only a switch on HP-out PIN */
0afe5f89 5489 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5490 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5491 if (err < 0)
e9edcee0
TI
5492 return err;
5493 }
5494 return 0;
5495}
5496
5497/* create input playback/capture controls for the given pin */
f12ab1e0 5498static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5499 const char *ctlname, int ctlidx,
df694daa 5500 int idx, hda_nid_t mix_nid)
e9edcee0 5501{
df694daa 5502 int err;
e9edcee0 5503
66ceeb6b 5504 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5505 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5506 if (err < 0)
e9edcee0 5507 return err;
66ceeb6b 5508 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5509 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5510 if (err < 0)
e9edcee0
TI
5511 return err;
5512 return 0;
5513}
5514
05f5f477
TI
5515static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5516{
5517 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5518 return (pincap & AC_PINCAP_IN) != 0;
5519}
5520
e9edcee0 5521/* create playback/capture controls for input pins */
05f5f477
TI
5522static int alc_auto_create_input_ctls(struct hda_codec *codec,
5523 const struct auto_pin_cfg *cfg,
5524 hda_nid_t mixer,
5525 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5526{
05f5f477 5527 struct alc_spec *spec = codec->spec;
61b9b9b1 5528 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5529 int i, err, idx, type_idx = 0;
5530 const char *prev_label = NULL;
e9edcee0 5531
66ceeb6b 5532 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5533 hda_nid_t pin;
10a20af7 5534 const char *label;
05f5f477 5535
66ceeb6b 5536 pin = cfg->inputs[i].pin;
05f5f477
TI
5537 if (!alc_is_input_pin(codec, pin))
5538 continue;
5539
5322bf27
DH
5540 label = hda_get_autocfg_input_label(codec, cfg, i);
5541 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5542 type_idx++;
5543 else
5544 type_idx = 0;
5322bf27
DH
5545 prev_label = label;
5546
05f5f477
TI
5547 if (mixer) {
5548 idx = get_connection_index(codec, mixer, pin);
5549 if (idx >= 0) {
5550 err = new_analog_input(spec, pin,
10a20af7
TI
5551 label, type_idx,
5552 idx, mixer);
05f5f477
TI
5553 if (err < 0)
5554 return err;
5555 }
5556 }
5557
5558 if (!cap1)
5559 continue;
5560 idx = get_connection_index(codec, cap1, pin);
5561 if (idx < 0 && cap2)
5562 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5563 if (idx >= 0)
5564 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5565 }
5566 return 0;
5567}
5568
05f5f477
TI
5569static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5570 const struct auto_pin_cfg *cfg)
5571{
5572 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5573}
5574
f6c7e546
TI
5575static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5576 unsigned int pin_type)
5577{
5578 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5579 pin_type);
5580 /* unmute pin */
d260cdf6
TI
5581 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5582 AMP_OUT_UNMUTE);
f6c7e546
TI
5583}
5584
df694daa
KY
5585static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5586 hda_nid_t nid, int pin_type,
e9edcee0
TI
5587 int dac_idx)
5588{
f6c7e546 5589 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5590 /* need the manual connection? */
5591 if (alc880_is_multi_pin(nid)) {
5592 struct alc_spec *spec = codec->spec;
5593 int idx = alc880_multi_pin_idx(nid);
5594 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5595 AC_VERB_SET_CONNECT_SEL,
5596 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5597 }
5598}
5599
baba8ee9
TI
5600static int get_pin_type(int line_out_type)
5601{
5602 if (line_out_type == AUTO_PIN_HP_OUT)
5603 return PIN_HP;
5604 else
5605 return PIN_OUT;
5606}
5607
050ea753 5608static void alc880_auto_init_dac(struct hda_codec *codec, hda_nid_t dac)
1f0f4b80 5609{
050ea753
TI
5610 hda_nid_t nid, mix;
5611
5612 if (!dac)
1f0f4b80 5613 return;
050ea753
TI
5614 mix = alc880_idx_to_mixer(alc880_dac_to_idx(dac));
5615 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5616 nid = dac;
5617 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
5618 nid = mix;
5619 else
5620 nid = 0;
5621 if (nid)
5622 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5623 AMP_OUT_ZERO);
5624 if (query_amp_caps(codec, mix, HDA_INPUT) & AC_AMPCAP_MUTE) {
5625 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5626 AMP_IN_UNMUTE(0));
5627 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5628 AMP_IN_UNMUTE(1));
5629 }
1f0f4b80
TI
5630}
5631
e9edcee0
TI
5632static void alc880_auto_init_multi_out(struct hda_codec *codec)
5633{
5634 struct alc_spec *spec = codec->spec;
5635 int i;
ea1fb29a 5636
e9edcee0
TI
5637 for (i = 0; i < spec->autocfg.line_outs; i++) {
5638 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5639 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5640 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0 5641 }
1f0f4b80
TI
5642 /* mute DACs */
5643 for (i = 0; i < spec->multiout.num_dacs; i++)
5644 alc880_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9edcee0
TI
5645}
5646
8d88bc3d 5647static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5648{
5649 struct alc_spec *spec = codec->spec;
5650 hda_nid_t pin;
1f0f4b80 5651 int i;
e9edcee0 5652
82bc955f 5653 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5654 if (pin) /* connect to front */
5655 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5656 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5657 if (pin) /* connect to front */
5658 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
1f0f4b80
TI
5659 /* mute DACs */
5660 alc880_auto_init_dac(codec, spec->multiout.hp_nid);
5661 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
5662 alc880_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9edcee0
TI
5663}
5664
5665static void alc880_auto_init_analog_input(struct hda_codec *codec)
5666{
5667 struct alc_spec *spec = codec->spec;
66ceeb6b 5668 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5669 int i;
5670
66ceeb6b
TI
5671 for (i = 0; i < cfg->num_inputs; i++) {
5672 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5673 if (alc_is_input_pin(codec, nid)) {
30ea098f 5674 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
1f0f4b80 5675 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
f12ab1e0
TI
5676 snd_hda_codec_write(codec, nid, 0,
5677 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5678 AMP_OUT_MUTE);
5679 }
5680 }
1f0f4b80
TI
5681
5682 /* mute all loopback inputs */
5683 if (spec->mixer_nid) {
5684 int nums = snd_hda_get_conn_list(codec, spec->mixer_nid, NULL);
5685 for (i = 0; i < nums; i++)
5686 snd_hda_codec_write(codec, spec->mixer_nid, 0,
5687 AC_VERB_SET_AMP_GAIN_MUTE,
5688 AMP_IN_MUTE(i));
5689 }
e9edcee0
TI
5690}
5691
7f311a46
TI
5692static void alc880_auto_init_input_src(struct hda_codec *codec)
5693{
5694 struct alc_spec *spec = codec->spec;
5695 int c;
5696
5697 for (c = 0; c < spec->num_adc_nids; c++) {
5698 unsigned int mux_idx;
5699 const struct hda_input_mux *imux;
5700 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5701 imux = &spec->input_mux[mux_idx];
5702 if (!imux->num_items && mux_idx > 0)
5703 imux = &spec->input_mux[0];
5704 if (imux)
5705 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5706 AC_VERB_SET_CONNECT_SEL,
5707 imux->items[0].index);
1f0f4b80
TI
5708 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5709 AC_VERB_SET_AMP_GAIN_MUTE,
5710 AMP_IN_MUTE(0));
7f311a46
TI
5711 }
5712}
5713
cb053a82
TI
5714static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
5715 int (*fill_dac)(struct hda_codec *));
ce764ab2 5716
e9edcee0 5717/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5718/* return 1 if successful, 0 if the proper config is not found,
5719 * or a negative error code
5720 */
e9edcee0
TI
5721static int alc880_parse_auto_config(struct hda_codec *codec)
5722{
5723 struct alc_spec *spec = codec->spec;
757899ac 5724 int err;
4c6d72d1 5725 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5726
f12ab1e0
TI
5727 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5728 alc880_ignore);
5729 if (err < 0)
e9edcee0 5730 return err;
f12ab1e0 5731 if (!spec->autocfg.line_outs)
e9edcee0 5732 return 0; /* can't find valid BIOS pin config */
df694daa 5733
cb053a82 5734 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
5735 if (err < 0)
5736 return err;
cb053a82 5737 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
f12ab1e0
TI
5738 if (err < 0)
5739 return err;
5740 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5741 if (err < 0)
5742 return err;
5743 err = alc880_auto_create_extra_out(spec,
5744 spec->autocfg.speaker_pins[0],
5745 "Speaker");
5746 if (err < 0)
5747 return err;
5748 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5749 "Headphone");
5750 if (err < 0)
5751 return err;
05f5f477 5752 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5753 if (err < 0)
e9edcee0
TI
5754 return err;
5755
5756 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5757
757899ac 5758 alc_auto_parse_digital(codec);
e9edcee0 5759
603c4019 5760 if (spec->kctls.list)
d88897ea 5761 add_mixer(spec, spec->kctls.list);
e9edcee0 5762
a1e8d2da 5763 spec->num_mux_defs = 1;
61b9b9b1 5764 spec->input_mux = &spec->private_imux[0];
e9edcee0 5765
6227cdce 5766 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5767
e9edcee0
TI
5768 return 1;
5769}
5770
ae6b813a
TI
5771/* additional initialization for auto-configuration model */
5772static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5773{
f6c7e546 5774 struct alc_spec *spec = codec->spec;
e9edcee0 5775 alc880_auto_init_multi_out(codec);
8d88bc3d 5776 alc880_auto_init_extra_out(codec);
e9edcee0 5777 alc880_auto_init_analog_input(codec);
7f311a46 5778 alc880_auto_init_input_src(codec);
757899ac 5779 alc_auto_init_digital(codec);
f6c7e546 5780 if (spec->unsol_event)
7fb0d78f 5781 alc_inithook(codec);
e9edcee0
TI
5782}
5783
b59bdf3b
TI
5784/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5785 * one of two digital mic pins, e.g. on ALC272
5786 */
5787static void fixup_automic_adc(struct hda_codec *codec)
5788{
5789 struct alc_spec *spec = codec->spec;
5790 int i;
5791
5792 for (i = 0; i < spec->num_adc_nids; i++) {
5793 hda_nid_t cap = spec->capsrc_nids ?
5794 spec->capsrc_nids[i] : spec->adc_nids[i];
5795 int iidx, eidx;
5796
5797 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5798 if (iidx < 0)
5799 continue;
5800 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5801 if (eidx < 0)
5802 continue;
5803 spec->int_mic.mux_idx = iidx;
5804 spec->ext_mic.mux_idx = eidx;
5805 if (spec->capsrc_nids)
5806 spec->capsrc_nids += i;
5807 spec->adc_nids += i;
5808 spec->num_adc_nids = 1;
8ed99d97
TI
5809 /* optional dock-mic */
5810 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5811 if (eidx < 0)
5812 spec->dock_mic.pin = 0;
5813 else
5814 spec->dock_mic.mux_idx = eidx;
b59bdf3b
TI
5815 return;
5816 }
5817 snd_printd(KERN_INFO "hda_codec: %s: "
5818 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5819 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5820 spec->auto_mic = 0; /* disable auto-mic to be sure */
5821}
5822
748cce43
TI
5823/* select or unmute the given capsrc route */
5824static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5825 int idx)
5826{
5827 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5828 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5829 HDA_AMP_MUTE, 0);
5830 } else {
5831 snd_hda_codec_write_cache(codec, cap, 0,
5832 AC_VERB_SET_CONNECT_SEL, idx);
5833 }
5834}
5835
840b64c0
TI
5836/* set the default connection to that pin */
5837static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5838{
5839 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5840 int i;
5841
8ed99d97
TI
5842 if (!pin)
5843 return 0;
eaa9b3a7
TI
5844 for (i = 0; i < spec->num_adc_nids; i++) {
5845 hda_nid_t cap = spec->capsrc_nids ?
5846 spec->capsrc_nids[i] : spec->adc_nids[i];
5847 int idx;
5848
5849 idx = get_connection_index(codec, cap, pin);
5850 if (idx < 0)
5851 continue;
748cce43 5852 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5853 return i; /* return the found index */
5854 }
5855 return -1; /* not found */
5856}
5857
5858/* choose the ADC/MUX containing the input pin and initialize the setup */
5859static void fixup_single_adc(struct hda_codec *codec)
5860{
5861 struct alc_spec *spec = codec->spec;
66ceeb6b 5862 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5863 int i;
5864
5865 /* search for the input pin; there must be only one */
66ceeb6b 5866 if (cfg->num_inputs != 1)
eaa9b3a7 5867 return;
66ceeb6b 5868 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5869 if (i >= 0) {
5870 /* use only this ADC */
5871 if (spec->capsrc_nids)
5872 spec->capsrc_nids += i;
5873 spec->adc_nids += i;
5874 spec->num_adc_nids = 1;
584c0c4c 5875 spec->single_input_src = 1;
eaa9b3a7
TI
5876 }
5877}
5878
840b64c0
TI
5879/* initialize dual adcs */
5880static void fixup_dual_adc_switch(struct hda_codec *codec)
5881{
5882 struct alc_spec *spec = codec->spec;
5883 init_capsrc_for_pin(codec, spec->ext_mic.pin);
8ed99d97 5884 init_capsrc_for_pin(codec, spec->dock_mic.pin);
840b64c0
TI
5885 init_capsrc_for_pin(codec, spec->int_mic.pin);
5886}
5887
584c0c4c
TI
5888/* initialize some special cases for input sources */
5889static void alc_init_special_input_src(struct hda_codec *codec)
5890{
5891 struct alc_spec *spec = codec->spec;
5892 if (spec->dual_adc_switch)
5893 fixup_dual_adc_switch(codec);
5894 else if (spec->single_input_src)
5895 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5896}
5897
b59bdf3b 5898static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5899{
b59bdf3b 5900 struct alc_spec *spec = codec->spec;
a9111321 5901 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5902 { alc_capture_mixer_nosrc1,
5903 alc_capture_mixer_nosrc2,
5904 alc_capture_mixer_nosrc3 },
5905 { alc_capture_mixer1,
5906 alc_capture_mixer2,
5907 alc_capture_mixer3 },
f9e336f6 5908 };
a23b688f 5909 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5910 int mux = 0;
840b64c0
TI
5911 int num_adcs = spec->num_adc_nids;
5912 if (spec->dual_adc_switch)
584c0c4c 5913 num_adcs = 1;
840b64c0 5914 else if (spec->auto_mic)
b59bdf3b 5915 fixup_automic_adc(codec);
eaa9b3a7
TI
5916 else if (spec->input_mux) {
5917 if (spec->input_mux->num_items > 1)
5918 mux = 1;
5919 else if (spec->input_mux->num_items == 1)
5920 fixup_single_adc(codec);
5921 }
840b64c0 5922 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5923 }
f9e336f6
TI
5924}
5925
6694635d 5926/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5927static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5928 int num_nids)
5929{
5930 struct alc_spec *spec = codec->spec;
66ceeb6b 5931 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5932 int n;
5933 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5934
5935 for (n = 0; n < num_nids; n++) {
5936 hda_nid_t adc, cap;
5937 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5938 int nconns, i, j;
5939
5940 adc = nids[n];
5941 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5942 continue;
5943 cap = adc;
5944 nconns = snd_hda_get_connections(codec, cap, conn,
5945 ARRAY_SIZE(conn));
5946 if (nconns == 1) {
5947 cap = conn[0];
5948 nconns = snd_hda_get_connections(codec, cap, conn,
5949 ARRAY_SIZE(conn));
5950 }
5951 if (nconns <= 0)
5952 continue;
5953 if (!fallback_adc) {
5954 fallback_adc = adc;
5955 fallback_cap = cap;
5956 }
66ceeb6b
TI
5957 for (i = 0; i < cfg->num_inputs; i++) {
5958 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5959 for (j = 0; j < nconns; j++) {
5960 if (conn[j] == nid)
5961 break;
5962 }
5963 if (j >= nconns)
5964 break;
5965 }
66ceeb6b 5966 if (i >= cfg->num_inputs) {
6694635d
TI
5967 int num_adcs = spec->num_adc_nids;
5968 spec->private_adc_nids[num_adcs] = adc;
5969 spec->private_capsrc_nids[num_adcs] = cap;
5970 spec->num_adc_nids++;
5971 spec->adc_nids = spec->private_adc_nids;
5972 if (adc != cap)
5973 spec->capsrc_nids = spec->private_capsrc_nids;
5974 }
5975 }
5976 if (!spec->num_adc_nids) {
5977 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5978 " using fallback 0x%x\n",
5979 codec->chip_name, fallback_adc);
6694635d
TI
5980 spec->private_adc_nids[0] = fallback_adc;
5981 spec->adc_nids = spec->private_adc_nids;
5982 if (fallback_adc != fallback_cap) {
5983 spec->private_capsrc_nids[0] = fallback_cap;
5984 spec->capsrc_nids = spec->private_adc_nids;
5985 }
5986 }
5987}
5988
67d634c0 5989#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5990#define set_beep_amp(spec, nid, idx, dir) \
5991 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5992
a9111321 5993static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5994 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5995 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5996 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
39dfe138 5997 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
e096c8e6 5998 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5999 {}
6000};
6001
6002static inline int has_cdefine_beep(struct hda_codec *codec)
6003{
6004 struct alc_spec *spec = codec->spec;
6005 const struct snd_pci_quirk *q;
6006 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
6007 if (q)
6008 return q->value;
6009 return spec->cdefine.enable_pcbeep;
6010}
67d634c0
TI
6011#else
6012#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 6013#define has_cdefine_beep(codec) 0
67d634c0 6014#endif
45bdd1c1
TI
6015
6016/*
6017 * OK, here we have finally the patch for ALC880
6018 */
6019
1da177e4
LT
6020static int patch_alc880(struct hda_codec *codec)
6021{
6022 struct alc_spec *spec;
6023 int board_config;
df694daa 6024 int err;
1da177e4 6025
e560d8d8 6026 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
6027 if (spec == NULL)
6028 return -ENOMEM;
6029
6030 codec->spec = spec;
6031
1f0f4b80
TI
6032 spec->mixer_nid = 0x0b;
6033
f5fcc13c
TI
6034 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
6035 alc880_models,
6036 alc880_cfg_tbl);
6037 if (board_config < 0) {
9a11f1aa
TI
6038 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6039 codec->chip_name);
e9edcee0 6040 board_config = ALC880_AUTO;
1da177e4 6041 }
1da177e4 6042
e9edcee0
TI
6043 if (board_config == ALC880_AUTO) {
6044 /* automatic parse from the BIOS config */
6045 err = alc880_parse_auto_config(codec);
6046 if (err < 0) {
6047 alc_free(codec);
6048 return err;
f12ab1e0 6049 } else if (!err) {
9c7f852e
TI
6050 printk(KERN_INFO
6051 "hda_codec: Cannot set up configuration "
6052 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
6053 board_config = ALC880_3ST;
6054 }
1da177e4
LT
6055 }
6056
680cd536
KK
6057 err = snd_hda_attach_beep_device(codec, 0x1);
6058 if (err < 0) {
6059 alc_free(codec);
6060 return err;
6061 }
6062
df694daa 6063 if (board_config != ALC880_AUTO)
e9c364c0 6064 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 6065
1da177e4
LT
6066 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6067 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 6068 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 6069
1da177e4
LT
6070 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6071 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6072
f12ab1e0 6073 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 6074 /* check whether NID 0x07 is valid */
54d17403 6075 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 6076 /* get type */
a22d543a 6077 wcap = get_wcaps_type(wcap);
e9edcee0
TI
6078 if (wcap != AC_WID_AUD_IN) {
6079 spec->adc_nids = alc880_adc_nids_alt;
6080 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
6081 } else {
6082 spec->adc_nids = alc880_adc_nids;
6083 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
6084 }
6085 }
b59bdf3b 6086 set_capture_mixer(codec);
45bdd1c1 6087 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 6088
2134ea4f
TI
6089 spec->vmaster_nid = 0x0c;
6090
1da177e4 6091 codec->patch_ops = alc_patch_ops;
e9edcee0 6092 if (board_config == ALC880_AUTO)
ae6b813a 6093 spec->init_hook = alc880_auto_init;
cb53c626
TI
6094#ifdef CONFIG_SND_HDA_POWER_SAVE
6095 if (!spec->loopback.amplist)
6096 spec->loopback.amplist = alc880_loopbacks;
6097#endif
1da177e4
LT
6098
6099 return 0;
6100}
6101
e9edcee0 6102
1da177e4
LT
6103/*
6104 * ALC260 support
6105 */
6106
4c6d72d1 6107static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6108 /* front */
6109 0x02,
6110};
6111
4c6d72d1 6112static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6113 /* ADC0 */
6114 0x04,
6115};
6116
4c6d72d1 6117static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6118 /* ADC1 */
6119 0x05,
6120};
6121
d57fdac0
JW
6122/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6123 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6124 */
4c6d72d1 6125static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6126 /* ADC0, ADC1 */
6127 0x04, 0x05
6128};
6129
e9edcee0
TI
6130#define ALC260_DIGOUT_NID 0x03
6131#define ALC260_DIGIN_NID 0x06
6132
a9111321 6133static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6134 .num_items = 4,
6135 .items = {
6136 { "Mic", 0x0 },
6137 { "Front Mic", 0x1 },
6138 { "Line", 0x2 },
6139 { "CD", 0x4 },
6140 },
6141};
6142
17e7aec6 6143/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6144 * headphone jack and the internal CD lines since these are the only pins at
6145 * which audio can appear. For flexibility, also allow the option of
6146 * recording the mixer output on the second ADC (ADC0 doesn't have a
6147 * connection to the mixer output).
a9430dd8 6148 */
a9111321 6149static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6150 {
6151 .num_items = 3,
6152 .items = {
6153 { "Mic/Line", 0x0 },
6154 { "CD", 0x4 },
6155 { "Headphone", 0x2 },
6156 },
a9430dd8 6157 },
a1e8d2da
JW
6158 {
6159 .num_items = 4,
6160 .items = {
6161 { "Mic/Line", 0x0 },
6162 { "CD", 0x4 },
6163 { "Headphone", 0x2 },
6164 { "Mixer", 0x5 },
6165 },
6166 },
6167
a9430dd8
JW
6168};
6169
a1e8d2da
JW
6170/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6171 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6172 */
a9111321 6173static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6174 {
6175 .num_items = 4,
6176 .items = {
6177 { "Mic", 0x0 },
6178 { "Line", 0x2 },
6179 { "CD", 0x4 },
6180 { "Headphone", 0x5 },
6181 },
6182 },
6183 {
6184 .num_items = 5,
6185 .items = {
6186 { "Mic", 0x0 },
6187 { "Line", 0x2 },
6188 { "CD", 0x4 },
6189 { "Headphone", 0x6 },
6190 { "Mixer", 0x5 },
6191 },
0bfc90e9
JW
6192 },
6193};
cc959489
MS
6194
6195/* Maxdata Favorit 100XS */
a9111321 6196static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6197 {
6198 .num_items = 2,
6199 .items = {
6200 { "Line/Mic", 0x0 },
6201 { "CD", 0x4 },
6202 },
6203 },
6204 {
6205 .num_items = 3,
6206 .items = {
6207 { "Line/Mic", 0x0 },
6208 { "CD", 0x4 },
6209 { "Mixer", 0x5 },
6210 },
6211 },
6212};
6213
1da177e4
LT
6214/*
6215 * This is just place-holder, so there's something for alc_build_pcms to look
6216 * at when it calculates the maximum number of channels. ALC260 has no mixer
6217 * element which allows changing the channel mode, so the verb list is
6218 * never used.
6219 */
a9111321 6220static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6221 { 2, NULL },
6222};
6223
df694daa
KY
6224
6225/* Mixer combinations
6226 *
6227 * basic: base_output + input + pc_beep + capture
6228 * HP: base_output + input + capture_alt
6229 * HP_3013: hp_3013 + input + capture
6230 * fujitsu: fujitsu + capture
0bfc90e9 6231 * acer: acer + capture
df694daa
KY
6232 */
6233
a9111321 6234static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6235 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6236 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6237 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6238 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6239 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6240 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6241 { } /* end */
f12ab1e0 6242};
1da177e4 6243
a9111321 6244static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6245 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6246 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6247 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6248 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6249 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6250 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6251 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6252 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6253 { } /* end */
6254};
6255
bec15c3a 6256/* update HP, line and mono out pins according to the master switch */
e9427969 6257static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a 6258{
e9427969 6259 update_speakers(codec);
bec15c3a
TI
6260}
6261
6262static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6263 struct snd_ctl_elem_value *ucontrol)
6264{
6265 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6266 struct alc_spec *spec = codec->spec;
e9427969 6267 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6268 return 0;
6269}
6270
6271static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6272 struct snd_ctl_elem_value *ucontrol)
6273{
6274 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6275 struct alc_spec *spec = codec->spec;
e9427969 6276 int val = !*ucontrol->value.integer.value;
bec15c3a 6277
e9427969 6278 if (val == spec->master_mute)
bec15c3a 6279 return 0;
e9427969
TI
6280 spec->master_mute = val;
6281 alc260_hp_master_update(codec);
bec15c3a
TI
6282 return 1;
6283}
6284
a9111321 6285static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6286 {
6287 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6288 .name = "Master Playback Switch",
5b0cb1d8 6289 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6290 .info = snd_ctl_boolean_mono_info,
6291 .get = alc260_hp_master_sw_get,
6292 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6293 },
6294 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6295 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6296 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6297 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6298 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6299 HDA_OUTPUT),
6300 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6301 { } /* end */
6302};
6303
a9111321 6304static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6305 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6306 {},
6307};
6308
e9427969 6309static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6310{
6311 struct alc_spec *spec = codec->spec;
bec15c3a 6312
e9427969
TI
6313 spec->autocfg.hp_pins[0] = 0x0f;
6314 spec->autocfg.speaker_pins[0] = 0x10;
6315 spec->autocfg.speaker_pins[1] = 0x11;
6316 spec->automute = 1;
6317 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6318}
6319
a9111321 6320static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6321 {
6322 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6323 .name = "Master Playback Switch",
5b0cb1d8 6324 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6325 .info = snd_ctl_boolean_mono_info,
6326 .get = alc260_hp_master_sw_get,
6327 .put = alc260_hp_master_sw_put,
bec15c3a 6328 },
df694daa
KY
6329 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6330 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6331 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6332 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6333 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6334 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6335 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6336 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6337 { } /* end */
6338};
6339
e9427969
TI
6340static void alc260_hp_3013_setup(struct hda_codec *codec)
6341{
6342 struct alc_spec *spec = codec->spec;
6343
6344 spec->autocfg.hp_pins[0] = 0x15;
6345 spec->autocfg.speaker_pins[0] = 0x10;
6346 spec->autocfg.speaker_pins[1] = 0x11;
6347 spec->automute = 1;
6348 spec->automute_mode = ALC_AUTOMUTE_PIN;
6349}
6350
a9111321 6351static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6352 .ops = &snd_hda_bind_vol,
6353 .values = {
6354 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6355 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6356 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6357 0
6358 },
6359};
6360
a9111321 6361static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6362 .ops = &snd_hda_bind_sw,
6363 .values = {
6364 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6365 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6366 0
6367 },
6368};
6369
a9111321 6370static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6371 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6372 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6373 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6374 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6375 { } /* end */
6376};
6377
a9111321 6378static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6379 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6380 {},
6381};
6382
e9427969 6383static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6384{
6385 struct alc_spec *spec = codec->spec;
bec15c3a 6386
e9427969
TI
6387 spec->autocfg.hp_pins[0] = 0x10;
6388 spec->autocfg.speaker_pins[0] = 0x0f;
6389 spec->autocfg.speaker_pins[1] = 0x11;
6390 spec->autocfg.speaker_pins[2] = 0x15;
6391 spec->automute = 1;
6392 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6393}
6394
6395/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6396 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6397 */
a9111321 6398static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6399 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6400 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6401 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6402 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6403 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6404 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6405 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6406 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6407 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6408 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6409 { } /* end */
6410};
6411
a1e8d2da
JW
6412/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6413 * versions of the ALC260 don't act on requests to enable mic bias from NID
6414 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6415 * datasheet doesn't mention this restriction. At this stage it's not clear
6416 * whether this behaviour is intentional or is a hardware bug in chip
6417 * revisions available in early 2006. Therefore for now allow the
6418 * "Headphone Jack Mode" control to span all choices, but if it turns out
6419 * that the lack of mic bias for this NID is intentional we could change the
6420 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6421 *
6422 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6423 * don't appear to make the mic bias available from the "line" jack, even
6424 * though the NID used for this jack (0x14) can supply it. The theory is
6425 * that perhaps Acer have included blocking capacitors between the ALC260
6426 * and the output jack. If this turns out to be the case for all such
6427 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6428 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6429 *
6430 * The C20x Tablet series have a mono internal speaker which is controlled
6431 * via the chip's Mono sum widget and pin complex, so include the necessary
6432 * controls for such models. On models without a "mono speaker" the control
6433 * won't do anything.
a1e8d2da 6434 */
a9111321 6435static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6436 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6437 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6438 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6439 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6440 HDA_OUTPUT),
31bffaa9 6441 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6442 HDA_INPUT),
0bfc90e9
JW
6443 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6444 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6446 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6447 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6448 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6449 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6450 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6451 { } /* end */
6452};
6453
cc959489
MS
6454/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6455 */
a9111321 6456static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6457 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6458 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6459 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6460 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6461 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6462 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6463 { } /* end */
6464};
6465
bc9f98a9
KY
6466/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6467 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6468 */
a9111321 6469static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6470 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6471 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6472 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6473 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6474 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6475 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6476 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6477 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6478 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6479 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6480 { } /* end */
6481};
6482
6483/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6484 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6485 */
a9111321 6486static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6487 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6488 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6489 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6490 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6491 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6492 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6493 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6494 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6495 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6496 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6497 { } /* end */
6498};
6499
df694daa
KY
6500/*
6501 * initialization verbs
6502 */
a9111321 6503static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6504 /* Line In pin widget for input */
05acb863 6505 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6506 /* CD pin widget for input */
05acb863 6507 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6508 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6509 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6510 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6511 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6512 /* LINE-2 is used for line-out in rear */
05acb863 6513 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6514 /* select line-out */
fd56f2db 6515 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6516 /* LINE-OUT pin */
05acb863 6517 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6518 /* enable HP */
05acb863 6519 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6520 /* enable Mono */
05acb863
TI
6521 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6522 /* mute capture amp left and right */
16ded525 6523 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6524 /* set connection select to line in (default select for this ADC) */
6525 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6526 /* mute capture amp left and right */
6527 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6528 /* set connection select to line in (default select for this ADC) */
6529 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6530 /* set vol=0 Line-Out mixer amp left and right */
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6532 /* unmute pin widget amp left and right (no gain on this amp) */
6533 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6534 /* set vol=0 HP mixer amp left and right */
6535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6536 /* unmute pin widget amp left and right (no gain on this amp) */
6537 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6538 /* set vol=0 Mono mixer amp left and right */
6539 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6540 /* unmute pin widget amp left and right (no gain on this amp) */
6541 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6542 /* unmute LINE-2 out pin */
6543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6544 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6545 * Line In 2 = 0x03
6546 */
cb53c626
TI
6547 /* mute analog inputs */
6548 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6553 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6554 /* mute Front out path */
6555 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6557 /* mute Headphone out path */
6558 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6560 /* mute Mono out path */
6561 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6563 { }
6564};
6565
474167d6 6566#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6567static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6568 /* Headphone and output */
6569 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6570 /* mono output */
6571 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6572 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6573 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6574 /* Mic2 (front panel) pin widget for input and vref at 80% */
6575 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6576 /* Line In pin widget for input */
6577 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6578 /* Line-2 pin widget for output */
6579 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6580 /* CD pin widget for input */
6581 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6582 /* unmute amp left and right */
6583 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6584 /* set connection select to line in (default select for this ADC) */
6585 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6586 /* unmute Line-Out mixer amp left and right (volume = 0) */
6587 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6588 /* mute pin widget amp left and right (no gain on this amp) */
6589 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6590 /* unmute HP mixer amp left and right (volume = 0) */
6591 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6592 /* mute pin widget amp left and right (no gain on this amp) */
6593 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6594 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6595 * Line In 2 = 0x03
6596 */
cb53c626
TI
6597 /* mute analog inputs */
6598 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6603 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6604 /* Unmute Front out path */
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6607 /* Unmute Headphone out path */
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6610 /* Unmute Mono out path */
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6613 { }
6614};
474167d6 6615#endif
df694daa 6616
a9111321 6617static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6618 /* Line out and output */
6619 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6620 /* mono output */
6621 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6622 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6623 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6624 /* Mic2 (front panel) pin widget for input and vref at 80% */
6625 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6626 /* Line In pin widget for input */
6627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6628 /* Headphone pin widget for output */
6629 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6630 /* CD pin widget for input */
6631 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6632 /* unmute amp left and right */
6633 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6634 /* set connection select to line in (default select for this ADC) */
6635 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6636 /* unmute Line-Out mixer amp left and right (volume = 0) */
6637 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6638 /* mute pin widget amp left and right (no gain on this amp) */
6639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6640 /* unmute HP mixer amp left and right (volume = 0) */
6641 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6642 /* mute pin widget amp left and right (no gain on this amp) */
6643 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6644 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6645 * Line In 2 = 0x03
6646 */
cb53c626
TI
6647 /* mute analog inputs */
6648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6650 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6651 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6652 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6653 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6654 /* Unmute Front out path */
6655 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6656 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6657 /* Unmute Headphone out path */
6658 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6659 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6660 /* Unmute Mono out path */
6661 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6662 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6663 { }
6664};
6665
a9430dd8 6666/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6667 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6668 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6669 */
a9111321 6670static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6671 /* Disable all GPIOs */
6672 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6673 /* Internal speaker is connected to headphone pin */
6674 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6675 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6676 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6677 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6678 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6679 /* Ensure all other unused pins are disabled and muted. */
6680 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6681 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6682 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6683 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6684 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6685 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6686 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6687 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6688
6689 /* Disable digital (SPDIF) pins */
6690 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6691 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6692
ea1fb29a 6693 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6694 * when acting as an output.
6695 */
6696 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6697
f7ace40d 6698 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6699 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6700 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6701 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6702 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6703 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6704 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6705 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6706 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6707 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6708
f7ace40d
JW
6709 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6710 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6711 /* Unmute Line1 pin widget output buffer since it starts as an output.
6712 * If the pin mode is changed by the user the pin mode control will
6713 * take care of enabling the pin's input/output buffers as needed.
6714 * Therefore there's no need to enable the input buffer at this
6715 * stage.
cdcd9268 6716 */
f7ace40d 6717 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6718 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6719 * mixer ctrl)
6720 */
f7ace40d
JW
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)},
ea1fb29a 6725 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6726 * in (on mic1 pin)
6727 */
6728 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6729
6730 /* Do the same for the second ADC: mute capture input amp and
6731 * set ADC connection to line in (on mic1 pin)
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 */
4a471b7d
TI
6745
6746 { }
a9430dd8
JW
6747};
6748
0bfc90e9
JW
6749/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6750 * similar laptops (adapted from Fujitsu init verbs).
6751 */
a9111321 6752static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6753 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6754 * the headphone jack. Turn this on and rely on the standard mute
6755 * methods whenever the user wants to turn these outputs off.
6756 */
6757 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6758 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6759 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6760 /* Internal speaker/Headphone jack is connected to Line-out pin */
6761 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6762 /* Internal microphone/Mic jack is connected to Mic1 pin */
6763 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6764 /* Line In jack is connected to Line1 pin */
6765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6766 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6767 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6768 /* Ensure all other unused pins are disabled and muted. */
6769 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6770 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6771 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6772 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6773 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Disable digital (SPDIF) pins */
6776 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6777 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6778
ea1fb29a 6779 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6780 * bus when acting as outputs.
6781 */
6782 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6783 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6784
6785 /* Start with output sum widgets muted and their output gains at min */
6786 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6789 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6791 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6792 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6793 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6794 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6795
f12ab1e0
TI
6796 /* Unmute Line-out pin widget amp left and right
6797 * (no equiv mixer ctrl)
6798 */
0bfc90e9 6799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6800 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6801 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6802 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6803 * inputs. If the pin mode is changed by the user the pin mode control
6804 * will take care of enabling the pin's input/output buffers as needed.
6805 * Therefore there's no need to enable the input buffer at this
6806 * stage.
6807 */
6808 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6810
6811 /* Mute capture amp left and right */
6812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6813 /* Set ADC connection select to match default mixer setting - mic
6814 * (on mic1 pin)
6815 */
6816 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6817
6818 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6819 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6820 */
6821 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6822 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6823
6824 /* Mute all inputs to mixer widget (even unconnected ones) */
6825 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6826 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6827 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6829 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6831 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6832 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6833
6834 { }
6835};
6836
cc959489
MS
6837/* Initialisation sequence for Maxdata Favorit 100XS
6838 * (adapted from Acer init verbs).
6839 */
a9111321 6840static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6841 /* GPIO 0 enables the output jack.
6842 * Turn this on and rely on the standard mute
6843 * methods whenever the user wants to turn these outputs off.
6844 */
6845 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6846 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6847 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6848 /* Line/Mic input jack is connected to Mic1 pin */
6849 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6850 /* Ensure all other unused pins are disabled and muted. */
6851 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6852 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6853 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6854 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6855 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6856 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6858 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6859 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6860 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6861 /* Disable digital (SPDIF) pins */
6862 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6863 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6864
6865 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6866 * bus when acting as outputs.
6867 */
6868 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6869 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6870
6871 /* Start with output sum widgets muted and their output gains at min */
6872 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6873 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6874 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6875 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6877 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6878 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6879 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6880 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6881
6882 /* Unmute Line-out pin widget amp left and right
6883 * (no equiv mixer ctrl)
6884 */
6885 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6886 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6887 * inputs. If the pin mode is changed by the user the pin mode control
6888 * will take care of enabling the pin's input/output buffers as needed.
6889 * Therefore there's no need to enable the input buffer at this
6890 * stage.
6891 */
6892 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6893
6894 /* Mute capture amp left and right */
6895 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6896 /* Set ADC connection select to match default mixer setting - mic
6897 * (on mic1 pin)
6898 */
6899 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6900
6901 /* Do similar with the second ADC: mute capture input amp and
6902 * set ADC connection to mic to match ALSA's default state.
6903 */
6904 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6905 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6906
6907 /* Mute all inputs to mixer widget (even unconnected ones) */
6908 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6909 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6910 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6911 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6913 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6914 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6915 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6916
6917 { }
6918};
6919
a9111321 6920static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6921 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6922 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6923 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6924 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6925 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6926 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6927 {}
6928};
6929
a9111321 6930static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6931 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6932 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6933 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6934
6935 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6936 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6937 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6938
6939 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6940 {}
6941};
6942
6943/* toggle speaker-output according to the hp-jack state */
6944static void alc260_replacer_672v_automute(struct hda_codec *codec)
6945{
6946 unsigned int present;
6947
6948 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6949 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6950 if (present) {
82beb8fd
TI
6951 snd_hda_codec_write_cache(codec, 0x01, 0,
6952 AC_VERB_SET_GPIO_DATA, 1);
6953 snd_hda_codec_write_cache(codec, 0x0f, 0,
6954 AC_VERB_SET_PIN_WIDGET_CONTROL,
6955 PIN_HP);
bc9f98a9 6956 } else {
82beb8fd
TI
6957 snd_hda_codec_write_cache(codec, 0x01, 0,
6958 AC_VERB_SET_GPIO_DATA, 0);
6959 snd_hda_codec_write_cache(codec, 0x0f, 0,
6960 AC_VERB_SET_PIN_WIDGET_CONTROL,
6961 PIN_OUT);
bc9f98a9
KY
6962 }
6963}
6964
6965static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6966 unsigned int res)
6967{
6968 if ((res >> 26) == ALC880_HP_EVENT)
6969 alc260_replacer_672v_automute(codec);
6970}
6971
a9111321 6972static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6973 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6974 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6975 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6976 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6977 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6980 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6981 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6982 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6983 {}
6984};
6985
7cf51e48
JW
6986/* Test configuration for debugging, modelled after the ALC880 test
6987 * configuration.
6988 */
6989#ifdef CONFIG_SND_DEBUG
4c6d72d1 6990static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6991 0x02,
6992};
4c6d72d1 6993static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6994 0x04, 0x05,
6995};
a1e8d2da 6996/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6997 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6998 * is NID 0x04.
17e7aec6 6999 */
a9111321 7000static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
7001 {
7002 .num_items = 7,
7003 .items = {
7004 { "MIC1 pin", 0x0 },
7005 { "MIC2 pin", 0x1 },
7006 { "LINE1 pin", 0x2 },
7007 { "LINE2 pin", 0x3 },
7008 { "CD pin", 0x4 },
7009 { "LINE-OUT pin", 0x5 },
7010 { "HP-OUT pin", 0x6 },
7011 },
7012 },
7013 {
7014 .num_items = 8,
7015 .items = {
7016 { "MIC1 pin", 0x0 },
7017 { "MIC2 pin", 0x1 },
7018 { "LINE1 pin", 0x2 },
7019 { "LINE2 pin", 0x3 },
7020 { "CD pin", 0x4 },
7021 { "Mixer", 0x5 },
7022 { "LINE-OUT pin", 0x6 },
7023 { "HP-OUT pin", 0x7 },
7024 },
7cf51e48
JW
7025 },
7026};
a9111321 7027static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
7028 /* Output driver widgets */
7029 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
7030 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
7031 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
7032 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
7033 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
7034 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
7035
a1e8d2da
JW
7036 /* Modes for retasking pin widgets
7037 * Note: the ALC260 doesn't seem to act on requests to enable mic
7038 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
7039 * mention this restriction. At this stage it's not clear whether
7040 * this behaviour is intentional or is a hardware bug in chip
7041 * revisions available at least up until early 2006. Therefore for
7042 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
7043 * choices, but if it turns out that the lack of mic bias for these
7044 * NIDs is intentional we could change their modes from
7045 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
7046 */
7cf51e48
JW
7047 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
7048 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7049 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7050 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7051 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7052 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7053
7054 /* Loopback mixer controls */
7055 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7056 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7057 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7058 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7059 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7060 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7061 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7062 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7063 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7064 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
7065 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7066 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7067 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7068 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
7069
7070 /* Controls for GPIO pins, assuming they are configured as outputs */
7071 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7072 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7073 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7074 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7075
92621f13
JW
7076 /* Switches to allow the digital IO pins to be enabled. The datasheet
7077 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 7078 * make this output available should provide clarification.
92621f13
JW
7079 */
7080 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7081 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7082
f8225f6d
JW
7083 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7084 * this output to turn on an external amplifier.
7085 */
7086 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7087 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7088
7cf51e48
JW
7089 { } /* end */
7090};
a9111321 7091static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
7092 /* Enable all GPIOs as outputs with an initial value of 0 */
7093 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7094 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7095 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7096
7cf51e48
JW
7097 /* Enable retasking pins as output, initially without power amp */
7098 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7099 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7100 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7101 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7102 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7103 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7104
92621f13
JW
7105 /* Disable digital (SPDIF) pins initially, but users can enable
7106 * them via a mixer switch. In the case of SPDIF-out, this initverb
7107 * payload also sets the generation to 0, output to be in "consumer"
7108 * PCM format, copyright asserted, no pre-emphasis and no validity
7109 * control.
7110 */
7cf51e48
JW
7111 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7112 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7113
ea1fb29a 7114 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7115 * OUT1 sum bus when acting as an output.
7116 */
7117 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7118 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7119 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7120 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7121
7122 /* Start with output sum widgets muted and their output gains at min */
7123 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7124 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7125 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7126 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7127 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7128 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7129 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7130 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7131 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7132
cdcd9268
JW
7133 /* Unmute retasking pin widget output buffers since the default
7134 * state appears to be output. As the pin mode is changed by the
7135 * user the pin mode control will take care of enabling the pin's
7136 * input/output buffers as needed.
7137 */
7cf51e48
JW
7138 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7139 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7140 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7142 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7143 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7144 /* Also unmute the mono-out pin widget */
7145 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7146
7cf51e48
JW
7147 /* Mute capture amp left and right */
7148 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7149 /* Set ADC connection select to match default mixer setting (mic1
7150 * pin)
7cf51e48
JW
7151 */
7152 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7153
7154 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7155 * set ADC connection to mic1 pin
7cf51e48
JW
7156 */
7157 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7158 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7159
7160 /* Mute all inputs to mixer widget (even unconnected ones) */
7161 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7162 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7163 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7164 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7165 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7166 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7167 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7168 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7169
7170 { }
7171};
7172#endif
7173
6330079f
TI
7174#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7175#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7176
a3bcba38
TI
7177#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7178#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7179
df694daa
KY
7180/*
7181 * for BIOS auto-configuration
7182 */
16ded525 7183
6d86b4fb
TI
7184/* convert from pin to volume-mixer widget */
7185static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7186{
7187 if (nid >= 0x0f && nid <= 0x11)
7188 return nid - 0x7;
7189 else if (nid >= 0x12 && nid <= 0x15)
7190 return 0x08;
7191 else
7192 return 0;
7193}
7194
df694daa 7195static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7196 const char *pfx, int *vol_bits)
df694daa
KY
7197{
7198 hda_nid_t nid_vol;
7199 unsigned long vol_val, sw_val;
6d86b4fb 7200 int chs, err;
df694daa 7201
6d86b4fb
TI
7202 nid_vol = alc260_pin_to_vol_mix(nid);
7203 if (!nid_vol)
df694daa 7204 return 0; /* N/A */
6d86b4fb
TI
7205 if (nid == 0x11)
7206 chs = 2;
7207 else
7208 chs = 3;
7209 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, chs, 0, HDA_OUTPUT);
7210 sw_val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT);
ea1fb29a 7211
863b4518
TI
7212 if (!(*vol_bits & (1 << nid_vol))) {
7213 /* first control for the volume widget */
0afe5f89 7214 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7215 if (err < 0)
7216 return err;
7217 *vol_bits |= (1 << nid_vol);
7218 }
0afe5f89 7219 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7220 if (err < 0)
df694daa
KY
7221 return err;
7222 return 1;
7223}
7224
7225/* add playback controls from the parsed DAC table */
7226static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7227 const struct auto_pin_cfg *cfg)
7228{
7229 hda_nid_t nid;
7230 int err;
863b4518 7231 int vols = 0;
df694daa
KY
7232
7233 spec->multiout.num_dacs = 1;
7234 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7235 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7236
7237 nid = cfg->line_out_pins[0];
7238 if (nid) {
23112d6d 7239 const char *pfx;
2e925dde
TI
7240 int index;
7241 pfx = alc_get_line_out_pfx(spec, 0, true, &index);
23112d6d 7242 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7243 if (err < 0)
7244 return err;
7245 }
7246
82bc955f 7247 nid = cfg->speaker_pins[0];
df694daa 7248 if (nid) {
863b4518 7249 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7250 if (err < 0)
7251 return err;
7252 }
7253
eb06ed8f 7254 nid = cfg->hp_pins[0];
df694daa 7255 if (nid) {
863b4518
TI
7256 err = alc260_add_playback_controls(spec, nid, "Headphone",
7257 &vols);
df694daa
KY
7258 if (err < 0)
7259 return err;
7260 }
f12ab1e0 7261 return 0;
df694daa
KY
7262}
7263
7264/* create playback/capture controls for input pins */
05f5f477 7265static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7266 const struct auto_pin_cfg *cfg)
7267{
05f5f477 7268 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7269}
7270
7271static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7272 hda_nid_t nid, int pin_type,
7273 int sel_idx)
7274{
6d86b4fb
TI
7275 hda_nid_t mix;
7276
f6c7e546 7277 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7278 /* need the manual connection? */
7279 if (nid >= 0x12) {
7280 int idx = nid - 0x12;
7281 snd_hda_codec_write(codec, idx + 0x0b, 0,
7282 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa 7283 }
df694daa 7284
6d86b4fb
TI
7285 mix = alc260_pin_to_vol_mix(nid);
7286 if (!mix)
1f0f4b80 7287 return;
6d86b4fb 7288 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1f0f4b80 7289 AMP_OUT_ZERO);
6d86b4fb
TI
7290 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7291 AMP_IN_UNMUTE(0));
7292 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7293 AMP_IN_UNMUTE(1));
1f0f4b80
TI
7294}
7295
df694daa
KY
7296static void alc260_auto_init_multi_out(struct hda_codec *codec)
7297{
7298 struct alc_spec *spec = codec->spec;
7299 hda_nid_t nid;
7300
f12ab1e0 7301 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7302 if (nid) {
7303 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7304 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7305 }
ea1fb29a 7306
82bc955f 7307 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7308 if (nid)
7309 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7310
eb06ed8f 7311 nid = spec->autocfg.hp_pins[0];
df694daa 7312 if (nid)
baba8ee9 7313 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
df694daa
KY
7314}
7315
1f0f4b80 7316#define alc260_auto_init_analog_input alc880_auto_init_analog_input
7f311a46
TI
7317#define alc260_auto_init_input_src alc880_auto_init_input_src
7318
df694daa
KY
7319static int alc260_parse_auto_config(struct hda_codec *codec)
7320{
7321 struct alc_spec *spec = codec->spec;
df694daa 7322 int err;
4c6d72d1 7323 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7324
f12ab1e0
TI
7325 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7326 alc260_ignore);
7327 if (err < 0)
df694daa 7328 return err;
f12ab1e0
TI
7329 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7330 if (err < 0)
4a471b7d 7331 return err;
603c4019 7332 if (!spec->kctls.list)
df694daa 7333 return 0; /* can't find valid BIOS pin config */
05f5f477 7334 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7335 if (err < 0)
df694daa
KY
7336 return err;
7337
7338 spec->multiout.max_channels = 2;
7339
0852d7a6 7340 if (spec->autocfg.dig_outs)
df694daa 7341 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7342 if (spec->kctls.list)
d88897ea 7343 add_mixer(spec, spec->kctls.list);
df694daa 7344
a1e8d2da 7345 spec->num_mux_defs = 1;
61b9b9b1 7346 spec->input_mux = &spec->private_imux[0];
df694daa 7347
6227cdce 7348 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7349
df694daa
KY
7350 return 1;
7351}
7352
ae6b813a
TI
7353/* additional initialization for auto-configuration model */
7354static void alc260_auto_init(struct hda_codec *codec)
df694daa 7355{
f6c7e546 7356 struct alc_spec *spec = codec->spec;
df694daa
KY
7357 alc260_auto_init_multi_out(codec);
7358 alc260_auto_init_analog_input(codec);
7f311a46 7359 alc260_auto_init_input_src(codec);
757899ac 7360 alc_auto_init_digital(codec);
f6c7e546 7361 if (spec->unsol_event)
7fb0d78f 7362 alc_inithook(codec);
df694daa
KY
7363}
7364
cb53c626 7365#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7366static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7367 { 0x07, HDA_INPUT, 0 },
7368 { 0x07, HDA_INPUT, 1 },
7369 { 0x07, HDA_INPUT, 2 },
7370 { 0x07, HDA_INPUT, 3 },
7371 { 0x07, HDA_INPUT, 4 },
7372 { } /* end */
7373};
7374#endif
7375
fc091769
TI
7376/*
7377 * Pin config fixes
7378 */
7379enum {
7380 PINFIX_HP_DC5750,
7381};
7382
fc091769
TI
7383static const struct alc_fixup alc260_fixups[] = {
7384 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7385 .type = ALC_FIXUP_PINS,
7386 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7387 { 0x11, 0x90130110 }, /* speaker */
7388 { }
7389 }
fc091769
TI
7390 },
7391};
7392
a9111321 7393static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7394 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7395 {}
7396};
7397
df694daa
KY
7398/*
7399 * ALC260 configurations
7400 */
ea734963 7401static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7402 [ALC260_BASIC] = "basic",
7403 [ALC260_HP] = "hp",
7404 [ALC260_HP_3013] = "hp-3013",
2922c9af 7405 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7406 [ALC260_FUJITSU_S702X] = "fujitsu",
7407 [ALC260_ACER] = "acer",
bc9f98a9
KY
7408 [ALC260_WILL] = "will",
7409 [ALC260_REPLACER_672V] = "replacer",
cc959489 7410 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7411#ifdef CONFIG_SND_DEBUG
f5fcc13c 7412 [ALC260_TEST] = "test",
7cf51e48 7413#endif
f5fcc13c
TI
7414 [ALC260_AUTO] = "auto",
7415};
7416
a9111321 7417static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7418 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7419 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7420 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7421 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7422 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7423 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7424 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7425 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7426 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7427 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7428 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7429 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7430 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7432 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7433 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7435 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7436 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7437 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7438 {}
7439};
7440
a9111321 7441static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7442 [ALC260_BASIC] = {
7443 .mixers = { alc260_base_output_mixer,
45bdd1c1 7444 alc260_input_mixer },
df694daa
KY
7445 .init_verbs = { alc260_init_verbs },
7446 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7447 .dac_nids = alc260_dac_nids,
f9e336f6 7448 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7449 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7450 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7451 .channel_mode = alc260_modes,
7452 .input_mux = &alc260_capture_source,
7453 },
7454 [ALC260_HP] = {
bec15c3a 7455 .mixers = { alc260_hp_output_mixer,
f9e336f6 7456 alc260_input_mixer },
bec15c3a
TI
7457 .init_verbs = { alc260_init_verbs,
7458 alc260_hp_unsol_verbs },
df694daa
KY
7459 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7460 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7461 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7462 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7463 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7464 .channel_mode = alc260_modes,
7465 .input_mux = &alc260_capture_source,
e9427969
TI
7466 .unsol_event = alc_sku_unsol_event,
7467 .setup = alc260_hp_setup,
7468 .init_hook = alc_inithook,
df694daa 7469 },
3f878308
KY
7470 [ALC260_HP_DC7600] = {
7471 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7472 alc260_input_mixer },
3f878308
KY
7473 .init_verbs = { alc260_init_verbs,
7474 alc260_hp_dc7600_verbs },
7475 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7476 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7477 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7478 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7479 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7480 .channel_mode = alc260_modes,
7481 .input_mux = &alc260_capture_source,
e9427969
TI
7482 .unsol_event = alc_sku_unsol_event,
7483 .setup = alc260_hp_3012_setup,
7484 .init_hook = alc_inithook,
3f878308 7485 },
df694daa
KY
7486 [ALC260_HP_3013] = {
7487 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7488 alc260_input_mixer },
bec15c3a
TI
7489 .init_verbs = { alc260_hp_3013_init_verbs,
7490 alc260_hp_3013_unsol_verbs },
df694daa
KY
7491 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7492 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7493 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7494 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7495 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7496 .channel_mode = alc260_modes,
7497 .input_mux = &alc260_capture_source,
e9427969
TI
7498 .unsol_event = alc_sku_unsol_event,
7499 .setup = alc260_hp_3013_setup,
7500 .init_hook = alc_inithook,
df694daa
KY
7501 },
7502 [ALC260_FUJITSU_S702X] = {
f9e336f6 7503 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7504 .init_verbs = { alc260_fujitsu_init_verbs },
7505 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7506 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7507 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7508 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7509 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7510 .channel_mode = alc260_modes,
a1e8d2da
JW
7511 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7512 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7513 },
0bfc90e9 7514 [ALC260_ACER] = {
f9e336f6 7515 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7516 .init_verbs = { alc260_acer_init_verbs },
7517 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7518 .dac_nids = alc260_dac_nids,
7519 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7520 .adc_nids = alc260_dual_adc_nids,
7521 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7522 .channel_mode = alc260_modes,
a1e8d2da
JW
7523 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7524 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7525 },
cc959489
MS
7526 [ALC260_FAVORIT100] = {
7527 .mixers = { alc260_favorit100_mixer },
7528 .init_verbs = { alc260_favorit100_init_verbs },
7529 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7530 .dac_nids = alc260_dac_nids,
7531 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7532 .adc_nids = alc260_dual_adc_nids,
7533 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7534 .channel_mode = alc260_modes,
7535 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7536 .input_mux = alc260_favorit100_capture_sources,
7537 },
bc9f98a9 7538 [ALC260_WILL] = {
f9e336f6 7539 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7540 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7541 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7542 .dac_nids = alc260_dac_nids,
7543 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7544 .adc_nids = alc260_adc_nids,
7545 .dig_out_nid = ALC260_DIGOUT_NID,
7546 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7547 .channel_mode = alc260_modes,
7548 .input_mux = &alc260_capture_source,
7549 },
7550 [ALC260_REPLACER_672V] = {
f9e336f6 7551 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7552 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7553 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7554 .dac_nids = alc260_dac_nids,
7555 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7556 .adc_nids = alc260_adc_nids,
7557 .dig_out_nid = ALC260_DIGOUT_NID,
7558 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7559 .channel_mode = alc260_modes,
7560 .input_mux = &alc260_capture_source,
7561 .unsol_event = alc260_replacer_672v_unsol_event,
7562 .init_hook = alc260_replacer_672v_automute,
7563 },
7cf51e48
JW
7564#ifdef CONFIG_SND_DEBUG
7565 [ALC260_TEST] = {
f9e336f6 7566 .mixers = { alc260_test_mixer },
7cf51e48
JW
7567 .init_verbs = { alc260_test_init_verbs },
7568 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7569 .dac_nids = alc260_test_dac_nids,
7570 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7571 .adc_nids = alc260_test_adc_nids,
7572 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7573 .channel_mode = alc260_modes,
a1e8d2da
JW
7574 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7575 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7576 },
7577#endif
df694daa
KY
7578};
7579
7580static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7581{
7582 struct alc_spec *spec;
df694daa 7583 int err, board_config;
1da177e4 7584
e560d8d8 7585 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7586 if (spec == NULL)
7587 return -ENOMEM;
7588
7589 codec->spec = spec;
7590
1f0f4b80
TI
7591 spec->mixer_nid = 0x07;
7592
f5fcc13c
TI
7593 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7594 alc260_models,
7595 alc260_cfg_tbl);
7596 if (board_config < 0) {
9a11f1aa 7597 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7598 codec->chip_name);
df694daa 7599 board_config = ALC260_AUTO;
16ded525 7600 }
1da177e4 7601
b5bfbc67
TI
7602 if (board_config == ALC260_AUTO) {
7603 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7604 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7605 }
fc091769 7606
df694daa
KY
7607 if (board_config == ALC260_AUTO) {
7608 /* automatic parse from the BIOS config */
7609 err = alc260_parse_auto_config(codec);
7610 if (err < 0) {
7611 alc_free(codec);
7612 return err;
f12ab1e0 7613 } else if (!err) {
9c7f852e
TI
7614 printk(KERN_INFO
7615 "hda_codec: Cannot set up configuration "
7616 "from BIOS. Using base mode...\n");
df694daa
KY
7617 board_config = ALC260_BASIC;
7618 }
a9430dd8 7619 }
e9edcee0 7620
680cd536
KK
7621 err = snd_hda_attach_beep_device(codec, 0x1);
7622 if (err < 0) {
7623 alc_free(codec);
7624 return err;
7625 }
7626
df694daa 7627 if (board_config != ALC260_AUTO)
e9c364c0 7628 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7629
1da177e4
LT
7630 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7631 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7632 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7633
a3bcba38
TI
7634 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7635 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7636
4ef0ef19
TI
7637 if (!spec->adc_nids && spec->input_mux) {
7638 /* check whether NID 0x04 is valid */
7639 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7640 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7641 /* get type */
7642 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7643 spec->adc_nids = alc260_adc_nids_alt;
7644 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7645 } else {
7646 spec->adc_nids = alc260_adc_nids;
7647 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7648 }
7649 }
b59bdf3b 7650 set_capture_mixer(codec);
45bdd1c1 7651 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7652
b5bfbc67 7653 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7654
2134ea4f
TI
7655 spec->vmaster_nid = 0x08;
7656
1da177e4 7657 codec->patch_ops = alc_patch_ops;
df694daa 7658 if (board_config == ALC260_AUTO)
ae6b813a 7659 spec->init_hook = alc260_auto_init;
1c716153 7660 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7661#ifdef CONFIG_SND_HDA_POWER_SAVE
7662 if (!spec->loopback.amplist)
7663 spec->loopback.amplist = alc260_loopbacks;
7664#endif
1da177e4
LT
7665
7666 return 0;
7667}
7668
e9edcee0 7669
1da177e4 7670/*
4953550a 7671 * ALC882/883/885/888/889 support
1da177e4
LT
7672 *
7673 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7674 * configuration. Each pin widget can choose any input DACs and a mixer.
7675 * Each ADC is connected from a mixer of all inputs. This makes possible
7676 * 6-channel independent captures.
7677 *
7678 * In addition, an independent DAC for the multi-playback (not used in this
7679 * driver yet).
7680 */
df694daa
KY
7681#define ALC882_DIGOUT_NID 0x06
7682#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7683#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7684#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7685#define ALC1200_DIGOUT_NID 0x10
7686
1da177e4 7687
a9111321 7688static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7689 { 8, NULL }
7690};
7691
4953550a 7692/* DACs */
4c6d72d1 7693static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7694 /* front, rear, clfe, rear_surr */
7695 0x02, 0x03, 0x04, 0x05
7696};
4953550a 7697#define alc883_dac_nids alc882_dac_nids
1da177e4 7698
4953550a 7699/* ADCs */
df694daa
KY
7700#define alc882_adc_nids alc880_adc_nids
7701#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7702#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7703static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7704static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7705#define alc889_adc_nids alc880_adc_nids
1da177e4 7706
4c6d72d1
TI
7707static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7708static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7709#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7710static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7711#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7712
1da177e4
LT
7713/* input MUX */
7714/* FIXME: should be a matrix-type input source selection */
7715
a9111321 7716static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7717 .num_items = 4,
7718 .items = {
7719 { "Mic", 0x0 },
7720 { "Front Mic", 0x1 },
7721 { "Line", 0x2 },
7722 { "CD", 0x4 },
7723 },
7724};
41d5545d 7725
4953550a
TI
7726#define alc883_capture_source alc882_capture_source
7727
a9111321 7728static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7729 .num_items = 3,
7730 .items = {
7731 { "Front Mic", 0x0 },
7732 { "Mic", 0x3 },
7733 { "Line", 0x2 },
7734 },
7735};
7736
a9111321 7737static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7738 .num_items = 3,
7739 .items = {
7740 { "Mic", 0x1 },
b8f171e7 7741 { "Line", 0x7 },
41d5545d
KS
7742 { "CD", 0x4 },
7743 },
7744};
7745
a9111321 7746static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7747 .num_items = 2,
7748 .items = {
7749 { "Line", 0x2 },
7750 { "CD", 0x4 },
7751 },
7752};
7753
a9111321 7754static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7755 .num_items = 4,
7756 .items = {
7757 { "Mic", 0x1 },
7758 { "Front Mic", 0x0 },
7759 { "Line", 0x2 },
7760 { "CD", 0x4 },
7761 },
7762};
7763
a9111321 7764static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7765 .num_items = 2,
7766 .items = {
7767 { "Mic", 0x1 },
7768 { "Line", 0x2 },
7769 },
7770};
7771
a9111321 7772static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7773 .num_items = 4,
7774 .items = {
7775 { "Mic", 0x0 },
28c4edb7 7776 { "Internal Mic", 0x1 },
4953550a
TI
7777 { "Line", 0x2 },
7778 { "CD", 0x4 },
7779 },
7780};
7781
a9111321 7782static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7783 .num_items = 2,
7784 .items = {
7785 { "Mic", 0x0 },
28c4edb7 7786 { "Internal Mic", 0x1 },
4953550a
TI
7787 },
7788};
7789
a9111321 7790static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7791 .num_items = 3,
7792 .items = {
7793 { "Mic", 0x0 },
7794 { "Front Mic", 0x1 },
7795 { "Line", 0x4 },
7796 },
7797};
7798
a9111321 7799static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7800 .num_items = 2,
7801 .items = {
7802 { "Mic", 0x0 },
7803 { "Line", 0x2 },
7804 },
7805};
7806
a9111321 7807static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7808 .num_items = 2,
7809 .items = {
7810 { "Mic", 0x0 },
7811 /* Front Mic (0x01) unused */
7812 { "Line", 0x2 },
7813 /* Line 2 (0x03) unused */
af901ca1 7814 /* CD (0x04) unused? */
4953550a
TI
7815 },
7816};
7817
a9111321 7818static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7819 .num_items = 2,
7820 .items = {
7821 { "Mic", 0x01 },
7822 { "Line", 0x2 }, /* Not sure! */
7823 },
7824};
7825
4953550a
TI
7826/*
7827 * 2ch mode
7828 */
a9111321 7829static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7830 { 2, NULL }
7831};
7832
272a527c
KY
7833/*
7834 * 2ch mode
7835 */
a9111321 7836static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7841 { } /* end */
7842};
7843
4953550a
TI
7844/*
7845 * 4ch mode
7846 */
a9111321 7847static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7852 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7853 { } /* end */
7854};
7855
272a527c
KY
7856/*
7857 * 6ch mode
7858 */
a9111321 7859static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867};
7868
a9111321 7869static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7870 { 2, alc882_3ST_ch2_init },
4953550a 7871 { 4, alc882_3ST_ch4_init },
272a527c
KY
7872 { 6, alc882_3ST_ch6_init },
7873};
7874
4953550a
TI
7875#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7876
a65cc60f 7877/*
7878 * 2ch mode
7879 */
a9111321 7880static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7886 { } /* end */
7887};
7888
7889/*
7890 * 4ch mode
7891 */
a9111321 7892static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7893 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7898 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7899 { } /* end */
7900};
7901
7902/*
7903 * 6ch mode
7904 */
a9111321 7905static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7913 { } /* end */
7914};
7915
a9111321 7916static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7917 { 2, alc883_3ST_ch2_clevo_init },
7918 { 4, alc883_3ST_ch4_clevo_init },
7919 { 6, alc883_3ST_ch6_clevo_init },
7920};
7921
7922
df694daa
KY
7923/*
7924 * 6ch mode
7925 */
a9111321 7926static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7927 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931 { } /* end */
7932};
7933
7934/*
7935 * 8ch mode
7936 */
a9111321 7937static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { } /* end */
7943};
7944
a9111321 7945static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7946 { 6, alc882_sixstack_ch6_init },
7947 { 8, alc882_sixstack_ch8_init },
7948};
7949
76e6f5a9
RH
7950
7951/* Macbook Air 2,1 */
7952
a9111321 7953static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7954 { 2, NULL },
7955};
7956
87350ad0 7957/*
def319f9 7958 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7959 */
7960
7961/*
7962 * 2ch mode
7963 */
a9111321 7964static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7968 { } /* end */
7969};
7970
7971/*
a3f730af 7972 * 4ch mode
87350ad0 7973 */
a9111321 7974static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7980 { } /* end */
7981};
7982
a9111321 7983static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7984 { 2, alc885_mbp_ch2_init },
a3f730af 7985 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7986};
7987
92b9de83
KS
7988/*
7989 * 2ch
7990 * Speakers/Woofer/HP = Front
7991 * LineIn = Input
7992 */
a9111321 7993static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7996 { } /* end */
7997};
7998
7999/*
8000 * 6ch mode
8001 * Speakers/HP = Front
8002 * Woofer = LFE
8003 * LineIn = Surround
8004 */
a9111321 8005static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
8006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8009 { } /* end */
8010};
8011
a9111321 8012static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
8013 { 2, alc885_mb5_ch2_init },
8014 { 6, alc885_mb5_ch6_init },
8015};
87350ad0 8016
d01aecdf 8017#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
8018
8019/*
8020 * 2ch mode
8021 */
a9111321 8022static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
8023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8029 { } /* end */
8030};
8031
8032/*
8033 * 4ch mode
8034 */
a9111321 8035static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8043 { } /* end */
8044};
8045
8046/*
8047 * 6ch mode
8048 */
a9111321 8049static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8050 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8051 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8058 { } /* end */
8059};
8060
8061/*
8062 * 8ch mode
8063 */
a9111321 8064static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8065 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8073 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8074 { } /* end */
8075};
8076
a9111321 8077static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8078 { 2, alc883_4ST_ch2_init },
8079 { 4, alc883_4ST_ch4_init },
8080 { 6, alc883_4ST_ch6_init },
8081 { 8, alc883_4ST_ch8_init },
8082};
8083
8084
8085/*
8086 * 2ch mode
8087 */
a9111321 8088static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8090 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8093 { } /* end */
8094};
8095
8096/*
8097 * 4ch mode
8098 */
a9111321 8099static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8100 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8101 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8104 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8105 { } /* end */
8106};
8107
8108/*
8109 * 6ch mode
8110 */
a9111321 8111static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8114 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118 { } /* end */
8119};
8120
a9111321 8121static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8122 { 2, alc883_3ST_ch2_intel_init },
8123 { 4, alc883_3ST_ch4_intel_init },
8124 { 6, alc883_3ST_ch6_intel_init },
8125};
8126
dd7714c9
WF
8127/*
8128 * 2ch mode
8129 */
a9111321 8130static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8131 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8137 { } /* end */
8138};
8139
87a8c370
JK
8140/*
8141 * 6ch mode
8142 */
a9111321 8143static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150 { } /* end */
8151};
8152
8153/*
8154 * 8ch mode
8155 */
a9111321 8156static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8164 { } /* end */
8165};
8166
a9111321 8167static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8168 { 2, alc889_ch2_intel_init },
87a8c370
JK
8169 { 6, alc889_ch6_intel_init },
8170 { 8, alc889_ch8_intel_init },
8171};
8172
4953550a
TI
8173/*
8174 * 6ch mode
8175 */
a9111321 8176static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8177 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8181 { } /* end */
8182};
8183
8184/*
8185 * 8ch mode
8186 */
a9111321 8187static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8188 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192 { } /* end */
8193};
8194
a9111321 8195static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8196 { 6, alc883_sixstack_ch6_init },
8197 { 8, alc883_sixstack_ch8_init },
8198};
8199
8200
1da177e4
LT
8201/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8202 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8203 */
a9111321 8204static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8214 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8224 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8225 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8226 { } /* end */
8227};
8228
76e6f5a9
RH
8229/* Macbook Air 2,1 same control for HP and internal Speaker */
8230
a9111321 8231static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8234 { }
8235};
8236
8237
a9111321 8238static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8248 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8250 { } /* end */
8251};
41d5545d 8252
a9111321 8253static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8261 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8262 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8266 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8268 { } /* end */
8269};
92b9de83 8270
a9111321 8271static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8277 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8279 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8282 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8283 { } /* end */
8284};
8285
a9111321 8286static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8289 { } /* end */
8290};
8291
8292
a9111321 8293static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8303 { } /* end */
8304};
8305
a9111321 8306static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8319 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8320 { } /* end */
8321};
8322
8323/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8325 */
a9111321 8326static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8340 { } /* end */
8341};
8342
a9111321 8343static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8354 { } /* end */
8355};
8356
a9111321 8357static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8358 {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Channel Mode",
8361 .info = alc_ch_mode_info,
8362 .get = alc_ch_mode_get,
8363 .put = alc_ch_mode_put,
8364 },
8365 { } /* end */
8366};
8367
a9111321 8368static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8372 /* Rear mixer */
05acb863
TI
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8375 /* CLFE mixer */
05acb863
TI
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8378 /* Side mixer */
05acb863
TI
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8381
e9edcee0 8382 /* Front Pin: output 0 (0x0c) */
05acb863 8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8386 /* Rear Pin: output 1 (0x0d) */
05acb863 8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8390 /* CLFE Pin: output 2 (0x0e) */
05acb863 8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8393 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8394 /* Side Pin: output 3 (0x0f) */
05acb863 8395 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8397 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8398 /* Mic (rear) pin: input vref at 80% */
16ded525 8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401 /* Front Mic pin: input vref at 80% */
16ded525 8402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8404 /* Line In pin: input */
05acb863 8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8411 /* CD pin widget for input */
05acb863 8412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8413
8414 /* FIXME: use matrix-type input source selection */
8415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8416 /* Input mixer2 */
05acb863 8417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8418 /* Input mixer3 */
05acb863 8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8420 /* ADC2: mute amp left and right */
8421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8422 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8423 /* ADC3: mute amp left and right */
8424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8425 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8426
8427 { }
8428};
8429
a9111321 8430static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8431 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8436 /* ADC1: mute amp left and right */
8437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8439 { }
8440};
8441
a9111321 8442static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8443 /* change to EAPD mode */
8444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8445 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8446 { }
4b146cb0
TI
8447};
8448
a9111321 8449static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8452 { }
8453};
8454
a9111321 8455static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8458 {}
8459};
87a8c370 8460
a9111321 8461static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8462 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8465 /* Rear mixer */
88102f3f
KY
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8468 /* CLFE mixer */
88102f3f
KY
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8471 /* Side mixer */
88102f3f
KY
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8474
8475 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Front Pin: output 0 (0x0c) */
8480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* Rear Pin: output 1 (0x0d) */
8484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8487 /* CLFE Pin: output 2 (0x0e) */
8488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8491 /* Side Pin: output 3 (0x0f) */
8492 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8495 /* Mic (rear) pin: input vref at 80% */
8496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8498 /* Front Mic pin: input vref at 80% */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Line In pin: input */
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504
8505 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8506 /* Input mixer1 */
88102f3f 8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8508 /* Input mixer2 */
8509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8510 /* Input mixer3 */
88102f3f 8511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8512 /* ADC2: mute amp left and right */
8513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 /* ADC3: mute amp left and right */
8515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516
8517 { }
8518};
8519
a9111321 8520static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8524 { }
8525};
8526
8527
8528/* Unmute Selector 24h and set the default input to front mic */
a9111321 8529static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8530 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8532 { }
8533};
8534
8535
4953550a
TI
8536#define alc883_init_verbs alc882_base_init_verbs
8537
9102cd1c 8538/* Mac Pro test */
a9111321 8539static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8545 /* FIXME: this looks suspicious...
d355c82a
JK
8546 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8548 */
9102cd1c
TD
8549 { } /* end */
8550};
8551
a9111321 8552static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8553 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8557 /* Front Pin: output 0 (0x0c) */
8558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
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 /* Speaker: output */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8568 /* Headphone output (output 0 - 0x0c) */
8569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8572
8573 /* FIXME: use matrix-type input source selection */
8574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8575 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* Input mixer2 */
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8585 /* Input mixer3 */
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8590 /* ADC1: mute amp left and right */
8591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8593 /* ADC2: mute amp left and right */
8594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* ADC3: mute amp left and right */
8597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8598 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8599
8600 { }
8601};
f12ab1e0 8602
41d5545d 8603/* Macbook 5,1 */
a9111321 8604static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8605 /* DACs */
8606 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8610 /* Front mixer */
41d5545d
KS
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8614 /* Surround mixer */
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8618 /* LFE mixer */
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8622 /* HP mixer */
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8626 /* Front Pin (0x0c) */
41d5545d
KS
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* LFE Pin (0x0e) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8634 /* HP Pin (0x0f) */
41d5545d
KS
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8639 /* Front Mic pin: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 /* Line In pin */
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8645
b8f171e7
AM
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8649 { }
8650};
8651
e458b1fa 8652/* Macmini 3,1 */
a9111321 8653static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8654 /* DACs */
8655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8659 /* Front mixer */
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8663 /* Surround mixer */
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8667 /* LFE mixer */
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8671 /* HP mixer */
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8675 /* Front Pin (0x0c) */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 /* LFE Pin (0x0e) */
8680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8683 /* HP Pin (0x0f) */
8684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8687 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8688 /* Line In pin */
8689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8691
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8696 { }
8697};
8698
76e6f5a9 8699
a9111321 8700static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8701 /*Internal and HP Speaker Mixer*/
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8705 /*Internal Speaker Pin (0x0c)*/
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* HP Pin: output 0 (0x0e) */
8710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8713 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8714 /* Line in (is hp when jack connected)*/
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8717
8718 { }
8719 };
8720
8721
87350ad0 8722/* Macbook Pro rev3 */
a9111321 8723static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8724 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8728 /* Rear mixer */
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8732 /* HP mixer */
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8736 /* Front Pin: output 0 (0x0c) */
8737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8740 /* HP Pin: output 0 (0x0e) */
87350ad0 8741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8745 /* Mic (rear) pin: input vref at 80% */
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8748 /* Front Mic pin: input vref at 80% */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8751 /* Line In pin: use output 1 when in LineOut mode */
8752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8755
8756 /* FIXME: use matrix-type input source selection */
8757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8763 /* Input mixer2 */
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8768 /* Input mixer3 */
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8773 /* ADC1: mute amp left and right */
8774 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8775 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8776 /* ADC2: mute amp left and right */
8777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* ADC3: mute amp left and right */
8780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8781 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8782
8783 { }
8784};
8785
4b7e1803 8786/* iMac 9,1 */
a9111321 8787static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8788 /* Internal Speaker Pin (0x0c) */
8789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8795 /* HP Pin: Rear */
4b7e1803
JM
8796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8800 /* Line in Rear */
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8803 /* Front Mic pin: input vref at 80% */
8804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8806 /* Rear mixer */
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8814 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8819 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8823 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8824 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8829 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8832 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8835 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8837 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8838 { }
8839};
8840
c54728d8 8841/* iMac 24 mixer. */
a9111321 8842static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8843 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8845 { } /* end */
8846};
8847
8848/* iMac 24 init verbs. */
a9111321 8849static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Internal speakers: output 0 (0x0c) */
8855 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8856 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 /* Headphone: output 0 (0x0c) */
8859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8861 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8863 /* Front Mic: input vref at 80% */
8864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8866 { }
8867};
8868
8869/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8870static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8871{
a9fd4f3f 8872 struct alc_spec *spec = codec->spec;
c54728d8 8873
a9fd4f3f
TI
8874 spec->autocfg.hp_pins[0] = 0x14;
8875 spec->autocfg.speaker_pins[0] = 0x18;
8876 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8877 spec->automute = 1;
8878 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8879}
8880
9d54f08b
TI
8881#define alc885_mb5_setup alc885_imac24_setup
8882#define alc885_macmini3_setup alc885_imac24_setup
8883
76e6f5a9
RH
8884/* Macbook Air 2,1 */
8885static void alc885_mba21_setup(struct hda_codec *codec)
8886{
8887 struct alc_spec *spec = codec->spec;
8888
8889 spec->autocfg.hp_pins[0] = 0x14;
8890 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8891 spec->automute = 1;
8892 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8893}
8894
8895
8896
4f5d1706 8897static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8898{
a9fd4f3f 8899 struct alc_spec *spec = codec->spec;
87350ad0 8900
a9fd4f3f
TI
8901 spec->autocfg.hp_pins[0] = 0x15;
8902 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8903 spec->automute = 1;
8904 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8905}
8906
9d54f08b 8907static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8908{
9d54f08b 8909 struct alc_spec *spec = codec->spec;
4b7e1803 8910
9d54f08b 8911 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8912 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8913 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8914 spec->automute = 1;
8915 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8916}
87350ad0 8917
a9111321 8918static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8921
8922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8924
272a527c
KY
8925 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8928
8929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8930 { } /* end */
8931};
8932
8933/* toggle speaker-output according to the hp-jack state */
8934static void alc882_targa_automute(struct hda_codec *codec)
8935{
a9fd4f3f 8936 struct alc_spec *spec = codec->spec;
d922b51d 8937 alc_hp_automute(codec);
82beb8fd 8938 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8939 spec->jack_present ? 1 : 3);
8940}
8941
4f5d1706 8942static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8943{
8944 struct alc_spec *spec = codec->spec;
8945
8946 spec->autocfg.hp_pins[0] = 0x14;
8947 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8948 spec->automute = 1;
8949 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8950}
8951
8952static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8953{
a9fd4f3f 8954 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8955 alc882_targa_automute(codec);
272a527c
KY
8956}
8957
a9111321 8958static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8961
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8965
272a527c
KY
8966 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8969
8970 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8973 { } /* end */
8974};
8975
a9111321 8976static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8979
8980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8983
914759b7
TI
8984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8987
8988 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8989 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8990 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8991 { } /* end */
8992};
8993
9102cd1c
TD
8994static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8995{
8996 unsigned int gpiostate, gpiomask, gpiodir;
8997
8998 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8999 AC_VERB_GET_GPIO_DATA, 0);
9000
9001 if (!muted)
9002 gpiostate |= (1 << pin);
9003 else
9004 gpiostate &= ~(1 << pin);
9005
9006 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_MASK, 0);
9008 gpiomask |= (1 << pin);
9009
9010 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9011 AC_VERB_GET_GPIO_DIRECTION, 0);
9012 gpiodir |= (1 << pin);
9013
9014
9015 snd_hda_codec_write(codec, codec->afg, 0,
9016 AC_VERB_SET_GPIO_MASK, gpiomask);
9017 snd_hda_codec_write(codec, codec->afg, 0,
9018 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9019
9020 msleep(1);
9021
9022 snd_hda_codec_write(codec, codec->afg, 0,
9023 AC_VERB_SET_GPIO_DATA, gpiostate);
9024}
9025
7debbe51
TI
9026/* set up GPIO at initialization */
9027static void alc885_macpro_init_hook(struct hda_codec *codec)
9028{
9029 alc882_gpio_mute(codec, 0, 0);
9030 alc882_gpio_mute(codec, 1, 0);
9031}
9032
9033/* set up GPIO and update auto-muting at initialization */
9034static void alc885_imac24_init_hook(struct hda_codec *codec)
9035{
9036 alc885_macpro_init_hook(codec);
d922b51d 9037 alc_hp_automute(codec);
7debbe51
TI
9038}
9039
eb4c41d3 9040/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9041static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9042 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9043 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9044 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9045 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9046 { } /* end */
9047};
9048
9049/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9050static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9051 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9052 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9053 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9054 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9055 { } /* end */
9056};
9057
9058/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9059static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9060 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9061 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9062 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9063 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9064 { } /* end */
9065};
9066
9067/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9068static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9069 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9070 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9071 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9072 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9073 { } /* end */
9074};
9075
a9111321 9076static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9077 { 2, alc889A_mb31_ch2_init },
9078 { 4, alc889A_mb31_ch4_init },
9079 { 5, alc889A_mb31_ch5_init },
9080 { 6, alc889A_mb31_ch6_init },
9081};
9082
a9111321 9083static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9084 /* eanable EAPD on medion laptop */
9085 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9086 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9087 { }
9088};
9089
4953550a 9090#define alc883_base_mixer alc882_base_mixer
834be88d 9091
a9111321 9092static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9093 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9094 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9095 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9097 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9098 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9101 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9104 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9105 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9106 { } /* end */
9107};
9108
a9111321 9109static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9110 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9111 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9113 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9117 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9118 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9119 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9120 { } /* end */
9121};
9122
a9111321 9123static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9124 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9125 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9126 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9127 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9131 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9132 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9133 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9134 { } /* end */
9135};
9136
a9111321 9137static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9138 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9141 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9142 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9144 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9148 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9149 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9151 { } /* end */
9152};
df694daa 9153
a9111321 9154static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9158 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9159 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9161 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9162 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9163 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9164 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9165 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9166 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9167 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9173 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9174 { } /* end */
9175};
9176
a9111321 9177static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9178 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9179 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9180 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9182 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9183 HDA_OUTPUT),
9184 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9185 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9186 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9187 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9188 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9189 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9191 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9192 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9194 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9195 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9197 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9198 { } /* end */
9199};
9200
a9111321 9201static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9202 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9204 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9205 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9206 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9207 HDA_OUTPUT),
9208 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9209 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9210 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9212 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9214 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9215 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9216 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9217 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9219 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9220 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9222 { } /* end */
9223};
9224
a9111321 9225static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9227 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9228 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9229 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9230 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9231 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9232 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9233 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9234 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9235 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9236 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9238 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9239 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9240 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9241 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9243 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9244 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9245 { } /* end */
9246};
9247
a9111321 9248static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9249 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9250 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9251 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9253 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9254 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9255 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9256 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9257 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9258 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9259 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9260 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9262 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9263 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9264 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9265 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9266 { } /* end */
f12ab1e0 9267};
ccc656ce 9268
a9111321 9269static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9270 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9271 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9272 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9273 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9274 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9275 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9277 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9278 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9279 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9280 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9281 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9282 { } /* end */
f12ab1e0 9283};
ccc656ce 9284
a9111321 9285static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9286 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9287 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9288 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9290 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9291 { } /* end */
9292};
9293
a9111321 9294static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9295 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9296 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9297 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9298 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9299 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9303 { } /* end */
f12ab1e0 9304};
bc9f98a9 9305
a9111321 9306static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9307 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9308 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9312 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9313 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9314 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9315 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9316 { } /* end */
ea1fb29a 9317};
272a527c 9318
a9111321 9319static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9320 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9321 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9324 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9325 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9326 { } /* end */
9327};
9328
a9111321 9329static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9330 /* Unmute front mixer */
9331 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9332 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9333
9334 /* Set speaker pin to front mixer */
9335 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9336
9337 /* Init headphone pin */
9338 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9339 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9340 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9341 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9342
9343 { } /* end */
9344};
9345
9346/* toggle speaker-output according to the hp-jack state */
9347static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9348{
9349 struct alc_spec *spec = codec->spec;
9350
9351 spec->autocfg.hp_pins[0] = 0x1a;
9352 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9353 spec->automute = 1;
9354 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9355}
9356
a9111321 9357static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9360 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9361 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9362 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9363 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9364 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9365 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9366 { } /* end */
d1a991a6 9367};
2880a867 9368
a9111321 9369static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9370 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9371 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9372 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9373 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9374 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9375 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9377 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9379 { } /* end */
9380};
9381
a9111321 9382static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9383 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9384 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9385 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9386 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9387 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9388 0x0d, 1, 0x0, HDA_OUTPUT),
9389 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9390 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9391 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9393 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9394 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9395 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9396 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9397 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9398 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9399 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9400 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9401 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9402 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9403 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9404 { } /* end */
9405};
9406
a9111321 9407static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9408 /* Output mixers */
9409 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9410 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9411 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9412 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9413 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9414 HDA_OUTPUT),
9415 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9416 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9417 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9418 /* Output switches */
9419 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9420 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9421 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9422 /* Boost mixers */
5f99f86a
DH
9423 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9425 /* Input mixers */
9426 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9427 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9428 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9429 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9430 { } /* end */
9431};
9432
a9111321 9433static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9434 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9435 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9436 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9437 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9438 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9440 { } /* end */
9441};
9442
a9111321 9443static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9444 .ops = &snd_hda_bind_vol,
9445 .values = {
9446 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9447 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9448 0
9449 },
9450};
9451
a9111321 9452static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9453 .ops = &snd_hda_bind_sw,
9454 .values = {
9455 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9456 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9457 0
9458 },
9459};
9460
a9111321 9461static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9462 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9463 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9464 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9465 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9466 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9468 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9470 { } /* end */
9471};
df694daa 9472
a9111321 9473static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9474 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9475 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9476 {
9477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9478 /* .name = "Capture Source", */
9479 .name = "Input Source",
9480 .count = 1,
9481 .info = alc_mux_enum_info,
9482 .get = alc_mux_enum_get,
9483 .put = alc_mux_enum_put,
9484 },
9485 { } /* end */
9486};
9c7f852e 9487
a9111321 9488static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9489 {
9490 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9491 .name = "Channel Mode",
9492 .info = alc_ch_mode_info,
9493 .get = alc_ch_mode_get,
9494 .put = alc_ch_mode_put,
9495 },
9496 { } /* end */
9c7f852e
TI
9497};
9498
a8848bd6 9499/* toggle speaker-output according to the hp-jack state */
4f5d1706 9500static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9501{
a9fd4f3f 9502 struct alc_spec *spec = codec->spec;
a8848bd6 9503
a9fd4f3f
TI
9504 spec->autocfg.hp_pins[0] = 0x15;
9505 spec->autocfg.speaker_pins[0] = 0x14;
9506 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9507 spec->automute = 1;
9508 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9509}
9510
a9111321 9511static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9512 /* HP */
9513 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9514 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9515 /* Subwoofer */
9516 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9517 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9518
9519 /* enable unsolicited event */
9520 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9521 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9522
9523 { } /* end */
9524};
9525
a9111321 9526static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9527 /* HP */
9528 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9529 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9530 /* Int speaker */
9531 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9532
9533 /* enable unsolicited event */
9534 /*
9535 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9536 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9537 */
9538
9539 { } /* end */
9540};
9541
a9111321 9542static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9543 /* HP */
9544 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9546 /* Int speaker */
9547 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9548 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9549
9550 /* enable unsolicited event */
9551 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9552 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9553
9554 { } /* end */
9555};
9556
a9111321 9557static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9558 /* HP */
9559 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9560 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9561 /* Subwoofer */
9562 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9563 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9564
9565 /* enable unsolicited event */
9566 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9567
9568 { } /* end */
9569};
9570
a9111321 9571static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9574
9575 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9576 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9577
64a8be74
DH
9578/* Connect Line-Out side jack (SPDIF) to Side */
9579 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9580 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9581 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9582/* Connect Mic jack to CLFE */
9583 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9586/* Connect Line-in jack to Surround */
9587 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9589 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9590/* Connect HP out jack to Front */
9591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9592 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9593 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9594
9595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9596
9597 { } /* end */
9598};
9599
a9111321 9600static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9601 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9602 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9603 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9604 { } /* end */
9605};
9606
a9111321 9607static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9608 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9609 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9610 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9612 { } /* end */
9613};
9614
a9111321 9615static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9617 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9618 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9619 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9620 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9621 { } /* end */
9622};
9623
a9111321 9624static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9625 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9626 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9627
9628 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9629
9630 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9631 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9632 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9634 { } /* end */
9635};
9636
a9111321 9637static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9638 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9639 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9640 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9641 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9642 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9643 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9644 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9645 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9646 { } /* end */
9647};
9648
a9111321 9649static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9650 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9651 { }
9652};
9653
a9111321 9654static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9655 /* HP */
9656 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9657 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9658
9659 /* enable unsolicited event */
9660 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9661
9662 { } /* end */
9663};
9664
4f5d1706 9665static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9666{
a9fd4f3f 9667 struct alc_spec *spec = codec->spec;
8718b700 9668
a9fd4f3f
TI
9669 spec->autocfg.hp_pins[0] = 0x1b;
9670 spec->autocfg.speaker_pins[0] = 0x14;
9671 spec->autocfg.speaker_pins[1] = 0x16;
9672 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9673 spec->automute = 1;
9674 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9675}
9676
a9111321 9677static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9678 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9679 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9680 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9681 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9682 { } /* end */
5795b9e6
CM
9683};
9684
3ea0d7cf
HRK
9685/*
9686 * 2ch mode
9687 */
a9111321 9688static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9689 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9690 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9691 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9692 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9693 { } /* end */
8341de60
CM
9694};
9695
3ea0d7cf
HRK
9696/*
9697 * 4ch mode
9698 */
a9111321 9699static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9700 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9701 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9702 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9703 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9704 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9705 { } /* end */
9706};
9707
9708/*
9709 * 6ch mode
9710 */
a9111321 9711static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9712 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9713 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9714 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9715 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9716 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9717 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9718 { } /* end */
8341de60
CM
9719};
9720
a9111321 9721static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9722 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9723 { 4, alc888_3st_hp_4ch_init },
4723c022 9724 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9725};
9726
e6a5e1b7 9727static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9728{
e6a5e1b7 9729 struct alc_spec *spec = codec->spec;
47fd830a 9730
e6a5e1b7
TI
9731 spec->autocfg.hp_pins[0] = 0x1b;
9732 spec->autocfg.line_out_pins[0] = 0x14;
9733 spec->autocfg.speaker_pins[0] = 0x15;
9734 spec->automute = 1;
9735 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9736}
9737
272a527c 9738/* toggle speaker-output according to the hp-jack state */
dc427170 9739static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9740{
a9fd4f3f 9741 struct alc_spec *spec = codec->spec;
272a527c 9742
a9fd4f3f
TI
9743 spec->autocfg.hp_pins[0] = 0x14;
9744 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9745 spec->automute = 1;
9746 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9747}
9748
ccc656ce 9749/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9750#define alc883_targa_init_hook alc882_targa_init_hook
9751#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9752
4f5d1706 9753static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9754{
a9fd4f3f
TI
9755 struct alc_spec *spec = codec->spec;
9756
9757 spec->autocfg.hp_pins[0] = 0x15;
9758 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9759 spec->automute = 1;
9760 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9761}
9762
9763static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9764{
d922b51d 9765 alc_hp_automute(codec);
eeb43387 9766 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9767}
9768
9769static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9770 unsigned int res)
9771{
0c4cc443 9772 switch (res >> 26) {
0c4cc443 9773 case ALC880_MIC_EVENT:
eeb43387 9774 alc88x_simple_mic_automute(codec);
0c4cc443 9775 break;
a9fd4f3f 9776 default:
d922b51d 9777 alc_sku_unsol_event(codec, res);
a9fd4f3f 9778 break;
0c4cc443 9779 }
368c7a95
J
9780}
9781
fb97dc67 9782/* toggle speaker-output according to the hp-jack state */
4f5d1706 9783static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9784{
a9fd4f3f 9785 struct alc_spec *spec = codec->spec;
fb97dc67 9786
a9fd4f3f
TI
9787 spec->autocfg.hp_pins[0] = 0x14;
9788 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9789 spec->automute = 1;
9790 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9791}
9792
4f5d1706 9793static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9794{
a9fd4f3f 9795 struct alc_spec *spec = codec->spec;
189609ae 9796
a9fd4f3f
TI
9797 spec->autocfg.hp_pins[0] = 0x1b;
9798 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9799 spec->automute = 1;
9800 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9801}
9802
e6a5e1b7 9803static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9804{
e6a5e1b7 9805 struct alc_spec *spec = codec->spec;
bc9f98a9 9806
e6a5e1b7
TI
9807 spec->autocfg.hp_pins[0] = 0x1b;
9808 spec->autocfg.line_out_pins[0] = 0x14;
9809 spec->autocfg.speaker_pins[0] = 0x15;
9810 spec->automute = 1;
9811 spec->detect_line = 1;
9812 spec->automute_lines = 1;
9813 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9814}
9815
676a9b53 9816/* toggle speaker-output according to the hp-jack state */
4f5d1706 9817static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9818{
a9fd4f3f 9819 struct alc_spec *spec = codec->spec;
676a9b53 9820
a9fd4f3f
TI
9821 spec->autocfg.hp_pins[0] = 0x14;
9822 spec->autocfg.speaker_pins[0] = 0x15;
9823 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9824 spec->automute = 1;
9825 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9826}
9827
a9111321 9828static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9829 /* HP Pin: output 0 (0x0c) */
9830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9833 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9834 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9835 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9836 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9837 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9838 /* eanable EAPD on medion laptop */
9839 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9840 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9841 /* enable unsolicited event */
9842 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9843 { }
9844};
9845
4f5d1706 9846static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9847{
a9fd4f3f 9848 struct alc_spec *spec = codec->spec;
5795b9e6 9849
a9fd4f3f
TI
9850 spec->autocfg.hp_pins[0] = 0x1b;
9851 spec->autocfg.speaker_pins[0] = 0x14;
9852 spec->autocfg.speaker_pins[1] = 0x15;
9853 spec->autocfg.speaker_pins[2] = 0x16;
9854 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9855 spec->automute = 1;
9856 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9857}
9858
4f5d1706 9859static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9860{
a9fd4f3f 9861 struct alc_spec *spec = codec->spec;
e2757d5e 9862
a9fd4f3f
TI
9863 spec->autocfg.hp_pins[0] = 0x1b;
9864 spec->autocfg.speaker_pins[0] = 0x14;
9865 spec->autocfg.speaker_pins[1] = 0x15;
9866 spec->autocfg.speaker_pins[2] = 0x16;
9867 spec->autocfg.speaker_pins[3] = 0x17;
9868 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9869 spec->automute = 1;
9870 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9871}
9872
4f5d1706 9873static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9874{
9875 struct alc_spec *spec = codec->spec;
9876
9877 spec->autocfg.hp_pins[0] = 0x15;
9878 spec->autocfg.speaker_pins[0] = 0x14;
9879 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9880 spec->automute = 1;
9881 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9882}
9883
a9111321 9884static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9885 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9886 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9887 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9888 /* enable unsolicited event */
9889 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9890 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9891 { } /* end */
9892};
9893
4f5d1706 9894static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9895{
a9fd4f3f 9896 struct alc_spec *spec = codec->spec;
e2757d5e 9897
a9fd4f3f
TI
9898 spec->autocfg.hp_pins[0] = 0x1b;
9899 spec->autocfg.speaker_pins[0] = 0x14;
9900 spec->autocfg.speaker_pins[1] = 0x15;
9901 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9902 spec->ext_mic.pin = 0x18;
9903 spec->int_mic.pin = 0x19;
9904 spec->ext_mic.mux_idx = 0;
9905 spec->int_mic.mux_idx = 1;
9906 spec->auto_mic = 1;
d922b51d
TI
9907 spec->automute = 1;
9908 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9909}
9910
a9111321 9911static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9912 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9913 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9915 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9916 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9917 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9918 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9919 /* enable unsolicited event */
9920 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9921 { } /* end */
9922};
9923
e2757d5e
KY
9924static void alc883_eee1601_inithook(struct hda_codec *codec)
9925{
a9fd4f3f
TI
9926 struct alc_spec *spec = codec->spec;
9927
9928 spec->autocfg.hp_pins[0] = 0x14;
9929 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9930 alc_hp_automute(codec);
e2757d5e
KY
9931}
9932
a9111321 9933static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9934 /* Init rear pin (used as headphone output) */
9935 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9936 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9937 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9938 /* Init line pin (used as output in 4ch and 6ch mode) */
9939 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9940 /* Init line 2 pin (used as headphone out by default) */
9941 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9942 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9943 { } /* end */
9944};
9945
9946/* Mute speakers according to the headphone jack state */
9947static void alc889A_mb31_automute(struct hda_codec *codec)
9948{
9949 unsigned int present;
9950
9951 /* Mute only in 2ch or 4ch mode */
9952 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9953 == 0x00) {
864f92be 9954 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9955 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9956 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9957 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9958 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9959 }
9960}
9961
9962static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9963{
9964 if ((res >> 26) == ALC880_HP_EVENT)
9965 alc889A_mb31_automute(codec);
9966}
9967
4953550a 9968
cb53c626 9969#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9970#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9971#endif
9972
def319f9 9973/* pcm configuration: identical with ALC880 */
4953550a
TI
9974#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9975#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9976#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9977#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9978
4c6d72d1 9979static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9980 ALC1200_DIGOUT_NID, 0,
9981};
9982
4c6d72d1 9983static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9984 ALC883_DIGOUT_NID, 0,
9985};
9c7f852e
TI
9986
9987/*
9988 * configuration and preset
9989 */
ea734963 9990static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9991 [ALC882_3ST_DIG] = "3stack-dig",
9992 [ALC882_6ST_DIG] = "6stack-dig",
9993 [ALC882_ARIMA] = "arima",
9994 [ALC882_W2JC] = "w2jc",
9995 [ALC882_TARGA] = "targa",
9996 [ALC882_ASUS_A7J] = "asus-a7j",
9997 [ALC882_ASUS_A7M] = "asus-a7m",
9998 [ALC885_MACPRO] = "macpro",
9999 [ALC885_MB5] = "mb5",
e458b1fa 10000 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 10001 [ALC885_MBA21] = "mba21",
4953550a
TI
10002 [ALC885_MBP3] = "mbp3",
10003 [ALC885_IMAC24] = "imac24",
4b7e1803 10004 [ALC885_IMAC91] = "imac91",
4953550a 10005 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10006 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10007 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10008 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10009 [ALC883_TARGA_DIG] = "targa-dig",
10010 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10011 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10012 [ALC883_ACER] = "acer",
2880a867 10013 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10014 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10015 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10016 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10017 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10018 [ALC883_MEDION] = "medion",
7ad7b218 10019 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10020 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10021 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10022 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10023 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10024 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10025 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10026 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10027 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10028 [ALC883_MITAC] = "mitac",
a65cc60f 10029 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10030 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10031 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10032 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10033 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10034 [ALC889A_INTEL] = "intel-alc889a",
10035 [ALC889_INTEL] = "intel-x58",
3ab90935 10036 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10037 [ALC889A_MB31] = "mb31",
3e1647c5 10038 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10039 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10040};
10041
a9111321 10042static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10043 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10044
ac3e3741 10045 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10046 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10047 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10048 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10049 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10050 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10051 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10052 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10053 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10054 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10055 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10056 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10057 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10058 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10059 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10060 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10061 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10062 ALC888_ACER_ASPIRE_6530G),
cc374c47 10063 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10064 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10065 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10066 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10067 /* default Acer -- disabled as it causes more problems.
10068 * model=auto should work fine now
10069 */
10070 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10071
5795b9e6 10072 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10073
25985edc 10074 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10075 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10076 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10077 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10078 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10079 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10080
10081 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10082 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10083 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10084 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10085 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10086 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10087 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10088 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10089 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10090 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10091 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10092
10093 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10094 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10095 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10096 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10097 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10098 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10099 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10100 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10101 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10102
6f3bf657 10103 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10104 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10105 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10106 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10107 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10108 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10109 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10110 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10111 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10112 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10113 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10114 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10115 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10116 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10117 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10118 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10119 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10120 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10121 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10122 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10123 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10124 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10125 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10126 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10127 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10128 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10129 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10130 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10131 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10132 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10133 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10134
ac3e3741 10135 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10136 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10137 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10138 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10139 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10140 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10141 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10142 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10143 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10144 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10145 ALC883_FUJITSU_PI2515),
bfb53037 10146 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10147 ALC888_FUJITSU_XA3530),
272a527c 10148 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10149 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10150 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10151 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10152 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10153 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10154 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10155 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10156
17bba1b7
J
10157 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10158 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10159 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10160 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10161 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10162 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10163 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10164
4953550a 10165 {}
f3cd3f5d
WF
10166};
10167
4953550a 10168/* codec SSID table for Intel Mac */
a9111321 10169static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10170 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10171 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10172 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10173 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10174 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10175 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10176 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10177 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10178 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10179 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10180 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10181 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10182 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10183 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10184 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10185 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10186 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10187 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10188 * so apparently no perfect solution yet
4953550a
TI
10189 */
10190 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10191 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10192 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10193 {} /* terminator */
b25c9da1
WF
10194};
10195
a9111321 10196static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10197 [ALC882_3ST_DIG] = {
10198 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10199 .init_verbs = { alc882_base_init_verbs,
10200 alc882_adc1_init_verbs },
4953550a
TI
10201 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10202 .dac_nids = alc882_dac_nids,
10203 .dig_out_nid = ALC882_DIGOUT_NID,
10204 .dig_in_nid = ALC882_DIGIN_NID,
10205 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10206 .channel_mode = alc882_ch_modes,
10207 .need_dac_fix = 1,
10208 .input_mux = &alc882_capture_source,
10209 },
10210 [ALC882_6ST_DIG] = {
10211 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10212 .init_verbs = { alc882_base_init_verbs,
10213 alc882_adc1_init_verbs },
4953550a
TI
10214 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10215 .dac_nids = alc882_dac_nids,
10216 .dig_out_nid = ALC882_DIGOUT_NID,
10217 .dig_in_nid = ALC882_DIGIN_NID,
10218 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10219 .channel_mode = alc882_sixstack_modes,
10220 .input_mux = &alc882_capture_source,
10221 },
10222 [ALC882_ARIMA] = {
10223 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10224 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10225 alc882_eapd_verbs },
4953550a
TI
10226 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10227 .dac_nids = alc882_dac_nids,
10228 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10229 .channel_mode = alc882_sixstack_modes,
10230 .input_mux = &alc882_capture_source,
10231 },
10232 [ALC882_W2JC] = {
10233 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10234 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10235 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10236 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10237 .dac_nids = alc882_dac_nids,
10238 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10239 .channel_mode = alc880_threestack_modes,
10240 .need_dac_fix = 1,
10241 .input_mux = &alc882_capture_source,
10242 .dig_out_nid = ALC882_DIGOUT_NID,
10243 },
76e6f5a9
RH
10244 [ALC885_MBA21] = {
10245 .mixers = { alc885_mba21_mixer },
10246 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10247 .num_dacs = 2,
10248 .dac_nids = alc882_dac_nids,
10249 .channel_mode = alc885_mba21_ch_modes,
10250 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10251 .input_mux = &alc882_capture_source,
d922b51d 10252 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10253 .setup = alc885_mba21_setup,
d922b51d 10254 .init_hook = alc_hp_automute,
76e6f5a9 10255 },
4953550a
TI
10256 [ALC885_MBP3] = {
10257 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10258 .init_verbs = { alc885_mbp3_init_verbs,
10259 alc880_gpio1_init_verbs },
be0ae923 10260 .num_dacs = 2,
4953550a 10261 .dac_nids = alc882_dac_nids,
be0ae923
TI
10262 .hp_nid = 0x04,
10263 .channel_mode = alc885_mbp_4ch_modes,
10264 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10265 .input_mux = &alc882_capture_source,
10266 .dig_out_nid = ALC882_DIGOUT_NID,
10267 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10268 .unsol_event = alc_sku_unsol_event,
4f5d1706 10269 .setup = alc885_mbp3_setup,
d922b51d 10270 .init_hook = alc_hp_automute,
4953550a
TI
10271 },
10272 [ALC885_MB5] = {
10273 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10274 .init_verbs = { alc885_mb5_init_verbs,
10275 alc880_gpio1_init_verbs },
10276 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10277 .dac_nids = alc882_dac_nids,
10278 .channel_mode = alc885_mb5_6ch_modes,
10279 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10280 .input_mux = &mb5_capture_source,
10281 .dig_out_nid = ALC882_DIGOUT_NID,
10282 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10283 .unsol_event = alc_sku_unsol_event,
9d54f08b 10284 .setup = alc885_mb5_setup,
d922b51d 10285 .init_hook = alc_hp_automute,
4953550a 10286 },
e458b1fa
LY
10287 [ALC885_MACMINI3] = {
10288 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10289 .init_verbs = { alc885_macmini3_init_verbs,
10290 alc880_gpio1_init_verbs },
10291 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10292 .dac_nids = alc882_dac_nids,
10293 .channel_mode = alc885_macmini3_6ch_modes,
10294 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10295 .input_mux = &macmini3_capture_source,
10296 .dig_out_nid = ALC882_DIGOUT_NID,
10297 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10298 .unsol_event = alc_sku_unsol_event,
9d54f08b 10299 .setup = alc885_macmini3_setup,
d922b51d 10300 .init_hook = alc_hp_automute,
e458b1fa 10301 },
4953550a
TI
10302 [ALC885_MACPRO] = {
10303 .mixers = { alc882_macpro_mixer },
10304 .init_verbs = { alc882_macpro_init_verbs },
10305 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10306 .dac_nids = alc882_dac_nids,
10307 .dig_out_nid = ALC882_DIGOUT_NID,
10308 .dig_in_nid = ALC882_DIGIN_NID,
10309 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10310 .channel_mode = alc882_ch_modes,
10311 .input_mux = &alc882_capture_source,
10312 .init_hook = alc885_macpro_init_hook,
10313 },
10314 [ALC885_IMAC24] = {
10315 .mixers = { alc885_imac24_mixer },
10316 .init_verbs = { alc885_imac24_init_verbs },
10317 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10318 .dac_nids = alc882_dac_nids,
10319 .dig_out_nid = ALC882_DIGOUT_NID,
10320 .dig_in_nid = ALC882_DIGIN_NID,
10321 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10322 .channel_mode = alc882_ch_modes,
10323 .input_mux = &alc882_capture_source,
d922b51d 10324 .unsol_event = alc_sku_unsol_event,
4f5d1706 10325 .setup = alc885_imac24_setup,
4953550a
TI
10326 .init_hook = alc885_imac24_init_hook,
10327 },
4b7e1803 10328 [ALC885_IMAC91] = {
b7cccc52 10329 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10330 .init_verbs = { alc885_imac91_init_verbs,
10331 alc880_gpio1_init_verbs },
10332 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10333 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10334 .channel_mode = alc885_mba21_ch_modes,
10335 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10336 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10337 .dig_out_nid = ALC882_DIGOUT_NID,
10338 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10339 .unsol_event = alc_sku_unsol_event,
9d54f08b 10340 .setup = alc885_imac91_setup,
d922b51d 10341 .init_hook = alc_hp_automute,
4b7e1803 10342 },
4953550a
TI
10343 [ALC882_TARGA] = {
10344 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10345 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10346 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10347 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10348 .dac_nids = alc882_dac_nids,
10349 .dig_out_nid = ALC882_DIGOUT_NID,
10350 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10351 .adc_nids = alc882_adc_nids,
10352 .capsrc_nids = alc882_capsrc_nids,
10353 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10354 .channel_mode = alc882_3ST_6ch_modes,
10355 .need_dac_fix = 1,
10356 .input_mux = &alc882_capture_source,
d922b51d 10357 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10358 .setup = alc882_targa_setup,
10359 .init_hook = alc882_targa_automute,
4953550a
TI
10360 },
10361 [ALC882_ASUS_A7J] = {
10362 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10363 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10364 alc882_asus_a7j_verbs},
4953550a
TI
10365 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10366 .dac_nids = alc882_dac_nids,
10367 .dig_out_nid = ALC882_DIGOUT_NID,
10368 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10369 .adc_nids = alc882_adc_nids,
10370 .capsrc_nids = alc882_capsrc_nids,
10371 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10372 .channel_mode = alc882_3ST_6ch_modes,
10373 .need_dac_fix = 1,
10374 .input_mux = &alc882_capture_source,
10375 },
10376 [ALC882_ASUS_A7M] = {
10377 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10378 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10379 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10380 alc882_asus_a7m_verbs },
10381 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10382 .dac_nids = alc882_dac_nids,
10383 .dig_out_nid = ALC882_DIGOUT_NID,
10384 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10385 .channel_mode = alc880_threestack_modes,
10386 .need_dac_fix = 1,
10387 .input_mux = &alc882_capture_source,
10388 },
9c7f852e
TI
10389 [ALC883_3ST_2ch_DIG] = {
10390 .mixers = { alc883_3ST_2ch_mixer },
10391 .init_verbs = { alc883_init_verbs },
10392 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10393 .dac_nids = alc883_dac_nids,
10394 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10395 .dig_in_nid = ALC883_DIGIN_NID,
10396 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10397 .channel_mode = alc883_3ST_2ch_modes,
10398 .input_mux = &alc883_capture_source,
10399 },
10400 [ALC883_3ST_6ch_DIG] = {
10401 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10402 .init_verbs = { alc883_init_verbs },
10403 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10404 .dac_nids = alc883_dac_nids,
10405 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10406 .dig_in_nid = ALC883_DIGIN_NID,
10407 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10408 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10409 .need_dac_fix = 1,
9c7f852e 10410 .input_mux = &alc883_capture_source,
f12ab1e0 10411 },
9c7f852e
TI
10412 [ALC883_3ST_6ch] = {
10413 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10414 .init_verbs = { alc883_init_verbs },
10415 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10416 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10417 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10418 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10419 .need_dac_fix = 1,
9c7f852e 10420 .input_mux = &alc883_capture_source,
f12ab1e0 10421 },
17bba1b7
J
10422 [ALC883_3ST_6ch_INTEL] = {
10423 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10424 .init_verbs = { alc883_init_verbs },
10425 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10426 .dac_nids = alc883_dac_nids,
10427 .dig_out_nid = ALC883_DIGOUT_NID,
10428 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10429 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10430 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10431 .channel_mode = alc883_3ST_6ch_intel_modes,
10432 .need_dac_fix = 1,
10433 .input_mux = &alc883_3stack_6ch_intel,
10434 },
87a8c370
JK
10435 [ALC889A_INTEL] = {
10436 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10437 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10438 alc_hp15_unsol_verbs },
87a8c370
JK
10439 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10440 .dac_nids = alc883_dac_nids,
10441 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10442 .adc_nids = alc889_adc_nids,
10443 .dig_out_nid = ALC883_DIGOUT_NID,
10444 .dig_in_nid = ALC883_DIGIN_NID,
10445 .slave_dig_outs = alc883_slave_dig_outs,
10446 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10447 .channel_mode = alc889_8ch_intel_modes,
10448 .capsrc_nids = alc889_capsrc_nids,
10449 .input_mux = &alc889_capture_source,
4f5d1706 10450 .setup = alc889_automute_setup,
d922b51d
TI
10451 .init_hook = alc_hp_automute,
10452 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10453 .need_dac_fix = 1,
10454 },
10455 [ALC889_INTEL] = {
10456 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10457 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10458 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10459 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10460 .dac_nids = alc883_dac_nids,
10461 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10462 .adc_nids = alc889_adc_nids,
10463 .dig_out_nid = ALC883_DIGOUT_NID,
10464 .dig_in_nid = ALC883_DIGIN_NID,
10465 .slave_dig_outs = alc883_slave_dig_outs,
10466 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10467 .channel_mode = alc889_8ch_intel_modes,
10468 .capsrc_nids = alc889_capsrc_nids,
10469 .input_mux = &alc889_capture_source,
4f5d1706 10470 .setup = alc889_automute_setup,
6732bd0d 10471 .init_hook = alc889_intel_init_hook,
d922b51d 10472 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10473 .need_dac_fix = 1,
10474 },
9c7f852e
TI
10475 [ALC883_6ST_DIG] = {
10476 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10477 .init_verbs = { alc883_init_verbs },
10478 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10479 .dac_nids = alc883_dac_nids,
10480 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10481 .dig_in_nid = ALC883_DIGIN_NID,
10482 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10483 .channel_mode = alc883_sixstack_modes,
10484 .input_mux = &alc883_capture_source,
10485 },
ccc656ce 10486 [ALC883_TARGA_DIG] = {
c259249f 10487 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10488 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10489 alc883_targa_verbs},
ccc656ce
KY
10490 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10491 .dac_nids = alc883_dac_nids,
10492 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10493 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10494 .channel_mode = alc883_3ST_6ch_modes,
10495 .need_dac_fix = 1,
10496 .input_mux = &alc883_capture_source,
c259249f 10497 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10498 .setup = alc882_targa_setup,
10499 .init_hook = alc882_targa_automute,
ccc656ce
KY
10500 },
10501 [ALC883_TARGA_2ch_DIG] = {
c259249f 10502 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10503 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10504 alc883_targa_verbs},
ccc656ce
KY
10505 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10506 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10507 .adc_nids = alc883_adc_nids_alt,
10508 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10509 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10510 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10511 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10512 .channel_mode = alc883_3ST_2ch_modes,
10513 .input_mux = &alc883_capture_source,
c259249f 10514 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10515 .setup = alc882_targa_setup,
10516 .init_hook = alc882_targa_automute,
ccc656ce 10517 },
64a8be74 10518 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10519 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10520 alc883_chmode_mixer },
64a8be74 10521 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10522 alc883_targa_verbs },
64a8be74
DH
10523 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10524 .dac_nids = alc883_dac_nids,
10525 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10526 .adc_nids = alc883_adc_nids_rev,
10527 .capsrc_nids = alc883_capsrc_nids_rev,
10528 .dig_out_nid = ALC883_DIGOUT_NID,
10529 .dig_in_nid = ALC883_DIGIN_NID,
10530 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10531 .channel_mode = alc883_4ST_8ch_modes,
10532 .need_dac_fix = 1,
10533 .input_mux = &alc883_capture_source,
c259249f 10534 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10535 .setup = alc882_targa_setup,
10536 .init_hook = alc882_targa_automute,
64a8be74 10537 },
bab282b9 10538 [ALC883_ACER] = {
676a9b53 10539 .mixers = { alc883_base_mixer },
bab282b9
VA
10540 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10541 * and the headphone jack. Turn this on and rely on the
10542 * standard mute methods whenever the user wants to turn
10543 * these outputs off.
10544 */
10545 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10546 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10547 .dac_nids = alc883_dac_nids,
bab282b9
VA
10548 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10549 .channel_mode = alc883_3ST_2ch_modes,
10550 .input_mux = &alc883_capture_source,
10551 },
2880a867 10552 [ALC883_ACER_ASPIRE] = {
676a9b53 10553 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10554 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10555 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10556 .dac_nids = alc883_dac_nids,
10557 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10558 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10559 .channel_mode = alc883_3ST_2ch_modes,
10560 .input_mux = &alc883_capture_source,
d922b51d 10561 .unsol_event = alc_sku_unsol_event,
4f5d1706 10562 .setup = alc883_acer_aspire_setup,
d922b51d 10563 .init_hook = alc_hp_automute,
d1a991a6 10564 },
5b2d1eca 10565 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10566 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10567 alc883_chmode_mixer },
10568 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10569 alc888_acer_aspire_4930g_verbs },
10570 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10571 .dac_nids = alc883_dac_nids,
10572 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10573 .adc_nids = alc883_adc_nids_rev,
10574 .capsrc_nids = alc883_capsrc_nids_rev,
10575 .dig_out_nid = ALC883_DIGOUT_NID,
10576 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10577 .channel_mode = alc883_3ST_6ch_modes,
10578 .need_dac_fix = 1,
973b8cb0 10579 .const_channel_count = 6,
5b2d1eca 10580 .num_mux_defs =
ef8ef5fb
VP
10581 ARRAY_SIZE(alc888_2_capture_sources),
10582 .input_mux = alc888_2_capture_sources,
d922b51d 10583 .unsol_event = alc_sku_unsol_event,
4f5d1706 10584 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10585 .init_hook = alc_hp_automute,
d2fd4b09
TV
10586 },
10587 [ALC888_ACER_ASPIRE_6530G] = {
10588 .mixers = { alc888_acer_aspire_6530_mixer },
10589 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10590 alc888_acer_aspire_6530g_verbs },
10591 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10592 .dac_nids = alc883_dac_nids,
10593 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10594 .adc_nids = alc883_adc_nids_rev,
10595 .capsrc_nids = alc883_capsrc_nids_rev,
10596 .dig_out_nid = ALC883_DIGOUT_NID,
10597 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10598 .channel_mode = alc883_3ST_2ch_modes,
10599 .num_mux_defs =
10600 ARRAY_SIZE(alc888_2_capture_sources),
10601 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10602 .unsol_event = alc_sku_unsol_event,
4f5d1706 10603 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10604 .init_hook = alc_hp_automute,
5b2d1eca 10605 },
3b315d70 10606 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10607 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10608 alc883_chmode_mixer },
10609 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10610 alc889_acer_aspire_8930g_verbs,
10611 alc889_eapd_verbs},
3b315d70
HM
10612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10613 .dac_nids = alc883_dac_nids,
018df418
HM
10614 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10615 .adc_nids = alc889_adc_nids,
10616 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10619 .channel_mode = alc883_3ST_6ch_modes,
10620 .need_dac_fix = 1,
10621 .const_channel_count = 6,
10622 .num_mux_defs =
018df418
HM
10623 ARRAY_SIZE(alc889_capture_sources),
10624 .input_mux = alc889_capture_sources,
d922b51d 10625 .unsol_event = alc_sku_unsol_event,
4f5d1706 10626 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10627 .init_hook = alc_hp_automute,
f5de24b0 10628#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10629 .power_hook = alc_power_eapd,
f5de24b0 10630#endif
3b315d70 10631 },
fc86f954
DK
10632 [ALC888_ACER_ASPIRE_7730G] = {
10633 .mixers = { alc883_3ST_6ch_mixer,
10634 alc883_chmode_mixer },
10635 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10636 alc888_acer_aspire_7730G_verbs },
10637 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10638 .dac_nids = alc883_dac_nids,
10639 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10640 .adc_nids = alc883_adc_nids_rev,
10641 .capsrc_nids = alc883_capsrc_nids_rev,
10642 .dig_out_nid = ALC883_DIGOUT_NID,
10643 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10644 .channel_mode = alc883_3ST_6ch_modes,
10645 .need_dac_fix = 1,
10646 .const_channel_count = 6,
10647 .input_mux = &alc883_capture_source,
d922b51d 10648 .unsol_event = alc_sku_unsol_event,
d9477207 10649 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10650 .init_hook = alc_hp_automute,
fc86f954 10651 },
c07584c8
TD
10652 [ALC883_MEDION] = {
10653 .mixers = { alc883_fivestack_mixer,
10654 alc883_chmode_mixer },
10655 .init_verbs = { alc883_init_verbs,
b373bdeb 10656 alc883_medion_eapd_verbs },
c07584c8
TD
10657 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10658 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10659 .adc_nids = alc883_adc_nids_alt,
10660 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10661 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10662 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10663 .channel_mode = alc883_sixstack_modes,
10664 .input_mux = &alc883_capture_source,
b373bdeb 10665 },
7ad7b218
MC
10666 [ALC883_MEDION_WIM2160] = {
10667 .mixers = { alc883_medion_wim2160_mixer },
10668 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10669 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10670 .dac_nids = alc883_dac_nids,
10671 .dig_out_nid = ALC883_DIGOUT_NID,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10673 .adc_nids = alc883_adc_nids,
10674 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10675 .channel_mode = alc883_3ST_2ch_modes,
10676 .input_mux = &alc883_capture_source,
d922b51d 10677 .unsol_event = alc_sku_unsol_event,
7ad7b218 10678 .setup = alc883_medion_wim2160_setup,
d922b51d 10679 .init_hook = alc_hp_automute,
7ad7b218 10680 },
b373bdeb 10681 [ALC883_LAPTOP_EAPD] = {
676a9b53 10682 .mixers = { alc883_base_mixer },
b373bdeb
AN
10683 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10684 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10685 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10686 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10687 .channel_mode = alc883_3ST_2ch_modes,
10688 .input_mux = &alc883_capture_source,
10689 },
a65cc60f 10690 [ALC883_CLEVO_M540R] = {
10691 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10692 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10693 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10694 .dac_nids = alc883_dac_nids,
10695 .dig_out_nid = ALC883_DIGOUT_NID,
10696 .dig_in_nid = ALC883_DIGIN_NID,
10697 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10698 .channel_mode = alc883_3ST_6ch_clevo_modes,
10699 .need_dac_fix = 1,
10700 .input_mux = &alc883_capture_source,
10701 /* This machine has the hardware HP auto-muting, thus
10702 * we need no software mute via unsol event
10703 */
10704 },
0c4cc443
HRK
10705 [ALC883_CLEVO_M720] = {
10706 .mixers = { alc883_clevo_m720_mixer },
10707 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10708 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10709 .dac_nids = alc883_dac_nids,
10710 .dig_out_nid = ALC883_DIGOUT_NID,
10711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10712 .channel_mode = alc883_3ST_2ch_modes,
10713 .input_mux = &alc883_capture_source,
0c4cc443 10714 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10715 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10716 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10717 },
bc9f98a9
KY
10718 [ALC883_LENOVO_101E_2ch] = {
10719 .mixers = { alc883_lenovo_101e_2ch_mixer},
10720 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10721 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10722 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10723 .adc_nids = alc883_adc_nids_alt,
10724 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10725 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10726 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10727 .channel_mode = alc883_3ST_2ch_modes,
10728 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10729 .setup = alc883_lenovo_101e_setup,
10730 .unsol_event = alc_sku_unsol_event,
10731 .init_hook = alc_inithook,
bc9f98a9 10732 },
272a527c
KY
10733 [ALC883_LENOVO_NB0763] = {
10734 .mixers = { alc883_lenovo_nb0763_mixer },
10735 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10736 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10737 .dac_nids = alc883_dac_nids,
272a527c
KY
10738 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10739 .channel_mode = alc883_3ST_2ch_modes,
10740 .need_dac_fix = 1,
10741 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10742 .unsol_event = alc_sku_unsol_event,
dc427170 10743 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10744 .init_hook = alc_hp_automute,
272a527c
KY
10745 },
10746 [ALC888_LENOVO_MS7195_DIG] = {
10747 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10748 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .dac_nids = alc883_dac_nids,
10751 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10752 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10753 .channel_mode = alc883_3ST_6ch_modes,
10754 .need_dac_fix = 1,
10755 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10756 .unsol_event = alc_sku_unsol_event,
10757 .setup = alc888_lenovo_ms7195_setup,
10758 .init_hook = alc_inithook,
189609ae
KY
10759 },
10760 [ALC883_HAIER_W66] = {
c259249f 10761 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10762 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
10765 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10766 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10767 .channel_mode = alc883_3ST_2ch_modes,
10768 .input_mux = &alc883_capture_source,
d922b51d 10769 .unsol_event = alc_sku_unsol_event,
4f5d1706 10770 .setup = alc883_haier_w66_setup,
d922b51d 10771 .init_hook = alc_hp_automute,
eea6419e 10772 },
4723c022 10773 [ALC888_3ST_HP] = {
eea6419e 10774 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10775 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10776 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10777 .dac_nids = alc883_dac_nids,
4723c022
CM
10778 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10779 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10780 .need_dac_fix = 1,
10781 .input_mux = &alc883_capture_source,
d922b51d 10782 .unsol_event = alc_sku_unsol_event,
4f5d1706 10783 .setup = alc888_3st_hp_setup,
d922b51d 10784 .init_hook = alc_hp_automute,
8341de60 10785 },
5795b9e6 10786 [ALC888_6ST_DELL] = {
f24dbdc6 10787 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10788 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10789 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10790 .dac_nids = alc883_dac_nids,
10791 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10792 .dig_in_nid = ALC883_DIGIN_NID,
10793 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10794 .channel_mode = alc883_sixstack_modes,
10795 .input_mux = &alc883_capture_source,
d922b51d 10796 .unsol_event = alc_sku_unsol_event,
4f5d1706 10797 .setup = alc888_6st_dell_setup,
d922b51d 10798 .init_hook = alc_hp_automute,
5795b9e6 10799 },
a8848bd6
AS
10800 [ALC883_MITAC] = {
10801 .mixers = { alc883_mitac_mixer },
10802 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10803 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10804 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10805 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10806 .channel_mode = alc883_3ST_2ch_modes,
10807 .input_mux = &alc883_capture_source,
d922b51d 10808 .unsol_event = alc_sku_unsol_event,
4f5d1706 10809 .setup = alc883_mitac_setup,
d922b51d 10810 .init_hook = alc_hp_automute,
a8848bd6 10811 },
fb97dc67
J
10812 [ALC883_FUJITSU_PI2515] = {
10813 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10814 .init_verbs = { alc883_init_verbs,
10815 alc883_2ch_fujitsu_pi2515_verbs},
10816 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10817 .dac_nids = alc883_dac_nids,
10818 .dig_out_nid = ALC883_DIGOUT_NID,
10819 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10820 .channel_mode = alc883_3ST_2ch_modes,
10821 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10822 .unsol_event = alc_sku_unsol_event,
4f5d1706 10823 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10824 .init_hook = alc_hp_automute,
fb97dc67 10825 },
ef8ef5fb
VP
10826 [ALC888_FUJITSU_XA3530] = {
10827 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10828 .init_verbs = { alc883_init_verbs,
10829 alc888_fujitsu_xa3530_verbs },
10830 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10831 .dac_nids = alc883_dac_nids,
10832 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10833 .adc_nids = alc883_adc_nids_rev,
10834 .capsrc_nids = alc883_capsrc_nids_rev,
10835 .dig_out_nid = ALC883_DIGOUT_NID,
10836 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10837 .channel_mode = alc888_4ST_8ch_intel_modes,
10838 .num_mux_defs =
10839 ARRAY_SIZE(alc888_2_capture_sources),
10840 .input_mux = alc888_2_capture_sources,
d922b51d 10841 .unsol_event = alc_sku_unsol_event,
4f5d1706 10842 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10843 .init_hook = alc_hp_automute,
ef8ef5fb 10844 },
e2757d5e
KY
10845 [ALC888_LENOVO_SKY] = {
10846 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10847 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10848 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10849 .dac_nids = alc883_dac_nids,
10850 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10851 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10852 .channel_mode = alc883_sixstack_modes,
10853 .need_dac_fix = 1,
10854 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10855 .unsol_event = alc_sku_unsol_event,
4f5d1706 10856 .setup = alc888_lenovo_sky_setup,
d922b51d 10857 .init_hook = alc_hp_automute,
e2757d5e
KY
10858 },
10859 [ALC888_ASUS_M90V] = {
10860 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10861 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10862 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10863 .dac_nids = alc883_dac_nids,
10864 .dig_out_nid = ALC883_DIGOUT_NID,
10865 .dig_in_nid = ALC883_DIGIN_NID,
10866 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10867 .channel_mode = alc883_3ST_6ch_modes,
10868 .need_dac_fix = 1,
10869 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10870 .unsol_event = alc_sku_unsol_event,
10871 .setup = alc883_mode2_setup,
10872 .init_hook = alc_inithook,
e2757d5e
KY
10873 },
10874 [ALC888_ASUS_EEE1601] = {
10875 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10876 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10877 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10878 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10879 .dac_nids = alc883_dac_nids,
10880 .dig_out_nid = ALC883_DIGOUT_NID,
10881 .dig_in_nid = ALC883_DIGIN_NID,
10882 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10883 .channel_mode = alc883_3ST_2ch_modes,
10884 .need_dac_fix = 1,
10885 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10886 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10887 .init_hook = alc883_eee1601_inithook,
10888 },
3ab90935
WF
10889 [ALC1200_ASUS_P5Q] = {
10890 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10891 .init_verbs = { alc883_init_verbs },
10892 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10893 .dac_nids = alc883_dac_nids,
10894 .dig_out_nid = ALC1200_DIGOUT_NID,
10895 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10896 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10897 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10898 .channel_mode = alc883_sixstack_modes,
10899 .input_mux = &alc883_capture_source,
10900 },
eb4c41d3
TS
10901 [ALC889A_MB31] = {
10902 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10903 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10904 alc880_gpio1_init_verbs },
10905 .adc_nids = alc883_adc_nids,
10906 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10907 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10908 .dac_nids = alc883_dac_nids,
10909 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10910 .channel_mode = alc889A_mb31_6ch_modes,
10911 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10912 .input_mux = &alc889A_mb31_capture_source,
10913 .dig_out_nid = ALC883_DIGOUT_NID,
10914 .unsol_event = alc889A_mb31_unsol_event,
10915 .init_hook = alc889A_mb31_automute,
10916 },
3e1647c5
GG
10917 [ALC883_SONY_VAIO_TT] = {
10918 .mixers = { alc883_vaiott_mixer },
10919 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10921 .dac_nids = alc883_dac_nids,
10922 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10923 .channel_mode = alc883_3ST_2ch_modes,
10924 .input_mux = &alc883_capture_source,
d922b51d 10925 .unsol_event = alc_sku_unsol_event,
4f5d1706 10926 .setup = alc883_vaiott_setup,
d922b51d 10927 .init_hook = alc_hp_automute,
3e1647c5 10928 },
9c7f852e
TI
10929};
10930
10931
4953550a
TI
10932/*
10933 * Pin config fixes
10934 */
10935enum {
954a29c8 10936 PINFIX_ABIT_AW9D_MAX,
32eea388 10937 PINFIX_LENOVO_Y530,
954a29c8 10938 PINFIX_PB_M5210,
c3d226ab 10939 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10940};
10941
f8f25ba3
TI
10942static const struct alc_fixup alc882_fixups[] = {
10943 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10944 .type = ALC_FIXUP_PINS,
10945 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10946 { 0x15, 0x01080104 }, /* side */
10947 { 0x16, 0x01011012 }, /* rear */
10948 { 0x17, 0x01016011 }, /* clfe */
10949 { }
10950 }
f8f25ba3 10951 },
32eea388
DH
10952 [PINFIX_LENOVO_Y530] = {
10953 .type = ALC_FIXUP_PINS,
10954 .v.pins = (const struct alc_pincfg[]) {
10955 { 0x15, 0x99130112 }, /* rear int speakers */
10956 { 0x16, 0x99130111 }, /* subwoofer */
10957 { }
10958 }
10959 },
954a29c8 10960 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10961 .type = ALC_FIXUP_VERBS,
10962 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10963 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10964 {}
10965 }
954a29c8 10966 },
c3d226ab 10967 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10968 .type = ALC_FIXUP_SKU,
10969 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10970 },
4953550a
TI
10971};
10972
a9111321 10973static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10974 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10975 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10976 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10977 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10978 {}
10979};
10980
9c7f852e
TI
10981/*
10982 * BIOS auto configuration
10983 */
05f5f477
TI
10984static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10985 const struct auto_pin_cfg *cfg)
10986{
10987 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10988}
10989
4953550a 10990static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10991 hda_nid_t nid, int pin_type,
489008cd 10992 hda_nid_t dac)
9c7f852e 10993{
f12ab1e0
TI
10994 int idx;
10995
489008cd 10996 /* set as output */
f6c7e546 10997 alc_set_pin_output(codec, nid, pin_type);
489008cd 10998
1f0f4b80
TI
10999 if (snd_hda_get_conn_list(codec, nid, NULL) < 2)
11000 return;
11001
489008cd 11002 if (dac == 0x25)
9c7f852e 11003 idx = 4;
489008cd
TI
11004 else if (dac >= 0x02 && dac <= 0x05)
11005 idx = dac - 2;
f9700d5a 11006 else
489008cd 11007 return;
9c7f852e 11008 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11009}
11010
1f0f4b80
TI
11011#define alc882_auto_init_dac alc880_auto_init_dac
11012
4953550a 11013static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11014{
11015 struct alc_spec *spec = codec->spec;
11016 int i;
11017
11018 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11019 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11020 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11021 if (nid)
4953550a 11022 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11023 spec->multiout.dac_nids[i]);
9c7f852e 11024 }
1f0f4b80
TI
11025 /* mute DACs */
11026 for (i = 0; i < spec->multiout.num_dacs; i++)
11027 alc882_auto_init_dac(codec, spec->multiout.dac_nids[i]);
9c7f852e
TI
11028}
11029
4953550a 11030static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11031{
11032 struct alc_spec *spec = codec->spec;
489008cd 11033 hda_nid_t pin, dac;
5855fb80 11034 int i;
9c7f852e 11035
0a3fabe3
DH
11036 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11037 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11038 pin = spec->autocfg.hp_pins[i];
11039 if (!pin)
11040 break;
11041 dac = spec->multiout.hp_nid;
11042 if (!dac)
11043 dac = spec->multiout.dac_nids[0]; /* to front */
11044 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11045 }
489008cd 11046 }
0a3fabe3
DH
11047
11048 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11049 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11050 pin = spec->autocfg.speaker_pins[i];
11051 if (!pin)
11052 break;
11053 dac = spec->multiout.extra_out_nid[0];
11054 if (!dac)
11055 dac = spec->multiout.dac_nids[0]; /* to front */
11056 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11057 }
489008cd 11058 }
9c7f852e 11059
1f0f4b80
TI
11060 /* mute DACs */
11061 alc882_auto_init_dac(codec, spec->multiout.hp_nid);
11062 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
11063 alc882_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
4953550a
TI
11064}
11065
1f0f4b80
TI
11066#define alc882_auto_init_analog_input alc880_auto_init_analog_input
11067
4953550a
TI
11068static void alc882_auto_init_input_src(struct hda_codec *codec)
11069{
11070 struct alc_spec *spec = codec->spec;
11071 int c;
11072
11073 for (c = 0; c < spec->num_adc_nids; c++) {
4953550a
TI
11074 hda_nid_t nid = spec->capsrc_nids[c];
11075 unsigned int mux_idx;
11076 const struct hda_input_mux *imux;
11077 int conns, mute, idx, item;
7ec9c6cc 11078 unsigned int wid_type;
4953550a 11079
10696aa0 11080 /* mute ADC */
4f574b7b
TI
11081 if (query_amp_caps(codec, spec->adc_nids[c], HDA_INPUT) &
11082 AC_AMPCAP_MUTE)
11083 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
10696aa0
TI
11084 AC_VERB_SET_AMP_GAIN_MUTE,
11085 AMP_IN_MUTE(0));
4f574b7b
TI
11086 else if (query_amp_caps(codec, nid, HDA_OUTPUT) &
11087 AC_AMPCAP_MUTE)
11088 snd_hda_codec_write(codec, nid, 0,
11089 AC_VERB_SET_AMP_GAIN_MUTE,
11090 AMP_OUT_MUTE);
10696aa0 11091
1f0f4b80
TI
11092 conns = snd_hda_get_conn_list(codec, nid, NULL);
11093 if (conns <= 0)
4953550a
TI
11094 continue;
11095 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11096 imux = &spec->input_mux[mux_idx];
5311114d
TI
11097 if (!imux->num_items && mux_idx > 0)
11098 imux = &spec->input_mux[0];
7ec9c6cc 11099 wid_type = get_wcaps_type(get_wcaps(codec, nid));
4953550a
TI
11100 for (idx = 0; idx < conns; idx++) {
11101 /* if the current connection is the selected one,
11102 * unmute it as default - otherwise mute it
11103 */
11104 mute = AMP_IN_MUTE(idx);
11105 for (item = 0; item < imux->num_items; item++) {
11106 if (imux->items[item].index == idx) {
11107 if (spec->cur_mux[c] == item)
11108 mute = AMP_IN_UNMUTE(idx);
11109 break;
11110 }
11111 }
7ec9c6cc
TI
11112 /* initialize the mute status if mute-amp is present */
11113 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE)
9c7f852e
TI
11114 snd_hda_codec_write(codec, nid, 0,
11115 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a 11116 mute);
7ec9c6cc
TI
11117 if (wid_type == AC_WID_AUD_SEL &&
11118 mute != AMP_IN_MUTE(idx))
4953550a
TI
11119 snd_hda_codec_write(codec, nid, 0,
11120 AC_VERB_SET_CONNECT_SEL,
11121 idx);
9c7f852e
TI
11122 }
11123 }
11124}
11125
4953550a
TI
11126/* add mic boosts if needed */
11127static int alc_auto_add_mic_boost(struct hda_codec *codec)
11128{
11129 struct alc_spec *spec = codec->spec;
66ceeb6b 11130 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11131 int i, err;
53e8c323 11132 int type_idx = 0;
4953550a 11133 hda_nid_t nid;
5322bf27 11134 const char *prev_label = NULL;
4953550a 11135
66ceeb6b 11136 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11137 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11138 break;
11139 nid = cfg->inputs[i].pin;
11140 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11141 const char *label;
11142 char boost_label[32];
11143
11144 label = hda_get_autocfg_input_label(codec, cfg, i);
11145 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11146 type_idx++;
11147 else
11148 type_idx = 0;
5322bf27
DH
11149 prev_label = label;
11150
11151 snprintf(boost_label, sizeof(boost_label),
11152 "%s Boost Volume", label);
11153 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11154 boost_label, type_idx,
4953550a 11155 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11156 if (err < 0)
11157 return err;
11158 }
4953550a
TI
11159 }
11160 return 0;
11161}
f511b01c 11162
9c7f852e 11163/* almost identical with ALC880 parser... */
4953550a 11164static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11165{
11166 struct alc_spec *spec = codec->spec;
4c6d72d1 11167 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11168 int err;
9c7f852e 11169
05f5f477
TI
11170 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11171 alc882_ignore);
9c7f852e
TI
11172 if (err < 0)
11173 return err;
05f5f477
TI
11174 if (!spec->autocfg.line_outs)
11175 return 0; /* can't find valid BIOS pin config */
776e184e 11176
cb053a82 11177 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
11178 if (err < 0)
11179 return err;
cb053a82 11180 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
05f5f477
TI
11181 if (err < 0)
11182 return err;
569ed348 11183 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11184 if (err < 0)
11185 return err;
11186 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11187 "Headphone");
05f5f477
TI
11188 if (err < 0)
11189 return err;
11190 err = alc880_auto_create_extra_out(spec,
11191 spec->autocfg.speaker_pins[0],
11192 "Speaker");
11193 if (err < 0)
11194 return err;
05f5f477 11195 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11196 if (err < 0)
11197 return err;
11198
05f5f477
TI
11199 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11200
757899ac 11201 alc_auto_parse_digital(codec);
05f5f477
TI
11202
11203 if (spec->kctls.list)
11204 add_mixer(spec, spec->kctls.list);
11205
4953550a 11206 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11207 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11208 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11209
05f5f477
TI
11210 spec->num_mux_defs = 1;
11211 spec->input_mux = &spec->private_imux[0];
11212
6227cdce 11213 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11214
11215 err = alc_auto_add_mic_boost(codec);
11216 if (err < 0)
11217 return err;
61b9b9b1 11218
776e184e 11219 return 1; /* config found */
9c7f852e
TI
11220}
11221
11222/* additional initialization for auto-configuration model */
4953550a 11223static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11224{
f6c7e546 11225 struct alc_spec *spec = codec->spec;
4953550a
TI
11226 alc882_auto_init_multi_out(codec);
11227 alc882_auto_init_hp_out(codec);
11228 alc882_auto_init_analog_input(codec);
11229 alc882_auto_init_input_src(codec);
757899ac 11230 alc_auto_init_digital(codec);
f6c7e546 11231 if (spec->unsol_event)
7fb0d78f 11232 alc_inithook(codec);
9c7f852e
TI
11233}
11234
4953550a 11235static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11236{
11237 struct alc_spec *spec;
11238 int err, board_config;
11239
11240 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11241 if (spec == NULL)
11242 return -ENOMEM;
11243
11244 codec->spec = spec;
11245
1f0f4b80
TI
11246 spec->mixer_nid = 0x0b;
11247
4953550a
TI
11248 switch (codec->vendor_id) {
11249 case 0x10ec0882:
11250 case 0x10ec0885:
11251 break;
11252 default:
11253 /* ALC883 and variants */
11254 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11255 break;
11256 }
2c3bf9ab 11257
4953550a
TI
11258 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11259 alc882_models,
11260 alc882_cfg_tbl);
11261
11262 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11263 board_config = snd_hda_check_board_codec_sid_config(codec,
11264 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11265
11266 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11267 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11268 codec->chip_name);
11269 board_config = ALC882_AUTO;
9c7f852e
TI
11270 }
11271
b5bfbc67
TI
11272 if (board_config == ALC882_AUTO) {
11273 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11274 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11275 }
4953550a 11276
90622917
DH
11277 alc_auto_parse_customize_define(codec);
11278
4953550a 11279 if (board_config == ALC882_AUTO) {
9c7f852e 11280 /* automatic parse from the BIOS config */
4953550a 11281 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11282 if (err < 0) {
11283 alc_free(codec);
11284 return err;
f12ab1e0 11285 } else if (!err) {
9c7f852e
TI
11286 printk(KERN_INFO
11287 "hda_codec: Cannot set up configuration "
11288 "from BIOS. Using base mode...\n");
4953550a 11289 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11290 }
11291 }
11292
dc1eae25 11293 if (has_cdefine_beep(codec)) {
8af2591d
TI
11294 err = snd_hda_attach_beep_device(codec, 0x1);
11295 if (err < 0) {
11296 alc_free(codec);
11297 return err;
11298 }
680cd536
KK
11299 }
11300
4953550a 11301 if (board_config != ALC882_AUTO)
e9c364c0 11302 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11303
4953550a
TI
11304 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11305 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11306 /* FIXME: setup DAC5 */
11307 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11308 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11309
11310 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11311 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11312
4953550a 11313 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11314 int i, j;
4953550a
TI
11315 spec->num_adc_nids = 0;
11316 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11317 const struct hda_input_mux *imux = spec->input_mux;
4953550a
TI
11318 hda_nid_t cap;
11319 hda_nid_t nid = alc882_adc_nids[i];
11320 unsigned int wcap = get_wcaps(codec, nid);
11321 /* get type */
a22d543a 11322 wcap = get_wcaps_type(wcap);
4953550a
TI
11323 if (wcap != AC_WID_AUD_IN)
11324 continue;
11325 spec->private_adc_nids[spec->num_adc_nids] = nid;
11326 err = snd_hda_get_connections(codec, nid, &cap, 1);
11327 if (err < 0)
11328 continue;
1f0f4b80 11329 err = snd_hda_get_conn_list(codec, cap, NULL);
d11f74c6
TI
11330 if (err < 0)
11331 continue;
11332 for (j = 0; j < imux->num_items; j++)
11333 if (imux->items[j].index >= err)
11334 break;
11335 if (j < imux->num_items)
11336 continue;
4953550a
TI
11337 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11338 spec->num_adc_nids++;
61b9b9b1 11339 }
4953550a
TI
11340 spec->adc_nids = spec->private_adc_nids;
11341 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11342 }
11343
b59bdf3b 11344 set_capture_mixer(codec);
da00c244 11345
dc1eae25 11346 if (has_cdefine_beep(codec))
da00c244 11347 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11348
b5bfbc67 11349 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11350
2134ea4f
TI
11351 spec->vmaster_nid = 0x0c;
11352
9c7f852e 11353 codec->patch_ops = alc_patch_ops;
4953550a
TI
11354 if (board_config == ALC882_AUTO)
11355 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11356
11357 alc_init_jacks(codec);
cb53c626
TI
11358#ifdef CONFIG_SND_HDA_POWER_SAVE
11359 if (!spec->loopback.amplist)
4953550a 11360 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11361#endif
9c7f852e
TI
11362
11363 return 0;
11364}
11365
4953550a 11366
9c7f852e
TI
11367/*
11368 * ALC262 support
11369 */
11370
11371#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11372#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11373
11374#define alc262_dac_nids alc260_dac_nids
11375#define alc262_adc_nids alc882_adc_nids
11376#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11377#define alc262_capsrc_nids alc882_capsrc_nids
11378#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11379
11380#define alc262_modes alc260_modes
11381#define alc262_capture_source alc882_capture_source
11382
4c6d72d1 11383static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11384 /* ADC0 */
11385 0x09
11386};
11387
4c6d72d1 11388static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11389
a9111321 11390static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11391 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11392 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11393 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11394 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11395 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11396 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11399 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11400 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11401 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11402 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11403 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11404 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11405 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11406 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11407 { } /* end */
11408};
11409
ce875f07 11410/* update HP, line and mono-out pins according to the master switch */
e9427969 11411#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11412
e9427969 11413static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11414{
11415 struct alc_spec *spec = codec->spec;
864f92be 11416
e9427969
TI
11417 spec->autocfg.hp_pins[0] = 0x1b;
11418 spec->autocfg.speaker_pins[0] = 0x16;
11419 spec->automute = 1;
11420 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11421}
11422
e9427969 11423static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11424{
11425 struct alc_spec *spec = codec->spec;
864f92be 11426
e9427969
TI
11427 spec->autocfg.hp_pins[0] = 0x15;
11428 spec->autocfg.speaker_pins[0] = 0x16;
11429 spec->automute = 1;
11430 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11431}
11432
b72519b5 11433#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11434#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11435
b72519b5
TI
11436#define ALC262_HP_MASTER_SWITCH \
11437 { \
11438 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11439 .name = "Master Playback Switch", \
11440 .info = snd_ctl_boolean_mono_info, \
11441 .get = alc262_hp_master_sw_get, \
11442 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11443 }, \
11444 { \
11445 .iface = NID_MAPPING, \
11446 .name = "Master Playback Switch", \
11447 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11448 }
11449
5b0cb1d8 11450
a9111321 11451static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11452 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11453 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11454 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11455 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11456 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11457 HDA_OUTPUT),
11458 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11459 HDA_OUTPUT),
9c7f852e
TI
11460 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11461 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11462 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11463 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11464 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11465 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11466 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11468 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11469 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11470 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11471 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11472 { } /* end */
11473};
11474
a9111321 11475static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11476 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11477 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11478 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11479 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11480 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11481 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11482 HDA_OUTPUT),
11483 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11484 HDA_OUTPUT),
cd7509a4
KY
11485 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11486 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11487 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11488 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11489 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11490 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11491 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11492 { } /* end */
11493};
11494
a9111321 11495static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11496 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11497 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11498 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11499 { } /* end */
11500};
11501
66d2a9d6 11502/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11503static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11504{
11505 struct alc_spec *spec = codec->spec;
66d2a9d6 11506
a9fd4f3f 11507 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11508 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11509 spec->automute = 1;
11510 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11511}
11512
a9111321 11513static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11514 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11515 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11516 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 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),
5f99f86a 11520 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11521 { } /* end */
11522};
11523
a9111321 11524static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11525 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11526 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11527
11528 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11529 { }
11530};
11531
a9111321 11532static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11534 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11535 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11536 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11537 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11538 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11539 { } /* end */
11540};
11541
a9111321 11542static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11543 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11544 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11545 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11546 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11547 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11548 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11549 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11550 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11551 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11553 {}
11554};
11555
a9111321 11556static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11557 .num_items = 1,
11558 .items = {
11559 { "Line", 0x1 },
11560 },
11561};
11562
42171c17 11563/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11564#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11565#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11566#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11567
11568#define ALC262_HIPPO_MASTER_SWITCH \
11569 { \
11570 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11571 .name = "Master Playback Switch", \
11572 .info = snd_ctl_boolean_mono_info, \
11573 .get = alc262_hippo_master_sw_get, \
11574 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11575 }, \
11576 { \
11577 .iface = NID_MAPPING, \
11578 .name = "Master Playback Switch", \
11579 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11580 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11581 }
42171c17 11582
a9111321 11583static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11584 ALC262_HIPPO_MASTER_SWITCH,
11585 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11586 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11587 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11588 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11589 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11590 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11591 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11592 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11593 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11594 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11595 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11596 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11597 { } /* end */
11598};
11599
a9111321 11600static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11601 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11602 ALC262_HIPPO_MASTER_SWITCH,
11603 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11604 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11605 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11606 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11607 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11608 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11609 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11610 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11611 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11612 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11613 { } /* end */
11614};
11615
11616/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11617static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11618{
11619 struct alc_spec *spec = codec->spec;
11620
11621 spec->autocfg.hp_pins[0] = 0x15;
11622 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11623 spec->automute = 1;
11624 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11625}
11626
4f5d1706 11627static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11628{
11629 struct alc_spec *spec = codec->spec;
11630
11631 spec->autocfg.hp_pins[0] = 0x1b;
11632 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11633 spec->automute = 1;
11634 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11635}
11636
11637
a9111321 11638static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11639 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11640 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11641 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11642 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11643 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11644 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11645 { } /* end */
11646};
11647
a9111321 11648static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11649 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11650 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11651 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11652 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11653 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11654 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11655 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11656 { } /* end */
11657};
272a527c 11658
a9111321 11659static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11660 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11661 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11662 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11663 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11664 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11665 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11666 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11667 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11668 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11669 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11670 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11671 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11672 { } /* end */
11673};
11674
a9111321 11675static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11676 /* Headphone automute */
11677 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11678 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11679 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11680
11681 /* P11 AUX_IN, white 4-pin connector */
11682 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11683 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11684 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11685 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11686
11687 {}
11688};
11689
11690/* unsolicited event for HP jack sensing */
4f5d1706 11691static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11692{
a9fd4f3f 11693 struct alc_spec *spec = codec->spec;
ba340e82 11694
a9fd4f3f
TI
11695 spec->autocfg.hp_pins[0] = 0x1b;
11696 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11697 spec->automute = 1;
11698 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11699}
11700
ba340e82 11701
9c7f852e
TI
11702#define alc262_capture_mixer alc882_capture_mixer
11703#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11704
11705/*
11706 * generic initialization of ADC, input mixers and output mixers
11707 */
a9111321 11708static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11709 /*
11710 * Unmute ADC0-2 and set the default input to mic-in
11711 */
11712 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11713 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11714 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11715 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11716 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11717 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11718
cb53c626 11719 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11720 * mixer widget
f12ab1e0
TI
11721 * Note: PASD motherboards uses the Line In 2 as the input for
11722 * front panel mic (mic 2)
9c7f852e
TI
11723 */
11724 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11726 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11727 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11728 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11729 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11730
11731 /*
df694daa
KY
11732 * Set up output mixers (0x0c - 0x0e)
11733 */
11734 /* set vol=0 to output mixers */
11735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11737 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11738 /* set up input amps for analog loopback */
11739 /* Amp Indices: DAC = 0, mixer = 1 */
11740 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11741 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11742 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11743 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11744 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11745 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11746
11747 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11748 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11750 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11751 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11752 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11753
11754 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11755 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11756 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11757 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11758 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11759
df694daa
KY
11760 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11761 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11762
df694daa
KY
11763 /* FIXME: use matrix-type input source selection */
11764 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11765 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11766 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11767 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11768 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11770 /* Input mixer2 */
11771 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11773 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11775 /* Input mixer3 */
11776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11778 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11780
11781 { }
11782};
1da177e4 11783
a9111321 11784static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11785 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11786 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11787 { }
11788};
11789
a9111321 11790static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11792 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11793 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11794
11795 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11796 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11797 {}
11798};
11799
a9111321 11800static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11801 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11803 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11804
11805 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11806 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11807 {}
272a527c
KY
11808};
11809
a9111321 11810static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11811 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11812 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11813 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11814 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11815 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11816 { } /* end */
11817};
11818
a9111321 11819static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11820 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11821 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11823 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11824 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11825 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11826 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11827 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11828 {}
11829};
11830
4f5d1706 11831static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11832{
a9fd4f3f
TI
11833 struct alc_spec *spec = codec->spec;
11834
11835 spec->autocfg.hp_pins[0] = 0x15;
11836 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11837 spec->ext_mic.pin = 0x18;
11838 spec->ext_mic.mux_idx = 0;
11839 spec->int_mic.pin = 0x12;
11840 spec->int_mic.mux_idx = 9;
11841 spec->auto_mic = 1;
d922b51d
TI
11842 spec->automute = 1;
11843 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11844}
11845
e8f9ae2a
PT
11846/*
11847 * nec model
11848 * 0x15 = headphone
11849 * 0x16 = internal speaker
11850 * 0x18 = external mic
11851 */
11852
a9111321 11853static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11854 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11855 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11856
11857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11859 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11860
11861 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11862 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11863 { } /* end */
11864};
11865
a9111321 11866static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11867 /* Unmute Speaker */
11868 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11869
11870 /* Headphone */
11871 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11872 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11873
11874 /* External mic to headphone */
11875 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11876 /* External mic to speaker */
11877 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11878 {}
11879};
11880
834be88d
TI
11881/*
11882 * fujitsu model
5d9fab2d
TV
11883 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11884 * 0x1b = port replicator headphone out
834be88d
TI
11885 */
11886
20f5e0b3 11887#define ALC_HP_EVENT ALC880_HP_EVENT
834be88d 11888
a9111321 11889static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11890 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11892 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11893 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11894 {}
11895};
11896
a9111321 11897static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11898 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11899 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11900 {}
11901};
11902
a9111321 11903static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11904 /* Front Mic pin: input vref at 50% */
11905 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11906 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11907 {}
11908};
11909
a9111321 11910static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11911 .num_items = 3,
834be88d
TI
11912 .items = {
11913 { "Mic", 0x0 },
28c4edb7 11914 { "Internal Mic", 0x1 },
834be88d
TI
11915 { "CD", 0x4 },
11916 },
11917};
11918
a9111321 11919static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11920 .num_items = 5,
11921 .items = {
11922 { "Mic", 0x0 },
accbe498 11923 { "Front Mic", 0x1 },
9c7f852e
TI
11924 { "Line", 0x2 },
11925 { "CD", 0x4 },
11926 { "AUX IN", 0x6 },
11927 },
11928};
11929
a9111321 11930static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11931 .num_items = 4,
11932 .items = {
11933 { "Mic", 0x0 },
11934 { "Front Mic", 0x2 },
11935 { "Line", 0x1 },
11936 { "CD", 0x4 },
11937 },
11938};
11939
0f0f391c 11940static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11941{
11942 struct alc_spec *spec = codec->spec;
834be88d 11943
0f0f391c
TI
11944 spec->autocfg.hp_pins[0] = 0x14;
11945 spec->autocfg.hp_pins[1] = 0x1b;
11946 spec->autocfg.speaker_pins[0] = 0x15;
11947 spec->automute = 1;
11948 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11949}
11950
834be88d 11951/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11952static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11953 .ops = &snd_hda_bind_vol,
11954 .values = {
11955 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11956 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11957 0
11958 },
11959};
834be88d 11960
a9111321 11961static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11962 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11963 {
11964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11965 .name = "Master Playback Switch",
0f0f391c
TI
11966 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11967 .info = snd_ctl_boolean_mono_info,
11968 .get = alc262_hp_master_sw_get,
11969 .put = alc262_hp_master_sw_put,
834be88d 11970 },
5b0cb1d8
JK
11971 {
11972 .iface = NID_MAPPING,
11973 .name = "Master Playback Switch",
11974 .private_value = 0x1b,
11975 },
834be88d
TI
11976 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11977 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11978 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11979 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11980 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11981 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11982 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11983 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11984 { } /* end */
11985};
11986
0f0f391c 11987static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11988{
0f0f391c 11989 struct alc_spec *spec = codec->spec;
0e31daf7 11990
0f0f391c
TI
11991 spec->autocfg.hp_pins[0] = 0x1b;
11992 spec->autocfg.speaker_pins[0] = 0x14;
11993 spec->autocfg.speaker_pins[1] = 0x16;
11994 spec->automute = 1;
11995 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11996}
11997
a9111321 11998static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11999 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12000 {
12001 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12002 .name = "Master Playback Switch",
0f0f391c
TI
12003 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12004 .info = snd_ctl_boolean_mono_info,
12005 .get = alc262_hp_master_sw_get,
12006 .put = alc262_hp_master_sw_put,
0e31daf7
J
12007 },
12008 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12009 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12010 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12013 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12014 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12015 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12016 { } /* end */
12017};
12018
a9111321 12019static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12020 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12021 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12022 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12023 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12024 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12025 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12026 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12027 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12028 { } /* end */
12029};
12030
304dcaac 12031/* additional init verbs for Benq laptops */
a9111321 12032static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12033 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12034 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12035 {}
12036};
12037
a9111321 12038static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12039 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12040 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12041
12042 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12043 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12044 {}
12045};
12046
f651b50b 12047/* Samsung Q1 Ultra Vista model setup */
a9111321 12048static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12049 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12050 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12052 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12053 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12054 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12055 { } /* end */
12056};
12057
a9111321 12058static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12059 /* output mixer */
12060 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12061 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12063 /* speaker */
12064 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12065 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12066 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12067 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12068 /* HP */
f651b50b 12069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12071 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12072 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12073 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12074 /* internal mic */
12075 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12076 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12077 /* ADC, choose mic */
12078 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12083 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12084 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12085 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12086 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12088 {}
12089};
12090
f651b50b
TD
12091/* mute/unmute internal speaker according to the hp jack and mute state */
12092static void alc262_ultra_automute(struct hda_codec *codec)
12093{
12094 struct alc_spec *spec = codec->spec;
12095 unsigned int mute;
f651b50b 12096
bb9f76cd
TI
12097 mute = 0;
12098 /* auto-mute only when HP is used as HP */
12099 if (!spec->cur_mux[0]) {
864f92be 12100 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12101 if (spec->jack_present)
12102 mute = HDA_AMP_MUTE;
f651b50b 12103 }
bb9f76cd
TI
12104 /* mute/unmute internal speaker */
12105 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12106 HDA_AMP_MUTE, mute);
12107 /* mute/unmute HP */
12108 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12109 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12110}
12111
12112/* unsolicited event for HP jack sensing */
12113static void alc262_ultra_unsol_event(struct hda_codec *codec,
12114 unsigned int res)
12115{
12116 if ((res >> 26) != ALC880_HP_EVENT)
12117 return;
12118 alc262_ultra_automute(codec);
12119}
12120
a9111321 12121static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12122 .num_items = 2,
12123 .items = {
12124 { "Mic", 0x1 },
12125 { "Headphone", 0x7 },
12126 },
12127};
12128
12129static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12130 struct snd_ctl_elem_value *ucontrol)
12131{
12132 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12133 struct alc_spec *spec = codec->spec;
12134 int ret;
12135
54cbc9ab 12136 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12137 if (!ret)
12138 return 0;
12139 /* reprogram the HP pin as mic or HP according to the input source */
12140 snd_hda_codec_write_cache(codec, 0x15, 0,
12141 AC_VERB_SET_PIN_WIDGET_CONTROL,
12142 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12143 alc262_ultra_automute(codec); /* mute/unmute HP */
12144 return ret;
12145}
12146
a9111321 12147static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12148 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12149 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12150 {
12151 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12152 .name = "Capture Source",
54cbc9ab
TI
12153 .info = alc_mux_enum_info,
12154 .get = alc_mux_enum_get,
bb9f76cd
TI
12155 .put = alc262_ultra_mux_enum_put,
12156 },
5b0cb1d8
JK
12157 {
12158 .iface = NID_MAPPING,
12159 .name = "Capture Source",
12160 .private_value = 0x15,
12161 },
bb9f76cd
TI
12162 { } /* end */
12163};
12164
c3fc1f50
TI
12165/* We use two mixers depending on the output pin; 0x16 is a mono output
12166 * and thus it's bound with a different mixer.
12167 * This function returns which mixer amp should be used.
12168 */
12169static int alc262_check_volbit(hda_nid_t nid)
12170{
12171 if (!nid)
12172 return 0;
12173 else if (nid == 0x16)
12174 return 2;
12175 else
12176 return 1;
12177}
12178
12179static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12180 const char *pfx, int *vbits, int idx)
c3fc1f50 12181{
c3fc1f50
TI
12182 unsigned long val;
12183 int vbit;
12184
12185 vbit = alc262_check_volbit(nid);
12186 if (!vbit)
12187 return 0;
12188 if (*vbits & vbit) /* a volume control for this mixer already there */
12189 return 0;
12190 *vbits |= vbit;
c3fc1f50
TI
12191 if (vbit == 2)
12192 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12193 else
12194 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12195 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12196}
12197
12198static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12199 const char *pfx, int idx)
c3fc1f50 12200{
c3fc1f50
TI
12201 unsigned long val;
12202
12203 if (!nid)
12204 return 0;
c3fc1f50
TI
12205 if (nid == 0x16)
12206 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12207 else
12208 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12209 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12210}
12211
df694daa 12212/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12213static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12214 const struct auto_pin_cfg *cfg)
df694daa 12215{
c3fc1f50
TI
12216 const char *pfx;
12217 int vbits;
6843ca16 12218 int i, index, err;
df694daa
KY
12219
12220 spec->multiout.num_dacs = 1; /* only use one dac */
12221 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12222 spec->private_dac_nids[0] = 2;
df694daa 12223
033688a5 12224 for (i = 0; i < 2; i++) {
6843ca16
TI
12225 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12226 if (!pfx)
12227 pfx = "PCM";
12228 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx,
12229 index);
033688a5
TI
12230 if (err < 0)
12231 return err;
12232 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12233 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12234 "Speaker", i);
12235 if (err < 0)
12236 return err;
12237 }
12238 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12239 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12240 "Headphone", i);
12241 if (err < 0)
12242 return err;
12243 }
12244 }
df694daa 12245
c3fc1f50
TI
12246 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12247 alc262_check_volbit(cfg->speaker_pins[0]) |
12248 alc262_check_volbit(cfg->hp_pins[0]);
c3fc1f50 12249 vbits = 0;
033688a5 12250 for (i = 0; i < 2; i++) {
6843ca16
TI
12251 pfx = alc_get_line_out_pfx(spec, i, true, &index);
12252 if (!pfx)
12253 pfx = "PCM";
033688a5
TI
12254 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12255 &vbits, i);
12256 if (err < 0)
12257 return err;
12258 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12259 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12260 "Speaker", &vbits, i);
12261 if (err < 0)
12262 return err;
12263 }
12264 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12265 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12266 "Headphone", &vbits, i);
12267 if (err < 0)
12268 return err;
12269 }
12270 }
f12ab1e0 12271 return 0;
df694daa
KY
12272}
12273
05f5f477 12274#define alc262_auto_create_input_ctls \
eaa9b3a7 12275 alc882_auto_create_input_ctls
df694daa 12276
a9111321 12277static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12278 /*
12279 * Unmute ADC0-2 and set the default input to mic-in
12280 */
12281 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12282 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12283 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12284 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12285 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12286 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12287
cb53c626 12288 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12289 * mixer widget
f12ab1e0
TI
12290 * Note: PASD motherboards uses the Line In 2 as the input for
12291 * front panel mic (mic 2)
9c7f852e
TI
12292 */
12293 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12294 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12295 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12296 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12297 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12298 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12299 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12300 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12301
9c7f852e
TI
12302 /*
12303 * Set up output mixers (0x0c - 0x0e)
12304 */
12305 /* set vol=0 to output mixers */
12306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12307 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12308 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12309
12310 /* set up input amps for analog loopback */
12311 /* Amp Indices: DAC = 0, mixer = 1 */
12312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12313 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12318
ce875f07 12319 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12320 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12321 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12322
12323 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12324 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12325
12326 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12328
12329 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12330 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12331 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12332 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12333 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12334
0e4835c1 12335 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12336 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12337 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12338 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12339 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12340 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12341
12342
12343 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12344 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12345 /* Input mixer1: only unmute Mic */
9c7f852e 12346 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12348 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12349 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12350 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12351 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12352 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12353 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12354 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12355 /* Input mixer2 */
12356 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12358 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12359 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12360 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12361 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12362 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12363 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12364 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12365 /* Input mixer3 */
12366 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12367 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12368 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12369 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12370 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12371 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12375
ce875f07
TI
12376 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12377
9c7f852e
TI
12378 { }
12379};
12380
a9111321 12381static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12382 /*
12383 * Unmute ADC0-2 and set the default input to mic-in
12384 */
12385 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12386 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12387 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12388 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12389 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12390 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12391
cb53c626 12392 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12393 * mixer widget
12394 * Note: PASD motherboards uses the Line In 2 as the input for front
12395 * panel mic (mic 2)
12396 */
12397 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12404 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12405 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12406 /*
12407 * Set up output mixers (0x0c - 0x0e)
12408 */
12409 /* set vol=0 to output mixers */
12410 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12412 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12413
12414 /* set up input amps for analog loopback */
12415 /* Amp Indices: DAC = 0, mixer = 1 */
12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12419 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12421 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12422
12423
12424 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12425 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12426 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12427 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12428 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12429 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12430 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12431
12432 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12433 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12434
12435 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12436 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12437
12438 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12442 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12444
12445 /* FIXME: use matrix-type input source selection */
12446 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12447 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12448 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12453 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12455 /* Input mixer2 */
12456 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12457 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12458 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12461 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12463 /* Input mixer3 */
12464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12466 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12467 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12468 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12469 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12471
ce875f07
TI
12472 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12473
cd7509a4
KY
12474 { }
12475};
12476
a9111321 12477static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12478
12479 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12480 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12481 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12482
12483 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12485 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12486 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12487
12488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12489 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12490 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12491 {}
12492};
12493
18675e42
TI
12494/*
12495 * Pin config fixes
12496 */
12497enum {
12498 PINFIX_FSC_H270,
d2a19da7 12499 PINFIX_HP_Z200,
18675e42
TI
12500};
12501
12502static const struct alc_fixup alc262_fixups[] = {
12503 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12504 .type = ALC_FIXUP_PINS,
12505 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12506 { 0x14, 0x99130110 }, /* speaker */
12507 { 0x15, 0x0221142f }, /* front HP */
12508 { 0x1b, 0x0121141f }, /* rear HP */
12509 { }
12510 }
12511 },
d2a19da7
DH
12512 [PINFIX_HP_Z200] = {
12513 .type = ALC_FIXUP_PINS,
12514 .v.pins = (const struct alc_pincfg[]) {
12515 { 0x16, 0x99130120 }, /* internal speaker */
12516 { }
12517 }
12518 },
18675e42
TI
12519};
12520
a9111321 12521static const struct snd_pci_quirk alc262_fixup_tbl[] = {
d2a19da7 12522 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
18675e42
TI
12523 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12524 {}
12525};
12526
9f99a638 12527
cb53c626
TI
12528#ifdef CONFIG_SND_HDA_POWER_SAVE
12529#define alc262_loopbacks alc880_loopbacks
12530#endif
12531
def319f9 12532/* pcm configuration: identical with ALC880 */
df694daa
KY
12533#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12534#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12535#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12536#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12537
12538/*
12539 * BIOS auto configuration
12540 */
12541static int alc262_parse_auto_config(struct hda_codec *codec)
12542{
12543 struct alc_spec *spec = codec->spec;
12544 int err;
4c6d72d1 12545 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12546
f12ab1e0
TI
12547 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12548 alc262_ignore);
12549 if (err < 0)
df694daa 12550 return err;
e64f14f4 12551 if (!spec->autocfg.line_outs) {
0852d7a6 12552 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12553 spec->multiout.max_channels = 2;
12554 spec->no_analog = 1;
12555 goto dig_only;
12556 }
df694daa 12557 return 0; /* can't find valid BIOS pin config */
e64f14f4 12558 }
f12ab1e0
TI
12559 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12560 if (err < 0)
12561 return err;
05f5f477 12562 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12563 if (err < 0)
df694daa
KY
12564 return err;
12565
12566 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12567
e64f14f4 12568 dig_only:
757899ac 12569 alc_auto_parse_digital(codec);
df694daa 12570
603c4019 12571 if (spec->kctls.list)
d88897ea 12572 add_mixer(spec, spec->kctls.list);
df694daa 12573
a1e8d2da 12574 spec->num_mux_defs = 1;
61b9b9b1 12575 spec->input_mux = &spec->private_imux[0];
df694daa 12576
776e184e
TI
12577 err = alc_auto_add_mic_boost(codec);
12578 if (err < 0)
12579 return err;
12580
6227cdce 12581 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12582
df694daa
KY
12583 return 1;
12584}
12585
12586#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12587#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12588#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12589#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12590
12591
12592/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12593static void alc262_auto_init(struct hda_codec *codec)
df694daa 12594{
f6c7e546 12595 struct alc_spec *spec = codec->spec;
df694daa
KY
12596 alc262_auto_init_multi_out(codec);
12597 alc262_auto_init_hp_out(codec);
12598 alc262_auto_init_analog_input(codec);
f511b01c 12599 alc262_auto_init_input_src(codec);
757899ac 12600 alc_auto_init_digital(codec);
f6c7e546 12601 if (spec->unsol_event)
7fb0d78f 12602 alc_inithook(codec);
df694daa
KY
12603}
12604
12605/*
12606 * configuration and preset
12607 */
ea734963 12608static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12609 [ALC262_BASIC] = "basic",
12610 [ALC262_HIPPO] = "hippo",
12611 [ALC262_HIPPO_1] = "hippo_1",
12612 [ALC262_FUJITSU] = "fujitsu",
12613 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12614 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12615 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12616 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12617 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12618 [ALC262_BENQ_T31] = "benq-t31",
12619 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12620 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12621 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12622 [ALC262_ULTRA] = "ultra",
0e31daf7 12623 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12624 [ALC262_NEC] = "nec",
ba340e82 12625 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12626 [ALC262_AUTO] = "auto",
12627};
12628
a9111321 12629static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12630 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12631 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12633 ALC262_HP_BPC),
12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12635 ALC262_HP_BPC),
5734a07c
TI
12636 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12637 ALC262_HP_BPC),
d2a19da7
DH
12638 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12639 ALC262_AUTO),
53eff7e1
TI
12640 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12641 ALC262_HP_BPC),
cd7509a4 12642 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12643 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12644 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12645 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12646 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12647 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12648 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12649 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12650 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12651 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12652 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12653 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12654 ALC262_HP_TC_T5735),
8c427226 12655 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12656 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12657 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12658 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12659 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12660 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12661 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12662 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12663#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12664 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12665 ALC262_SONY_ASSAMD),
c5b5165c 12666#endif
36ca6e13 12667 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12668 ALC262_TOSHIBA_RX1),
80ffe869 12669 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12670 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12671 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12672 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12673 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12674 ALC262_ULTRA),
3e420e78 12675 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12676 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12677 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12678 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12679 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12680 {}
12681};
12682
a9111321 12683static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12684 [ALC262_BASIC] = {
12685 .mixers = { alc262_base_mixer },
12686 .init_verbs = { alc262_init_verbs },
12687 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12688 .dac_nids = alc262_dac_nids,
12689 .hp_nid = 0x03,
12690 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12691 .channel_mode = alc262_modes,
a3bcba38 12692 .input_mux = &alc262_capture_source,
df694daa 12693 },
ccc656ce 12694 [ALC262_HIPPO] = {
42171c17 12695 .mixers = { alc262_hippo_mixer },
6732bd0d 12696 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12697 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12698 .dac_nids = alc262_dac_nids,
12699 .hp_nid = 0x03,
12700 .dig_out_nid = ALC262_DIGOUT_NID,
12701 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12702 .channel_mode = alc262_modes,
12703 .input_mux = &alc262_capture_source,
e9427969 12704 .unsol_event = alc_sku_unsol_event,
4f5d1706 12705 .setup = alc262_hippo_setup,
e9427969 12706 .init_hook = alc_inithook,
ccc656ce
KY
12707 },
12708 [ALC262_HIPPO_1] = {
12709 .mixers = { alc262_hippo1_mixer },
12710 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12711 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12712 .dac_nids = alc262_dac_nids,
12713 .hp_nid = 0x02,
12714 .dig_out_nid = ALC262_DIGOUT_NID,
12715 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12716 .channel_mode = alc262_modes,
12717 .input_mux = &alc262_capture_source,
e9427969 12718 .unsol_event = alc_sku_unsol_event,
4f5d1706 12719 .setup = alc262_hippo1_setup,
e9427969 12720 .init_hook = alc_inithook,
ccc656ce 12721 },
834be88d
TI
12722 [ALC262_FUJITSU] = {
12723 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12724 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12725 alc262_fujitsu_unsol_verbs },
834be88d
TI
12726 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12727 .dac_nids = alc262_dac_nids,
12728 .hp_nid = 0x03,
12729 .dig_out_nid = ALC262_DIGOUT_NID,
12730 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12731 .channel_mode = alc262_modes,
12732 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12733 .unsol_event = alc_sku_unsol_event,
12734 .setup = alc262_fujitsu_setup,
12735 .init_hook = alc_inithook,
834be88d 12736 },
9c7f852e
TI
12737 [ALC262_HP_BPC] = {
12738 .mixers = { alc262_HP_BPC_mixer },
12739 .init_verbs = { alc262_HP_BPC_init_verbs },
12740 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12741 .dac_nids = alc262_dac_nids,
12742 .hp_nid = 0x03,
12743 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12744 .channel_mode = alc262_modes,
12745 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12746 .unsol_event = alc_sku_unsol_event,
12747 .setup = alc262_hp_bpc_setup,
12748 .init_hook = alc_inithook,
f12ab1e0 12749 },
cd7509a4
KY
12750 [ALC262_HP_BPC_D7000_WF] = {
12751 .mixers = { alc262_HP_BPC_WildWest_mixer },
12752 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12753 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12754 .dac_nids = alc262_dac_nids,
12755 .hp_nid = 0x03,
12756 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12757 .channel_mode = alc262_modes,
accbe498 12758 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12759 .unsol_event = alc_sku_unsol_event,
12760 .setup = alc262_hp_wildwest_setup,
12761 .init_hook = alc_inithook,
f12ab1e0 12762 },
cd7509a4
KY
12763 [ALC262_HP_BPC_D7000_WL] = {
12764 .mixers = { alc262_HP_BPC_WildWest_mixer,
12765 alc262_HP_BPC_WildWest_option_mixer },
12766 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12767 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12768 .dac_nids = alc262_dac_nids,
12769 .hp_nid = 0x03,
12770 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12771 .channel_mode = alc262_modes,
accbe498 12772 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12773 .unsol_event = alc_sku_unsol_event,
12774 .setup = alc262_hp_wildwest_setup,
12775 .init_hook = alc_inithook,
f12ab1e0 12776 },
66d2a9d6
KY
12777 [ALC262_HP_TC_T5735] = {
12778 .mixers = { alc262_hp_t5735_mixer },
12779 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12780 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12781 .dac_nids = alc262_dac_nids,
12782 .hp_nid = 0x03,
12783 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784 .channel_mode = alc262_modes,
12785 .input_mux = &alc262_capture_source,
dc99be47 12786 .unsol_event = alc_sku_unsol_event,
4f5d1706 12787 .setup = alc262_hp_t5735_setup,
dc99be47 12788 .init_hook = alc_inithook,
8c427226
KY
12789 },
12790 [ALC262_HP_RP5700] = {
12791 .mixers = { alc262_hp_rp5700_mixer },
12792 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12793 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12794 .dac_nids = alc262_dac_nids,
12795 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12796 .channel_mode = alc262_modes,
12797 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12798 },
304dcaac
TI
12799 [ALC262_BENQ_ED8] = {
12800 .mixers = { alc262_base_mixer },
12801 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12802 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12803 .dac_nids = alc262_dac_nids,
12804 .hp_nid = 0x03,
12805 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12806 .channel_mode = alc262_modes,
12807 .input_mux = &alc262_capture_source,
f12ab1e0 12808 },
272a527c
KY
12809 [ALC262_SONY_ASSAMD] = {
12810 .mixers = { alc262_sony_mixer },
12811 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12812 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12813 .dac_nids = alc262_dac_nids,
12814 .hp_nid = 0x02,
12815 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12816 .channel_mode = alc262_modes,
12817 .input_mux = &alc262_capture_source,
e9427969 12818 .unsol_event = alc_sku_unsol_event,
4f5d1706 12819 .setup = alc262_hippo_setup,
e9427969 12820 .init_hook = alc_inithook,
83c34218
KY
12821 },
12822 [ALC262_BENQ_T31] = {
12823 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12824 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12825 alc_hp15_unsol_verbs },
83c34218
KY
12826 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12827 .dac_nids = alc262_dac_nids,
12828 .hp_nid = 0x03,
12829 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12830 .channel_mode = alc262_modes,
12831 .input_mux = &alc262_capture_source,
e9427969 12832 .unsol_event = alc_sku_unsol_event,
4f5d1706 12833 .setup = alc262_hippo_setup,
e9427969 12834 .init_hook = alc_inithook,
ea1fb29a 12835 },
f651b50b 12836 [ALC262_ULTRA] = {
f9e336f6
TI
12837 .mixers = { alc262_ultra_mixer },
12838 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12839 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12841 .dac_nids = alc262_dac_nids,
f651b50b
TD
12842 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12843 .channel_mode = alc262_modes,
12844 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12845 .adc_nids = alc262_adc_nids, /* ADC0 */
12846 .capsrc_nids = alc262_capsrc_nids,
12847 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12848 .unsol_event = alc262_ultra_unsol_event,
12849 .init_hook = alc262_ultra_automute,
12850 },
0e31daf7
J
12851 [ALC262_LENOVO_3000] = {
12852 .mixers = { alc262_lenovo_3000_mixer },
12853 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12854 alc262_lenovo_3000_unsol_verbs,
12855 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12856 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12857 .dac_nids = alc262_dac_nids,
12858 .hp_nid = 0x03,
12859 .dig_out_nid = ALC262_DIGOUT_NID,
12860 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12861 .channel_mode = alc262_modes,
12862 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12863 .unsol_event = alc_sku_unsol_event,
12864 .setup = alc262_lenovo_3000_setup,
12865 .init_hook = alc_inithook,
0e31daf7 12866 },
e8f9ae2a
PT
12867 [ALC262_NEC] = {
12868 .mixers = { alc262_nec_mixer },
12869 .init_verbs = { alc262_nec_verbs },
12870 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12871 .dac_nids = alc262_dac_nids,
12872 .hp_nid = 0x03,
12873 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12874 .channel_mode = alc262_modes,
12875 .input_mux = &alc262_capture_source,
12876 },
4e555fe5
KY
12877 [ALC262_TOSHIBA_S06] = {
12878 .mixers = { alc262_toshiba_s06_mixer },
12879 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12880 alc262_eapd_verbs },
12881 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12882 .capsrc_nids = alc262_dmic_capsrc_nids,
12883 .dac_nids = alc262_dac_nids,
12884 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12885 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12886 .dig_out_nid = ALC262_DIGOUT_NID,
12887 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12888 .channel_mode = alc262_modes,
4f5d1706
TI
12889 .unsol_event = alc_sku_unsol_event,
12890 .setup = alc262_toshiba_s06_setup,
12891 .init_hook = alc_inithook,
4e555fe5 12892 },
9f99a638
HM
12893 [ALC262_TOSHIBA_RX1] = {
12894 .mixers = { alc262_toshiba_rx1_mixer },
12895 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12896 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12897 .dac_nids = alc262_dac_nids,
12898 .hp_nid = 0x03,
12899 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12900 .channel_mode = alc262_modes,
12901 .input_mux = &alc262_capture_source,
e9427969 12902 .unsol_event = alc_sku_unsol_event,
4f5d1706 12903 .setup = alc262_hippo_setup,
e9427969 12904 .init_hook = alc_inithook,
9f99a638 12905 },
ba340e82
TV
12906 [ALC262_TYAN] = {
12907 .mixers = { alc262_tyan_mixer },
12908 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12909 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12910 .dac_nids = alc262_dac_nids,
12911 .hp_nid = 0x02,
12912 .dig_out_nid = ALC262_DIGOUT_NID,
12913 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12914 .channel_mode = alc262_modes,
12915 .input_mux = &alc262_capture_source,
d922b51d 12916 .unsol_event = alc_sku_unsol_event,
4f5d1706 12917 .setup = alc262_tyan_setup,
d922b51d 12918 .init_hook = alc_hp_automute,
ba340e82 12919 },
df694daa
KY
12920};
12921
12922static int patch_alc262(struct hda_codec *codec)
12923{
12924 struct alc_spec *spec;
12925 int board_config;
12926 int err;
12927
dc041e0b 12928 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12929 if (spec == NULL)
12930 return -ENOMEM;
12931
12932 codec->spec = spec;
1f0f4b80
TI
12933
12934 spec->mixer_nid = 0x0b;
12935
df694daa 12936#if 0
f12ab1e0
TI
12937 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12938 * under-run
12939 */
df694daa
KY
12940 {
12941 int tmp;
12942 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12943 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12944 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12945 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12946 }
12947#endif
da00c244 12948 alc_auto_parse_customize_define(codec);
df694daa 12949
2c3bf9ab
TI
12950 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12951
f5fcc13c
TI
12952 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12953 alc262_models,
12954 alc262_cfg_tbl);
cd7509a4 12955
f5fcc13c 12956 if (board_config < 0) {
9a11f1aa
TI
12957 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12958 codec->chip_name);
df694daa
KY
12959 board_config = ALC262_AUTO;
12960 }
12961
b5bfbc67
TI
12962 if (board_config == ALC262_AUTO) {
12963 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12964 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12965 }
18675e42 12966
df694daa
KY
12967 if (board_config == ALC262_AUTO) {
12968 /* automatic parse from the BIOS config */
12969 err = alc262_parse_auto_config(codec);
12970 if (err < 0) {
12971 alc_free(codec);
12972 return err;
f12ab1e0 12973 } else if (!err) {
9c7f852e
TI
12974 printk(KERN_INFO
12975 "hda_codec: Cannot set up configuration "
12976 "from BIOS. Using base mode...\n");
df694daa
KY
12977 board_config = ALC262_BASIC;
12978 }
12979 }
12980
dc1eae25 12981 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
12982 err = snd_hda_attach_beep_device(codec, 0x1);
12983 if (err < 0) {
12984 alc_free(codec);
12985 return err;
12986 }
680cd536
KK
12987 }
12988
df694daa 12989 if (board_config != ALC262_AUTO)
e9c364c0 12990 setup_preset(codec, &alc262_presets[board_config]);
df694daa 12991
df694daa
KY
12992 spec->stream_analog_playback = &alc262_pcm_analog_playback;
12993 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 12994
df694daa
KY
12995 spec->stream_digital_playback = &alc262_pcm_digital_playback;
12996 spec->stream_digital_capture = &alc262_pcm_digital_capture;
12997
f12ab1e0 12998 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
12999 int i;
13000 /* check whether the digital-mic has to be supported */
13001 for (i = 0; i < spec->input_mux->num_items; i++) {
13002 if (spec->input_mux->items[i].index >= 9)
13003 break;
13004 }
13005 if (i < spec->input_mux->num_items) {
13006 /* use only ADC0 */
13007 spec->adc_nids = alc262_dmic_adc_nids;
13008 spec->num_adc_nids = 1;
13009 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13010 } else {
8c927b4a
TI
13011 /* all analog inputs */
13012 /* check whether NID 0x07 is valid */
13013 unsigned int wcap = get_wcaps(codec, 0x07);
13014
13015 /* get type */
a22d543a 13016 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13017 if (wcap != AC_WID_AUD_IN) {
13018 spec->adc_nids = alc262_adc_nids_alt;
13019 spec->num_adc_nids =
13020 ARRAY_SIZE(alc262_adc_nids_alt);
13021 spec->capsrc_nids = alc262_capsrc_nids_alt;
13022 } else {
13023 spec->adc_nids = alc262_adc_nids;
13024 spec->num_adc_nids =
13025 ARRAY_SIZE(alc262_adc_nids);
13026 spec->capsrc_nids = alc262_capsrc_nids;
13027 }
df694daa
KY
13028 }
13029 }
e64f14f4 13030 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13031 set_capture_mixer(codec);
dc1eae25 13032 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13033 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13034
b5bfbc67 13035 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13036
2134ea4f
TI
13037 spec->vmaster_nid = 0x0c;
13038
df694daa
KY
13039 codec->patch_ops = alc_patch_ops;
13040 if (board_config == ALC262_AUTO)
ae6b813a 13041 spec->init_hook = alc262_auto_init;
1c716153 13042 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13043
13044 alc_init_jacks(codec);
cb53c626
TI
13045#ifdef CONFIG_SND_HDA_POWER_SAVE
13046 if (!spec->loopback.amplist)
13047 spec->loopback.amplist = alc262_loopbacks;
13048#endif
ea1fb29a 13049
df694daa
KY
13050 return 0;
13051}
13052
a361d84b
KY
13053/*
13054 * ALC268 channel source setting (2 channel)
13055 */
13056#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13057#define alc268_modes alc260_modes
ea1fb29a 13058
4c6d72d1 13059static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13060 /* front, hp */
13061 0x02, 0x03
13062};
13063
4c6d72d1 13064static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13065 /* ADC0-1 */
13066 0x08, 0x07
13067};
13068
4c6d72d1 13069static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13070 /* ADC0 */
13071 0x08
13072};
13073
4c6d72d1 13074static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13075
a9111321 13076static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13077 /* output mixer control */
13078 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13079 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13082 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13083 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13084 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13085 { }
13086};
13087
a9111321 13088static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13089 /* output mixer control */
13090 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13091 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13092 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13094 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13095 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13096 { }
13097};
13098
aef9d318 13099/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13100static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13101 .ops = &snd_hda_bind_sw,
13102 .values = {
13103 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13104 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13105 0
13106 },
13107};
13108
a9111321 13109static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13110 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13111 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13112 { }
13113};
13114
a9111321 13115static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13116 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13117 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13118 { }
13119};
13120
d273809e 13121/* Toshiba specific */
a9111321 13122static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13123 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13124 { } /* end */
13125};
13126
13127/* Acer specific */
889c4395 13128/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13129static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13130 .ops = &snd_hda_bind_vol,
13131 .values = {
13132 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13133 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13134 0
13135 },
13136};
13137
0f0f391c 13138static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13139{
13140 struct alc_spec *spec = codec->spec;
889c4395 13141
0f0f391c
TI
13142 spec->autocfg.hp_pins[0] = 0x14;
13143 spec->autocfg.speaker_pins[0] = 0x15;
13144 spec->automute = 1;
13145 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13146}
13147
0f0f391c
TI
13148#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13149#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13150
a9111321 13151static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13152 /* output mixer control */
13153 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13154 {
13155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13156 .name = "Master Playback Switch",
0f0f391c
TI
13157 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13158 .info = snd_ctl_boolean_mono_info,
13159 .get = alc268_acer_master_sw_get,
8ef355da 13160 .put = alc268_acer_master_sw_put,
8ef355da
KY
13161 },
13162 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13163 { }
13164};
13165
a9111321 13166static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13167 /* output mixer control */
13168 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13169 {
13170 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13171 .name = "Master Playback Switch",
0f0f391c
TI
13172 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13173 .info = snd_ctl_boolean_mono_info,
13174 .get = alc268_acer_master_sw_get,
d273809e 13175 .put = alc268_acer_master_sw_put,
d273809e 13176 },
5f99f86a
DH
13177 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13178 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13179 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13180 { }
13181};
13182
a9111321 13183static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13184 /* output mixer control */
13185 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13186 {
13187 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13188 .name = "Master Playback Switch",
0f0f391c
TI
13189 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13190 .info = snd_ctl_boolean_mono_info,
13191 .get = alc268_acer_master_sw_get,
c238b4f4 13192 .put = alc268_acer_master_sw_put,
c238b4f4 13193 },
5f99f86a
DH
13194 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13195 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13196 { }
13197};
13198
a9111321 13199static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13200 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13201 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13202 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13203 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13204 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13205 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13206 { }
13207};
13208
a9111321 13209static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13210 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13211 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13212 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13213 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13214 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13215 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13216 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13217 { }
13218};
13219
13220/* unsolicited event for HP jack sensing */
4f5d1706 13221#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13222
4f5d1706
TI
13223static void alc268_acer_lc_setup(struct hda_codec *codec)
13224{
13225 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13226 spec->autocfg.hp_pins[0] = 0x15;
13227 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce 13228 spec->automute = 1;
54463a66 13229 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
13230 spec->ext_mic.pin = 0x18;
13231 spec->ext_mic.mux_idx = 0;
13232 spec->int_mic.pin = 0x12;
13233 spec->int_mic.mux_idx = 6;
13234 spec->auto_mic = 1;
8ef355da
KY
13235}
13236
a9111321 13237static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13238 /* output mixer control */
13239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13240 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13243 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13244 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13245 { }
13246};
13247
a9111321 13248static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13249 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13250 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13251 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13252 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13253 { }
13254};
13255
13256/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13257static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13258{
a9fd4f3f 13259 struct alc_spec *spec = codec->spec;
3866f0b0 13260
a9fd4f3f
TI
13261 spec->autocfg.hp_pins[0] = 0x15;
13262 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13263 spec->ext_mic.pin = 0x18;
13264 spec->ext_mic.mux_idx = 0;
13265 spec->int_mic.pin = 0x19;
13266 spec->int_mic.mux_idx = 1;
13267 spec->auto_mic = 1;
d922b51d
TI
13268 spec->automute = 1;
13269 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13270}
13271
a9111321 13272static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13273 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13274 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13275 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13277 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13278 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13279 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13280 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13281 { }
13282};
13283
a9111321 13284static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13285 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13286 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13287 { }
13288};
13289
4f5d1706 13290static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13291{
a9fd4f3f 13292 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13293 spec->autocfg.hp_pins[0] = 0x15;
13294 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13295 spec->ext_mic.pin = 0x18;
13296 spec->ext_mic.mux_idx = 0;
13297 spec->int_mic.pin = 0x19;
13298 spec->int_mic.mux_idx = 1;
13299 spec->auto_mic = 1;
d922b51d
TI
13300 spec->automute = 1;
13301 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13302}
13303
a361d84b
KY
13304/*
13305 * generic initialization of ADC, input mixers and output mixers
13306 */
a9111321 13307static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13308 /* Unmute DAC0-1 and set vol = 0 */
13309 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13310 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13311
13312 /*
13313 * Set up output mixers (0x0c - 0x0e)
13314 */
13315 /* set vol=0 to output mixers */
13316 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13317 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13318
13319 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13320 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13321
13322 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13323 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13324 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13326 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13327 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13328 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13329 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13330
13331 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13332 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13333 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13334 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13335 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13336
13337 /* set PCBEEP vol = 0, mute connections */
13338 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13339 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13340 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13341
a9b3aa8a 13342 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13343
a9b3aa8a
JZ
13344 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13345 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13346 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13347 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13348
a361d84b
KY
13349 { }
13350};
13351
1f0f4b80
TI
13352/* only for model=test */
13353#ifdef CONFIG_SND_DEBUG
a361d84b
KY
13354/*
13355 * generic initialization of ADC, input mixers and output mixers
13356 */
a9111321 13357static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13358 /* set output DAC */
4cfb91c6
TI
13359 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13360 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13361
13362 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13363 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13364 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13365 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13366 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13367
a361d84b 13368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13370 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13371
13372 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13373 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1f0f4b80
TI
13374 { }
13375};
13376#endif /* CONFIG_SND_DEBUG */
a361d84b 13377
1f0f4b80
TI
13378/* set PCBEEP vol = 0, mute connections */
13379static const struct hda_verb alc268_beep_init_verbs[] = {
aef9d318
TI
13380 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13381 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13382 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13383 { }
13384};
13385
a9111321 13386static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13387 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13388 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13389 { } /* end */
13390};
13391
a9111321 13392static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13393 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13394 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13395 _DEFINE_CAPSRC(1),
a361d84b
KY
13396 { } /* end */
13397};
13398
a9111321 13399static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13400 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13401 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13404 _DEFINE_CAPSRC(2),
a361d84b
KY
13405 { } /* end */
13406};
13407
a9111321 13408static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13409 .num_items = 4,
13410 .items = {
13411 { "Mic", 0x0 },
13412 { "Front Mic", 0x1 },
13413 { "Line", 0x2 },
13414 { "CD", 0x3 },
13415 },
13416};
13417
a9111321 13418static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13419 .num_items = 3,
13420 .items = {
13421 { "Mic", 0x0 },
13422 { "Internal Mic", 0x1 },
13423 { "Line", 0x2 },
13424 },
13425};
13426
a9111321 13427static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13428 .num_items = 3,
13429 .items = {
13430 { "Mic", 0x0 },
13431 { "Internal Mic", 0x6 },
13432 { "Line", 0x2 },
13433 },
13434};
13435
86c53bd2 13436#ifdef CONFIG_SND_DEBUG
a9111321 13437static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13438 /* Volume widgets */
13439 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13440 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13441 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13442 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13443 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13444 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13445 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13446 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13447 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13448 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13449 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13450 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13451 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13452 /* The below appears problematic on some hardwares */
13453 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13454 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13455 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13456 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13457 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13458
13459 /* Modes for retasking pin widgets */
13460 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13461 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13462 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13463 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13464
13465 /* Controls for GPIO pins, assuming they are configured as outputs */
13466 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13467 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13468 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13469 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13470
13471 /* Switches to allow the digital SPDIF output pin to be enabled.
13472 * The ALC268 does not have an SPDIF input.
13473 */
13474 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13475
13476 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13477 * this output to turn on an external amplifier.
13478 */
13479 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13480 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13481
13482 { } /* end */
13483};
13484#endif
13485
a361d84b
KY
13486/* create input playback/capture controls for the given pin */
13487static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13488 const char *ctlname, int idx)
13489{
3f3b7c1a 13490 hda_nid_t dac;
a361d84b
KY
13491 int err;
13492
3f3b7c1a
TI
13493 switch (nid) {
13494 case 0x14:
13495 case 0x16:
13496 dac = 0x02;
13497 break;
13498 case 0x15:
b08b1637
TI
13499 case 0x1a: /* ALC259/269 only */
13500 case 0x1b: /* ALC259/269 only */
531d8791 13501 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13502 dac = 0x03;
13503 break;
13504 default:
c7a9434d
TI
13505 snd_printd(KERN_WARNING "hda_codec: "
13506 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13507 return 0;
13508 }
13509 if (spec->multiout.dac_nids[0] != dac &&
13510 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13511 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13512 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13513 HDA_OUTPUT));
13514 if (err < 0)
13515 return err;
dda14410 13516 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13517 }
13518
3f3b7c1a 13519 if (nid != 0x16)
0afe5f89 13520 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13521 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13522 else /* mono */
0afe5f89 13523 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13524 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13525 if (err < 0)
13526 return err;
13527 return 0;
13528}
13529
13530/* add playback controls from the parsed DAC table */
13531static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13532 const struct auto_pin_cfg *cfg)
13533{
13534 hda_nid_t nid;
13535 int err;
13536
a361d84b 13537 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13538
13539 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13540 if (nid) {
13541 const char *name;
2e925dde
TI
13542 int index;
13543 name = alc_get_line_out_pfx(spec, 0, true, &index);
3f3b7c1a
TI
13544 err = alc268_new_analog_output(spec, nid, name, 0);
13545 if (err < 0)
13546 return err;
13547 }
a361d84b
KY
13548
13549 nid = cfg->speaker_pins[0];
13550 if (nid == 0x1d) {
0afe5f89 13551 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13552 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13553 if (err < 0)
13554 return err;
7bfb9c03 13555 } else if (nid) {
3f3b7c1a
TI
13556 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13557 if (err < 0)
13558 return err;
a361d84b
KY
13559 }
13560 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13561 if (nid) {
13562 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13563 if (err < 0)
13564 return err;
13565 }
a361d84b
KY
13566
13567 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13568 if (nid == 0x16) {
0afe5f89 13569 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13570 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13571 if (err < 0)
13572 return err;
13573 }
ea1fb29a 13574 return 0;
a361d84b
KY
13575}
13576
13577/* create playback/capture controls for input pins */
05f5f477 13578static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13579 const struct auto_pin_cfg *cfg)
13580{
05f5f477 13581 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13582}
13583
e9af4f36
TI
13584static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13585 hda_nid_t nid, int pin_type)
13586{
13587 int idx;
13588
13589 alc_set_pin_output(codec, nid, pin_type);
4f574b7b
TI
13590 if (snd_hda_get_conn_list(codec, nid, NULL) <= 1)
13591 return;
e9af4f36
TI
13592 if (nid == 0x14 || nid == 0x16)
13593 idx = 0;
13594 else
13595 idx = 1;
13596 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13597}
13598
1f0f4b80
TI
13599static void alc268_auto_init_dac(struct hda_codec *codec, hda_nid_t nid)
13600{
13601 if (!nid)
13602 return;
13603 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
7ec9c6cc 13604 AMP_OUT_ZERO);
1f0f4b80
TI
13605}
13606
e9af4f36
TI
13607static void alc268_auto_init_multi_out(struct hda_codec *codec)
13608{
13609 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13610 int i;
13611
13612 for (i = 0; i < spec->autocfg.line_outs; i++) {
13613 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13614 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13615 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13616 }
1f0f4b80
TI
13617 /* mute DACs */
13618 for (i = 0; i < spec->multiout.num_dacs; i++)
13619 alc268_auto_init_dac(codec, spec->multiout.dac_nids[i]);
e9af4f36
TI
13620}
13621
13622static void alc268_auto_init_hp_out(struct hda_codec *codec)
13623{
13624 struct alc_spec *spec = codec->spec;
13625 hda_nid_t pin;
e1ca7b4e 13626 int i;
e9af4f36 13627
e1ca7b4e
TI
13628 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13629 pin = spec->autocfg.hp_pins[i];
e9af4f36 13630 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13631 }
13632 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13633 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13634 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13635 }
13636 if (spec->autocfg.mono_out_pin)
13637 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13638 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1f0f4b80
TI
13639 /* mute DACs */
13640 alc268_auto_init_dac(codec, spec->multiout.hp_nid);
13641 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
13642 alc268_auto_init_dac(codec, spec->multiout.extra_out_nid[i]);
e9af4f36
TI
13643}
13644
a361d84b
KY
13645static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13646{
13647 struct alc_spec *spec = codec->spec;
13648 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13649 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13650 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13651 unsigned int dac_vol1, dac_vol2;
13652
e9af4f36 13653 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13654 snd_hda_codec_write(codec, speaker_nid, 0,
13655 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13656 /* mute mixer inputs from 0x1d */
a361d84b
KY
13657 snd_hda_codec_write(codec, 0x0f, 0,
13658 AC_VERB_SET_AMP_GAIN_MUTE,
13659 AMP_IN_UNMUTE(1));
13660 snd_hda_codec_write(codec, 0x10, 0,
13661 AC_VERB_SET_AMP_GAIN_MUTE,
13662 AMP_IN_UNMUTE(1));
13663 } else {
e9af4f36 13664 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13665 snd_hda_codec_write(codec, 0x0f, 0,
13666 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13667 snd_hda_codec_write(codec, 0x10, 0,
13668 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13669 }
13670
13671 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13672 if (line_nid == 0x14)
a361d84b
KY
13673 dac_vol2 = AMP_OUT_ZERO;
13674 else if (line_nid == 0x15)
13675 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13676 if (hp_nid == 0x14)
a361d84b
KY
13677 dac_vol2 = AMP_OUT_ZERO;
13678 else if (hp_nid == 0x15)
13679 dac_vol1 = AMP_OUT_ZERO;
13680 if (line_nid != 0x16 || hp_nid != 0x16 ||
13681 spec->autocfg.line_out_pins[1] != 0x16 ||
13682 spec->autocfg.line_out_pins[2] != 0x16)
13683 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13684
13685 snd_hda_codec_write(codec, 0x02, 0,
13686 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13687 snd_hda_codec_write(codec, 0x03, 0,
13688 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13689}
13690
def319f9 13691/* pcm configuration: identical with ALC880 */
a361d84b
KY
13692#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13693#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13694#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13695#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13696
13697/*
13698 * BIOS auto configuration
13699 */
13700static int alc268_parse_auto_config(struct hda_codec *codec)
13701{
13702 struct alc_spec *spec = codec->spec;
13703 int err;
4c6d72d1 13704 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13705
13706 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13707 alc268_ignore);
13708 if (err < 0)
13709 return err;
7e0e44d4
TI
13710 if (!spec->autocfg.line_outs) {
13711 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13712 spec->multiout.max_channels = 2;
13713 spec->no_analog = 1;
13714 goto dig_only;
13715 }
a361d84b 13716 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13717 }
a361d84b
KY
13718 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13719 if (err < 0)
13720 return err;
05f5f477 13721 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13722 if (err < 0)
13723 return err;
13724
13725 spec->multiout.max_channels = 2;
13726
7e0e44d4 13727 dig_only:
a361d84b 13728 /* digital only support output */
757899ac 13729 alc_auto_parse_digital(codec);
603c4019 13730 if (spec->kctls.list)
d88897ea 13731 add_mixer(spec, spec->kctls.list);
a361d84b 13732
4f574b7b 13733 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d) {
d88897ea 13734 add_mixer(spec, alc268_beep_mixer);
4f574b7b
TI
13735 add_verb(spec, alc268_beep_init_verbs);
13736 }
aef9d318 13737
5908589f 13738 spec->num_mux_defs = 2;
61b9b9b1 13739 spec->input_mux = &spec->private_imux[0];
a361d84b 13740
776e184e
TI
13741 err = alc_auto_add_mic_boost(codec);
13742 if (err < 0)
13743 return err;
13744
6227cdce 13745 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13746
a361d84b
KY
13747 return 1;
13748}
13749
a361d84b 13750#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13751#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13752
13753/* init callback for auto-configuration model -- overriding the default init */
13754static void alc268_auto_init(struct hda_codec *codec)
13755{
f6c7e546 13756 struct alc_spec *spec = codec->spec;
a361d84b
KY
13757 alc268_auto_init_multi_out(codec);
13758 alc268_auto_init_hp_out(codec);
13759 alc268_auto_init_mono_speaker_out(codec);
13760 alc268_auto_init_analog_input(codec);
ae0ebbf7 13761 alc268_auto_init_input_src(codec);
757899ac 13762 alc_auto_init_digital(codec);
f6c7e546 13763 if (spec->unsol_event)
7fb0d78f 13764 alc_inithook(codec);
a361d84b
KY
13765}
13766
13767/*
13768 * configuration and preset
13769 */
ea734963 13770static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13771 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13772 [ALC268_3ST] = "3stack",
983f8ae4 13773 [ALC268_TOSHIBA] = "toshiba",
d273809e 13774 [ALC268_ACER] = "acer",
c238b4f4 13775 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13776 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13777 [ALC268_DELL] = "dell",
f12462c5 13778 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13779#ifdef CONFIG_SND_DEBUG
13780 [ALC268_TEST] = "test",
13781#endif
a361d84b
KY
13782 [ALC268_AUTO] = "auto",
13783};
13784
a9111321 13785static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13786 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13787 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13788 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13789 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13790 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13791 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13792 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13793 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
0a1896b2 13794 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
a1bf8088
DC
13795 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13796 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13797 /* almost compatible with toshiba but with optional digital outs;
13798 * auto-probing seems working fine
13799 */
8871e5b9 13800 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13801 ALC268_AUTO),
a361d84b 13802 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13803 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13804 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
eb5a6621 13805 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13806 {}
13807};
13808
3abf2f36 13809/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13810static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13811 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13812 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13813 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13814 ALC268_TOSHIBA),
13815 {}
13816};
13817
a9111321 13818static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13819 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13820 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13821 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13822 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13823 alc267_quanta_il1_verbs },
13824 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13825 .dac_nids = alc268_dac_nids,
13826 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13827 .adc_nids = alc268_adc_nids_alt,
13828 .hp_nid = 0x03,
13829 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13830 .channel_mode = alc268_modes,
4f5d1706
TI
13831 .unsol_event = alc_sku_unsol_event,
13832 .setup = alc267_quanta_il1_setup,
13833 .init_hook = alc_inithook,
eb5a6621 13834 },
a361d84b 13835 [ALC268_3ST] = {
aef9d318
TI
13836 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13837 alc268_beep_mixer },
a361d84b
KY
13838 .init_verbs = { alc268_base_init_verbs },
13839 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13840 .dac_nids = alc268_dac_nids,
13841 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13842 .adc_nids = alc268_adc_nids_alt,
e1406348 13843 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13844 .hp_nid = 0x03,
13845 .dig_out_nid = ALC268_DIGOUT_NID,
13846 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13847 .channel_mode = alc268_modes,
13848 .input_mux = &alc268_capture_source,
13849 },
d1a991a6 13850 [ALC268_TOSHIBA] = {
42171c17 13851 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13852 alc268_beep_mixer },
d273809e
TI
13853 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13854 alc268_toshiba_verbs },
d1a991a6
KY
13855 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13856 .dac_nids = alc268_dac_nids,
13857 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13858 .adc_nids = alc268_adc_nids_alt,
e1406348 13859 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13860 .hp_nid = 0x03,
13861 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13862 .channel_mode = alc268_modes,
13863 .input_mux = &alc268_capture_source,
e9427969 13864 .unsol_event = alc_sku_unsol_event,
4f5d1706 13865 .setup = alc268_toshiba_setup,
e9427969 13866 .init_hook = alc_inithook,
d273809e
TI
13867 },
13868 [ALC268_ACER] = {
432fd133 13869 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13870 alc268_beep_mixer },
d273809e
TI
13871 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13872 alc268_acer_verbs },
13873 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13874 .dac_nids = alc268_dac_nids,
13875 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13876 .adc_nids = alc268_adc_nids_alt,
e1406348 13877 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13878 .hp_nid = 0x02,
13879 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13880 .channel_mode = alc268_modes,
0ccb541c 13881 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13882 .unsol_event = alc_sku_unsol_event,
13883 .setup = alc268_acer_setup,
13884 .init_hook = alc_inithook,
d1a991a6 13885 },
c238b4f4
TI
13886 [ALC268_ACER_DMIC] = {
13887 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13888 alc268_beep_mixer },
13889 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13890 alc268_acer_verbs },
13891 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13892 .dac_nids = alc268_dac_nids,
13893 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13894 .adc_nids = alc268_adc_nids_alt,
13895 .capsrc_nids = alc268_capsrc_nids,
13896 .hp_nid = 0x02,
13897 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13898 .channel_mode = alc268_modes,
13899 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13900 .unsol_event = alc_sku_unsol_event,
13901 .setup = alc268_acer_setup,
13902 .init_hook = alc_inithook,
c238b4f4 13903 },
8ef355da
KY
13904 [ALC268_ACER_ASPIRE_ONE] = {
13905 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13906 alc268_beep_mixer,
fdbc6626 13907 alc268_capture_nosrc_mixer },
8ef355da
KY
13908 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13909 alc268_acer_aspire_one_verbs },
13910 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13911 .dac_nids = alc268_dac_nids,
13912 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13913 .adc_nids = alc268_adc_nids_alt,
13914 .capsrc_nids = alc268_capsrc_nids,
13915 .hp_nid = 0x03,
13916 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13917 .channel_mode = alc268_modes,
3b8510ce 13918 .unsol_event = alc_sku_unsol_event,
4f5d1706 13919 .setup = alc268_acer_lc_setup,
3b8510ce 13920 .init_hook = alc_inithook,
8ef355da 13921 },
3866f0b0 13922 [ALC268_DELL] = {
fdbc6626
TI
13923 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13924 alc268_capture_nosrc_mixer },
3866f0b0
TI
13925 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13926 alc268_dell_verbs },
13927 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13928 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13929 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13930 .adc_nids = alc268_adc_nids_alt,
13931 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13932 .hp_nid = 0x02,
13933 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13934 .channel_mode = alc268_modes,
a9fd4f3f 13935 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13936 .setup = alc268_dell_setup,
13937 .init_hook = alc_inithook,
3866f0b0 13938 },
f12462c5 13939 [ALC268_ZEPTO] = {
aef9d318
TI
13940 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13941 alc268_beep_mixer },
f12462c5
MT
13942 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13943 alc268_toshiba_verbs },
13944 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13945 .dac_nids = alc268_dac_nids,
13946 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13947 .adc_nids = alc268_adc_nids_alt,
e1406348 13948 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13949 .hp_nid = 0x03,
13950 .dig_out_nid = ALC268_DIGOUT_NID,
13951 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13952 .channel_mode = alc268_modes,
13953 .input_mux = &alc268_capture_source,
e9427969 13954 .unsol_event = alc_sku_unsol_event,
4f5d1706 13955 .setup = alc268_toshiba_setup,
e9427969 13956 .init_hook = alc_inithook,
f12462c5 13957 },
86c53bd2
JW
13958#ifdef CONFIG_SND_DEBUG
13959 [ALC268_TEST] = {
13960 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13961 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
1f0f4b80
TI
13962 alc268_volume_init_verbs,
13963 alc268_beep_init_verbs },
86c53bd2
JW
13964 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13965 .dac_nids = alc268_dac_nids,
13966 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13967 .adc_nids = alc268_adc_nids_alt,
e1406348 13968 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13969 .hp_nid = 0x03,
13970 .dig_out_nid = ALC268_DIGOUT_NID,
13971 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13972 .channel_mode = alc268_modes,
13973 .input_mux = &alc268_capture_source,
13974 },
13975#endif
a361d84b
KY
13976};
13977
13978static int patch_alc268(struct hda_codec *codec)
13979{
13980 struct alc_spec *spec;
13981 int board_config;
22971e3a 13982 int i, has_beep, err;
a361d84b 13983
ef86f581 13984 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
13985 if (spec == NULL)
13986 return -ENOMEM;
13987
13988 codec->spec = spec;
13989
1f0f4b80
TI
13990 /* ALC268 has no aa-loopback mixer */
13991
a361d84b
KY
13992 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
13993 alc268_models,
13994 alc268_cfg_tbl);
13995
3abf2f36
TI
13996 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
13997 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 13998 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 13999
a361d84b 14000 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14001 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14002 codec->chip_name);
a361d84b
KY
14003 board_config = ALC268_AUTO;
14004 }
14005
14006 if (board_config == ALC268_AUTO) {
14007 /* automatic parse from the BIOS config */
14008 err = alc268_parse_auto_config(codec);
14009 if (err < 0) {
14010 alc_free(codec);
14011 return err;
14012 } else if (!err) {
14013 printk(KERN_INFO
14014 "hda_codec: Cannot set up configuration "
14015 "from BIOS. Using base mode...\n");
14016 board_config = ALC268_3ST;
14017 }
14018 }
14019
14020 if (board_config != ALC268_AUTO)
e9c364c0 14021 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14022
a361d84b
KY
14023 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14024 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14025 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14026
a361d84b
KY
14027 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14028
22971e3a
TI
14029 has_beep = 0;
14030 for (i = 0; i < spec->num_mixers; i++) {
14031 if (spec->mixers[i] == alc268_beep_mixer) {
14032 has_beep = 1;
14033 break;
14034 }
14035 }
14036
14037 if (has_beep) {
14038 err = snd_hda_attach_beep_device(codec, 0x1);
14039 if (err < 0) {
14040 alc_free(codec);
14041 return err;
14042 }
14043 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14044 /* override the amp caps for beep generator */
14045 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14046 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14047 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14048 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14049 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14050 }
aef9d318 14051
7e0e44d4 14052 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14053 /* check whether NID 0x07 is valid */
14054 unsigned int wcap = get_wcaps(codec, 0x07);
14055
defb5ab2 14056 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14057 /* get type */
a22d543a 14058 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14059 if (spec->auto_mic ||
14060 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14061 spec->adc_nids = alc268_adc_nids_alt;
14062 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14063 if (spec->auto_mic)
14064 fixup_automic_adc(codec);
fdbc6626
TI
14065 if (spec->auto_mic || spec->input_mux->num_items == 1)
14066 add_mixer(spec, alc268_capture_nosrc_mixer);
14067 else
14068 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14069 } else {
14070 spec->adc_nids = alc268_adc_nids;
14071 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14072 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14073 }
14074 }
2134ea4f
TI
14075
14076 spec->vmaster_nid = 0x02;
14077
a361d84b
KY
14078 codec->patch_ops = alc_patch_ops;
14079 if (board_config == ALC268_AUTO)
14080 spec->init_hook = alc268_auto_init;
1c716153 14081 spec->shutup = alc_eapd_shutup;
ea1fb29a 14082
bf1b0225
KY
14083 alc_init_jacks(codec);
14084
a361d84b
KY
14085 return 0;
14086}
14087
f6a92248
KY
14088/*
14089 * ALC269 channel source setting (2 channel)
14090 */
14091#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14092
14093#define alc269_dac_nids alc260_dac_nids
14094
4c6d72d1 14095static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14096 /* ADC1 */
f53281e6
KY
14097 0x08,
14098};
14099
4c6d72d1 14100static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14101 0x23,
14102};
14103
4c6d72d1 14104static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14105 /* ADC1 */
14106 0x09,
14107};
14108
4c6d72d1 14109static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14110 0x22,
14111};
14112
4c6d72d1 14113static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14114 0x08, 0x09, 0x07, 0x11,
6694635d 14115};
e01bf509 14116
f6a92248
KY
14117#define alc269_modes alc260_modes
14118#define alc269_capture_source alc880_lg_lw_capture_source
14119
a9111321 14120static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14121 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14122 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14123 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14124 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14127 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14128 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14129 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14130 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14132 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14133 { } /* end */
14134};
14135
a9111321 14136static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
14137 /* output mixer control */
14138 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14139 {
14140 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14141 .name = "Master Playback Switch",
5e26dfd0 14142 .subdevice = HDA_SUBDEV_AMP_FLAG,
60db6b53
KY
14143 .info = snd_hda_mixer_amp_switch_info,
14144 .get = snd_hda_mixer_amp_switch_get,
14145 .put = alc268_acer_master_sw_put,
14146 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14147 },
14148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14149 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14150 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
60db6b53
KY
14151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14153 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
60db6b53
KY
14154 { }
14155};
14156
a9111321 14157static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14158 /* output mixer control */
14159 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14160 {
14161 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14162 .name = "Master Playback Switch",
5e26dfd0 14163 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14164 .info = snd_hda_mixer_amp_switch_info,
14165 .get = snd_hda_mixer_amp_switch_get,
14166 .put = alc268_acer_master_sw_put,
14167 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14168 },
14169 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14170 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14172 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14173 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14174 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14175 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14176 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14177 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14178 { }
14179};
14180
a9111321 14181static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14182 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14183 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14184 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14185 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14186 { } /* end */
14187};
14188
a9111321 14189static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14190 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14191 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14192 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14193 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14194 { } /* end */
14195};
14196
a9111321 14197static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14198 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14199 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14200 { } /* end */
14201};
14202
f53281e6 14203/* capture mixer elements */
a9111321 14204static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14205 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14206 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14208 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14209 { } /* end */
14210};
14211
a9111321 14212static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14213 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14214 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14215 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14216 { } /* end */
14217};
14218
a9111321 14219static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14220 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14221 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14223 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14224 { } /* end */
14225};
14226
a9111321 14227static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14228 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14229 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14230 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14231 { } /* end */
14232};
14233
26f5df26 14234/* FSC amilo */
84898e87 14235#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14236
a9111321 14237static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14238 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14239 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14240 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14241 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14242 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14243 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14244 { }
14245};
f6a92248 14246
a9111321 14247static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14249 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14250 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14251 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14252 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14253 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14254 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14255 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14256 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14257 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14258 { }
14259};
14260
60db6b53
KY
14261/* toggle speaker-output according to the hp-jack state */
14262static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14263{
3b8510ce 14264 alc_hp_automute(codec);
f6a92248 14265
60db6b53
KY
14266 snd_hda_codec_write(codec, 0x20, 0,
14267 AC_VERB_SET_COEF_INDEX, 0x0c);
14268 snd_hda_codec_write(codec, 0x20, 0,
14269 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14270
60db6b53
KY
14271 snd_hda_codec_write(codec, 0x20, 0,
14272 AC_VERB_SET_COEF_INDEX, 0x0c);
14273 snd_hda_codec_write(codec, 0x20, 0,
14274 AC_VERB_SET_PROC_COEF, 0x480);
14275}
f6a92248 14276
3b8510ce
TI
14277#define alc269_lifebook_speaker_automute \
14278 alc269_quanta_fl1_speaker_automute
64154835 14279
64154835
TV
14280static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14281{
14282 unsigned int present_laptop;
14283 unsigned int present_dock;
14284
864f92be
WF
14285 present_laptop = snd_hda_jack_detect(codec, 0x18);
14286 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14287
14288 /* Laptop mic port overrides dock mic port, design decision */
14289 if (present_dock)
14290 snd_hda_codec_write(codec, 0x23, 0,
14291 AC_VERB_SET_CONNECT_SEL, 0x3);
14292 if (present_laptop)
14293 snd_hda_codec_write(codec, 0x23, 0,
14294 AC_VERB_SET_CONNECT_SEL, 0x0);
14295 if (!present_dock && !present_laptop)
14296 snd_hda_codec_write(codec, 0x23, 0,
14297 AC_VERB_SET_CONNECT_SEL, 0x1);
14298}
14299
60db6b53
KY
14300static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14301 unsigned int res)
14302{
4f5d1706
TI
14303 switch (res >> 26) {
14304 case ALC880_HP_EVENT:
60db6b53 14305 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14306 break;
14307 case ALC880_MIC_EVENT:
14308 alc_mic_automute(codec);
14309 break;
14310 }
60db6b53 14311}
f6a92248 14312
64154835
TV
14313static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14314 unsigned int res)
14315{
14316 if ((res >> 26) == ALC880_HP_EVENT)
14317 alc269_lifebook_speaker_automute(codec);
14318 if ((res >> 26) == ALC880_MIC_EVENT)
14319 alc269_lifebook_mic_autoswitch(codec);
14320}
14321
4f5d1706
TI
14322static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14323{
14324 struct alc_spec *spec = codec->spec;
20645d70
TI
14325 spec->autocfg.hp_pins[0] = 0x15;
14326 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14327 spec->automute_mixer_nid[0] = 0x0c;
14328 spec->automute = 1;
14329 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14330 spec->ext_mic.pin = 0x18;
14331 spec->ext_mic.mux_idx = 0;
14332 spec->int_mic.pin = 0x19;
14333 spec->int_mic.mux_idx = 1;
14334 spec->auto_mic = 1;
14335}
14336
60db6b53
KY
14337static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14338{
14339 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14340 alc_mic_automute(codec);
60db6b53 14341}
f6a92248 14342
3b8510ce
TI
14343static void alc269_lifebook_setup(struct hda_codec *codec)
14344{
14345 struct alc_spec *spec = codec->spec;
14346 spec->autocfg.hp_pins[0] = 0x15;
14347 spec->autocfg.hp_pins[1] = 0x1a;
14348 spec->autocfg.speaker_pins[0] = 0x14;
14349 spec->automute_mixer_nid[0] = 0x0c;
14350 spec->automute = 1;
14351 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14352}
14353
64154835
TV
14354static void alc269_lifebook_init_hook(struct hda_codec *codec)
14355{
14356 alc269_lifebook_speaker_automute(codec);
14357 alc269_lifebook_mic_autoswitch(codec);
14358}
14359
a9111321 14360static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14362 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14363 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14364 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14365 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14366 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14367 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14368 {}
14369};
14370
a9111321 14371static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14372 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14373 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14374 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14377 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14378 {}
14379};
14380
a9111321 14381static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14382 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14383 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14384 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14385 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14386 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14387 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14388 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14389 {}
14390};
14391
a9111321 14392static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14393 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14394 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14395 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14396 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14397 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14398 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14399 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14400 {}
14401};
14402
a9111321 14403static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14404 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14405 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14406 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14407 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14408 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14409 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14410 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14411 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14412 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14413 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14414 { }
14415};
14416
226b1ec8 14417static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14418{
4f5d1706 14419 struct alc_spec *spec = codec->spec;
20645d70
TI
14420 spec->autocfg.hp_pins[0] = 0x15;
14421 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14422 spec->automute_mixer_nid[0] = 0x0c;
14423 spec->automute = 1;
14424 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14425 spec->ext_mic.pin = 0x18;
14426 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14427 spec->int_mic.pin = 0x19;
14428 spec->int_mic.mux_idx = 1;
4f5d1706 14429 spec->auto_mic = 1;
f53281e6
KY
14430}
14431
226b1ec8 14432static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14433{
14434 struct alc_spec *spec = codec->spec;
20645d70
TI
14435 spec->autocfg.hp_pins[0] = 0x15;
14436 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14437 spec->automute_mixer_nid[0] = 0x0c;
14438 spec->automute = 1;
14439 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14440 spec->ext_mic.pin = 0x18;
14441 spec->ext_mic.mux_idx = 0;
14442 spec->int_mic.pin = 0x12;
226b1ec8 14443 spec->int_mic.mux_idx = 5;
84898e87
KY
14444 spec->auto_mic = 1;
14445}
14446
226b1ec8 14447static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14448{
4f5d1706 14449 struct alc_spec *spec = codec->spec;
226b1ec8 14450 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14451 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14452 spec->automute_mixer_nid[0] = 0x0c;
14453 spec->automute = 1;
14454 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14455 spec->ext_mic.pin = 0x18;
14456 spec->ext_mic.mux_idx = 0;
14457 spec->int_mic.pin = 0x19;
14458 spec->int_mic.mux_idx = 1;
14459 spec->auto_mic = 1;
f53281e6
KY
14460}
14461
226b1ec8
KY
14462static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14463{
14464 struct alc_spec *spec = codec->spec;
14465 spec->autocfg.hp_pins[0] = 0x21;
14466 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14467 spec->automute_mixer_nid[0] = 0x0c;
14468 spec->automute = 1;
14469 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14470 spec->ext_mic.pin = 0x18;
14471 spec->ext_mic.mux_idx = 0;
14472 spec->int_mic.pin = 0x12;
14473 spec->int_mic.mux_idx = 6;
14474 spec->auto_mic = 1;
14475}
14476
60db6b53
KY
14477/*
14478 * generic initialization of ADC, input mixers and output mixers
14479 */
a9111321 14480static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14481 /*
14482 * Unmute ADC0 and set the default input to mic-in
14483 */
84898e87 14484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14485
14486 /*
84898e87 14487 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14488 */
14489 /* set vol=0 to output mixers */
14490 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14491 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14492
14493 /* set up input amps for analog loopback */
14494 /* Amp Indices: DAC = 0, mixer = 1 */
14495 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14496 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14497 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14498 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14499 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14500 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14501
14502 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14504 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14505 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14506 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14509
14510 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14511 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14512
84898e87
KY
14513 /* FIXME: use Mux-type input source selection */
14514 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14515 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14516 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14517
84898e87
KY
14518 /* set EAPD */
14519 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14520 { }
14521};
14522
a9111321 14523static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14524 /*
14525 * Unmute ADC0 and set the default input to mic-in
14526 */
14527 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14528
14529 /*
14530 * Set up output mixers (0x02 - 0x03)
14531 */
14532 /* set vol=0 to output mixers */
14533 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14534 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14535
14536 /* set up input amps for analog loopback */
14537 /* Amp Indices: DAC = 0, mixer = 1 */
14538 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14539 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14540 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14541 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14542 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14543 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14544
14545 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14546 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14547 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14548 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14550 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14551 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14552
14553 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14554 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14555
14556 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14557 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14558 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14559 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14560
14561 /* set EAPD */
14562 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14563 { }
14564};
14565
9d0b71b1
TI
14566#define alc269_auto_create_multi_out_ctls \
14567 alc268_auto_create_multi_out_ctls
05f5f477
TI
14568#define alc269_auto_create_input_ctls \
14569 alc268_auto_create_input_ctls
f6a92248
KY
14570
14571#ifdef CONFIG_SND_HDA_POWER_SAVE
14572#define alc269_loopbacks alc880_loopbacks
14573#endif
14574
def319f9 14575/* pcm configuration: identical with ALC880 */
f6a92248
KY
14576#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14577#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14578#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14579#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14580
a9111321 14581static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14582 .substreams = 1,
14583 .channels_min = 2,
14584 .channels_max = 8,
14585 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14586 /* NID is set in alc_build_pcms */
14587 .ops = {
14588 .open = alc880_playback_pcm_open,
14589 .prepare = alc880_playback_pcm_prepare,
14590 .cleanup = alc880_playback_pcm_cleanup
14591 },
14592};
14593
a9111321 14594static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14595 .substreams = 1,
14596 .channels_min = 2,
14597 .channels_max = 2,
14598 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14599 /* NID is set in alc_build_pcms */
14600};
14601
ad35879a
TI
14602#ifdef CONFIG_SND_HDA_POWER_SAVE
14603static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14604{
14605 switch (codec->subsystem_id) {
14606 case 0x103c1586:
14607 return 1;
14608 }
14609 return 0;
14610}
14611
14612static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14613{
14614 /* update mute-LED according to the speaker mute state */
14615 if (nid == 0x01 || nid == 0x14) {
14616 int pinval;
14617 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14618 HDA_AMP_MUTE)
14619 pinval = 0x24;
14620 else
14621 pinval = 0x20;
14622 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14623 snd_hda_codec_update_cache(codec, 0x19, 0,
14624 AC_VERB_SET_PIN_WIDGET_CONTROL,
14625 pinval);
ad35879a
TI
14626 }
14627 return alc_check_power_status(codec, nid);
14628}
14629#endif /* CONFIG_SND_HDA_POWER_SAVE */
14630
840b64c0
TI
14631static int alc275_setup_dual_adc(struct hda_codec *codec)
14632{
14633 struct alc_spec *spec = codec->spec;
14634
14635 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14636 return 0;
14637 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14638 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14639 if (spec->ext_mic.pin <= 0x12) {
14640 spec->private_adc_nids[0] = 0x08;
14641 spec->private_adc_nids[1] = 0x11;
14642 spec->private_capsrc_nids[0] = 0x23;
14643 spec->private_capsrc_nids[1] = 0x22;
14644 } else {
14645 spec->private_adc_nids[0] = 0x11;
14646 spec->private_adc_nids[1] = 0x08;
14647 spec->private_capsrc_nids[0] = 0x22;
14648 spec->private_capsrc_nids[1] = 0x23;
14649 }
14650 spec->adc_nids = spec->private_adc_nids;
14651 spec->capsrc_nids = spec->private_capsrc_nids;
14652 spec->num_adc_nids = 2;
14653 spec->dual_adc_switch = 1;
14654 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14655 spec->adc_nids[0], spec->adc_nids[1]);
14656 return 1;
14657 }
14658 return 0;
14659}
14660
d433a678
TI
14661/* different alc269-variants */
14662enum {
14663 ALC269_TYPE_NORMAL,
48c88e82 14664 ALC269_TYPE_ALC258,
d433a678 14665 ALC269_TYPE_ALC259,
48c88e82
KY
14666 ALC269_TYPE_ALC269VB,
14667 ALC269_TYPE_ALC270,
d433a678
TI
14668 ALC269_TYPE_ALC271X,
14669};
14670
f6a92248
KY
14671/*
14672 * BIOS auto configuration
14673 */
14674static int alc269_parse_auto_config(struct hda_codec *codec)
14675{
14676 struct alc_spec *spec = codec->spec;
cfb9fb55 14677 int err;
4c6d72d1 14678 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14679
14680 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14681 alc269_ignore);
14682 if (err < 0)
14683 return err;
14684
14685 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14686 if (err < 0)
14687 return err;
f3550d1b
TI
14688 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14689 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14690 else
14691 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14692 0x22, 0);
f6a92248
KY
14693 if (err < 0)
14694 return err;
14695
14696 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14697
757899ac 14698 alc_auto_parse_digital(codec);
f6a92248 14699
603c4019 14700 if (spec->kctls.list)
d88897ea 14701 add_mixer(spec, spec->kctls.list);
f6a92248 14702
1f0f4b80 14703 if (spec->codec_variant != ALC269_TYPE_NORMAL)
6227cdce 14704 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
1f0f4b80 14705 else
6227cdce 14706 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87 14707
f6a92248 14708 spec->num_mux_defs = 1;
61b9b9b1 14709 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14710
14711 if (!alc275_setup_dual_adc(codec))
14712 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14713 sizeof(alc269_adc_candidates));
6694635d 14714
f6a92248
KY
14715 err = alc_auto_add_mic_boost(codec);
14716 if (err < 0)
14717 return err;
14718
7e0e44d4 14719 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14720 set_capture_mixer(codec);
f53281e6 14721
f6a92248
KY
14722 return 1;
14723}
14724
e9af4f36
TI
14725#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14726#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14727#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14728#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14729
14730
14731/* init callback for auto-configuration model -- overriding the default init */
14732static void alc269_auto_init(struct hda_codec *codec)
14733{
f6c7e546 14734 struct alc_spec *spec = codec->spec;
f6a92248
KY
14735 alc269_auto_init_multi_out(codec);
14736 alc269_auto_init_hp_out(codec);
14737 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14738 if (!spec->dual_adc_switch)
14739 alc269_auto_init_input_src(codec);
757899ac 14740 alc_auto_init_digital(codec);
f6c7e546 14741 if (spec->unsol_event)
7fb0d78f 14742 alc_inithook(codec);
f6a92248
KY
14743}
14744
0ec33d1f
TI
14745static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14746{
14747 int val = alc_read_coef_idx(codec, 0x04);
14748 if (power_up)
14749 val |= 1 << 11;
14750 else
14751 val &= ~(1 << 11);
14752 alc_write_coef_idx(codec, 0x04, val);
14753}
14754
5402e4cb 14755static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14756{
0ec33d1f
TI
14757 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14758 alc269_toggle_power_output(codec, 0);
977ddd6b 14759 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14760 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14761 msleep(150);
14762 }
977ddd6b 14763}
0ec33d1f 14764
5402e4cb 14765#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14766static int alc269_resume(struct hda_codec *codec)
14767{
977ddd6b 14768 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14769 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14770 msleep(150);
14771 }
14772
14773 codec->patch_ops.init(codec);
14774
14775 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14776 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14777 msleep(200);
14778 }
14779
0ec33d1f
TI
14780 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14781 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14782
14783 snd_hda_codec_resume_amp(codec);
14784 snd_hda_codec_resume_cache(codec);
9e5341b9 14785 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14786 return 0;
14787}
0ec33d1f 14788#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14789
1a99d4a4 14790static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14791 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14792{
14793 int coef;
14794
58701120 14795 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14796 return;
1a99d4a4
KY
14797 coef = alc_read_coef_idx(codec, 0x1e);
14798 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14799}
14800
6981d184
TI
14801static void alc271_fixup_dmic(struct hda_codec *codec,
14802 const struct alc_fixup *fix, int action)
14803{
a9111321 14804 static const struct hda_verb verbs[] = {
6981d184
TI
14805 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14806 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14807 {}
14808 };
14809 unsigned int cfg;
14810
14811 if (strcmp(codec->chip_name, "ALC271X"))
14812 return;
14813 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14814 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14815 snd_hda_sequence_write(codec, verbs);
14816}
14817
ff818c24
TI
14818enum {
14819 ALC269_FIXUP_SONY_VAIO,
74dc8909 14820 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14821 ALC269_FIXUP_DELL_M101Z,
022c92be 14822 ALC269_FIXUP_SKU_IGNORE,
ac612407 14823 ALC269_FIXUP_ASUS_G73JW,
357f915e 14824 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14825 ALC275_FIXUP_SONY_HWEQ,
6981d184 14826 ALC271_FIXUP_DMIC,
ff818c24
TI
14827};
14828
ff818c24
TI
14829static const struct alc_fixup alc269_fixups[] = {
14830 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14831 .type = ALC_FIXUP_VERBS,
14832 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14833 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14834 {}
14835 }
ff818c24 14836 },
74dc8909 14837 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14838 .type = ALC_FIXUP_VERBS,
14839 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14840 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14841 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14842 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14843 { }
b5bfbc67
TI
14844 },
14845 .chained = true,
14846 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14847 },
145a902b 14848 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14849 .type = ALC_FIXUP_VERBS,
14850 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14851 /* Enables internal speaker */
14852 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14853 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14854 {}
14855 }
14856 },
022c92be 14857 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14858 .type = ALC_FIXUP_SKU,
14859 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14860 },
ac612407 14861 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14862 .type = ALC_FIXUP_PINS,
14863 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14864 { 0x17, 0x99130111 }, /* subwoofer */
14865 { }
14866 }
14867 },
357f915e 14868 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14869 .type = ALC_FIXUP_VERBS,
14870 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14871 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14872 {}
14873 }
14874 },
1a99d4a4 14875 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14876 .type = ALC_FIXUP_FUNC,
14877 .v.func = alc269_fixup_hweq,
14878 .chained = true,
14879 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14880 },
14881 [ALC271_FIXUP_DMIC] = {
14882 .type = ALC_FIXUP_FUNC,
14883 .v.func = alc271_fixup_dmic,
14884 },
ff818c24
TI
14885};
14886
a9111321 14887static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14888 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14889 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14890 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14891 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14892 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14893 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14894 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14895 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14896 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14897 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14898 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14899 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14900 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14901 {}
14902};
14903
14904
f6a92248
KY
14905/*
14906 * configuration and preset
14907 */
ea734963 14908static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14909 [ALC269_BASIC] = "basic",
2922c9af 14910 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14911 [ALC269_AMIC] = "laptop-amic",
14912 [ALC269_DMIC] = "laptop-dmic",
64154835 14913 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14914 [ALC269_LIFEBOOK] = "lifebook",
14915 [ALC269_AUTO] = "auto",
f6a92248
KY
14916};
14917
a9111321 14918static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14919 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14920 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14921 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14922 ALC269_AMIC),
14923 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14924 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14925 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14926 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14927 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14928 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14929 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14930 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14931 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14932 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14933 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14934 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14935 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14936 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14937 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14938 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14939 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14940 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14941 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14942 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14943 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14944 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14945 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14946 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14955 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14956 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14957 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14959 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14960 ALC269_DMIC),
60db6b53 14961 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14962 ALC269_DMIC),
14963 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14964 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14965 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14966 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14967 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14968 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14969 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14972 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14973 {}
14974};
14975
a9111321 14976static const struct alc_config_preset alc269_presets[] = {
f6a92248 14977 [ALC269_BASIC] = {
f9e336f6 14978 .mixers = { alc269_base_mixer },
f6a92248
KY
14979 .init_verbs = { alc269_init_verbs },
14980 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14981 .dac_nids = alc269_dac_nids,
14982 .hp_nid = 0x03,
14983 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14984 .channel_mode = alc269_modes,
14985 .input_mux = &alc269_capture_source,
14986 },
60db6b53
KY
14987 [ALC269_QUANTA_FL1] = {
14988 .mixers = { alc269_quanta_fl1_mixer },
14989 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14990 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14991 .dac_nids = alc269_dac_nids,
14992 .hp_nid = 0x03,
14993 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14994 .channel_mode = alc269_modes,
14995 .input_mux = &alc269_capture_source,
14996 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 14997 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
14998 .init_hook = alc269_quanta_fl1_init_hook,
14999 },
84898e87
KY
15000 [ALC269_AMIC] = {
15001 .mixers = { alc269_laptop_mixer },
15002 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15003 .init_verbs = { alc269_init_verbs,
84898e87 15004 alc269_laptop_amic_init_verbs },
f53281e6
KY
15005 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15006 .dac_nids = alc269_dac_nids,
15007 .hp_nid = 0x03,
15008 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15009 .channel_mode = alc269_modes,
3b8510ce 15010 .unsol_event = alc_sku_unsol_event,
84898e87 15011 .setup = alc269_laptop_amic_setup,
3b8510ce 15012 .init_hook = alc_inithook,
f53281e6 15013 },
84898e87
KY
15014 [ALC269_DMIC] = {
15015 .mixers = { alc269_laptop_mixer },
15016 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15017 .init_verbs = { alc269_init_verbs,
84898e87
KY
15018 alc269_laptop_dmic_init_verbs },
15019 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15020 .dac_nids = alc269_dac_nids,
15021 .hp_nid = 0x03,
15022 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15023 .channel_mode = alc269_modes,
3b8510ce 15024 .unsol_event = alc_sku_unsol_event,
84898e87 15025 .setup = alc269_laptop_dmic_setup,
3b8510ce 15026 .init_hook = alc_inithook,
84898e87
KY
15027 },
15028 [ALC269VB_AMIC] = {
15029 .mixers = { alc269vb_laptop_mixer },
15030 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15031 .init_verbs = { alc269vb_init_verbs,
15032 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15033 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15034 .dac_nids = alc269_dac_nids,
15035 .hp_nid = 0x03,
15036 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15037 .channel_mode = alc269_modes,
3b8510ce 15038 .unsol_event = alc_sku_unsol_event,
226b1ec8 15039 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15040 .init_hook = alc_inithook,
84898e87
KY
15041 },
15042 [ALC269VB_DMIC] = {
15043 .mixers = { alc269vb_laptop_mixer },
15044 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15045 .init_verbs = { alc269vb_init_verbs,
15046 alc269vb_laptop_dmic_init_verbs },
15047 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15048 .dac_nids = alc269_dac_nids,
15049 .hp_nid = 0x03,
15050 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15051 .channel_mode = alc269_modes,
3b8510ce 15052 .unsol_event = alc_sku_unsol_event,
84898e87 15053 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15054 .init_hook = alc_inithook,
f53281e6 15055 },
26f5df26 15056 [ALC269_FUJITSU] = {
45bdd1c1 15057 .mixers = { alc269_fujitsu_mixer },
84898e87 15058 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15059 .init_verbs = { alc269_init_verbs,
84898e87 15060 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15061 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15062 .dac_nids = alc269_dac_nids,
15063 .hp_nid = 0x03,
15064 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15065 .channel_mode = alc269_modes,
3b8510ce 15066 .unsol_event = alc_sku_unsol_event,
84898e87 15067 .setup = alc269_laptop_dmic_setup,
3b8510ce 15068 .init_hook = alc_inithook,
26f5df26 15069 },
64154835
TV
15070 [ALC269_LIFEBOOK] = {
15071 .mixers = { alc269_lifebook_mixer },
15072 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15073 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15074 .dac_nids = alc269_dac_nids,
15075 .hp_nid = 0x03,
15076 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15077 .channel_mode = alc269_modes,
15078 .input_mux = &alc269_capture_source,
15079 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15080 .setup = alc269_lifebook_setup,
64154835
TV
15081 .init_hook = alc269_lifebook_init_hook,
15082 },
fe3eb0a7
KY
15083 [ALC271_ACER] = {
15084 .mixers = { alc269_asus_mixer },
15085 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15086 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15087 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15088 .dac_nids = alc269_dac_nids,
15089 .adc_nids = alc262_dmic_adc_nids,
15090 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15091 .capsrc_nids = alc262_dmic_capsrc_nids,
15092 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15093 .channel_mode = alc269_modes,
15094 .input_mux = &alc269_capture_source,
15095 .dig_out_nid = ALC880_DIGOUT_NID,
15096 .unsol_event = alc_sku_unsol_event,
15097 .setup = alc269vb_laptop_dmic_setup,
15098 .init_hook = alc_inithook,
15099 },
f6a92248
KY
15100};
15101
977ddd6b
KY
15102static int alc269_fill_coef(struct hda_codec *codec)
15103{
15104 int val;
15105
15106 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15107 alc_write_coef_idx(codec, 0xf, 0x960b);
15108 alc_write_coef_idx(codec, 0xe, 0x8817);
15109 }
15110
15111 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15112 alc_write_coef_idx(codec, 0xf, 0x960b);
15113 alc_write_coef_idx(codec, 0xe, 0x8814);
15114 }
15115
15116 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15117 val = alc_read_coef_idx(codec, 0x04);
15118 /* Power up output pin */
15119 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15120 }
15121
15122 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15123 val = alc_read_coef_idx(codec, 0xd);
15124 if ((val & 0x0c00) >> 10 != 0x1) {
15125 /* Capless ramp up clock control */
b896b4eb 15126 alc_write_coef_idx(codec, 0xd, val | (1<<10));
977ddd6b
KY
15127 }
15128 val = alc_read_coef_idx(codec, 0x17);
15129 if ((val & 0x01c0) >> 6 != 0x4) {
15130 /* Class D power on reset */
b896b4eb 15131 alc_write_coef_idx(codec, 0x17, val | (1<<7));
977ddd6b
KY
15132 }
15133 }
b896b4eb
KY
15134
15135 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15136 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15137
15138 val = alc_read_coef_idx(codec, 0x4); /* HP */
15139 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15140
977ddd6b
KY
15141 return 0;
15142}
15143
f6a92248
KY
15144static int patch_alc269(struct hda_codec *codec)
15145{
15146 struct alc_spec *spec;
48c88e82 15147 int board_config, coef;
f6a92248
KY
15148 int err;
15149
15150 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15151 if (spec == NULL)
15152 return -ENOMEM;
15153
15154 codec->spec = spec;
15155
1f0f4b80
TI
15156 spec->mixer_nid = 0x0b;
15157
da00c244
KY
15158 alc_auto_parse_customize_define(codec);
15159
c793bec5
KY
15160 if (codec->vendor_id == 0x10ec0269) {
15161 coef = alc_read_coef_idx(codec, 0);
15162 if ((coef & 0x00f0) == 0x0010) {
15163 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15164 spec->cdefine.platform_type == 1) {
15165 alc_codec_rename(codec, "ALC271X");
15166 spec->codec_variant = ALC269_TYPE_ALC271X;
15167 } else if ((coef & 0xf000) == 0x1000) {
15168 spec->codec_variant = ALC269_TYPE_ALC270;
15169 } else if ((coef & 0xf000) == 0x2000) {
15170 alc_codec_rename(codec, "ALC259");
15171 spec->codec_variant = ALC269_TYPE_ALC259;
15172 } else if ((coef & 0xf000) == 0x3000) {
15173 alc_codec_rename(codec, "ALC258");
15174 spec->codec_variant = ALC269_TYPE_ALC258;
15175 } else {
15176 alc_codec_rename(codec, "ALC269VB");
15177 spec->codec_variant = ALC269_TYPE_ALC269VB;
15178 }
15179 } else
15180 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15181 alc269_fill_coef(codec);
15182 }
977ddd6b 15183
f6a92248
KY
15184 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15185 alc269_models,
15186 alc269_cfg_tbl);
15187
15188 if (board_config < 0) {
9a11f1aa
TI
15189 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15190 codec->chip_name);
f6a92248
KY
15191 board_config = ALC269_AUTO;
15192 }
15193
b5bfbc67
TI
15194 if (board_config == ALC269_AUTO) {
15195 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15196 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15197 }
ff818c24 15198
f6a92248
KY
15199 if (board_config == ALC269_AUTO) {
15200 /* automatic parse from the BIOS config */
15201 err = alc269_parse_auto_config(codec);
15202 if (err < 0) {
15203 alc_free(codec);
15204 return err;
15205 } else if (!err) {
15206 printk(KERN_INFO
15207 "hda_codec: Cannot set up configuration "
15208 "from BIOS. Using base mode...\n");
15209 board_config = ALC269_BASIC;
15210 }
15211 }
15212
dc1eae25 15213 if (has_cdefine_beep(codec)) {
8af2591d
TI
15214 err = snd_hda_attach_beep_device(codec, 0x1);
15215 if (err < 0) {
15216 alc_free(codec);
15217 return err;
15218 }
680cd536
KK
15219 }
15220
f6a92248 15221 if (board_config != ALC269_AUTO)
e9c364c0 15222 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15223
84898e87 15224 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15225 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15226 * fix the sample rate of analog I/O to 44.1kHz
15227 */
15228 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15229 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15230 } else if (spec->dual_adc_switch) {
15231 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15232 /* switch ADC dynamically */
15233 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15234 } else {
15235 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15236 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15237 }
f6a92248
KY
15238 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15239 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15240
6694635d 15241 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15242 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15243 spec->adc_nids = alc269_adc_nids;
15244 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15245 spec->capsrc_nids = alc269_capsrc_nids;
15246 } else {
15247 spec->adc_nids = alc269vb_adc_nids;
15248 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15249 spec->capsrc_nids = alc269vb_capsrc_nids;
15250 }
84898e87
KY
15251 }
15252
f9e336f6 15253 if (!spec->cap_mixer)
b59bdf3b 15254 set_capture_mixer(codec);
dc1eae25 15255 if (has_cdefine_beep(codec))
da00c244 15256 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15257
b5bfbc67 15258 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15259
100d5eb3
TI
15260 spec->vmaster_nid = 0x02;
15261
f6a92248 15262 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15263#ifdef SND_HDA_NEEDS_RESUME
15264 codec->patch_ops.resume = alc269_resume;
15265#endif
f6a92248
KY
15266 if (board_config == ALC269_AUTO)
15267 spec->init_hook = alc269_auto_init;
5402e4cb 15268 spec->shutup = alc269_shutup;
bf1b0225
KY
15269
15270 alc_init_jacks(codec);
f6a92248
KY
15271#ifdef CONFIG_SND_HDA_POWER_SAVE
15272 if (!spec->loopback.amplist)
15273 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15274 if (alc269_mic2_for_mute_led(codec))
15275 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15276#endif
15277
15278 return 0;
15279}
15280
df694daa
KY
15281/*
15282 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15283 */
15284
15285/*
15286 * set the path ways for 2 channel output
15287 * need to set the codec line out and mic 1 pin widgets to inputs
15288 */
a9111321 15289static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15290 /* set pin widget 1Ah (line in) for input */
15291 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15292 /* set pin widget 18h (mic1/2) for input, for mic also enable
15293 * the vref
15294 */
df694daa
KY
15295 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15296
9c7f852e
TI
15297 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15298#if 0
15299 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15300 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15301#endif
df694daa
KY
15302 { } /* end */
15303};
15304/*
15305 * 6ch mode
15306 * need to set the codec line out and mic 1 pin widgets to outputs
15307 */
a9111321 15308static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15309 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15310 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15311 /* set pin widget 18h (mic1) for output (CLFE)*/
15312 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15313
15314 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15315 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15316
9c7f852e
TI
15317 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15318#if 0
15319 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15320 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15321#endif
df694daa
KY
15322 { } /* end */
15323};
15324
a9111321 15325static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15326 { 2, alc861_threestack_ch2_init },
15327 { 6, alc861_threestack_ch6_init },
15328};
22309c3e 15329/* Set mic1 as input and unmute the mixer */
a9111321 15330static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15331 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15332 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15333 { } /* end */
15334};
15335/* Set mic1 as output and mute mixer */
a9111321 15336static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15337 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15338 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15339 { } /* end */
15340};
15341
a9111321 15342static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15343 { 2, alc861_uniwill_m31_ch2_init },
15344 { 4, alc861_uniwill_m31_ch4_init },
15345};
df694daa 15346
7cdbff94 15347/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15348static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15349 /* set pin widget 1Ah (line in) for input */
15350 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15351 /* set pin widget 18h (mic1/2) for input, for mic also enable
15352 * the vref
15353 */
7cdbff94
MD
15354 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15355
15356 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15357#if 0
15358 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15359 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15360#endif
15361 { } /* end */
15362};
15363/* Set mic1 nad line-in as output and mute mixer */
a9111321 15364static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15365 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15366 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15367 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15368 /* set pin widget 18h (mic1) for output (CLFE)*/
15369 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15370 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15371 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15372 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15373
15374 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15375#if 0
15376 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15377 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15378#endif
15379 { } /* end */
15380};
15381
a9111321 15382static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15383 { 2, alc861_asus_ch2_init },
15384 { 6, alc861_asus_ch6_init },
15385};
15386
df694daa
KY
15387/* patch-ALC861 */
15388
a9111321 15389static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15390 /* output mixer control */
15391 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15392 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15393 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15394 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15395 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15396
15397 /*Input mixer control */
15398 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15399 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15400 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15401 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15402 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15403 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15404 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15405 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15406 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15407 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15408
df694daa
KY
15409 { } /* end */
15410};
15411
a9111321 15412static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15413 /* output mixer control */
15414 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15415 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15416 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15417 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15418 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15419
15420 /* Input mixer control */
15421 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15422 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15423 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15424 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15425 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15426 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15427 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15428 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15429 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15430 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15431
df694daa
KY
15432 {
15433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15434 .name = "Channel Mode",
15435 .info = alc_ch_mode_info,
15436 .get = alc_ch_mode_get,
15437 .put = alc_ch_mode_put,
15438 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15439 },
15440 { } /* end */
a53d1aec
TD
15441};
15442
a9111321 15443static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15444 /* output mixer control */
15445 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15447 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15448
a53d1aec 15449 { } /* end */
f12ab1e0 15450};
a53d1aec 15451
a9111321 15452static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15453 /* output mixer control */
15454 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15455 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15456 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15457 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15458 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15459
15460 /* Input mixer control */
15461 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15463 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15464 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15465 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15466 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15467 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15468 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15469 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15470 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15471
22309c3e
TI
15472 {
15473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15474 .name = "Channel Mode",
15475 .info = alc_ch_mode_info,
15476 .get = alc_ch_mode_get,
15477 .put = alc_ch_mode_put,
15478 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15479 },
15480 { } /* end */
f12ab1e0 15481};
7cdbff94 15482
a9111321 15483static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15484 /* output mixer control */
15485 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15486 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15487 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15488 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15490
15491 /* Input mixer control */
15492 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15493 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15494 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15495 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15496 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15497 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15499 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15500 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15501 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15502
7cdbff94
MD
15503 {
15504 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15505 .name = "Channel Mode",
15506 .info = alc_ch_mode_info,
15507 .get = alc_ch_mode_get,
15508 .put = alc_ch_mode_put,
15509 .private_value = ARRAY_SIZE(alc861_asus_modes),
15510 },
15511 { }
56bb0cab
TI
15512};
15513
15514/* additional mixer */
a9111321 15515static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15516 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15517 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15518 { }
15519};
7cdbff94 15520
df694daa
KY
15521/*
15522 * generic initialization of ADC, input mixers and output mixers
15523 */
a9111321 15524static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15525 /*
15526 * Unmute ADC0 and set the default input to mic-in
15527 */
15528 /* port-A for surround (rear panel) */
15529 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15530 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15531 /* port-B for mic-in (rear panel) with vref */
15532 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15533 /* port-C for line-in (rear panel) */
15534 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15535 /* port-D for Front */
15536 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15537 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15538 /* port-E for HP out (front panel) */
15539 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15540 /* route front PCM to HP */
9dece1d7 15541 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15542 /* port-F for mic-in (front panel) with vref */
15543 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15544 /* port-G for CLFE (rear panel) */
15545 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15546 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15547 /* port-H for side (rear panel) */
15548 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15549 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15550 /* CD-in */
15551 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15552 /* route front mic to ADC1*/
15553 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15554 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15555
df694daa
KY
15556 /* Unmute DAC0~3 & spdif out*/
15557 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15558 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15559 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15560 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15561 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15562
df694daa
KY
15563 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15564 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15565 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15566 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15567 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15568
df694daa
KY
15569 /* Unmute Stereo Mixer 15 */
15570 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15571 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15572 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15574
15575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15578 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15579 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15582 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15583 /* hp used DAC 3 (Front) */
15584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15585 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15586
15587 { }
15588};
15589
a9111321 15590static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15591 /*
15592 * Unmute ADC0 and set the default input to mic-in
15593 */
15594 /* port-A for surround (rear panel) */
15595 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15596 /* port-B for mic-in (rear panel) with vref */
15597 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15598 /* port-C for line-in (rear panel) */
15599 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15600 /* port-D for Front */
15601 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15602 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15603 /* port-E for HP out (front panel) */
15604 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15605 /* route front PCM to HP */
9dece1d7 15606 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15607 /* port-F for mic-in (front panel) with vref */
15608 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15609 /* port-G for CLFE (rear panel) */
15610 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15611 /* port-H for side (rear panel) */
15612 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15613 /* CD-in */
15614 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15615 /* route front mic to ADC1*/
15616 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15618 /* Unmute DAC0~3 & spdif out*/
15619 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15620 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15621 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15622 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15624
df694daa
KY
15625 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15626 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15627 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15628 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15629 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15630
df694daa
KY
15631 /* Unmute Stereo Mixer 15 */
15632 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15634 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15635 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15636
15637 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15640 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15641 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15643 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15645 /* hp used DAC 3 (Front) */
15646 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15647 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15648 { }
15649};
22309c3e 15650
a9111321 15651static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15652 /*
15653 * Unmute ADC0 and set the default input to mic-in
15654 */
15655 /* port-A for surround (rear panel) */
15656 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15657 /* port-B for mic-in (rear panel) with vref */
15658 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15659 /* port-C for line-in (rear panel) */
15660 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15661 /* port-D for Front */
15662 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15663 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15664 /* port-E for HP out (front panel) */
f12ab1e0
TI
15665 /* this has to be set to VREF80 */
15666 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15667 /* route front PCM to HP */
9dece1d7 15668 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15669 /* port-F for mic-in (front panel) with vref */
15670 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15671 /* port-G for CLFE (rear panel) */
15672 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15673 /* port-H for side (rear panel) */
15674 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15675 /* CD-in */
15676 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15677 /* route front mic to ADC1*/
15678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15679 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15680 /* Unmute DAC0~3 & spdif out*/
15681 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15682 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15683 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15684 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15685 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15686
22309c3e
TI
15687 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15688 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15689 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15690 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15691 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15692
22309c3e
TI
15693 /* Unmute Stereo Mixer 15 */
15694 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15695 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15697 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15698
15699 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15700 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15701 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15702 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15703 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15707 /* hp used DAC 3 (Front) */
15708 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15709 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15710 { }
15711};
15712
a9111321 15713static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15714 /*
15715 * Unmute ADC0 and set the default input to mic-in
15716 */
f12ab1e0
TI
15717 /* port-A for surround (rear panel)
15718 * according to codec#0 this is the HP jack
15719 */
7cdbff94
MD
15720 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15721 /* route front PCM to HP */
15722 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15723 /* port-B for mic-in (rear panel) with vref */
15724 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15725 /* port-C for line-in (rear panel) */
15726 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15727 /* port-D for Front */
15728 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15729 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15730 /* port-E for HP out (front panel) */
f12ab1e0
TI
15731 /* this has to be set to VREF80 */
15732 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15733 /* route front PCM to HP */
9dece1d7 15734 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15735 /* port-F for mic-in (front panel) with vref */
15736 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15737 /* port-G for CLFE (rear panel) */
15738 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15739 /* port-H for side (rear panel) */
15740 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15741 /* CD-in */
15742 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15743 /* route front mic to ADC1*/
15744 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15745 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15746 /* Unmute DAC0~3 & spdif out*/
15747 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15748 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15753 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15754 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15755 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15757
7cdbff94
MD
15758 /* Unmute Stereo Mixer 15 */
15759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15760 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15763
15764 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15765 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15766 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15772 /* hp used DAC 3 (Front) */
15773 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15774 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15775 { }
15776};
15777
56bb0cab 15778/* additional init verbs for ASUS laptops */
a9111321 15779static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15780 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15781 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15782 { }
15783};
7cdbff94 15784
a9111321 15785static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15786 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15787
a53d1aec
TD
15788 { }
15789};
15790
15791/* toggle speaker-output according to the hp-jack state */
15792static void alc861_toshiba_automute(struct hda_codec *codec)
15793{
864f92be 15794 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15795
47fd830a
TI
15796 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15797 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15798 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15799 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15800}
15801
15802static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15803 unsigned int res)
15804{
a53d1aec
TD
15805 if ((res >> 26) == ALC880_HP_EVENT)
15806 alc861_toshiba_automute(codec);
15807}
15808
def319f9 15809/* pcm configuration: identical with ALC880 */
df694daa
KY
15810#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15811#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15812#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15813#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15814
15815
15816#define ALC861_DIGOUT_NID 0x07
15817
a9111321 15818static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15819 { 8, NULL }
15820};
15821
4c6d72d1 15822static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15823 /* front, surround, clfe, side */
15824 0x03, 0x06, 0x05, 0x04
15825};
15826
4c6d72d1 15827static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15828 /* front, clfe, surround */
15829 0x03, 0x05, 0x06
15830};
15831
4c6d72d1 15832static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15833 /* ADC0-2 */
15834 0x08,
15835};
15836
a9111321 15837static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15838 .num_items = 5,
15839 .items = {
15840 { "Mic", 0x0 },
15841 { "Front Mic", 0x3 },
15842 { "Line", 0x1 },
15843 { "CD", 0x4 },
15844 { "Mixer", 0x5 },
15845 },
15846};
15847
1c20930a
TI
15848static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15849{
15850 struct alc_spec *spec = codec->spec;
15851 hda_nid_t mix, srcs[5];
3af9ee6b 15852 int i, num;
1c20930a
TI
15853
15854 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15855 return 0;
15856 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15857 if (num < 0)
15858 return 0;
15859 for (i = 0; i < num; i++) {
15860 unsigned int type;
a22d543a 15861 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15862 if (type != AC_WID_AUD_OUT)
15863 continue;
3af9ee6b
TI
15864 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
15865 spec->multiout.num_dacs))
1c20930a
TI
15866 return srcs[i];
15867 }
15868 return 0;
15869}
15870
df694daa 15871/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 15872static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
df694daa 15873{
1c20930a 15874 struct alc_spec *spec = codec->spec;
cb053a82 15875 const struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa 15876 int i;
1c20930a 15877 hda_nid_t nid, dac;
df694daa
KY
15878
15879 spec->multiout.dac_nids = spec->private_dac_nids;
15880 for (i = 0; i < cfg->line_outs; i++) {
15881 nid = cfg->line_out_pins[i];
1c20930a
TI
15882 dac = alc861_look_for_dac(codec, nid);
15883 if (!dac)
15884 continue;
dda14410 15885 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15886 }
df694daa
KY
15887 return 0;
15888}
15889
bcb2f0f5
TI
15890static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15891 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15892{
bcb2f0f5 15893 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15894 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15895}
15896
bcb2f0f5
TI
15897#define alc861_create_out_sw(codec, pfx, nid, chs) \
15898 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15899
df694daa 15900/* add playback controls from the parsed DAC table */
1c20930a 15901static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15902 const struct auto_pin_cfg *cfg)
15903{
1c20930a 15904 struct alc_spec *spec = codec->spec;
df694daa 15905 hda_nid_t nid;
ce764ab2 15906 int i, err, noutputs;
1c20930a 15907
ce764ab2
TI
15908 noutputs = cfg->line_outs;
15909 if (spec->multi_ios > 0)
15910 noutputs += spec->multi_ios;
15911
15912 for (i = 0; i < noutputs; i++) {
6843ca16
TI
15913 const char *name;
15914 int index;
df694daa 15915 nid = spec->multiout.dac_nids[i];
f12ab1e0 15916 if (!nid)
df694daa 15917 continue;
6843ca16
TI
15918 name = alc_get_line_out_pfx(spec, i, true, &index);
15919 if (!name) {
df694daa 15920 /* Center/LFE */
1c20930a 15921 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15922 if (err < 0)
df694daa 15923 return err;
1c20930a 15924 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15925 if (err < 0)
df694daa
KY
15926 return err;
15927 } else {
5a882646 15928 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 15929 if (err < 0)
df694daa
KY
15930 return err;
15931 }
15932 }
15933 return 0;
15934}
15935
1c20930a 15936static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 15937{
1c20930a 15938 struct alc_spec *spec = codec->spec;
df694daa
KY
15939 int err;
15940 hda_nid_t nid;
15941
f12ab1e0 15942 if (!pin)
df694daa
KY
15943 return 0;
15944
15945 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
15946 nid = alc861_look_for_dac(codec, pin);
15947 if (nid) {
15948 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
15949 if (err < 0)
15950 return err;
15951 spec->multiout.hp_nid = nid;
15952 }
df694daa
KY
15953 }
15954 return 0;
15955}
15956
15957/* create playback/capture controls for input pins */
05f5f477 15958static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 15959 const struct auto_pin_cfg *cfg)
df694daa 15960{
05f5f477 15961 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
15962}
15963
f12ab1e0
TI
15964static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
15965 hda_nid_t nid,
1c20930a 15966 int pin_type, hda_nid_t dac)
df694daa 15967{
1c20930a
TI
15968 hda_nid_t mix, srcs[5];
15969 int i, num;
15970
564c5bea
JL
15971 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
15972 pin_type);
1c20930a 15973 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 15974 AMP_OUT_UNMUTE);
1c20930a
TI
15975 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
15976 return;
15977 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15978 if (num < 0)
15979 return;
15980 for (i = 0; i < num; i++) {
15981 unsigned int mute;
15982 if (srcs[i] == dac || srcs[i] == 0x15)
15983 mute = AMP_IN_UNMUTE(i);
15984 else
15985 mute = AMP_IN_MUTE(i);
15986 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
15987 mute);
15988 }
df694daa
KY
15989}
15990
15991static void alc861_auto_init_multi_out(struct hda_codec *codec)
15992{
15993 struct alc_spec *spec = codec->spec;
15994 int i;
15995
1f0f4b80 15996 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
df694daa 15997 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 15998 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 15999 if (nid)
baba8ee9 16000 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16001 spec->multiout.dac_nids[i]);
df694daa
KY
16002 }
16003}
16004
16005static void alc861_auto_init_hp_out(struct hda_codec *codec)
16006{
16007 struct alc_spec *spec = codec->spec;
df694daa 16008
15870f05
TI
16009 if (spec->autocfg.hp_outs)
16010 alc861_auto_set_output_and_unmute(codec,
16011 spec->autocfg.hp_pins[0],
16012 PIN_HP,
1c20930a 16013 spec->multiout.hp_nid);
15870f05
TI
16014 if (spec->autocfg.speaker_outs)
16015 alc861_auto_set_output_and_unmute(codec,
16016 spec->autocfg.speaker_pins[0],
16017 PIN_OUT,
1c20930a 16018 spec->multiout.dac_nids[0]);
df694daa
KY
16019}
16020
1f0f4b80 16021#define alc861_auto_init_analog_input alc880_auto_init_analog_input
df694daa
KY
16022
16023/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16024/* return 1 if successful, 0 if the proper config is not found,
16025 * or a negative error code
16026 */
df694daa
KY
16027static int alc861_parse_auto_config(struct hda_codec *codec)
16028{
16029 struct alc_spec *spec = codec->spec;
16030 int err;
4c6d72d1 16031 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16032
f12ab1e0
TI
16033 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16034 alc861_ignore);
16035 if (err < 0)
df694daa 16036 return err;
f12ab1e0 16037 if (!spec->autocfg.line_outs)
df694daa
KY
16038 return 0; /* can't find valid BIOS pin config */
16039
cb053a82 16040 err = alc861_auto_fill_dac_nids(codec);
ce764ab2
TI
16041 if (err < 0)
16042 return err;
cb053a82 16043 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids);
f12ab1e0
TI
16044 if (err < 0)
16045 return err;
1c20930a 16046 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16047 if (err < 0)
16048 return err;
1c20930a 16049 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16050 if (err < 0)
16051 return err;
05f5f477 16052 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16053 if (err < 0)
df694daa
KY
16054 return err;
16055
16056 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16057
757899ac 16058 alc_auto_parse_digital(codec);
df694daa 16059
603c4019 16060 if (spec->kctls.list)
d88897ea 16061 add_mixer(spec, spec->kctls.list);
df694daa 16062
a1e8d2da 16063 spec->num_mux_defs = 1;
61b9b9b1 16064 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16065
16066 spec->adc_nids = alc861_adc_nids;
16067 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16068 set_capture_mixer(codec);
df694daa 16069
6227cdce 16070 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16071
df694daa
KY
16072 return 1;
16073}
16074
ae6b813a
TI
16075/* additional initialization for auto-configuration model */
16076static void alc861_auto_init(struct hda_codec *codec)
df694daa 16077{
f6c7e546 16078 struct alc_spec *spec = codec->spec;
df694daa
KY
16079 alc861_auto_init_multi_out(codec);
16080 alc861_auto_init_hp_out(codec);
16081 alc861_auto_init_analog_input(codec);
757899ac 16082 alc_auto_init_digital(codec);
f6c7e546 16083 if (spec->unsol_event)
7fb0d78f 16084 alc_inithook(codec);
df694daa
KY
16085}
16086
cb53c626 16087#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16088static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16089 { 0x15, HDA_INPUT, 0 },
16090 { 0x15, HDA_INPUT, 1 },
16091 { 0x15, HDA_INPUT, 2 },
16092 { 0x15, HDA_INPUT, 3 },
16093 { } /* end */
16094};
16095#endif
16096
df694daa
KY
16097
16098/*
16099 * configuration and preset
16100 */
ea734963 16101static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16102 [ALC861_3ST] = "3stack",
16103 [ALC660_3ST] = "3stack-660",
16104 [ALC861_3ST_DIG] = "3stack-dig",
16105 [ALC861_6ST_DIG] = "6stack-dig",
16106 [ALC861_UNIWILL_M31] = "uniwill-m31",
16107 [ALC861_TOSHIBA] = "toshiba",
16108 [ALC861_ASUS] = "asus",
16109 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16110 [ALC861_AUTO] = "auto",
16111};
16112
a9111321 16113static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16114 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16115 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16116 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16117 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16118 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16119 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16120 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16121 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16122 * Any other models that need this preset?
16123 */
16124 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16125 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16126 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16127 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16128 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16129 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16130 /* FIXME: the below seems conflict */
16131 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16132 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16133 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16134 {}
16135};
16136
a9111321 16137static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16138 [ALC861_3ST] = {
16139 .mixers = { alc861_3ST_mixer },
16140 .init_verbs = { alc861_threestack_init_verbs },
16141 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16142 .dac_nids = alc861_dac_nids,
16143 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16144 .channel_mode = alc861_threestack_modes,
4e195a7b 16145 .need_dac_fix = 1,
df694daa
KY
16146 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16147 .adc_nids = alc861_adc_nids,
16148 .input_mux = &alc861_capture_source,
16149 },
16150 [ALC861_3ST_DIG] = {
16151 .mixers = { alc861_base_mixer },
16152 .init_verbs = { alc861_threestack_init_verbs },
16153 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16154 .dac_nids = alc861_dac_nids,
16155 .dig_out_nid = ALC861_DIGOUT_NID,
16156 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16157 .channel_mode = alc861_threestack_modes,
4e195a7b 16158 .need_dac_fix = 1,
df694daa
KY
16159 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16160 .adc_nids = alc861_adc_nids,
16161 .input_mux = &alc861_capture_source,
16162 },
16163 [ALC861_6ST_DIG] = {
16164 .mixers = { alc861_base_mixer },
16165 .init_verbs = { alc861_base_init_verbs },
16166 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16167 .dac_nids = alc861_dac_nids,
16168 .dig_out_nid = ALC861_DIGOUT_NID,
16169 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16170 .channel_mode = alc861_8ch_modes,
16171 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16172 .adc_nids = alc861_adc_nids,
16173 .input_mux = &alc861_capture_source,
16174 },
9c7f852e
TI
16175 [ALC660_3ST] = {
16176 .mixers = { alc861_3ST_mixer },
16177 .init_verbs = { alc861_threestack_init_verbs },
16178 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16179 .dac_nids = alc660_dac_nids,
16180 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16181 .channel_mode = alc861_threestack_modes,
4e195a7b 16182 .need_dac_fix = 1,
9c7f852e
TI
16183 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16184 .adc_nids = alc861_adc_nids,
16185 .input_mux = &alc861_capture_source,
16186 },
22309c3e
TI
16187 [ALC861_UNIWILL_M31] = {
16188 .mixers = { alc861_uniwill_m31_mixer },
16189 .init_verbs = { alc861_uniwill_m31_init_verbs },
16190 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16191 .dac_nids = alc861_dac_nids,
16192 .dig_out_nid = ALC861_DIGOUT_NID,
16193 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16194 .channel_mode = alc861_uniwill_m31_modes,
16195 .need_dac_fix = 1,
16196 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16197 .adc_nids = alc861_adc_nids,
16198 .input_mux = &alc861_capture_source,
16199 },
a53d1aec
TD
16200 [ALC861_TOSHIBA] = {
16201 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16202 .init_verbs = { alc861_base_init_verbs,
16203 alc861_toshiba_init_verbs },
a53d1aec
TD
16204 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16205 .dac_nids = alc861_dac_nids,
16206 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16207 .channel_mode = alc883_3ST_2ch_modes,
16208 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16209 .adc_nids = alc861_adc_nids,
16210 .input_mux = &alc861_capture_source,
16211 .unsol_event = alc861_toshiba_unsol_event,
16212 .init_hook = alc861_toshiba_automute,
16213 },
7cdbff94
MD
16214 [ALC861_ASUS] = {
16215 .mixers = { alc861_asus_mixer },
16216 .init_verbs = { alc861_asus_init_verbs },
16217 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16218 .dac_nids = alc861_dac_nids,
16219 .dig_out_nid = ALC861_DIGOUT_NID,
16220 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16221 .channel_mode = alc861_asus_modes,
16222 .need_dac_fix = 1,
16223 .hp_nid = 0x06,
16224 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16225 .adc_nids = alc861_adc_nids,
16226 .input_mux = &alc861_capture_source,
16227 },
56bb0cab
TI
16228 [ALC861_ASUS_LAPTOP] = {
16229 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16230 .init_verbs = { alc861_asus_init_verbs,
16231 alc861_asus_laptop_init_verbs },
16232 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16233 .dac_nids = alc861_dac_nids,
16234 .dig_out_nid = ALC861_DIGOUT_NID,
16235 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16236 .channel_mode = alc883_3ST_2ch_modes,
16237 .need_dac_fix = 1,
16238 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16239 .adc_nids = alc861_adc_nids,
16240 .input_mux = &alc861_capture_source,
16241 },
16242};
df694daa 16243
cfc9b06f
TI
16244/* Pin config fixes */
16245enum {
16246 PINFIX_FSC_AMILO_PI1505,
16247};
16248
cfc9b06f
TI
16249static const struct alc_fixup alc861_fixups[] = {
16250 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16251 .type = ALC_FIXUP_PINS,
16252 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16253 { 0x0b, 0x0221101f }, /* HP */
16254 { 0x0f, 0x90170310 }, /* speaker */
16255 { }
16256 }
cfc9b06f
TI
16257 },
16258};
16259
a9111321 16260static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16261 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16262 {}
16263};
df694daa
KY
16264
16265static int patch_alc861(struct hda_codec *codec)
16266{
16267 struct alc_spec *spec;
16268 int board_config;
16269 int err;
16270
dc041e0b 16271 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16272 if (spec == NULL)
16273 return -ENOMEM;
16274
f12ab1e0 16275 codec->spec = spec;
df694daa 16276
1f0f4b80
TI
16277 spec->mixer_nid = 0x15;
16278
f5fcc13c
TI
16279 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16280 alc861_models,
16281 alc861_cfg_tbl);
9c7f852e 16282
f5fcc13c 16283 if (board_config < 0) {
9a11f1aa
TI
16284 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16285 codec->chip_name);
df694daa
KY
16286 board_config = ALC861_AUTO;
16287 }
16288
b5bfbc67
TI
16289 if (board_config == ALC861_AUTO) {
16290 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16291 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16292 }
cfc9b06f 16293
df694daa
KY
16294 if (board_config == ALC861_AUTO) {
16295 /* automatic parse from the BIOS config */
16296 err = alc861_parse_auto_config(codec);
16297 if (err < 0) {
16298 alc_free(codec);
16299 return err;
f12ab1e0 16300 } else if (!err) {
9c7f852e
TI
16301 printk(KERN_INFO
16302 "hda_codec: Cannot set up configuration "
16303 "from BIOS. Using base mode...\n");
df694daa
KY
16304 board_config = ALC861_3ST_DIG;
16305 }
16306 }
16307
680cd536
KK
16308 err = snd_hda_attach_beep_device(codec, 0x23);
16309 if (err < 0) {
16310 alc_free(codec);
16311 return err;
16312 }
16313
df694daa 16314 if (board_config != ALC861_AUTO)
e9c364c0 16315 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16316
df694daa
KY
16317 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16318 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16319
df694daa
KY
16320 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16321 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16322
c7a8eb10
TI
16323 if (!spec->cap_mixer)
16324 set_capture_mixer(codec);
45bdd1c1
TI
16325 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16326
2134ea4f
TI
16327 spec->vmaster_nid = 0x03;
16328
b5bfbc67 16329 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16330
df694daa 16331 codec->patch_ops = alc_patch_ops;
c97259df 16332 if (board_config == ALC861_AUTO) {
ae6b813a 16333 spec->init_hook = alc861_auto_init;
c97259df
DC
16334#ifdef CONFIG_SND_HDA_POWER_SAVE
16335 spec->power_hook = alc_power_eapd;
16336#endif
16337 }
cb53c626
TI
16338#ifdef CONFIG_SND_HDA_POWER_SAVE
16339 if (!spec->loopback.amplist)
16340 spec->loopback.amplist = alc861_loopbacks;
16341#endif
ea1fb29a 16342
1da177e4
LT
16343 return 0;
16344}
16345
f32610ed
JS
16346/*
16347 * ALC861-VD support
16348 *
16349 * Based on ALC882
16350 *
16351 * In addition, an independent DAC
16352 */
16353#define ALC861VD_DIGOUT_NID 0x06
16354
4c6d72d1 16355static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16356 /* front, surr, clfe, side surr */
16357 0x02, 0x03, 0x04, 0x05
16358};
16359
16360/* dac_nids for ALC660vd are in a different order - according to
16361 * Realtek's driver.
def319f9 16362 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16363 * of ALC660vd codecs, but for now there is only 3stack mixer
16364 * - and it is the same as in 861vd.
16365 * adc_nids in ALC660vd are (is) the same as in 861vd
16366 */
4c6d72d1 16367static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16368 /* front, rear, clfe, rear_surr */
16369 0x02, 0x04, 0x03
16370};
16371
4c6d72d1 16372static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16373 /* ADC0 */
16374 0x09,
16375};
16376
4c6d72d1 16377static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16378
f32610ed
JS
16379/* input MUX */
16380/* FIXME: should be a matrix-type input source selection */
a9111321 16381static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16382 .num_items = 4,
16383 .items = {
16384 { "Mic", 0x0 },
16385 { "Front Mic", 0x1 },
16386 { "Line", 0x2 },
16387 { "CD", 0x4 },
16388 },
16389};
16390
a9111321 16391static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16392 .num_items = 2,
272a527c 16393 .items = {
8607f7c4 16394 { "Mic", 0x0 },
28c4edb7 16395 { "Internal Mic", 0x1 },
272a527c
KY
16396 },
16397};
16398
a9111321 16399static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16400 .num_items = 2,
16401 .items = {
16402 { "Front Mic", 0x0 },
16403 { "ATAPI Mic", 0x1 },
16404 },
16405};
16406
f32610ed
JS
16407/*
16408 * 2ch mode
16409 */
a9111321 16410static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16411 { 2, NULL }
16412};
16413
16414/*
16415 * 6ch mode
16416 */
a9111321 16417static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16418 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16419 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16420 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16421 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16422 { } /* end */
16423};
16424
16425/*
16426 * 8ch mode
16427 */
a9111321 16428static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16429 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16430 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16431 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16432 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16433 { } /* end */
16434};
16435
a9111321 16436static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16437 { 6, alc861vd_6stack_ch6_init },
16438 { 8, alc861vd_6stack_ch8_init },
16439};
16440
a9111321 16441static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16442 {
16443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16444 .name = "Channel Mode",
16445 .info = alc_ch_mode_info,
16446 .get = alc_ch_mode_get,
16447 .put = alc_ch_mode_put,
16448 },
16449 { } /* end */
16450};
16451
f32610ed
JS
16452/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16453 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16454 */
a9111321 16455static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16456 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16457 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16458
16459 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16460 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16461
16462 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16463 HDA_OUTPUT),
16464 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16465 HDA_OUTPUT),
16466 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16467 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16468
16469 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16470 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16471
16472 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16473
5f99f86a 16474 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16475 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16476 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16477
5f99f86a 16478 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16479 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16480 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16481
16482 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16483 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16484
16485 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16486 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16487
f32610ed
JS
16488 { } /* end */
16489};
16490
a9111321 16491static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16492 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16493 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16494
16495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16496
5f99f86a 16497 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16498 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16499 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16500
5f99f86a 16501 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16502 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16503 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16504
16505 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16506 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16507
16508 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16509 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16510
f32610ed
JS
16511 { } /* end */
16512};
16513
a9111321 16514static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16515 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16516 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16517 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16518
16519 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16520
5f99f86a 16521 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16524
5f99f86a 16525 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16526 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16527 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16528
16529 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16530 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16531
16532 { } /* end */
16533};
16534
b419f346 16535/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16536 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16537 */
a9111321 16538static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16539 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16540 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16541 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16542 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16543 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16544 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16545 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16546 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16547 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16548 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16549 { } /* end */
16550};
16551
d1a991a6
KY
16552/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16553 * Front Mic=0x18, ATAPI Mic = 0x19,
16554 */
a9111321 16555static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16556 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16557 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16558 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16559 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16560 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16561 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16562 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16563 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16564
d1a991a6
KY
16565 { } /* end */
16566};
16567
f32610ed
JS
16568/*
16569 * generic initialization of ADC, input mixers and output mixers
16570 */
a9111321 16571static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16572 /*
16573 * Unmute ADC0 and set the default input to mic-in
16574 */
16575 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16576 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16577
16578 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16579 * the analog-loopback mixer widget
16580 */
16581 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16582 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16583 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16584 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16587
16588 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16590 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16591 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16592 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16593
16594 /*
16595 * Set up output mixers (0x02 - 0x05)
16596 */
16597 /* set vol=0 to output mixers */
16598 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16599 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16600 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16601 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16602
16603 /* set up input amps for analog loopback */
16604 /* Amp Indices: DAC = 0, mixer = 1 */
16605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16606 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16608 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16609 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16610 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16611 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16612 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16613
16614 { }
16615};
16616
16617/*
16618 * 3-stack pin configuration:
16619 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16620 */
a9111321 16621static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16622 /*
16623 * Set pin mode and muting
16624 */
16625 /* set front pin widgets 0x14 for output */
16626 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16627 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16628 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16629
16630 /* Mic (rear) pin: input vref at 80% */
16631 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16632 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16633 /* Front Mic pin: input vref at 80% */
16634 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16635 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16636 /* Line In pin: input */
16637 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16638 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16639 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16640 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16641 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16642 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16643 /* CD pin widget for input */
16644 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16645
16646 { }
16647};
16648
16649/*
16650 * 6-stack pin configuration:
16651 */
a9111321 16652static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16653 /*
16654 * Set pin mode and muting
16655 */
16656 /* set front pin widgets 0x14 for output */
16657 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16658 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16659 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16660
16661 /* Rear Pin: output 1 (0x0d) */
16662 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16663 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16664 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16665 /* CLFE Pin: output 2 (0x0e) */
16666 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16667 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16668 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16669 /* Side Pin: output 3 (0x0f) */
16670 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16671 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16672 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16673
16674 /* Mic (rear) pin: input vref at 80% */
16675 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16676 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16677 /* Front Mic pin: input vref at 80% */
16678 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16679 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16680 /* Line In pin: input */
16681 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16682 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16683 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16684 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16685 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16686 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16687 /* CD pin widget for input */
16688 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16689
16690 { }
16691};
16692
a9111321 16693static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16694 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16695 { }
16696};
16697
a9111321 16698static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16699 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16700 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16701 { }
16702};
16703
a9111321 16704static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16705 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16706 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16707 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16708 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16709 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16710 {}
16711};
16712
4f5d1706 16713static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16714{
a9fd4f3f 16715 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16716 spec->autocfg.hp_pins[0] = 0x1b;
16717 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16718 spec->automute = 1;
16719 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16720}
16721
16722static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16723{
d922b51d 16724 alc_hp_automute(codec);
eeb43387 16725 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16726}
16727
16728static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16729 unsigned int res)
16730{
16731 switch (res >> 26) {
bdd148a3 16732 case ALC880_MIC_EVENT:
eeb43387 16733 alc88x_simple_mic_automute(codec);
bdd148a3 16734 break;
a9fd4f3f 16735 default:
d922b51d 16736 alc_sku_unsol_event(codec, res);
a9fd4f3f 16737 break;
bdd148a3
KY
16738 }
16739}
16740
a9111321 16741static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16742 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16743 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16744 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16745 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16746
16747 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16748 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16749 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16750 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16751 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16752 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16753 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16754 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16755
272a527c
KY
16756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16758 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16759 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16760 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16761 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16762 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16763 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16764
16765 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16766 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16768 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16769 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16770 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16771 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16772 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16773
16774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16775 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16776 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16777 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16778
16779 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16780 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16781 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16782
16783 { } /* end */
16784};
16785
16786/* toggle speaker-output according to the hp-jack state */
4f5d1706 16787static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16788{
a9fd4f3f 16789 struct alc_spec *spec = codec->spec;
272a527c 16790
a9fd4f3f
TI
16791 spec->autocfg.hp_pins[0] = 0x15;
16792 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16793 spec->automute = 1;
16794 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16795}
16796
cb53c626
TI
16797#ifdef CONFIG_SND_HDA_POWER_SAVE
16798#define alc861vd_loopbacks alc880_loopbacks
16799#endif
16800
def319f9 16801/* pcm configuration: identical with ALC880 */
f32610ed
JS
16802#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16803#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16804#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16805#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16806
16807/*
16808 * configuration and preset
16809 */
ea734963 16810static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16811 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16812 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16813 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16814 [ALC861VD_3ST] = "3stack",
16815 [ALC861VD_3ST_DIG] = "3stack-digout",
16816 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16817 [ALC861VD_LENOVO] = "lenovo",
272a527c 16818 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16819 [ALC861VD_HP] = "hp",
f32610ed
JS
16820 [ALC861VD_AUTO] = "auto",
16821};
16822
a9111321 16823static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16824 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16825 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16826 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16827 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16828 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16829 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16830 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16831 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16832 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16833 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16834 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16835 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16836 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16837 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16838 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16839 {}
16840};
16841
a9111321 16842static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16843 [ALC660VD_3ST] = {
16844 .mixers = { alc861vd_3st_mixer },
16845 .init_verbs = { alc861vd_volume_init_verbs,
16846 alc861vd_3stack_init_verbs },
16847 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16848 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16849 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16850 .channel_mode = alc861vd_3stack_2ch_modes,
16851 .input_mux = &alc861vd_capture_source,
16852 },
6963f84c
MC
16853 [ALC660VD_3ST_DIG] = {
16854 .mixers = { alc861vd_3st_mixer },
16855 .init_verbs = { alc861vd_volume_init_verbs,
16856 alc861vd_3stack_init_verbs },
16857 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16858 .dac_nids = alc660vd_dac_nids,
16859 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16860 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16861 .channel_mode = alc861vd_3stack_2ch_modes,
16862 .input_mux = &alc861vd_capture_source,
16863 },
f32610ed
JS
16864 [ALC861VD_3ST] = {
16865 .mixers = { alc861vd_3st_mixer },
16866 .init_verbs = { alc861vd_volume_init_verbs,
16867 alc861vd_3stack_init_verbs },
16868 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16869 .dac_nids = alc861vd_dac_nids,
16870 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16871 .channel_mode = alc861vd_3stack_2ch_modes,
16872 .input_mux = &alc861vd_capture_source,
16873 },
16874 [ALC861VD_3ST_DIG] = {
16875 .mixers = { alc861vd_3st_mixer },
16876 .init_verbs = { alc861vd_volume_init_verbs,
16877 alc861vd_3stack_init_verbs },
16878 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16879 .dac_nids = alc861vd_dac_nids,
16880 .dig_out_nid = ALC861VD_DIGOUT_NID,
16881 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16882 .channel_mode = alc861vd_3stack_2ch_modes,
16883 .input_mux = &alc861vd_capture_source,
16884 },
16885 [ALC861VD_6ST_DIG] = {
16886 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16887 .init_verbs = { alc861vd_volume_init_verbs,
16888 alc861vd_6stack_init_verbs },
16889 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16890 .dac_nids = alc861vd_dac_nids,
16891 .dig_out_nid = ALC861VD_DIGOUT_NID,
16892 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16893 .channel_mode = alc861vd_6stack_modes,
16894 .input_mux = &alc861vd_capture_source,
16895 },
bdd148a3
KY
16896 [ALC861VD_LENOVO] = {
16897 .mixers = { alc861vd_lenovo_mixer },
16898 .init_verbs = { alc861vd_volume_init_verbs,
16899 alc861vd_3stack_init_verbs,
16900 alc861vd_eapd_verbs,
16901 alc861vd_lenovo_unsol_verbs },
16902 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16903 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16904 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16905 .channel_mode = alc861vd_3stack_2ch_modes,
16906 .input_mux = &alc861vd_capture_source,
16907 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16908 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16909 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16910 },
272a527c
KY
16911 [ALC861VD_DALLAS] = {
16912 .mixers = { alc861vd_dallas_mixer },
16913 .init_verbs = { alc861vd_dallas_verbs },
16914 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16915 .dac_nids = alc861vd_dac_nids,
272a527c
KY
16916 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16917 .channel_mode = alc861vd_3stack_2ch_modes,
16918 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 16919 .unsol_event = alc_sku_unsol_event,
4f5d1706 16920 .setup = alc861vd_dallas_setup,
d922b51d 16921 .init_hook = alc_hp_automute,
d1a991a6
KY
16922 },
16923 [ALC861VD_HP] = {
16924 .mixers = { alc861vd_hp_mixer },
16925 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16926 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16927 .dac_nids = alc861vd_dac_nids,
d1a991a6 16928 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
16929 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16930 .channel_mode = alc861vd_3stack_2ch_modes,
16931 .input_mux = &alc861vd_hp_capture_source,
d922b51d 16932 .unsol_event = alc_sku_unsol_event,
4f5d1706 16933 .setup = alc861vd_dallas_setup,
d922b51d 16934 .init_hook = alc_hp_automute,
ea1fb29a 16935 },
13c94744
TI
16936 [ALC660VD_ASUS_V1S] = {
16937 .mixers = { alc861vd_lenovo_mixer },
16938 .init_verbs = { alc861vd_volume_init_verbs,
16939 alc861vd_3stack_init_verbs,
16940 alc861vd_eapd_verbs,
16941 alc861vd_lenovo_unsol_verbs },
16942 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16943 .dac_nids = alc660vd_dac_nids,
16944 .dig_out_nid = ALC861VD_DIGOUT_NID,
16945 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16946 .channel_mode = alc861vd_3stack_2ch_modes,
16947 .input_mux = &alc861vd_capture_source,
16948 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16949 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16950 .init_hook = alc861vd_lenovo_init_hook,
13c94744 16951 },
f32610ed
JS
16952};
16953
16954/*
16955 * BIOS auto configuration
16956 */
05f5f477
TI
16957static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
16958 const struct auto_pin_cfg *cfg)
16959{
7167594a 16960 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
16961}
16962
16963
1f0f4b80
TI
16964#define alc861vd_auto_init_multi_out alc882_auto_init_multi_out
16965#define alc861vd_auto_init_hp_out alc882_auto_init_hp_out
16966#define alc861vd_auto_init_analog_input alc882_auto_init_analog_input
f511b01c
TI
16967#define alc861vd_auto_init_input_src alc882_auto_init_input_src
16968
f32610ed
JS
16969#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16970#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16971
16972/* add playback controls from the parsed DAC table */
569ed348 16973/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
16974 * different NIDs for mute/unmute switch and volume control */
16975static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16976 const struct auto_pin_cfg *cfg)
16977{
f32610ed 16978 hda_nid_t nid_v, nid_s;
ce764ab2 16979 int i, err, noutputs;
f32610ed 16980
ce764ab2
TI
16981 noutputs = cfg->line_outs;
16982 if (spec->multi_ios > 0)
16983 noutputs += spec->multi_ios;
16984
16985 for (i = 0; i < noutputs; i++) {
6843ca16
TI
16986 const char *name;
16987 int index;
f12ab1e0 16988 if (!spec->multiout.dac_nids[i])
f32610ed
JS
16989 continue;
16990 nid_v = alc861vd_idx_to_mixer_vol(
16991 alc880_dac_to_idx(
16992 spec->multiout.dac_nids[i]));
16993 nid_s = alc861vd_idx_to_mixer_switch(
16994 alc880_dac_to_idx(
16995 spec->multiout.dac_nids[i]));
16996
6843ca16
TI
16997 name = alc_get_line_out_pfx(spec, i, true, &index);
16998 if (!name) {
f32610ed 16999 /* Center/LFE */
0afe5f89
TI
17000 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17001 "Center",
f12ab1e0
TI
17002 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17003 HDA_OUTPUT));
17004 if (err < 0)
f32610ed 17005 return err;
0afe5f89
TI
17006 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17007 "LFE",
f12ab1e0
TI
17008 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17009 HDA_OUTPUT));
17010 if (err < 0)
f32610ed 17011 return err;
0afe5f89
TI
17012 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17013 "Center",
f12ab1e0
TI
17014 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17015 HDA_INPUT));
17016 if (err < 0)
f32610ed 17017 return err;
0afe5f89
TI
17018 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17019 "LFE",
f12ab1e0
TI
17020 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17021 HDA_INPUT));
17022 if (err < 0)
f32610ed
JS
17023 return err;
17024 } else {
bcb2f0f5 17025 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17026 name, index,
f12ab1e0
TI
17027 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17028 HDA_OUTPUT));
17029 if (err < 0)
f32610ed 17030 return err;
bcb2f0f5 17031 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17032 name, index,
bdd148a3 17033 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17034 HDA_INPUT));
17035 if (err < 0)
f32610ed
JS
17036 return err;
17037 }
17038 }
17039 return 0;
17040}
17041
17042/* add playback controls for speaker and HP outputs */
17043/* Based on ALC880 version. But ALC861VD has separate,
17044 * different NIDs for mute/unmute switch and volume control */
17045static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17046 hda_nid_t pin, const char *pfx)
17047{
17048 hda_nid_t nid_v, nid_s;
17049 int err;
f32610ed 17050
f12ab1e0 17051 if (!pin)
f32610ed
JS
17052 return 0;
17053
17054 if (alc880_is_fixed_pin(pin)) {
17055 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17056 /* specify the DAC as the extra output */
f12ab1e0 17057 if (!spec->multiout.hp_nid)
f32610ed
JS
17058 spec->multiout.hp_nid = nid_v;
17059 else
17060 spec->multiout.extra_out_nid[0] = nid_v;
17061 /* control HP volume/switch on the output mixer amp */
17062 nid_v = alc861vd_idx_to_mixer_vol(
17063 alc880_fixed_pin_idx(pin));
17064 nid_s = alc861vd_idx_to_mixer_switch(
17065 alc880_fixed_pin_idx(pin));
17066
0afe5f89 17067 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17068 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17069 if (err < 0)
f32610ed 17070 return err;
0afe5f89 17071 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17072 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17073 if (err < 0)
f32610ed
JS
17074 return err;
17075 } else if (alc880_is_multi_pin(pin)) {
17076 /* set manual connection */
17077 /* we have only a switch on HP-out PIN */
0afe5f89 17078 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17079 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17080 if (err < 0)
f32610ed
JS
17081 return err;
17082 }
17083 return 0;
17084}
17085
17086/* parse the BIOS configuration and set up the alc_spec
17087 * return 1 if successful, 0 if the proper config is not found,
17088 * or a negative error code
17089 * Based on ALC880 version - had to change it to override
17090 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17091static int alc861vd_parse_auto_config(struct hda_codec *codec)
17092{
17093 struct alc_spec *spec = codec->spec;
17094 int err;
4c6d72d1 17095 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17096
f12ab1e0
TI
17097 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17098 alc861vd_ignore);
17099 if (err < 0)
f32610ed 17100 return err;
f12ab1e0 17101 if (!spec->autocfg.line_outs)
f32610ed
JS
17102 return 0; /* can't find valid BIOS pin config */
17103
cb053a82 17104 err = alc880_auto_fill_dac_nids(codec);
ce764ab2
TI
17105 if (err < 0)
17106 return err;
cb053a82 17107 err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids);
f12ab1e0
TI
17108 if (err < 0)
17109 return err;
17110 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17111 if (err < 0)
17112 return err;
17113 err = alc861vd_auto_create_extra_out(spec,
17114 spec->autocfg.speaker_pins[0],
17115 "Speaker");
17116 if (err < 0)
17117 return err;
17118 err = alc861vd_auto_create_extra_out(spec,
17119 spec->autocfg.hp_pins[0],
17120 "Headphone");
17121 if (err < 0)
17122 return err;
05f5f477 17123 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17124 if (err < 0)
f32610ed
JS
17125 return err;
17126
17127 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17128
757899ac 17129 alc_auto_parse_digital(codec);
f32610ed 17130
603c4019 17131 if (spec->kctls.list)
d88897ea 17132 add_mixer(spec, spec->kctls.list);
f32610ed 17133
f32610ed 17134 spec->num_mux_defs = 1;
61b9b9b1 17135 spec->input_mux = &spec->private_imux[0];
f32610ed 17136
776e184e
TI
17137 err = alc_auto_add_mic_boost(codec);
17138 if (err < 0)
17139 return err;
17140
6227cdce 17141 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17142
f32610ed
JS
17143 return 1;
17144}
17145
17146/* additional initialization for auto-configuration model */
17147static void alc861vd_auto_init(struct hda_codec *codec)
17148{
f6c7e546 17149 struct alc_spec *spec = codec->spec;
f32610ed
JS
17150 alc861vd_auto_init_multi_out(codec);
17151 alc861vd_auto_init_hp_out(codec);
17152 alc861vd_auto_init_analog_input(codec);
f511b01c 17153 alc861vd_auto_init_input_src(codec);
757899ac 17154 alc_auto_init_digital(codec);
f6c7e546 17155 if (spec->unsol_event)
7fb0d78f 17156 alc_inithook(codec);
f32610ed
JS
17157}
17158
f8f25ba3
TI
17159enum {
17160 ALC660VD_FIX_ASUS_GPIO1
17161};
17162
17163/* reset GPIO1 */
f8f25ba3
TI
17164static const struct alc_fixup alc861vd_fixups[] = {
17165 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17166 .type = ALC_FIXUP_VERBS,
17167 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17168 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17169 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17170 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17171 { }
17172 }
f8f25ba3
TI
17173 },
17174};
17175
a9111321 17176static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17177 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17178 {}
17179};
17180
f32610ed
JS
17181static int patch_alc861vd(struct hda_codec *codec)
17182{
17183 struct alc_spec *spec;
17184 int err, board_config;
17185
17186 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17187 if (spec == NULL)
17188 return -ENOMEM;
17189
17190 codec->spec = spec;
17191
1f0f4b80
TI
17192 spec->mixer_nid = 0x0b;
17193
f32610ed
JS
17194 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17195 alc861vd_models,
17196 alc861vd_cfg_tbl);
17197
17198 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17199 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17200 codec->chip_name);
f32610ed
JS
17201 board_config = ALC861VD_AUTO;
17202 }
17203
b5bfbc67
TI
17204 if (board_config == ALC861VD_AUTO) {
17205 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17206 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17207 }
f8f25ba3 17208
f32610ed
JS
17209 if (board_config == ALC861VD_AUTO) {
17210 /* automatic parse from the BIOS config */
17211 err = alc861vd_parse_auto_config(codec);
17212 if (err < 0) {
17213 alc_free(codec);
17214 return err;
f12ab1e0 17215 } else if (!err) {
f32610ed
JS
17216 printk(KERN_INFO
17217 "hda_codec: Cannot set up configuration "
17218 "from BIOS. Using base mode...\n");
17219 board_config = ALC861VD_3ST;
17220 }
17221 }
17222
680cd536
KK
17223 err = snd_hda_attach_beep_device(codec, 0x23);
17224 if (err < 0) {
17225 alc_free(codec);
17226 return err;
17227 }
17228
f32610ed 17229 if (board_config != ALC861VD_AUTO)
e9c364c0 17230 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17231
2f893286 17232 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17233 /* always turn on EAPD */
d88897ea 17234 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17235 }
17236
f32610ed
JS
17237 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17238 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17239
f32610ed
JS
17240 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17241 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17242
dd704698
TI
17243 if (!spec->adc_nids) {
17244 spec->adc_nids = alc861vd_adc_nids;
17245 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17246 }
17247 if (!spec->capsrc_nids)
17248 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17249
b59bdf3b 17250 set_capture_mixer(codec);
45bdd1c1 17251 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17252
2134ea4f
TI
17253 spec->vmaster_nid = 0x02;
17254
b5bfbc67 17255 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17256
f32610ed
JS
17257 codec->patch_ops = alc_patch_ops;
17258
17259 if (board_config == ALC861VD_AUTO)
17260 spec->init_hook = alc861vd_auto_init;
1c716153 17261 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17262#ifdef CONFIG_SND_HDA_POWER_SAVE
17263 if (!spec->loopback.amplist)
17264 spec->loopback.amplist = alc861vd_loopbacks;
17265#endif
f32610ed
JS
17266
17267 return 0;
17268}
17269
bc9f98a9
KY
17270/*
17271 * ALC662 support
17272 *
17273 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17274 * configuration. Each pin widget can choose any input DACs and a mixer.
17275 * Each ADC is connected from a mixer of all inputs. This makes possible
17276 * 6-channel independent captures.
17277 *
17278 * In addition, an independent DAC for the multi-playback (not used in this
17279 * driver yet).
17280 */
17281#define ALC662_DIGOUT_NID 0x06
17282#define ALC662_DIGIN_NID 0x0a
17283
4c6d72d1 17284static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17285 /* front, rear, clfe */
bc9f98a9
KY
17286 0x02, 0x03, 0x04
17287};
17288
4c6d72d1 17289static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17290 0x02, 0x03
17291};
17292
4c6d72d1 17293static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17294 /* ADC1-2 */
b59bdf3b 17295 0x09, 0x08
bc9f98a9 17296};
e1406348 17297
4c6d72d1 17298static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17299 /* ADC1-2 */
17300 0x08,
17301};
17302
4c6d72d1
TI
17303static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17304static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17305
e1406348 17306
bc9f98a9
KY
17307/* input MUX */
17308/* FIXME: should be a matrix-type input source selection */
a9111321 17309static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17310 .num_items = 4,
17311 .items = {
17312 { "Mic", 0x0 },
17313 { "Front Mic", 0x1 },
17314 { "Line", 0x2 },
17315 { "CD", 0x4 },
17316 },
17317};
17318
a9111321 17319static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17320 .num_items = 2,
17321 .items = {
17322 { "Mic", 0x1 },
17323 { "Line", 0x2 },
17324 },
17325};
291702f0 17326
a9111321 17327static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17328 .num_items = 3,
17329 .items = {
17330 { "Mic", 0x0 },
17331 { "Front Mic", 0x1 },
17332 { "Line", 0x2 },
17333 },
17334};
17335
4f5d1706 17336#if 0 /* set to 1 for testing other input sources below */
a9111321 17337static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17338 .num_items = 16,
17339 .items = {
17340 { "Autoselect Mic", 0x0 },
17341 { "Internal Mic", 0x1 },
17342 { "In-0x02", 0x2 },
17343 { "In-0x03", 0x3 },
17344 { "In-0x04", 0x4 },
17345 { "In-0x05", 0x5 },
17346 { "In-0x06", 0x6 },
17347 { "In-0x07", 0x7 },
17348 { "In-0x08", 0x8 },
17349 { "In-0x09", 0x9 },
17350 { "In-0x0a", 0x0a },
17351 { "In-0x0b", 0x0b },
17352 { "In-0x0c", 0x0c },
17353 { "In-0x0d", 0x0d },
17354 { "In-0x0e", 0x0e },
17355 { "In-0x0f", 0x0f },
17356 },
17357};
17358#endif
17359
bc9f98a9
KY
17360/*
17361 * 2ch mode
17362 */
a9111321 17363static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17364 { 2, NULL }
17365};
17366
17367/*
17368 * 2ch mode
17369 */
a9111321 17370static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17371 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17372 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17373 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17374 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17375 { } /* end */
17376};
17377
17378/*
17379 * 6ch mode
17380 */
a9111321 17381static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17382 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17383 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17384 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17385 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17386 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17387 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17388 { } /* end */
17389};
17390
a9111321 17391static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17392 { 2, alc662_3ST_ch2_init },
17393 { 6, alc662_3ST_ch6_init },
17394};
17395
17396/*
17397 * 2ch mode
17398 */
a9111321 17399static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17400 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17401 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17402 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17403 { } /* end */
17404};
17405
17406/*
17407 * 6ch mode
17408 */
a9111321 17409static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17410 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17411 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17412 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17413 { } /* end */
17414};
17415
a9111321 17416static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17417 { 2, alc662_sixstack_ch6_init },
17418 { 6, alc662_sixstack_ch8_init },
17419};
17420
17421/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17422 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17423 */
17424
a9111321 17425static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17426 /* output mixer control */
17427 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17428 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17429 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17430 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17431 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17432 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17433 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17434 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17435 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17436
17437 /*Input mixer control */
17438 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17439 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17440 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17441 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17442 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17443 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17444 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17446 { } /* end */
17447};
17448
a9111321 17449static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17450 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17451 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17452 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17453 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17454 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17455 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17456 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17457 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17458 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17459 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17460 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17461 { } /* end */
17462};
17463
a9111321 17464static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17465 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17466 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17467 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17468 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17469 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17470 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17471 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17472 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17474 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17475 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17476 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17477 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17478 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17480 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17482 { } /* end */
17483};
17484
a9111321 17485static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17486 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17487 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17488 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17489 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17490 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17491 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17492 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17493 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17494 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17495 { } /* end */
17496};
17497
a9111321 17498static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17499 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17500 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17501
5f99f86a 17502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17503 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17504 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17505
5f99f86a 17506 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17507 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17508 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17509 { } /* end */
17510};
17511
a9111321 17512static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17513 ALC262_HIPPO_MASTER_SWITCH,
17514 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17515 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17516 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17517 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17518 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17519 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17520 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17521 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17523 { } /* end */
17524};
17525
a9111321 17526static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17527 .ops = &snd_hda_bind_vol,
17528 .values = {
17529 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17530 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17531 0
17532 },
17533};
17534
a9111321 17535static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17536 .ops = &snd_hda_bind_sw,
17537 .values = {
17538 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17539 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17540 0
17541 },
17542};
17543
a9111321 17544static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17545 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17546 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17548 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17549 { } /* end */
17550};
17551
a9111321 17552static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17553 .ops = &snd_hda_bind_sw,
17554 .values = {
17555 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17556 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17557 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17558 0
17559 },
17560};
17561
a9111321 17562static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17563 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17564 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17566 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17567 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17568 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17569
17570 { } /* end */
17571};
17572
a9111321 17573static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17574 .ops = &snd_hda_bind_sw,
17575 .values = {
17576 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17577 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17578 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17579 0
17580 },
17581};
17582
a9111321 17583static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17584 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17585 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17586 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17588 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17589 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17590 { } /* end */
17591};
17592
a9111321 17593static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17594 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17595 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17596 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17599 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17600 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17601 { } /* end */
17602};
17603
a9111321 17604static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17605 .ops = &snd_hda_bind_vol,
17606 .values = {
17607 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17608 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17609 0
17610 },
17611};
17612
a9111321 17613static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17614 .ops = &snd_hda_bind_sw,
17615 .values = {
17616 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17617 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17618 0
17619 },
17620};
17621
a9111321 17622static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17623 HDA_BIND_VOL("Master Playback Volume",
17624 &alc663_asus_two_bind_master_vol),
17625 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17626 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17628 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17629 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17630 { } /* end */
17631};
17632
a9111321 17633static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17634 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17635 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17636 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17637 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17638 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17639 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17640 { } /* end */
17641};
17642
a9111321 17643static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17644 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17645 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17646 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17647 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17648 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17649
17650 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17651 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17652 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17653 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17654 { } /* end */
17655};
17656
a9111321 17657static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17658 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17659 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17660 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17661
17662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17664 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17665 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17666 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17667 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17668 { } /* end */
17669};
17670
a9111321 17671static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17672 .ops = &snd_hda_bind_sw,
17673 .values = {
17674 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17675 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17676 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17677 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17678 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17679 0
17680 },
17681};
17682
a9111321 17683static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17684 .ops = &snd_hda_bind_sw,
17685 .values = {
17686 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17687 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17688 0
17689 },
17690};
17691
a9111321 17692static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17693 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17694 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17695 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17696 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17697 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17698 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17699 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17700 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17701 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17702 { } /* end */
17703};
17704
a9111321 17705static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17706 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17707 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17708 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17709 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17710 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17711 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17712 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17713 { } /* end */
17714};
17715
17716
a9111321 17717static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17718 {
17719 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17720 .name = "Channel Mode",
17721 .info = alc_ch_mode_info,
17722 .get = alc_ch_mode_get,
17723 .put = alc_ch_mode_put,
17724 },
17725 { } /* end */
17726};
17727
a9111321 17728static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17729 /* ADC: mute amp left and right */
17730 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17731 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17732
b60dd394
KY
17733 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17734 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17735 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17736 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17737 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17738 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17739
17740 /* Front Pin: output 0 (0x0c) */
17741 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17743
17744 /* Rear Pin: output 1 (0x0d) */
17745 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17746 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17747
17748 /* CLFE Pin: output 2 (0x0e) */
17749 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17750 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17751
17752 /* Mic (rear) pin: input vref at 80% */
17753 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17754 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17755 /* Front Mic pin: input vref at 80% */
17756 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17757 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17758 /* Line In pin: input */
17759 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17760 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17761 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17763 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17764 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17765 /* CD pin widget for input */
17766 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17767
17768 /* FIXME: use matrix-type input source selection */
17769 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17770 /* Input mixer */
17771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17772 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17773
a7f2371f
TI
17774 { }
17775};
17776
a9111321 17777static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17778 /* always trun on EAPD */
17779 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17780 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17781 { }
17782};
17783
a9111321 17784static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17785 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17786 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17787 {}
17788};
17789
a9111321 17790static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17791 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17792 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17793 {}
bc9f98a9
KY
17794};
17795
8c427226 17796/* Set Unsolicited Event*/
a9111321 17797static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17798 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17800 {}
17801};
17802
a9111321 17803static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17804 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17806 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17807 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17808 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17809 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17810 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17811 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17812 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17813 {}
17814};
17815
a9111321 17816static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17817 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17818 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17819 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17821 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17822 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17823 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17824 {}
17825};
17826
a9111321 17827static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17828 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17829 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17830 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17831 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17832 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17833 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17834 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17835 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17836 {}
17837};
6dda9f4a 17838
a9111321 17839static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17840 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17841 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17842 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17843 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17844 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17845 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17846 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17847 {}
17848};
6dda9f4a 17849
a9111321 17850static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17851 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17852 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17853 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17854 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17855 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17856 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17857 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17858 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17859 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
17860 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17861 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
17862 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17863 {}
17864};
17865
a9111321 17866static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
17867 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17868 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17869 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17870 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17871 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17872 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17873 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17874 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17875 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17876 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17877 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17878 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
17879 {}
17880};
17881
a9111321 17882static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
17883 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17884 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17885 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17886
17887 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17888 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17889 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17890
17891 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17892 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17893 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17894 {}
17895};
17896
a9111321 17897static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
17898 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17899 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17900 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17901
17902 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17903 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17904 {}
17905};
17906
a9111321 17907static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
17908 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17909 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17910 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17911 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17912 {}
17913};
17914
a9111321 17915static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
17916 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17917 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17918 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17919 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17920 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17921 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17922 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17923 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17924 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17925 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17926 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17927 {}
17928};
17929
a9111321 17930static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
17931 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17932 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17933 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17934 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17935 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17936 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17937 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17938 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17939 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17940 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17941 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17942 {}
17943};
17944
a9111321 17945static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
17946 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17948 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17949 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17950 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17951 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17952 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17953 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17954 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17955 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17957 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17958 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17959 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17960 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17961 {}
17962};
17963
a9111321 17964static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
17965 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17966 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17967 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17969 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17970 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17971 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17972 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17973 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17974 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17975 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17976 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17977 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17978 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17979 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17980 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17981 {}
17982};
17983
a9111321 17984static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
17985 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17986 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17987 { } /* end */
17988};
17989
a9111321 17990static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
17991 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17992 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17993 { } /* end */
17994};
17995
e6a5e1b7 17996static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 17997{
e6a5e1b7 17998 struct alc_spec *spec = codec->spec;
bc9f98a9 17999
e6a5e1b7
TI
18000 spec->autocfg.hp_pins[0] = 0x1b;
18001 spec->autocfg.line_out_pins[0] = 0x14;
18002 spec->autocfg.speaker_pins[0] = 0x15;
18003 spec->automute = 1;
18004 spec->detect_line = 1;
18005 spec->automute_lines = 1;
18006 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18007}
18008
4f5d1706
TI
18009static void alc662_eeepc_setup(struct hda_codec *codec)
18010{
18011 struct alc_spec *spec = codec->spec;
18012
18013 alc262_hippo1_setup(codec);
18014 spec->ext_mic.pin = 0x18;
18015 spec->ext_mic.mux_idx = 0;
18016 spec->int_mic.pin = 0x19;
18017 spec->int_mic.mux_idx = 1;
18018 spec->auto_mic = 1;
18019}
18020
4f5d1706 18021static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18022{
42171c17
TI
18023 struct alc_spec *spec = codec->spec;
18024
18025 spec->autocfg.hp_pins[0] = 0x14;
18026 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18027 spec->automute = 1;
18028 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18029}
18030
4f5d1706
TI
18031static void alc663_m51va_setup(struct hda_codec *codec)
18032{
18033 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18034 spec->autocfg.hp_pins[0] = 0x21;
18035 spec->autocfg.speaker_pins[0] = 0x14;
18036 spec->automute_mixer_nid[0] = 0x0c;
18037 spec->automute = 1;
18038 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18039 spec->ext_mic.pin = 0x18;
18040 spec->ext_mic.mux_idx = 0;
18041 spec->int_mic.pin = 0x12;
ebb83eeb 18042 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18043 spec->auto_mic = 1;
18044}
18045
f1d4e28b 18046/* ***************** Mode1 ******************************/
ebb83eeb
KY
18047static void alc663_mode1_setup(struct hda_codec *codec)
18048{
18049 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18050 spec->autocfg.hp_pins[0] = 0x21;
18051 spec->autocfg.speaker_pins[0] = 0x14;
18052 spec->automute_mixer_nid[0] = 0x0c;
18053 spec->automute = 1;
18054 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18055 spec->ext_mic.pin = 0x18;
18056 spec->ext_mic.mux_idx = 0;
18057 spec->int_mic.pin = 0x19;
18058 spec->int_mic.mux_idx = 1;
18059 spec->auto_mic = 1;
18060}
18061
f1d4e28b 18062/* ***************** Mode2 ******************************/
3b8510ce 18063static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18064{
3b8510ce
TI
18065 struct alc_spec *spec = codec->spec;
18066 spec->autocfg.hp_pins[0] = 0x1b;
18067 spec->autocfg.speaker_pins[0] = 0x14;
18068 spec->automute = 1;
18069 spec->automute_mode = ALC_AUTOMUTE_PIN;
18070 spec->ext_mic.pin = 0x18;
18071 spec->ext_mic.mux_idx = 0;
18072 spec->int_mic.pin = 0x19;
18073 spec->int_mic.mux_idx = 1;
18074 spec->auto_mic = 1;
f1d4e28b
KY
18075}
18076
f1d4e28b 18077/* ***************** Mode3 ******************************/
3b8510ce 18078static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18079{
3b8510ce
TI
18080 struct alc_spec *spec = codec->spec;
18081 spec->autocfg.hp_pins[0] = 0x21;
18082 spec->autocfg.hp_pins[0] = 0x15;
18083 spec->autocfg.speaker_pins[0] = 0x14;
18084 spec->automute = 1;
18085 spec->automute_mode = ALC_AUTOMUTE_PIN;
18086 spec->ext_mic.pin = 0x18;
18087 spec->ext_mic.mux_idx = 0;
18088 spec->int_mic.pin = 0x19;
18089 spec->int_mic.mux_idx = 1;
18090 spec->auto_mic = 1;
f1d4e28b
KY
18091}
18092
f1d4e28b 18093/* ***************** Mode4 ******************************/
3b8510ce 18094static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18095{
3b8510ce
TI
18096 struct alc_spec *spec = codec->spec;
18097 spec->autocfg.hp_pins[0] = 0x21;
18098 spec->autocfg.speaker_pins[0] = 0x14;
18099 spec->autocfg.speaker_pins[1] = 0x16;
18100 spec->automute_mixer_nid[0] = 0x0c;
18101 spec->automute_mixer_nid[1] = 0x0e;
18102 spec->automute = 1;
18103 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18104 spec->ext_mic.pin = 0x18;
18105 spec->ext_mic.mux_idx = 0;
18106 spec->int_mic.pin = 0x19;
18107 spec->int_mic.mux_idx = 1;
18108 spec->auto_mic = 1;
f1d4e28b
KY
18109}
18110
f1d4e28b 18111/* ***************** Mode5 ******************************/
3b8510ce 18112static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18113{
3b8510ce
TI
18114 struct alc_spec *spec = codec->spec;
18115 spec->autocfg.hp_pins[0] = 0x15;
18116 spec->autocfg.speaker_pins[0] = 0x14;
18117 spec->autocfg.speaker_pins[1] = 0x16;
18118 spec->automute_mixer_nid[0] = 0x0c;
18119 spec->automute_mixer_nid[1] = 0x0e;
18120 spec->automute = 1;
18121 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18122 spec->ext_mic.pin = 0x18;
18123 spec->ext_mic.mux_idx = 0;
18124 spec->int_mic.pin = 0x19;
18125 spec->int_mic.mux_idx = 1;
18126 spec->auto_mic = 1;
f1d4e28b
KY
18127}
18128
f1d4e28b 18129/* ***************** Mode6 ******************************/
3b8510ce 18130static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18131{
3b8510ce
TI
18132 struct alc_spec *spec = codec->spec;
18133 spec->autocfg.hp_pins[0] = 0x1b;
18134 spec->autocfg.hp_pins[0] = 0x15;
18135 spec->autocfg.speaker_pins[0] = 0x14;
18136 spec->automute_mixer_nid[0] = 0x0c;
18137 spec->automute = 1;
18138 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18139 spec->ext_mic.pin = 0x18;
18140 spec->ext_mic.mux_idx = 0;
18141 spec->int_mic.pin = 0x19;
18142 spec->int_mic.mux_idx = 1;
18143 spec->auto_mic = 1;
f1d4e28b
KY
18144}
18145
ebb83eeb 18146/* ***************** Mode7 ******************************/
3b8510ce 18147static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18148{
3b8510ce
TI
18149 struct alc_spec *spec = codec->spec;
18150 spec->autocfg.hp_pins[0] = 0x1b;
18151 spec->autocfg.hp_pins[0] = 0x21;
18152 spec->autocfg.speaker_pins[0] = 0x14;
18153 spec->autocfg.speaker_pins[0] = 0x17;
18154 spec->automute = 1;
18155 spec->automute_mode = ALC_AUTOMUTE_PIN;
18156 spec->ext_mic.pin = 0x18;
18157 spec->ext_mic.mux_idx = 0;
18158 spec->int_mic.pin = 0x19;
18159 spec->int_mic.mux_idx = 1;
18160 spec->auto_mic = 1;
ebb83eeb
KY
18161}
18162
18163/* ***************** Mode8 ******************************/
3b8510ce 18164static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18165{
3b8510ce
TI
18166 struct alc_spec *spec = codec->spec;
18167 spec->autocfg.hp_pins[0] = 0x21;
18168 spec->autocfg.hp_pins[1] = 0x15;
18169 spec->autocfg.speaker_pins[0] = 0x14;
18170 spec->autocfg.speaker_pins[0] = 0x17;
18171 spec->automute = 1;
18172 spec->automute_mode = ALC_AUTOMUTE_PIN;
18173 spec->ext_mic.pin = 0x18;
18174 spec->ext_mic.mux_idx = 0;
18175 spec->int_mic.pin = 0x12;
18176 spec->int_mic.mux_idx = 9;
18177 spec->auto_mic = 1;
ebb83eeb
KY
18178}
18179
e6a5e1b7 18180static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18181{
e6a5e1b7
TI
18182 struct alc_spec *spec = codec->spec;
18183 spec->autocfg.hp_pins[0] = 0x21;
18184 spec->autocfg.line_out_pins[0] = 0x15;
18185 spec->autocfg.speaker_pins[0] = 0x14;
18186 spec->automute = 1;
18187 spec->automute_mode = ALC_AUTOMUTE_AMP;
18188 spec->detect_line = 1;
18189 spec->automute_lines = 1;
18190 spec->ext_mic.pin = 0x18;
18191 spec->ext_mic.mux_idx = 0;
18192 spec->int_mic.pin = 0x12;
18193 spec->int_mic.mux_idx = 9;
18194 spec->auto_mic = 1;
6dda9f4a
KY
18195}
18196
4f5d1706
TI
18197#define alc663_g50v_setup alc663_m51va_setup
18198
a9111321 18199static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18200 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18201 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18202
5f99f86a 18203 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18204 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18205 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18206
5f99f86a 18207 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18208 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18209 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18210 { } /* end */
18211};
18212
a9111321 18213static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18214 /* Master Playback automatically created from Speaker and Headphone */
18215 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18216 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18217 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18219
8607f7c4
DH
18220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18221 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18222 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18223
28c4edb7
DH
18224 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18225 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18226 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18227 { } /* end */
18228};
18229
cb53c626
TI
18230#ifdef CONFIG_SND_HDA_POWER_SAVE
18231#define alc662_loopbacks alc880_loopbacks
18232#endif
18233
bc9f98a9 18234
def319f9 18235/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18236#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18237#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18238#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18239#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18240
18241/*
18242 * configuration and preset
18243 */
ea734963 18244static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18245 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18246 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18247 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18248 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18249 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18250 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18251 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18252 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18253 [ALC663_ASUS_M51VA] = "m51va",
18254 [ALC663_ASUS_G71V] = "g71v",
18255 [ALC663_ASUS_H13] = "h13",
18256 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18257 [ALC663_ASUS_MODE1] = "asus-mode1",
18258 [ALC662_ASUS_MODE2] = "asus-mode2",
18259 [ALC663_ASUS_MODE3] = "asus-mode3",
18260 [ALC663_ASUS_MODE4] = "asus-mode4",
18261 [ALC663_ASUS_MODE5] = "asus-mode5",
18262 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18263 [ALC663_ASUS_MODE7] = "asus-mode7",
18264 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18265 [ALC272_DELL] = "dell",
18266 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18267 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18268 [ALC662_AUTO] = "auto",
18269};
18270
a9111321 18271static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18272 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18273 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18274 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18275 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18276 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18277 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18278 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18279 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18280 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18281 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18282 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18283 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18284 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18285 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18286 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18287 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18288 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18289 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18290 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18291 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18292 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18293 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18294 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18295 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18296 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18297 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18298 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18299 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18300 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18301 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18302 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18303 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18304 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18305 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18306 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18307 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18308 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18309 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18310 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18311 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18312 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18313 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18314 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18315 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18316 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18317 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18318 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18319 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18320 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18321 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18322 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18323 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18324 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18325 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18326 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18327 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18328 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18329 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18330 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18331 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18332 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18333 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18334 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18335 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18336 ALC662_3ST_6ch_DIG),
4dee8baa 18337 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18338 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18339 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18340 ALC662_3ST_6ch_DIG),
6227cdce 18341 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18342 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18343 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18344 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18345 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18346 ALC662_3ST_6ch_DIG),
dea0a509
TI
18347 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18348 ALC663_ASUS_H13),
965b76d2 18349 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18350 {}
18351};
18352
a9111321 18353static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18354 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18355 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18356 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18357 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18358 .dac_nids = alc662_dac_nids,
18359 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18360 .dig_in_nid = ALC662_DIGIN_NID,
18361 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18362 .channel_mode = alc662_3ST_2ch_modes,
18363 .input_mux = &alc662_capture_source,
18364 },
18365 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18366 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18367 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18368 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18369 .dac_nids = alc662_dac_nids,
18370 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18371 .dig_in_nid = ALC662_DIGIN_NID,
18372 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18373 .channel_mode = alc662_3ST_6ch_modes,
18374 .need_dac_fix = 1,
18375 .input_mux = &alc662_capture_source,
f12ab1e0 18376 },
bc9f98a9 18377 [ALC662_3ST_6ch] = {
f9e336f6 18378 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18379 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18380 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18381 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18382 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18383 .channel_mode = alc662_3ST_6ch_modes,
18384 .need_dac_fix = 1,
18385 .input_mux = &alc662_capture_source,
f12ab1e0 18386 },
bc9f98a9 18387 [ALC662_5ST_DIG] = {
f9e336f6 18388 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18389 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18390 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18391 .dac_nids = alc662_dac_nids,
18392 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18393 .dig_in_nid = ALC662_DIGIN_NID,
18394 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18395 .channel_mode = alc662_5stack_modes,
18396 .input_mux = &alc662_capture_source,
18397 },
18398 [ALC662_LENOVO_101E] = {
f9e336f6 18399 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18400 .init_verbs = { alc662_init_verbs,
18401 alc662_eapd_init_verbs,
18402 alc662_sue_init_verbs },
bc9f98a9
KY
18403 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18404 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18405 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18406 .channel_mode = alc662_3ST_2ch_modes,
18407 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18408 .unsol_event = alc_sku_unsol_event,
18409 .setup = alc662_lenovo_101e_setup,
18410 .init_hook = alc_inithook,
bc9f98a9 18411 },
291702f0 18412 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18413 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18414 .init_verbs = { alc662_init_verbs,
a7f2371f 18415 alc662_eapd_init_verbs,
291702f0
KY
18416 alc662_eeepc_sue_init_verbs },
18417 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18418 .dac_nids = alc662_dac_nids,
291702f0
KY
18419 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18420 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18421 .unsol_event = alc_sku_unsol_event,
4f5d1706 18422 .setup = alc662_eeepc_setup,
e9427969 18423 .init_hook = alc_inithook,
291702f0 18424 },
8c427226 18425 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18426 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18427 alc662_chmode_mixer },
18428 .init_verbs = { alc662_init_verbs,
a7f2371f 18429 alc662_eapd_init_verbs,
8c427226
KY
18430 alc662_eeepc_ep20_sue_init_verbs },
18431 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18432 .dac_nids = alc662_dac_nids,
8c427226
KY
18433 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18434 .channel_mode = alc662_3ST_6ch_modes,
18435 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18436 .unsol_event = alc_sku_unsol_event,
4f5d1706 18437 .setup = alc662_eeepc_ep20_setup,
e9427969 18438 .init_hook = alc_inithook,
8c427226 18439 },
f1d4e28b 18440 [ALC662_ECS] = {
f9e336f6 18441 .mixers = { alc662_ecs_mixer },
f1d4e28b 18442 .init_verbs = { alc662_init_verbs,
a7f2371f 18443 alc662_eapd_init_verbs,
f1d4e28b
KY
18444 alc662_ecs_init_verbs },
18445 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18446 .dac_nids = alc662_dac_nids,
18447 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18448 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18449 .unsol_event = alc_sku_unsol_event,
4f5d1706 18450 .setup = alc662_eeepc_setup,
e9427969 18451 .init_hook = alc_inithook,
f1d4e28b 18452 },
6dda9f4a 18453 [ALC663_ASUS_M51VA] = {
f9e336f6 18454 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18455 .init_verbs = { alc662_init_verbs,
18456 alc662_eapd_init_verbs,
18457 alc663_m51va_init_verbs },
6dda9f4a
KY
18458 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18459 .dac_nids = alc662_dac_nids,
18460 .dig_out_nid = ALC662_DIGOUT_NID,
18461 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18462 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18463 .unsol_event = alc_sku_unsol_event,
4f5d1706 18464 .setup = alc663_m51va_setup,
3b8510ce 18465 .init_hook = alc_inithook,
6dda9f4a
KY
18466 },
18467 [ALC663_ASUS_G71V] = {
f9e336f6 18468 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18469 .init_verbs = { alc662_init_verbs,
18470 alc662_eapd_init_verbs,
18471 alc663_g71v_init_verbs },
6dda9f4a
KY
18472 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18473 .dac_nids = alc662_dac_nids,
18474 .dig_out_nid = ALC662_DIGOUT_NID,
18475 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18476 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18477 .unsol_event = alc_sku_unsol_event,
4f5d1706 18478 .setup = alc663_g71v_setup,
e6a5e1b7 18479 .init_hook = alc_inithook,
6dda9f4a
KY
18480 },
18481 [ALC663_ASUS_H13] = {
f9e336f6 18482 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18483 .init_verbs = { alc662_init_verbs,
18484 alc662_eapd_init_verbs,
18485 alc663_m51va_init_verbs },
6dda9f4a
KY
18486 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18487 .dac_nids = alc662_dac_nids,
18488 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18489 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18490 .setup = alc663_m51va_setup,
18491 .unsol_event = alc_sku_unsol_event,
18492 .init_hook = alc_inithook,
6dda9f4a
KY
18493 },
18494 [ALC663_ASUS_G50V] = {
f9e336f6 18495 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18496 .init_verbs = { alc662_init_verbs,
18497 alc662_eapd_init_verbs,
18498 alc663_g50v_init_verbs },
6dda9f4a
KY
18499 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18500 .dac_nids = alc662_dac_nids,
18501 .dig_out_nid = ALC662_DIGOUT_NID,
18502 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18503 .channel_mode = alc662_3ST_6ch_modes,
18504 .input_mux = &alc663_capture_source,
3b8510ce 18505 .unsol_event = alc_sku_unsol_event,
4f5d1706 18506 .setup = alc663_g50v_setup,
3b8510ce 18507 .init_hook = alc_inithook,
6dda9f4a 18508 },
f1d4e28b 18509 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18510 .mixers = { alc663_m51va_mixer },
18511 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18512 .init_verbs = { alc662_init_verbs,
a7f2371f 18513 alc662_eapd_init_verbs,
f1d4e28b
KY
18514 alc663_21jd_amic_init_verbs },
18515 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18516 .hp_nid = 0x03,
18517 .dac_nids = alc662_dac_nids,
18518 .dig_out_nid = ALC662_DIGOUT_NID,
18519 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18520 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18521 .unsol_event = alc_sku_unsol_event,
4f5d1706 18522 .setup = alc663_mode1_setup,
3b8510ce 18523 .init_hook = alc_inithook,
f1d4e28b
KY
18524 },
18525 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18526 .mixers = { alc662_1bjd_mixer },
18527 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18528 .init_verbs = { alc662_init_verbs,
a7f2371f 18529 alc662_eapd_init_verbs,
f1d4e28b
KY
18530 alc662_1bjd_amic_init_verbs },
18531 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18532 .dac_nids = alc662_dac_nids,
18533 .dig_out_nid = ALC662_DIGOUT_NID,
18534 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18535 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18536 .unsol_event = alc_sku_unsol_event,
4f5d1706 18537 .setup = alc662_mode2_setup,
3b8510ce 18538 .init_hook = alc_inithook,
f1d4e28b
KY
18539 },
18540 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18541 .mixers = { alc663_two_hp_m1_mixer },
18542 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18543 .init_verbs = { alc662_init_verbs,
a7f2371f 18544 alc662_eapd_init_verbs,
f1d4e28b
KY
18545 alc663_two_hp_amic_m1_init_verbs },
18546 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18547 .hp_nid = 0x03,
18548 .dac_nids = alc662_dac_nids,
18549 .dig_out_nid = ALC662_DIGOUT_NID,
18550 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18551 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18552 .unsol_event = alc_sku_unsol_event,
4f5d1706 18553 .setup = alc663_mode3_setup,
3b8510ce 18554 .init_hook = alc_inithook,
f1d4e28b
KY
18555 },
18556 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18557 .mixers = { alc663_asus_21jd_clfe_mixer },
18558 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18559 .init_verbs = { alc662_init_verbs,
a7f2371f 18560 alc662_eapd_init_verbs,
f1d4e28b
KY
18561 alc663_21jd_amic_init_verbs},
18562 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18563 .hp_nid = 0x03,
18564 .dac_nids = alc662_dac_nids,
18565 .dig_out_nid = ALC662_DIGOUT_NID,
18566 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18567 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18568 .unsol_event = alc_sku_unsol_event,
4f5d1706 18569 .setup = alc663_mode4_setup,
3b8510ce 18570 .init_hook = alc_inithook,
f1d4e28b
KY
18571 },
18572 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18573 .mixers = { alc663_asus_15jd_clfe_mixer },
18574 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18575 .init_verbs = { alc662_init_verbs,
a7f2371f 18576 alc662_eapd_init_verbs,
f1d4e28b
KY
18577 alc663_15jd_amic_init_verbs },
18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18579 .hp_nid = 0x03,
18580 .dac_nids = alc662_dac_nids,
18581 .dig_out_nid = ALC662_DIGOUT_NID,
18582 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18583 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18584 .unsol_event = alc_sku_unsol_event,
4f5d1706 18585 .setup = alc663_mode5_setup,
3b8510ce 18586 .init_hook = alc_inithook,
f1d4e28b
KY
18587 },
18588 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18589 .mixers = { alc663_two_hp_m2_mixer },
18590 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18591 .init_verbs = { alc662_init_verbs,
a7f2371f 18592 alc662_eapd_init_verbs,
f1d4e28b
KY
18593 alc663_two_hp_amic_m2_init_verbs },
18594 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18595 .hp_nid = 0x03,
18596 .dac_nids = alc662_dac_nids,
18597 .dig_out_nid = ALC662_DIGOUT_NID,
18598 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18599 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18600 .unsol_event = alc_sku_unsol_event,
4f5d1706 18601 .setup = alc663_mode6_setup,
3b8510ce 18602 .init_hook = alc_inithook,
f1d4e28b 18603 },
ebb83eeb
KY
18604 [ALC663_ASUS_MODE7] = {
18605 .mixers = { alc663_mode7_mixer },
18606 .cap_mixer = alc662_auto_capture_mixer,
18607 .init_verbs = { alc662_init_verbs,
a7f2371f 18608 alc662_eapd_init_verbs,
ebb83eeb
KY
18609 alc663_mode7_init_verbs },
18610 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18611 .hp_nid = 0x03,
18612 .dac_nids = alc662_dac_nids,
18613 .dig_out_nid = ALC662_DIGOUT_NID,
18614 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18615 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18616 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18617 .setup = alc663_mode7_setup,
3b8510ce 18618 .init_hook = alc_inithook,
ebb83eeb
KY
18619 },
18620 [ALC663_ASUS_MODE8] = {
18621 .mixers = { alc663_mode8_mixer },
18622 .cap_mixer = alc662_auto_capture_mixer,
18623 .init_verbs = { alc662_init_verbs,
a7f2371f 18624 alc662_eapd_init_verbs,
ebb83eeb
KY
18625 alc663_mode8_init_verbs },
18626 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18627 .hp_nid = 0x03,
18628 .dac_nids = alc662_dac_nids,
18629 .dig_out_nid = ALC662_DIGOUT_NID,
18630 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18631 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18632 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18633 .setup = alc663_mode8_setup,
3b8510ce 18634 .init_hook = alc_inithook,
ebb83eeb 18635 },
622e84cd
KY
18636 [ALC272_DELL] = {
18637 .mixers = { alc663_m51va_mixer },
18638 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18639 .init_verbs = { alc662_init_verbs,
18640 alc662_eapd_init_verbs,
18641 alc272_dell_init_verbs },
622e84cd 18642 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18643 .dac_nids = alc272_dac_nids,
622e84cd
KY
18644 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18645 .adc_nids = alc272_adc_nids,
18646 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18647 .capsrc_nids = alc272_capsrc_nids,
18648 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18649 .unsol_event = alc_sku_unsol_event,
4f5d1706 18650 .setup = alc663_m51va_setup,
3b8510ce 18651 .init_hook = alc_inithook,
622e84cd
KY
18652 },
18653 [ALC272_DELL_ZM1] = {
18654 .mixers = { alc663_m51va_mixer },
18655 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18656 .init_verbs = { alc662_init_verbs,
18657 alc662_eapd_init_verbs,
18658 alc272_dell_zm1_init_verbs },
622e84cd 18659 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18660 .dac_nids = alc272_dac_nids,
622e84cd
KY
18661 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18662 .adc_nids = alc662_adc_nids,
b59bdf3b 18663 .num_adc_nids = 1,
622e84cd
KY
18664 .capsrc_nids = alc662_capsrc_nids,
18665 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18666 .unsol_event = alc_sku_unsol_event,
4f5d1706 18667 .setup = alc663_m51va_setup,
3b8510ce 18668 .init_hook = alc_inithook,
622e84cd 18669 },
9541ba1d
CP
18670 [ALC272_SAMSUNG_NC10] = {
18671 .mixers = { alc272_nc10_mixer },
18672 .init_verbs = { alc662_init_verbs,
a7f2371f 18673 alc662_eapd_init_verbs,
9541ba1d
CP
18674 alc663_21jd_amic_init_verbs },
18675 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18676 .dac_nids = alc272_dac_nids,
18677 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18678 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18679 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18680 .unsol_event = alc_sku_unsol_event,
4f5d1706 18681 .setup = alc663_mode4_setup,
3b8510ce 18682 .init_hook = alc_inithook,
9541ba1d 18683 },
bc9f98a9
KY
18684};
18685
18686
18687/*
18688 * BIOS auto configuration
18689 */
18690
7085ec12 18691/* convert from MIX nid to DAC */
604401a9 18692static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18693{
604401a9 18694 hda_nid_t list[5];
1304ac89
TI
18695 int i, num;
18696
18697 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18698 for (i = 0; i < num; i++) {
18699 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18700 return list[i];
18701 }
18702 return 0;
7085ec12
TI
18703}
18704
604401a9
TI
18705/* go down to the selector widget before the mixer */
18706static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18707{
18708 hda_nid_t srcs[5];
18709 int num = snd_hda_get_connections(codec, pin, srcs,
18710 ARRAY_SIZE(srcs));
18711 if (num != 1 ||
18712 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18713 return pin;
18714 return srcs[0];
18715}
18716
7085ec12 18717/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18718static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18719 hda_nid_t dac)
18720{
cc1c452e 18721 hda_nid_t mix[5];
7085ec12
TI
18722 int i, num;
18723
604401a9 18724 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18725 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18726 for (i = 0; i < num; i++) {
604401a9 18727 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18728 return mix[i];
18729 }
18730 return 0;
18731}
18732
ce764ab2
TI
18733/* select the connection from pin to DAC if needed */
18734static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18735 hda_nid_t dac)
18736{
18737 hda_nid_t mix[5];
18738 int i, num;
18739
18740 pin = alc_go_down_to_selector(codec, pin);
18741 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18742 if (num < 2)
18743 return 0;
18744 for (i = 0; i < num; i++) {
18745 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18746 snd_hda_codec_update_cache(codec, pin, 0,
18747 AC_VERB_SET_CONNECT_SEL, i);
18748 return 0;
18749 }
18750 }
18751 return 0;
18752}
18753
7085ec12 18754/* look for an empty DAC slot */
604401a9 18755static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18756{
18757 struct alc_spec *spec = codec->spec;
18758 hda_nid_t srcs[5];
3af9ee6b 18759 int i, num;
7085ec12 18760
604401a9 18761 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18762 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18763 for (i = 0; i < num; i++) {
604401a9 18764 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18765 if (!nid)
18766 continue;
3af9ee6b
TI
18767 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18768 spec->multiout.num_dacs))
18769 continue;
18770 if (spec->multiout.hp_nid == nid)
18771 continue;
18772 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18773 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18774 continue;
18775 return nid;
7085ec12
TI
18776 }
18777 return 0;
18778}
18779
3af9ee6b
TI
18780static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18781{
18782 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18783 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18784 return alc_auto_look_for_dac(codec, pin);
18785 return 0;
18786}
18787
7085ec12 18788/* fill in the dac_nids table from the parsed pin configuration */
cb053a82 18789static int alc662_auto_fill_dac_nids(struct hda_codec *codec)
7085ec12
TI
18790{
18791 struct alc_spec *spec = codec->spec;
cb053a82 18792 const struct auto_pin_cfg *cfg = &spec->autocfg;
3af9ee6b 18793 bool redone;
7085ec12 18794 int i;
7085ec12 18795
3af9ee6b 18796 again:
3fccdfd8 18797 spec->multiout.num_dacs = 0;
3af9ee6b
TI
18798 spec->multiout.hp_nid = 0;
18799 spec->multiout.extra_out_nid[0] = 0;
18800 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18801 spec->multiout.dac_nids = spec->private_dac_nids;
18802
18803 /* fill hard-wired DACs first */
18804 if (!redone) {
18805 for (i = 0; i < cfg->line_outs; i++)
18806 spec->private_dac_nids[i] =
18807 get_dac_if_single(codec, cfg->line_out_pins[i]);
18808 if (cfg->hp_outs)
18809 spec->multiout.hp_nid =
18810 get_dac_if_single(codec, cfg->hp_pins[0]);
18811 if (cfg->speaker_outs)
18812 spec->multiout.extra_out_nid[0] =
18813 get_dac_if_single(codec, cfg->speaker_pins[0]);
18814 }
18815
7085ec12 18816 for (i = 0; i < cfg->line_outs; i++) {
3af9ee6b
TI
18817 hda_nid_t pin = cfg->line_out_pins[i];
18818 if (spec->private_dac_nids[i])
7085ec12 18819 continue;
3af9ee6b
TI
18820 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18821 if (!spec->private_dac_nids[i] && !redone) {
18822 /* if we can't find primary DACs, re-probe without
18823 * checking the hard-wired DACs
18824 */
18825 redone = true;
18826 goto again;
18827 }
18828 }
18829
18830 for (i = 0; i < cfg->line_outs; i++) {
18831 if (spec->private_dac_nids[i])
18832 spec->multiout.num_dacs++;
18833 else
18834 memmove(spec->private_dac_nids + i,
18835 spec->private_dac_nids + i + 1,
18836 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
7085ec12 18837 }
3af9ee6b 18838
7085ec12
TI
18839 return 0;
18840}
18841
bcb2f0f5
TI
18842static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18843 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18844{
bcb2f0f5 18845 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18846 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18847}
18848
bcb2f0f5
TI
18849static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18850 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18851{
bcb2f0f5 18852 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
18853 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18854}
18855
bcb2f0f5
TI
18856#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18857 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18858#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18859 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
18860#define alc662_add_stereo_vol(spec, pfx, nid) \
18861 alc662_add_vol_ctl(spec, pfx, nid, 3)
18862#define alc662_add_stereo_sw(spec, pfx, nid) \
18863 alc662_add_sw_ctl(spec, pfx, nid, 3)
18864
bc9f98a9 18865/* add playback controls from the parsed DAC table */
7085ec12 18866static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18867 const struct auto_pin_cfg *cfg)
18868{
7085ec12 18869 struct alc_spec *spec = codec->spec;
ce764ab2
TI
18870 hda_nid_t nid, mix, pin;
18871 int i, err, noutputs;
bc9f98a9 18872
ce764ab2
TI
18873 noutputs = cfg->line_outs;
18874 if (spec->multi_ios > 0)
18875 noutputs += spec->multi_ios;
18876
18877 for (i = 0; i < noutputs; i++) {
6843ca16
TI
18878 const char *name;
18879 int index;
7085ec12
TI
18880 nid = spec->multiout.dac_nids[i];
18881 if (!nid)
18882 continue;
ce764ab2
TI
18883 if (i >= cfg->line_outs)
18884 pin = spec->multi_io[i - 1].pin;
18885 else
18886 pin = cfg->line_out_pins[i];
18887 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18888 if (!mix)
bc9f98a9 18889 continue;
6843ca16
TI
18890 name = alc_get_line_out_pfx(spec, i, true, &index);
18891 if (!name) {
bc9f98a9 18892 /* Center/LFE */
7085ec12 18893 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18894 if (err < 0)
18895 return err;
7085ec12 18896 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18897 if (err < 0)
18898 return err;
7085ec12 18899 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18900 if (err < 0)
18901 return err;
7085ec12 18902 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
18903 if (err < 0)
18904 return err;
18905 } else {
5a882646 18906 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
18907 if (err < 0)
18908 return err;
5a882646 18909 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
18910 if (err < 0)
18911 return err;
18912 }
18913 }
18914 return 0;
18915}
18916
18917/* add playback controls for speaker and HP outputs */
7085ec12 18918static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
3af9ee6b 18919 hda_nid_t dac, const char *pfx)
bc9f98a9 18920{
7085ec12 18921 struct alc_spec *spec = codec->spec;
3af9ee6b 18922 hda_nid_t mix;
bc9f98a9 18923 int err;
bc9f98a9
KY
18924
18925 if (!pin)
18926 return 0;
3af9ee6b 18927 if (!dac) {
7085ec12
TI
18928 /* the corresponding DAC is already occupied */
18929 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18930 return 0; /* no way */
18931 /* create a switch only */
0afe5f89 18932 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 18933 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
18934 }
18935
3af9ee6b 18936 mix = alc_auto_dac_to_mix(codec, pin, dac);
7085ec12
TI
18937 if (!mix)
18938 return 0;
3af9ee6b 18939 err = alc662_add_vol_ctl(spec, pfx, dac, 3);
7085ec12
TI
18940 if (err < 0)
18941 return err;
18942 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
18943 if (err < 0)
18944 return err;
3af9ee6b 18945 return 0;
bc9f98a9
KY
18946}
18947
18948/* create playback/capture controls for input pins */
05f5f477 18949#define alc662_auto_create_input_ctls \
4b7348a1 18950 alc882_auto_create_input_ctls
bc9f98a9
KY
18951
18952static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
18953 hda_nid_t nid, int pin_type,
7085ec12 18954 hda_nid_t dac)
bc9f98a9 18955{
7085ec12 18956 int i, num;
ce503f38 18957 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 18958
f6c7e546 18959 alc_set_pin_output(codec, nid, pin_type);
7085ec12 18960 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 18961 for (i = 0; i < num; i++) {
604401a9 18962 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 18963 continue;
0e53f344
TI
18964 /* need the manual connection? */
18965 if (num > 1)
18966 snd_hda_codec_write(codec, nid, 0,
18967 AC_VERB_SET_CONNECT_SEL, i);
18968 /* unmute mixer widget inputs */
18969 snd_hda_codec_write(codec, srcs[i], 0,
18970 AC_VERB_SET_AMP_GAIN_MUTE,
18971 AMP_IN_UNMUTE(0));
18972 snd_hda_codec_write(codec, srcs[i], 0,
18973 AC_VERB_SET_AMP_GAIN_MUTE,
18974 AMP_IN_UNMUTE(1));
7085ec12 18975 return;
bc9f98a9
KY
18976 }
18977}
18978
18979static void alc662_auto_init_multi_out(struct hda_codec *codec)
18980{
18981 struct alc_spec *spec = codec->spec;
7085ec12 18982 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
18983 int i;
18984
18985 for (i = 0; i <= HDA_SIDE; i++) {
18986 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18987 if (nid)
baba8ee9 18988 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 18989 spec->multiout.dac_nids[i]);
bc9f98a9
KY
18990 }
18991}
18992
18993static void alc662_auto_init_hp_out(struct hda_codec *codec)
18994{
18995 struct alc_spec *spec = codec->spec;
18996 hda_nid_t pin;
18997
18998 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
18999 if (pin)
19000 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19001 spec->multiout.hp_nid);
f6c7e546
TI
19002 pin = spec->autocfg.speaker_pins[0];
19003 if (pin)
7085ec12
TI
19004 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19005 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19006}
19007
1f0f4b80 19008#define alc662_auto_init_analog_input alc882_auto_init_analog_input
f511b01c
TI
19009#define alc662_auto_init_input_src alc882_auto_init_input_src
19010
ce764ab2
TI
19011/*
19012 * multi-io helper
19013 */
19014static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19015 unsigned int location)
19016{
19017 struct alc_spec *spec = codec->spec;
19018 struct auto_pin_cfg *cfg = &spec->autocfg;
19019 int type, i, num_pins = 0;
19020
19021 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19022 for (i = 0; i < cfg->num_inputs; i++) {
19023 hda_nid_t nid = cfg->inputs[i].pin;
19024 hda_nid_t dac;
19025 unsigned int defcfg, caps;
19026 if (cfg->inputs[i].type != type)
19027 continue;
19028 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19029 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19030 continue;
19031 if (location && get_defcfg_location(defcfg) != location)
19032 continue;
19033 caps = snd_hda_query_pin_caps(codec, nid);
19034 if (!(caps & AC_PINCAP_OUT))
19035 continue;
19036 dac = alc_auto_look_for_dac(codec, nid);
19037 if (!dac)
19038 continue;
19039 spec->multi_io[num_pins].pin = nid;
19040 spec->multi_io[num_pins].dac = dac;
19041 num_pins++;
dda14410 19042 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19043 }
19044 }
19045 spec->multiout.num_dacs = 1;
19046 if (num_pins < 2)
19047 return 0;
19048 return num_pins;
19049}
19050
19051static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19052 struct snd_ctl_elem_info *uinfo)
19053{
19054 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19055 struct alc_spec *spec = codec->spec;
19056
19057 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19058 uinfo->count = 1;
19059 uinfo->value.enumerated.items = spec->multi_ios + 1;
19060 if (uinfo->value.enumerated.item > spec->multi_ios)
19061 uinfo->value.enumerated.item = spec->multi_ios;
19062 sprintf(uinfo->value.enumerated.name, "%dch",
19063 (uinfo->value.enumerated.item + 1) * 2);
19064 return 0;
19065}
19066
19067static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19068 struct snd_ctl_elem_value *ucontrol)
19069{
19070 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19071 struct alc_spec *spec = codec->spec;
19072 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19073 return 0;
19074}
19075
19076static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19077{
19078 struct alc_spec *spec = codec->spec;
19079 hda_nid_t nid = spec->multi_io[idx].pin;
19080
19081 if (!spec->multi_io[idx].ctl_in)
19082 spec->multi_io[idx].ctl_in =
19083 snd_hda_codec_read(codec, nid, 0,
19084 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19085 if (output) {
19086 snd_hda_codec_update_cache(codec, nid, 0,
19087 AC_VERB_SET_PIN_WIDGET_CONTROL,
19088 PIN_OUT);
19089 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19090 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19091 HDA_AMP_MUTE, 0);
19092 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19093 } else {
19094 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19095 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19096 HDA_AMP_MUTE, HDA_AMP_MUTE);
19097 snd_hda_codec_update_cache(codec, nid, 0,
19098 AC_VERB_SET_PIN_WIDGET_CONTROL,
19099 spec->multi_io[idx].ctl_in);
19100 }
19101 return 0;
19102}
19103
19104static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19105 struct snd_ctl_elem_value *ucontrol)
19106{
19107 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19108 struct alc_spec *spec = codec->spec;
19109 int i, ch;
19110
19111 ch = ucontrol->value.enumerated.item[0];
19112 if (ch < 0 || ch > spec->multi_ios)
19113 return -EINVAL;
19114 if (ch == (spec->ext_channel_count - 1) / 2)
19115 return 0;
19116 spec->ext_channel_count = (ch + 1) * 2;
19117 for (i = 0; i < spec->multi_ios; i++)
19118 alc_set_multi_io(codec, i, i < ch);
19119 spec->multiout.max_channels = spec->ext_channel_count;
19120 return 1;
19121}
19122
a9111321 19123static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19124 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19125 .name = "Channel Mode",
19126 .info = alc_auto_ch_mode_info,
19127 .get = alc_auto_ch_mode_get,
19128 .put = alc_auto_ch_mode_put,
19129};
19130
cb053a82
TI
19131static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
19132 int (*fill_dac)(struct hda_codec *))
ce764ab2
TI
19133{
19134 struct alc_spec *spec = codec->spec;
19135 struct auto_pin_cfg *cfg = &spec->autocfg;
19136 unsigned int location, defcfg;
19137 int num_pins;
19138
3fccdfd8
TI
19139 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
19140 /* use HP as primary out */
19141 cfg->speaker_outs = cfg->line_outs;
19142 memcpy(cfg->speaker_pins, cfg->line_out_pins,
19143 sizeof(cfg->speaker_pins));
19144 cfg->line_outs = cfg->hp_outs;
19145 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
19146 cfg->hp_outs = 0;
19147 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
19148 cfg->line_out_type = AUTO_PIN_HP_OUT;
cb053a82
TI
19149 if (fill_dac)
19150 fill_dac(codec);
3fccdfd8 19151 }
ce764ab2 19152 if (cfg->line_outs != 1 ||
3fccdfd8 19153 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
ce764ab2
TI
19154 return 0;
19155
19156 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19157 location = get_defcfg_location(defcfg);
19158
19159 num_pins = alc_auto_fill_multi_ios(codec, location);
19160 if (num_pins > 0) {
19161 struct snd_kcontrol_new *knew;
19162
19163 knew = alc_kcontrol_new(spec);
19164 if (!knew)
19165 return -ENOMEM;
19166 *knew = alc_auto_channel_mode_enum;
19167 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19168 if (!knew->name)
19169 return -ENOMEM;
19170
19171 spec->multi_ios = num_pins;
19172 spec->ext_channel_count = 2;
19173 spec->multiout.num_dacs = num_pins + 1;
19174 }
19175 return 0;
19176}
19177
bc9f98a9
KY
19178static int alc662_parse_auto_config(struct hda_codec *codec)
19179{
19180 struct alc_spec *spec = codec->spec;
19181 int err;
4c6d72d1 19182 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19183
19184 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19185 alc662_ignore);
19186 if (err < 0)
19187 return err;
19188 if (!spec->autocfg.line_outs)
19189 return 0; /* can't find valid BIOS pin config */
19190
cb053a82 19191 err = alc662_auto_fill_dac_nids(codec);
ce764ab2
TI
19192 if (err < 0)
19193 return err;
cb053a82 19194 err = alc_auto_add_multi_channel_mode(codec, alc662_auto_fill_dac_nids);
f12ab1e0
TI
19195 if (err < 0)
19196 return err;
7085ec12 19197 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19198 if (err < 0)
19199 return err;
7085ec12 19200 err = alc662_auto_create_extra_out(codec,
f12ab1e0 19201 spec->autocfg.speaker_pins[0],
3af9ee6b 19202 spec->multiout.extra_out_nid[0],
f12ab1e0
TI
19203 "Speaker");
19204 if (err < 0)
19205 return err;
7085ec12 19206 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
3af9ee6b 19207 spec->multiout.hp_nid,
f12ab1e0
TI
19208 "Headphone");
19209 if (err < 0)
19210 return err;
05f5f477 19211 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19212 if (err < 0)
bc9f98a9
KY
19213 return err;
19214
19215 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19216
757899ac 19217 alc_auto_parse_digital(codec);
bc9f98a9 19218
603c4019 19219 if (spec->kctls.list)
d88897ea 19220 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19221
19222 spec->num_mux_defs = 1;
61b9b9b1 19223 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19224
ee979a14
TI
19225 err = alc_auto_add_mic_boost(codec);
19226 if (err < 0)
19227 return err;
19228
6227cdce
KY
19229 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19230 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19231 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19232 else
19233 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19234
8c87286f 19235 return 1;
bc9f98a9
KY
19236}
19237
19238/* additional initialization for auto-configuration model */
19239static void alc662_auto_init(struct hda_codec *codec)
19240{
f6c7e546 19241 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19242 alc662_auto_init_multi_out(codec);
19243 alc662_auto_init_hp_out(codec);
19244 alc662_auto_init_analog_input(codec);
f511b01c 19245 alc662_auto_init_input_src(codec);
757899ac 19246 alc_auto_init_digital(codec);
f6c7e546 19247 if (spec->unsol_event)
7fb0d78f 19248 alc_inithook(codec);
bc9f98a9
KY
19249}
19250
6be7948f 19251static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19252 const struct alc_fixup *fix, int action)
6fc398cb 19253{
b5bfbc67 19254 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19255 return;
6be7948f
TB
19256 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19257 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19258 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19259 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19260 (0 << AC_AMPCAP_MUTE_SHIFT)))
19261 printk(KERN_WARNING
19262 "hda_codec: failed to override amp caps for NID 0x2\n");
19263}
19264
6cb3b707 19265enum {
2df03514 19266 ALC662_FIXUP_ASPIRE,
6cb3b707 19267 ALC662_FIXUP_IDEAPAD,
6be7948f 19268 ALC272_FIXUP_MARIO,
d2ebd479 19269 ALC662_FIXUP_CZC_P10T,
94024cd1 19270 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19271};
19272
19273static const struct alc_fixup alc662_fixups[] = {
2df03514 19274 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19275 .type = ALC_FIXUP_PINS,
19276 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19277 { 0x15, 0x99130112 }, /* subwoofer */
19278 { }
19279 }
19280 },
6cb3b707 19281 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19282 .type = ALC_FIXUP_PINS,
19283 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19284 { 0x17, 0x99130112 }, /* subwoofer */
19285 { }
19286 }
19287 },
6be7948f 19288 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19289 .type = ALC_FIXUP_FUNC,
19290 .v.func = alc272_fixup_mario,
d2ebd479
AA
19291 },
19292 [ALC662_FIXUP_CZC_P10T] = {
19293 .type = ALC_FIXUP_VERBS,
19294 .v.verbs = (const struct hda_verb[]) {
19295 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19296 {}
19297 }
19298 },
94024cd1
DH
19299 [ALC662_FIXUP_SKU_IGNORE] = {
19300 .type = ALC_FIXUP_SKU,
19301 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19302 },
6cb3b707
DH
19303};
19304
a9111321 19305static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19306 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19307 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19308 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19309 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19310 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19311 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19312 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19313 {}
19314};
19315
6be7948f
TB
19316static const struct alc_model_fixup alc662_fixup_models[] = {
19317 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19318 {}
19319};
6cb3b707
DH
19320
19321
bc9f98a9
KY
19322static int patch_alc662(struct hda_codec *codec)
19323{
19324 struct alc_spec *spec;
19325 int err, board_config;
693194f3 19326 int coef;
bc9f98a9
KY
19327
19328 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19329 if (!spec)
19330 return -ENOMEM;
19331
19332 codec->spec = spec;
19333
1f0f4b80
TI
19334 spec->mixer_nid = 0x0b;
19335
da00c244
KY
19336 alc_auto_parse_customize_define(codec);
19337
2c3bf9ab
TI
19338 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19339
693194f3
KY
19340 coef = alc_read_coef_idx(codec, 0);
19341 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19342 alc_codec_rename(codec, "ALC661");
693194f3
KY
19343 else if (coef & (1 << 14) &&
19344 codec->bus->pci->subsystem_vendor == 0x1025 &&
19345 spec->cdefine.platform_type == 1)
c027ddcd 19346 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19347 else if (coef == 0x4011)
19348 alc_codec_rename(codec, "ALC656");
274693f3 19349
bc9f98a9
KY
19350 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19351 alc662_models,
19352 alc662_cfg_tbl);
19353 if (board_config < 0) {
9a11f1aa
TI
19354 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19355 codec->chip_name);
bc9f98a9
KY
19356 board_config = ALC662_AUTO;
19357 }
19358
19359 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19360 alc_pick_fixup(codec, alc662_fixup_models,
19361 alc662_fixup_tbl, alc662_fixups);
19362 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19363 /* automatic parse from the BIOS config */
19364 err = alc662_parse_auto_config(codec);
19365 if (err < 0) {
19366 alc_free(codec);
19367 return err;
8c87286f 19368 } else if (!err) {
bc9f98a9
KY
19369 printk(KERN_INFO
19370 "hda_codec: Cannot set up configuration "
19371 "from BIOS. Using base mode...\n");
19372 board_config = ALC662_3ST_2ch_DIG;
19373 }
19374 }
19375
dc1eae25 19376 if (has_cdefine_beep(codec)) {
8af2591d
TI
19377 err = snd_hda_attach_beep_device(codec, 0x1);
19378 if (err < 0) {
19379 alc_free(codec);
19380 return err;
19381 }
680cd536
KK
19382 }
19383
bc9f98a9 19384 if (board_config != ALC662_AUTO)
e9c364c0 19385 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19386
bc9f98a9
KY
19387 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19388 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19389
bc9f98a9
KY
19390 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19391 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19392
dd704698
TI
19393 if (!spec->adc_nids) {
19394 spec->adc_nids = alc662_adc_nids;
19395 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19396 }
19397 if (!spec->capsrc_nids)
19398 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19399
f9e336f6 19400 if (!spec->cap_mixer)
b59bdf3b 19401 set_capture_mixer(codec);
cec27c89 19402
dc1eae25 19403 if (has_cdefine_beep(codec)) {
da00c244
KY
19404 switch (codec->vendor_id) {
19405 case 0x10ec0662:
19406 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19407 break;
19408 case 0x10ec0272:
19409 case 0x10ec0663:
19410 case 0x10ec0665:
19411 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19412 break;
19413 case 0x10ec0273:
19414 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19415 break;
19416 }
cec27c89 19417 }
2134ea4f
TI
19418 spec->vmaster_nid = 0x02;
19419
b5bfbc67
TI
19420 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19421
bc9f98a9 19422 codec->patch_ops = alc_patch_ops;
b5bfbc67 19423 if (board_config == ALC662_AUTO)
bc9f98a9 19424 spec->init_hook = alc662_auto_init;
1c716153 19425 spec->shutup = alc_eapd_shutup;
6cb3b707 19426
bf1b0225
KY
19427 alc_init_jacks(codec);
19428
cb53c626
TI
19429#ifdef CONFIG_SND_HDA_POWER_SAVE
19430 if (!spec->loopback.amplist)
19431 spec->loopback.amplist = alc662_loopbacks;
19432#endif
bc9f98a9
KY
19433
19434 return 0;
19435}
19436
274693f3
KY
19437static int patch_alc888(struct hda_codec *codec)
19438{
19439 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19440 kfree(codec->chip_name);
01e0f137
KY
19441 if (codec->vendor_id == 0x10ec0887)
19442 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19443 else
19444 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19445 if (!codec->chip_name) {
19446 alc_free(codec);
274693f3 19447 return -ENOMEM;
ac2c92e0
TI
19448 }
19449 return patch_alc662(codec);
274693f3 19450 }
ac2c92e0 19451 return patch_alc882(codec);
274693f3
KY
19452}
19453
b478b998
KY
19454static int patch_alc899(struct hda_codec *codec)
19455{
19456 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19457 kfree(codec->chip_name);
19458 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19459 }
19460 return patch_alc882(codec);
19461}
19462
d1eb57f4
KY
19463/*
19464 * ALC680 support
19465 */
c69aefab 19466#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19467#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19468#define alc680_modes alc260_modes
19469
4c6d72d1 19470static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19471 /* Lout1, Lout2, hp */
19472 0x02, 0x03, 0x04
19473};
19474
4c6d72d1 19475static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19476 /* ADC0-2 */
19477 /* DMIC, MIC, Line-in*/
19478 0x07, 0x08, 0x09
19479};
19480
c69aefab
KY
19481/*
19482 * Analog capture ADC cgange
19483 */
66ceeb6b
TI
19484static void alc680_rec_autoswitch(struct hda_codec *codec)
19485{
19486 struct alc_spec *spec = codec->spec;
19487 struct auto_pin_cfg *cfg = &spec->autocfg;
19488 int pin_found = 0;
19489 int type_found = AUTO_PIN_LAST;
19490 hda_nid_t nid;
19491 int i;
19492
19493 for (i = 0; i < cfg->num_inputs; i++) {
19494 nid = cfg->inputs[i].pin;
06dec228 19495 if (!is_jack_detectable(codec, nid))
66ceeb6b
TI
19496 continue;
19497 if (snd_hda_jack_detect(codec, nid)) {
19498 if (cfg->inputs[i].type < type_found) {
19499 type_found = cfg->inputs[i].type;
19500 pin_found = nid;
19501 }
19502 }
19503 }
19504
19505 nid = 0x07;
19506 if (pin_found)
19507 snd_hda_get_connections(codec, pin_found, &nid, 1);
19508
19509 if (nid != spec->cur_adc)
19510 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19511 spec->cur_adc = nid;
19512 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19513 spec->cur_adc_format);
19514}
19515
c69aefab
KY
19516static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19517 struct hda_codec *codec,
19518 unsigned int stream_tag,
19519 unsigned int format,
19520 struct snd_pcm_substream *substream)
19521{
19522 struct alc_spec *spec = codec->spec;
c69aefab 19523
66ceeb6b 19524 spec->cur_adc = 0x07;
c69aefab
KY
19525 spec->cur_adc_stream_tag = stream_tag;
19526 spec->cur_adc_format = format;
19527
66ceeb6b 19528 alc680_rec_autoswitch(codec);
c69aefab
KY
19529 return 0;
19530}
19531
19532static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19533 struct hda_codec *codec,
19534 struct snd_pcm_substream *substream)
19535{
19536 snd_hda_codec_cleanup_stream(codec, 0x07);
19537 snd_hda_codec_cleanup_stream(codec, 0x08);
19538 snd_hda_codec_cleanup_stream(codec, 0x09);
19539 return 0;
19540}
19541
a9111321 19542static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19543 .substreams = 1, /* can be overridden */
19544 .channels_min = 2,
19545 .channels_max = 2,
19546 /* NID is set in alc_build_pcms */
19547 .ops = {
19548 .prepare = alc680_capture_pcm_prepare,
19549 .cleanup = alc680_capture_pcm_cleanup
19550 },
19551};
19552
a9111321 19553static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19554 /* output mixer control */
19555 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19556 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19559 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19560 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19561 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19562 { }
19563};
19564
a9111321 19565static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19566 .ops = &snd_hda_bind_vol,
19567 .values = {
19568 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19569 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19570 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19571 0
19572 },
19573};
19574
a9111321 19575static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19576 .ops = &snd_hda_bind_sw,
19577 .values = {
19578 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19579 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19580 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19581 0
19582 },
19583};
19584
a9111321 19585static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19586 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19587 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19588 { } /* end */
19589};
19590
19591/*
19592 * generic initialization of ADC, input mixers and output mixers
19593 */
a9111321 19594static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19595 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19596 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19597 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19598
c69aefab
KY
19599 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19600 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19601 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19602 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19603 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19604 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19605
19606 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19607 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19608 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19609 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19610 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19611
19612 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19613 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19614 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19615
d1eb57f4
KY
19616 { }
19617};
19618
c69aefab
KY
19619/* toggle speaker-output according to the hp-jack state */
19620static void alc680_base_setup(struct hda_codec *codec)
19621{
19622 struct alc_spec *spec = codec->spec;
19623
19624 spec->autocfg.hp_pins[0] = 0x16;
19625 spec->autocfg.speaker_pins[0] = 0x14;
19626 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19627 spec->autocfg.num_inputs = 2;
19628 spec->autocfg.inputs[0].pin = 0x18;
19629 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19630 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19631 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19632 spec->automute = 1;
19633 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19634}
19635
19636static void alc680_unsol_event(struct hda_codec *codec,
19637 unsigned int res)
19638{
19639 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19640 alc_hp_automute(codec);
c69aefab
KY
19641 if ((res >> 26) == ALC880_MIC_EVENT)
19642 alc680_rec_autoswitch(codec);
19643}
19644
19645static void alc680_inithook(struct hda_codec *codec)
19646{
d922b51d 19647 alc_hp_automute(codec);
c69aefab
KY
19648 alc680_rec_autoswitch(codec);
19649}
19650
d1eb57f4
KY
19651/* create input playback/capture controls for the given pin */
19652static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19653 const char *ctlname, int idx)
19654{
19655 hda_nid_t dac;
19656 int err;
19657
19658 switch (nid) {
19659 case 0x14:
19660 dac = 0x02;
19661 break;
19662 case 0x15:
19663 dac = 0x03;
19664 break;
19665 case 0x16:
19666 dac = 0x04;
19667 break;
19668 default:
19669 return 0;
19670 }
19671 if (spec->multiout.dac_nids[0] != dac &&
19672 spec->multiout.dac_nids[1] != dac) {
19673 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19674 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19675 HDA_OUTPUT));
19676 if (err < 0)
19677 return err;
19678
19679 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19680 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19681
19682 if (err < 0)
19683 return err;
dda14410 19684 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19685 }
19686
19687 return 0;
19688}
19689
19690/* add playback controls from the parsed DAC table */
19691static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19692 const struct auto_pin_cfg *cfg)
19693{
19694 hda_nid_t nid;
19695 int err;
19696
19697 spec->multiout.dac_nids = spec->private_dac_nids;
19698
19699 nid = cfg->line_out_pins[0];
19700 if (nid) {
19701 const char *name;
2e925dde
TI
19702 int index;
19703 name = alc_get_line_out_pfx(spec, 0, true, &index);
d1eb57f4
KY
19704 err = alc680_new_analog_output(spec, nid, name, 0);
19705 if (err < 0)
19706 return err;
19707 }
19708
19709 nid = cfg->speaker_pins[0];
19710 if (nid) {
19711 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19712 if (err < 0)
19713 return err;
19714 }
19715 nid = cfg->hp_pins[0];
19716 if (nid) {
19717 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19718 if (err < 0)
19719 return err;
19720 }
19721
19722 return 0;
19723}
19724
19725static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19726 hda_nid_t nid, int pin_type)
19727{
19728 alc_set_pin_output(codec, nid, pin_type);
19729}
19730
19731static void alc680_auto_init_multi_out(struct hda_codec *codec)
19732{
19733 struct alc_spec *spec = codec->spec;
19734 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19735 if (nid) {
19736 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19737 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19738 }
19739}
19740
19741static void alc680_auto_init_hp_out(struct hda_codec *codec)
19742{
19743 struct alc_spec *spec = codec->spec;
19744 hda_nid_t pin;
19745
19746 pin = spec->autocfg.hp_pins[0];
19747 if (pin)
19748 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19749 pin = spec->autocfg.speaker_pins[0];
19750 if (pin)
19751 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19752}
19753
19754/* pcm configuration: identical with ALC880 */
19755#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19756#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19757#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19758#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19759#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19760
19761/*
19762 * BIOS auto configuration
19763 */
19764static int alc680_parse_auto_config(struct hda_codec *codec)
19765{
19766 struct alc_spec *spec = codec->spec;
19767 int err;
4c6d72d1 19768 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19769
19770 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19771 alc680_ignore);
19772 if (err < 0)
19773 return err;
c69aefab 19774
d1eb57f4
KY
19775 if (!spec->autocfg.line_outs) {
19776 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19777 spec->multiout.max_channels = 2;
19778 spec->no_analog = 1;
19779 goto dig_only;
19780 }
19781 return 0; /* can't find valid BIOS pin config */
19782 }
19783 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19784 if (err < 0)
19785 return err;
19786
19787 spec->multiout.max_channels = 2;
19788
19789 dig_only:
19790 /* digital only support output */
757899ac 19791 alc_auto_parse_digital(codec);
d1eb57f4
KY
19792 if (spec->kctls.list)
19793 add_mixer(spec, spec->kctls.list);
19794
d1eb57f4
KY
19795 err = alc_auto_add_mic_boost(codec);
19796 if (err < 0)
19797 return err;
19798
19799 return 1;
19800}
19801
19802#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19803
19804/* init callback for auto-configuration model -- overriding the default init */
19805static void alc680_auto_init(struct hda_codec *codec)
19806{
19807 struct alc_spec *spec = codec->spec;
19808 alc680_auto_init_multi_out(codec);
19809 alc680_auto_init_hp_out(codec);
19810 alc680_auto_init_analog_input(codec);
757899ac 19811 alc_auto_init_digital(codec);
d1eb57f4
KY
19812 if (spec->unsol_event)
19813 alc_inithook(codec);
19814}
19815
19816/*
19817 * configuration and preset
19818 */
ea734963 19819static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19820 [ALC680_BASE] = "base",
19821 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19822};
19823
a9111321 19824static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19825 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19826 {}
19827};
19828
a9111321 19829static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19830 [ALC680_BASE] = {
19831 .mixers = { alc680_base_mixer },
c69aefab 19832 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19833 .init_verbs = { alc680_init_verbs },
19834 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19835 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19836 .dig_out_nid = ALC680_DIGOUT_NID,
19837 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19838 .channel_mode = alc680_modes,
c69aefab
KY
19839 .unsol_event = alc680_unsol_event,
19840 .setup = alc680_base_setup,
19841 .init_hook = alc680_inithook,
19842
d1eb57f4
KY
19843 },
19844};
19845
19846static int patch_alc680(struct hda_codec *codec)
19847{
19848 struct alc_spec *spec;
19849 int board_config;
19850 int err;
19851
19852 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19853 if (spec == NULL)
19854 return -ENOMEM;
19855
19856 codec->spec = spec;
19857
1f0f4b80
TI
19858 /* ALC680 has no aa-loopback mixer */
19859
d1eb57f4
KY
19860 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19861 alc680_models,
19862 alc680_cfg_tbl);
19863
19864 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19865 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19866 codec->chip_name);
19867 board_config = ALC680_AUTO;
19868 }
19869
19870 if (board_config == ALC680_AUTO) {
19871 /* automatic parse from the BIOS config */
19872 err = alc680_parse_auto_config(codec);
19873 if (err < 0) {
19874 alc_free(codec);
19875 return err;
19876 } else if (!err) {
19877 printk(KERN_INFO
19878 "hda_codec: Cannot set up configuration "
19879 "from BIOS. Using base mode...\n");
19880 board_config = ALC680_BASE;
19881 }
19882 }
19883
19884 if (board_config != ALC680_AUTO)
19885 setup_preset(codec, &alc680_presets[board_config]);
19886
19887 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19888 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19889 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19890 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19891
19892 if (!spec->adc_nids) {
19893 spec->adc_nids = alc680_adc_nids;
19894 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
19895 }
19896
19897 if (!spec->cap_mixer)
19898 set_capture_mixer(codec);
19899
19900 spec->vmaster_nid = 0x02;
19901
19902 codec->patch_ops = alc_patch_ops;
19903 if (board_config == ALC680_AUTO)
19904 spec->init_hook = alc680_auto_init;
19905
19906 return 0;
19907}
19908
1da177e4
LT
19909/*
19910 * patch entries
19911 */
a9111321 19912static const struct hda_codec_preset snd_hda_preset_realtek[] = {
296f0338 19913 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
1da177e4 19914 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 19915 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 19916 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 19917 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 19918 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 19919 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 19920 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 19921 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
296f0338 19922 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
f32610ed 19923 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 19924 .patch = patch_alc861 },
f32610ed
JS
19925 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
19926 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
19927 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 19928 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 19929 .patch = patch_alc882 },
bc9f98a9
KY
19930 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
19931 .patch = patch_alc662 },
6dda9f4a 19932 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 19933 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 19934 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 19935 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 19936 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 19937 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 19938 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 19939 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 19940 .patch = patch_alc882 },
cb308f97 19941 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 19942 .patch = patch_alc882 },
df694daa 19943 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 19944 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 19945 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 19946 .patch = patch_alc882 },
274693f3 19947 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 19948 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 19949 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
b478b998 19950 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
1da177e4
LT
19951 {} /* terminator */
19952};
1289e9e8
TI
19953
19954MODULE_ALIAS("snd-hda-codec-id:10ec*");
19955
19956MODULE_LICENSE("GPL");
19957MODULE_DESCRIPTION("Realtek HD-audio codec");
19958
19959static struct hda_codec_preset_list realtek_list = {
19960 .preset = snd_hda_preset_realtek,
19961 .owner = THIS_MODULE,
19962};
19963
19964static int __init patch_realtek_init(void)
19965{
19966 return snd_hda_add_codec_preset(&realtek_list);
19967}
19968
19969static void __exit patch_realtek_exit(void)
19970{
19971 snd_hda_delete_codec_preset(&realtek_list);
19972}
19973
19974module_init(patch_realtek_init)
19975module_exit(patch_realtek_exit)