]> git.ipfire.org Git - thirdparty/linux.git/blame - sound/pci/hda/patch_realtek.c
ALSA: hda - Add automute-mode enum to Conexant auto-parser
[thirdparty/linux.git] / sound / pci / hda / patch_realtek.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
df694daa
KY
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
1da177e4 8 * Takashi Iwai <tiwai@suse.de>
7cf51e48 9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
1da177e4
LT
10 *
11 * This driver is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
1da177e4
LT
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/slab.h>
29#include <linux/pci.h>
30#include <sound/core.h>
9ad0e496 31#include <sound/jack.h>
1da177e4
LT
32#include "hda_codec.h"
33#include "hda_local.h"
680cd536 34#include "hda_beep.h"
1da177e4 35
ccc656ce
KY
36#define ALC880_FRONT_EVENT 0x01
37#define ALC880_DCVOL_EVENT 0x02
38#define ALC880_HP_EVENT 0x04
39#define ALC880_MIC_EVENT 0x08
1da177e4
LT
40
41/* ALC880 board config type */
42enum {
1da177e4
LT
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
dfc0ff62 48 ALC880_Z71V,
b6482d48 49 ALC880_6ST,
16ded525
TI
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
df694daa 55 ALC880_ASUS_DIG2,
2cf9f0fc 56 ALC880_FUJITSU,
16ded525 57 ALC880_UNIWILL_DIG,
ccc656ce
KY
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
df694daa
KY
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
ae6b813a 62 ALC880_LG,
d681518a 63 ALC880_LG_LW,
df99cd33 64 ALC880_MEDION_RIM,
e9edcee0
TI
65#ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67#endif
df694daa 68 ALC880_AUTO,
16ded525
TI
69 ALC880_MODEL_LAST /* last tag */
70};
71
72/* ALC260 models */
73enum {
74 ALC260_BASIC,
75 ALC260_HP,
3f878308 76 ALC260_HP_DC7600,
df694daa
KY
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
0bfc90e9 79 ALC260_ACER,
bc9f98a9
KY
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
cc959489 82 ALC260_FAVORIT100,
7cf51e48
JW
83#ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85#endif
df694daa 86 ALC260_AUTO,
16ded525 87 ALC260_MODEL_LAST /* last tag */
1da177e4
LT
88};
89
df694daa
KY
90/* ALC262 models */
91enum {
92 ALC262_BASIC,
ccc656ce
KY
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
834be88d 95 ALC262_FUJITSU,
9c7f852e 96 ALC262_HP_BPC,
cd7509a4
KY
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
66d2a9d6 99 ALC262_HP_TC_T5735,
8c427226 100 ALC262_HP_RP5700,
304dcaac 101 ALC262_BENQ_ED8,
272a527c 102 ALC262_SONY_ASSAMD,
83c34218 103 ALC262_BENQ_T31,
f651b50b 104 ALC262_ULTRA,
0e31daf7 105 ALC262_LENOVO_3000,
e8f9ae2a 106 ALC262_NEC,
4e555fe5 107 ALC262_TOSHIBA_S06,
9f99a638 108 ALC262_TOSHIBA_RX1,
ba340e82 109 ALC262_TYAN,
df694daa
KY
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112};
113
a361d84b
KY
114/* ALC268 models */
115enum {
eb5a6621 116 ALC267_QUANTA_IL1,
a361d84b 117 ALC268_3ST,
d1a991a6 118 ALC268_TOSHIBA,
d273809e 119 ALC268_ACER,
c238b4f4 120 ALC268_ACER_DMIC,
8ef355da 121 ALC268_ACER_ASPIRE_ONE,
3866f0b0 122 ALC268_DELL,
f12462c5 123 ALC268_ZEPTO,
86c53bd2
JW
124#ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126#endif
a361d84b
KY
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129};
130
f6a92248
KY
131/* ALC269 models */
132enum {
133 ALC269_BASIC,
60db6b53 134 ALC269_QUANTA_FL1,
84898e87
KY
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
26f5df26 139 ALC269_FUJITSU,
64154835 140 ALC269_LIFEBOOK,
fe3eb0a7 141 ALC271_ACER,
f6a92248
KY
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144};
145
df694daa
KY
146/* ALC861 models */
147enum {
148 ALC861_3ST,
9c7f852e 149 ALC660_3ST,
df694daa
KY
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
22309c3e 152 ALC861_UNIWILL_M31,
a53d1aec 153 ALC861_TOSHIBA,
7cdbff94 154 ALC861_ASUS,
56bb0cab 155 ALC861_ASUS_LAPTOP,
df694daa
KY
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158};
159
f32610ed
JS
160/* ALC861-VD models */
161enum {
162 ALC660VD_3ST,
6963f84c 163 ALC660VD_3ST_DIG,
13c94744 164 ALC660VD_ASUS_V1S,
f32610ed
JS
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
bdd148a3 168 ALC861VD_LENOVO,
272a527c 169 ALC861VD_DALLAS,
d1a991a6 170 ALC861VD_HP,
f32610ed
JS
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173};
174
bc9f98a9
KY
175/* ALC662 models */
176enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
291702f0 182 ALC662_ASUS_EEEPC_P701,
8c427226 183 ALC662_ASUS_EEEPC_EP20,
6dda9f4a
KY
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
f1d4e28b
KY
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
ebb83eeb
KY
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
622e84cd
KY
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
9541ba1d 199 ALC272_SAMSUNG_NC10,
bc9f98a9
KY
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202};
203
df694daa
KY
204/* ALC882 models */
205enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
4b146cb0 208 ALC882_ARIMA,
bdd148a3 209 ALC882_W2JC,
272a527c
KY
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
914759b7 212 ALC882_ASUS_A7M,
9102cd1c 213 ALC885_MACPRO,
76e6f5a9 214 ALC885_MBA21,
87350ad0 215 ALC885_MBP3,
41d5545d 216 ALC885_MB5,
e458b1fa 217 ALC885_MACMINI3,
c54728d8 218 ALC885_IMAC24,
4b7e1803 219 ALC885_IMAC91,
9c7f852e
TI
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
ccc656ce
KY
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
64a8be74 226 ALC883_TARGA_8ch_DIG,
bab282b9 227 ALC883_ACER,
2880a867 228 ALC883_ACER_ASPIRE,
5b2d1eca 229 ALC888_ACER_ASPIRE_4930G,
d2fd4b09 230 ALC888_ACER_ASPIRE_6530G,
3b315d70 231 ALC888_ACER_ASPIRE_8930G,
fc86f954 232 ALC888_ACER_ASPIRE_7730G,
c07584c8 233 ALC883_MEDION,
7ad7b218 234 ALC883_MEDION_WIM2160,
b373bdeb 235 ALC883_LAPTOP_EAPD,
bc9f98a9 236 ALC883_LENOVO_101E_2ch,
272a527c 237 ALC883_LENOVO_NB0763,
189609ae 238 ALC888_LENOVO_MS7195_DIG,
e2757d5e 239 ALC888_LENOVO_SKY,
ea1fb29a 240 ALC883_HAIER_W66,
4723c022 241 ALC888_3ST_HP,
5795b9e6 242 ALC888_6ST_DELL,
a8848bd6 243 ALC883_MITAC,
a65cc60f 244 ALC883_CLEVO_M540R,
0c4cc443 245 ALC883_CLEVO_M720,
fb97dc67 246 ALC883_FUJITSU_PI2515,
ef8ef5fb 247 ALC888_FUJITSU_XA3530,
17bba1b7 248 ALC883_3ST_6ch_INTEL,
87a8c370
JK
249 ALC889A_INTEL,
250 ALC889_INTEL,
e2757d5e
KY
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
eb4c41d3 253 ALC889A_MB31,
3ab90935 254 ALC1200_ASUS_P5Q,
3e1647c5 255 ALC883_SONY_VAIO_TT,
4953550a
TI
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
9c7f852e
TI
258};
259
d4a86d81
TI
260/* ALC680 models */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266
df694daa
KY
267/* for GPIO Poll */
268#define GPIO_MASK 0x03
269
4a79ba34
TI
270/* extra amp-initialization sequence types */
271enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277};
278
6c819492
TI
279struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283};
284
285#define MUX_IDX_UNDEF ((unsigned char)-1)
286
da00c244
KY
287struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
90622917 297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
da00c244
KY
298};
299
b5bfbc67
TI
300struct alc_fixup;
301
ce764ab2
TI
302struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306};
307
d922b51d 308enum {
3b8510ce
TI
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
d922b51d
TI
312};
313
1da177e4
LT
314struct alc_spec {
315 /* codec parameterization */
a9111321 316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
1da177e4 317 unsigned int num_mixers;
a9111321 318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
45bdd1c1 319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
1da177e4 320
2d9c6482 321 const struct hda_verb *init_verbs[10]; /* initialization verbs
9c7f852e
TI
322 * don't forget NULL
323 * termination!
e9edcee0
TI
324 */
325 unsigned int num_init_verbs;
1da177e4 326
aa563af7 327 char stream_name_analog[32]; /* analog PCM stream */
a9111321
TI
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
1da177e4 332
aa563af7 333 char stream_name_digital[32]; /* digital PCM stream */
a9111321
TI
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
1da177e4
LT
336
337 /* playback */
16ded525
TI
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
6330079f 342 hda_nid_t alt_dac_nid;
6a05ac4a 343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
8c441982 344 int dig_out_type;
1da177e4
LT
345
346 /* capture */
347 unsigned int num_adc_nids;
4c6d72d1
TI
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
16ded525 350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
1da177e4 351
840b64c0
TI
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
1da177e4 358 /* capture source */
a1e8d2da 359 unsigned int num_mux_defs;
1da177e4
LT
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
6c819492
TI
362 struct alc_mic_route ext_mic;
363 struct alc_mic_route int_mic;
1da177e4
LT
364
365 /* channel model */
d2a6d7dc 366 const struct hda_channel_mode *channel_mode;
1da177e4 367 int num_channel_mode;
4e195a7b 368 int need_dac_fix;
3b315d70
HM
369 int const_channel_count;
370 int ext_channel_count;
1da177e4
LT
371
372 /* PCM information */
4c5186ed 373 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
41e41f1f 374
e9edcee0
TI
375 /* dynamic controls, init_verbs and input_mux */
376 struct auto_pin_cfg autocfg;
da00c244 377 struct alc_customize_define cdefine;
603c4019 378 struct snd_array kctls;
61b9b9b1 379 struct hda_input_mux private_imux[3];
41923e44 380 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
4953550a
TI
381 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
834be88d 383
ae6b813a
TI
384 /* hooks */
385 void (*init_hook)(struct hda_codec *codec);
386 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
f5de24b0 387#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 388 void (*power_hook)(struct hda_codec *codec);
f5de24b0 389#endif
1c716153 390 void (*shutup)(struct hda_codec *codec);
ae6b813a 391
834be88d 392 /* for pin sensing */
834be88d 393 unsigned int jack_present: 1;
e6a5e1b7 394 unsigned int line_jack_present:1;
e9427969 395 unsigned int master_mute:1;
6c819492 396 unsigned int auto_mic:1;
d922b51d 397 unsigned int automute:1; /* HP automute enabled */
e6a5e1b7
TI
398 unsigned int detect_line:1; /* Line-out detection enabled */
399 unsigned int automute_lines:1; /* automute line-out as well */
ae8a60a5 400 unsigned int automute_hp_lo:1; /* both HP and LO available */
cb53c626 401
e64f14f4
TI
402 /* other flags */
403 unsigned int no_analog :1; /* digital I/O only */
840b64c0 404 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
584c0c4c 405 unsigned int single_input_src:1;
d922b51d
TI
406
407 /* auto-mute control */
408 int automute_mode;
3b8510ce 409 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
d922b51d 410
4a79ba34 411 int init_amp;
d433a678 412 int codec_variant; /* flag for other variants */
e64f14f4 413
2134ea4f
TI
414 /* for virtual master */
415 hda_nid_t vmaster_nid;
cb53c626
TI
416#ifdef CONFIG_SND_HDA_POWER_SAVE
417 struct hda_loopback_check loopback;
418#endif
2c3bf9ab
TI
419
420 /* for PLL fix */
421 hda_nid_t pll_nid;
422 unsigned int pll_coef_idx, pll_coef_bit;
b5bfbc67
TI
423
424 /* fix-up list */
425 int fixup_id;
426 const struct alc_fixup *fixup_list;
427 const char *fixup_name;
ce764ab2
TI
428
429 /* multi-io */
430 int multi_ios;
431 struct alc_multi_io multi_io[4];
df694daa
KY
432};
433
434/*
435 * configuration template - to be copied to the spec instance
436 */
437struct alc_config_preset {
a9111321 438 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
9c7f852e
TI
439 * with spec
440 */
a9111321 441 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
df694daa
KY
442 const struct hda_verb *init_verbs[5];
443 unsigned int num_dacs;
4c6d72d1 444 const hda_nid_t *dac_nids;
df694daa
KY
445 hda_nid_t dig_out_nid; /* optional */
446 hda_nid_t hp_nid; /* optional */
4c6d72d1 447 const hda_nid_t *slave_dig_outs;
df694daa 448 unsigned int num_adc_nids;
4c6d72d1
TI
449 const hda_nid_t *adc_nids;
450 const hda_nid_t *capsrc_nids;
df694daa
KY
451 hda_nid_t dig_in_nid;
452 unsigned int num_channel_mode;
453 const struct hda_channel_mode *channel_mode;
4e195a7b 454 int need_dac_fix;
3b315d70 455 int const_channel_count;
a1e8d2da 456 unsigned int num_mux_defs;
df694daa 457 const struct hda_input_mux *input_mux;
ae6b813a 458 void (*unsol_event)(struct hda_codec *, unsigned int);
e9c364c0 459 void (*setup)(struct hda_codec *);
ae6b813a 460 void (*init_hook)(struct hda_codec *);
cb53c626 461#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 462 const struct hda_amp_list *loopbacks;
c97259df 463 void (*power_hook)(struct hda_codec *codec);
cb53c626 464#endif
1da177e4
LT
465};
466
1da177e4
LT
467
468/*
469 * input MUX handling
470 */
9c7f852e
TI
471static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
472 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
473{
474 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
475 struct alc_spec *spec = codec->spec;
a1e8d2da
JW
476 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
477 if (mux_idx >= spec->num_mux_defs)
478 mux_idx = 0;
5311114d
TI
479 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
480 mux_idx = 0;
a1e8d2da 481 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
1da177e4
LT
482}
483
9c7f852e
TI
484static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
485 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
486{
487 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
488 struct alc_spec *spec = codec->spec;
489 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
490
491 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
492 return 0;
493}
494
9c7f852e
TI
495static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
496 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
497{
498 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
499 struct alc_spec *spec = codec->spec;
cd896c33 500 const struct hda_input_mux *imux;
1da177e4 501 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
cd896c33 502 unsigned int mux_idx;
e1406348
TI
503 hda_nid_t nid = spec->capsrc_nids ?
504 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
0169b6b3 505 unsigned int type;
1da177e4 506
cd896c33
TI
507 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
508 imux = &spec->input_mux[mux_idx];
5311114d
TI
509 if (!imux->num_items && mux_idx > 0)
510 imux = &spec->input_mux[0];
cd896c33 511
a22d543a 512 type = get_wcaps_type(get_wcaps(codec, nid));
0169b6b3 513 if (type == AC_WID_AUD_MIX) {
54cbc9ab
TI
514 /* Matrix-mixer style (e.g. ALC882) */
515 unsigned int *cur_val = &spec->cur_mux[adc_idx];
516 unsigned int i, idx;
517
518 idx = ucontrol->value.enumerated.item[0];
519 if (idx >= imux->num_items)
520 idx = imux->num_items - 1;
521 if (*cur_val == idx)
522 return 0;
523 for (i = 0; i < imux->num_items; i++) {
524 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
525 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
526 imux->items[i].index,
527 HDA_AMP_MUTE, v);
528 }
529 *cur_val = idx;
530 return 1;
531 } else {
532 /* MUX style (e.g. ALC880) */
cd896c33 533 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
54cbc9ab
TI
534 &spec->cur_mux[adc_idx]);
535 }
536}
e9edcee0 537
1da177e4
LT
538/*
539 * channel mode setting
540 */
9c7f852e
TI
541static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
542 struct snd_ctl_elem_info *uinfo)
1da177e4
LT
543{
544 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
545 struct alc_spec *spec = codec->spec;
d2a6d7dc
TI
546 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
547 spec->num_channel_mode);
1da177e4
LT
548}
549
9c7f852e
TI
550static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
552{
553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554 struct alc_spec *spec = codec->spec;
d2a6d7dc 555 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
9c7f852e 556 spec->num_channel_mode,
3b315d70 557 spec->ext_channel_count);
1da177e4
LT
558}
559
9c7f852e
TI
560static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_value *ucontrol)
1da177e4
LT
562{
563 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
564 struct alc_spec *spec = codec->spec;
4e195a7b
TI
565 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
566 spec->num_channel_mode,
3b315d70
HM
567 &spec->ext_channel_count);
568 if (err >= 0 && !spec->const_channel_count) {
569 spec->multiout.max_channels = spec->ext_channel_count;
570 if (spec->need_dac_fix)
571 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
572 }
4e195a7b 573 return err;
1da177e4
LT
574}
575
a9430dd8 576/*
4c5186ed 577 * Control the mode of pin widget settings via the mixer. "pc" is used
25985edc 578 * instead of "%" to avoid consequences of accidentally treating the % as
4c5186ed
JW
579 * being part of a format specifier. Maximum allowed length of a value is
580 * 63 characters plus NULL terminator.
7cf51e48
JW
581 *
582 * Note: some retasking pin complexes seem to ignore requests for input
583 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
584 * are requested. Therefore order this list so that this behaviour will not
585 * cause problems when mixer clients move through the enum sequentially.
a1e8d2da
JW
586 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
587 * March 2006.
4c5186ed 588 */
a9111321 589static const char * const alc_pin_mode_names[] = {
7cf51e48
JW
590 "Mic 50pc bias", "Mic 80pc bias",
591 "Line in", "Line out", "Headphone out",
4c5186ed 592};
a9111321 593static const unsigned char alc_pin_mode_values[] = {
7cf51e48 594 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
4c5186ed
JW
595};
596/* The control can present all 5 options, or it can limit the options based
a1e8d2da
JW
597 * in the pin being assumed to be exclusively an input or an output pin. In
598 * addition, "input" pins may or may not process the mic bias option
599 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
600 * accept requests for bias as of chip versions up to March 2006) and/or
601 * wiring in the computer.
a9430dd8 602 */
a1e8d2da
JW
603#define ALC_PIN_DIR_IN 0x00
604#define ALC_PIN_DIR_OUT 0x01
605#define ALC_PIN_DIR_INOUT 0x02
606#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
607#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
4c5186ed 608
ea1fb29a 609/* Info about the pin modes supported by the different pin direction modes.
4c5186ed
JW
610 * For each direction the minimum and maximum values are given.
611 */
a9111321 612static const signed char alc_pin_mode_dir_info[5][2] = {
4c5186ed
JW
613 { 0, 2 }, /* ALC_PIN_DIR_IN */
614 { 3, 4 }, /* ALC_PIN_DIR_OUT */
615 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
a1e8d2da
JW
616 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
617 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
4c5186ed
JW
618};
619#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
620#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
621#define alc_pin_mode_n_items(_dir) \
622 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
623
9c7f852e
TI
624static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_info *uinfo)
a9430dd8 626{
4c5186ed
JW
627 unsigned int item_num = uinfo->value.enumerated.item;
628 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
629
630 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
a9430dd8 631 uinfo->count = 1;
4c5186ed
JW
632 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
633
634 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
635 item_num = alc_pin_mode_min(dir);
636 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
a9430dd8
JW
637 return 0;
638}
639
9c7f852e
TI
640static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
641 struct snd_ctl_elem_value *ucontrol)
a9430dd8 642{
4c5186ed 643 unsigned int i;
a9430dd8
JW
644 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
645 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed 646 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
a9430dd8 647 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
648 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
649 AC_VERB_GET_PIN_WIDGET_CONTROL,
650 0x00);
a9430dd8 651
4c5186ed
JW
652 /* Find enumerated value for current pinctl setting */
653 i = alc_pin_mode_min(dir);
4b35d2ca 654 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
4c5186ed 655 i++;
9c7f852e 656 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
a9430dd8
JW
657 return 0;
658}
659
9c7f852e
TI
660static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
661 struct snd_ctl_elem_value *ucontrol)
a9430dd8 662{
4c5186ed 663 signed int change;
a9430dd8
JW
664 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
665 hda_nid_t nid = kcontrol->private_value & 0xffff;
4c5186ed
JW
666 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
667 long val = *ucontrol->value.integer.value;
9c7f852e
TI
668 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
669 AC_VERB_GET_PIN_WIDGET_CONTROL,
670 0x00);
a9430dd8 671
f12ab1e0 672 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
4c5186ed
JW
673 val = alc_pin_mode_min(dir);
674
675 change = pinctl != alc_pin_mode_values[val];
cdcd9268
JW
676 if (change) {
677 /* Set pin mode to that requested */
82beb8fd
TI
678 snd_hda_codec_write_cache(codec, nid, 0,
679 AC_VERB_SET_PIN_WIDGET_CONTROL,
680 alc_pin_mode_values[val]);
cdcd9268 681
ea1fb29a 682 /* Also enable the retasking pin's input/output as required
cdcd9268
JW
683 * for the requested pin mode. Enum values of 2 or less are
684 * input modes.
685 *
686 * Dynamically switching the input/output buffers probably
a1e8d2da
JW
687 * reduces noise slightly (particularly on input) so we'll
688 * do it. However, having both input and output buffers
689 * enabled simultaneously doesn't seem to be problematic if
690 * this turns out to be necessary in the future.
cdcd9268
JW
691 */
692 if (val <= 2) {
47fd830a
TI
693 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
694 HDA_AMP_MUTE, HDA_AMP_MUTE);
695 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
696 HDA_AMP_MUTE, 0);
cdcd9268 697 } else {
47fd830a
TI
698 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
699 HDA_AMP_MUTE, HDA_AMP_MUTE);
700 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
701 HDA_AMP_MUTE, 0);
cdcd9268
JW
702 }
703 }
a9430dd8
JW
704 return change;
705}
706
4c5186ed 707#define ALC_PIN_MODE(xname, nid, dir) \
a9430dd8 708 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 709 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4c5186ed
JW
710 .info = alc_pin_mode_info, \
711 .get = alc_pin_mode_get, \
712 .put = alc_pin_mode_put, \
713 .private_value = nid | (dir<<16) }
df694daa 714
5c8f858d
JW
715/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
716 * together using a mask with more than one bit set. This control is
717 * currently used only by the ALC260 test model. At this stage they are not
718 * needed for any "production" models.
719 */
720#ifdef CONFIG_SND_DEBUG
a5ce8890 721#define alc_gpio_data_info snd_ctl_boolean_mono_info
f12ab1e0 722
9c7f852e
TI
723static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
724 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
725{
726 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
727 hda_nid_t nid = kcontrol->private_value & 0xffff;
728 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
729 long *valp = ucontrol->value.integer.value;
9c7f852e
TI
730 unsigned int val = snd_hda_codec_read(codec, nid, 0,
731 AC_VERB_GET_GPIO_DATA, 0x00);
5c8f858d
JW
732
733 *valp = (val & mask) != 0;
734 return 0;
735}
9c7f852e
TI
736static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
737 struct snd_ctl_elem_value *ucontrol)
5c8f858d
JW
738{
739 signed int change;
740 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
741 hda_nid_t nid = kcontrol->private_value & 0xffff;
742 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
743 long val = *ucontrol->value.integer.value;
9c7f852e
TI
744 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
745 AC_VERB_GET_GPIO_DATA,
746 0x00);
5c8f858d
JW
747
748 /* Set/unset the masked GPIO bit(s) as needed */
9c7f852e
TI
749 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
750 if (val == 0)
5c8f858d
JW
751 gpio_data &= ~mask;
752 else
753 gpio_data |= mask;
82beb8fd
TI
754 snd_hda_codec_write_cache(codec, nid, 0,
755 AC_VERB_SET_GPIO_DATA, gpio_data);
5c8f858d
JW
756
757 return change;
758}
759#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
760 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 761 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
5c8f858d
JW
762 .info = alc_gpio_data_info, \
763 .get = alc_gpio_data_get, \
764 .put = alc_gpio_data_put, \
765 .private_value = nid | (mask<<16) }
766#endif /* CONFIG_SND_DEBUG */
767
92621f13
JW
768/* A switch control to allow the enabling of the digital IO pins on the
769 * ALC260. This is incredibly simplistic; the intention of this control is
770 * to provide something in the test model allowing digital outputs to be
771 * identified if present. If models are found which can utilise these
772 * outputs a more complete mixer control can be devised for those models if
773 * necessary.
774 */
775#ifdef CONFIG_SND_DEBUG
a5ce8890 776#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
f12ab1e0 777
9c7f852e
TI
778static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
779 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
780{
781 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
782 hda_nid_t nid = kcontrol->private_value & 0xffff;
783 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
784 long *valp = ucontrol->value.integer.value;
9c7f852e 785 unsigned int val = snd_hda_codec_read(codec, nid, 0,
3982d17e 786 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
92621f13
JW
787
788 *valp = (val & mask) != 0;
789 return 0;
790}
9c7f852e
TI
791static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
792 struct snd_ctl_elem_value *ucontrol)
92621f13
JW
793{
794 signed int change;
795 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
796 hda_nid_t nid = kcontrol->private_value & 0xffff;
797 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
798 long val = *ucontrol->value.integer.value;
9c7f852e 799 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
3982d17e 800 AC_VERB_GET_DIGI_CONVERT_1,
9c7f852e 801 0x00);
92621f13
JW
802
803 /* Set/unset the masked control bit(s) as needed */
9c7f852e 804 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
92621f13
JW
805 if (val==0)
806 ctrl_data &= ~mask;
807 else
808 ctrl_data |= mask;
82beb8fd
TI
809 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
810 ctrl_data);
92621f13
JW
811
812 return change;
813}
814#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
815 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 816 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
92621f13
JW
817 .info = alc_spdif_ctrl_info, \
818 .get = alc_spdif_ctrl_get, \
819 .put = alc_spdif_ctrl_put, \
820 .private_value = nid | (mask<<16) }
821#endif /* CONFIG_SND_DEBUG */
822
f8225f6d
JW
823/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
824 * Again, this is only used in the ALC26x test models to help identify when
825 * the EAPD line must be asserted for features to work.
826 */
827#ifdef CONFIG_SND_DEBUG
828#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
829
830static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
831 struct snd_ctl_elem_value *ucontrol)
832{
833 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
834 hda_nid_t nid = kcontrol->private_value & 0xffff;
835 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
836 long *valp = ucontrol->value.integer.value;
837 unsigned int val = snd_hda_codec_read(codec, nid, 0,
838 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
839
840 *valp = (val & mask) != 0;
841 return 0;
842}
843
844static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
845 struct snd_ctl_elem_value *ucontrol)
846{
847 int change;
848 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
849 hda_nid_t nid = kcontrol->private_value & 0xffff;
850 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
851 long val = *ucontrol->value.integer.value;
852 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
853 AC_VERB_GET_EAPD_BTLENABLE,
854 0x00);
855
856 /* Set/unset the masked control bit(s) as needed */
857 change = (!val ? 0 : mask) != (ctrl_data & mask);
858 if (!val)
859 ctrl_data &= ~mask;
860 else
861 ctrl_data |= mask;
862 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
863 ctrl_data);
864
865 return change;
866}
867
868#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
869 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
5b0cb1d8 870 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
f8225f6d
JW
871 .info = alc_eapd_ctrl_info, \
872 .get = alc_eapd_ctrl_get, \
873 .put = alc_eapd_ctrl_put, \
874 .private_value = nid | (mask<<16) }
875#endif /* CONFIG_SND_DEBUG */
876
23f0c048
TI
877/*
878 * set up the input pin config (depending on the given auto-pin type)
879 */
880static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
881 int auto_pin_type)
882{
883 unsigned int val = PIN_IN;
884
86e2959a 885 if (auto_pin_type == AUTO_PIN_MIC) {
23f0c048 886 unsigned int pincap;
954a29c8
TI
887 unsigned int oldval;
888 oldval = snd_hda_codec_read(codec, nid, 0,
889 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1327a32b 890 pincap = snd_hda_query_pin_caps(codec, nid);
23f0c048 891 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
954a29c8
TI
892 /* if the default pin setup is vref50, we give it priority */
893 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
23f0c048 894 val = PIN_VREF80;
461c6c3a
TI
895 else if (pincap & AC_PINCAP_VREF_50)
896 val = PIN_VREF50;
897 else if (pincap & AC_PINCAP_VREF_100)
898 val = PIN_VREF100;
899 else if (pincap & AC_PINCAP_VREF_GRD)
900 val = PIN_VREFGRD;
23f0c048
TI
901 }
902 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
903}
904
f6837bbd
TI
905static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
906{
907 struct alc_spec *spec = codec->spec;
908 struct auto_pin_cfg *cfg = &spec->autocfg;
909
910 if (!cfg->line_outs) {
911 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
912 cfg->line_out_pins[cfg->line_outs])
913 cfg->line_outs++;
914 }
915 if (!cfg->speaker_outs) {
916 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
917 cfg->speaker_pins[cfg->speaker_outs])
918 cfg->speaker_outs++;
919 }
920 if (!cfg->hp_outs) {
921 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
922 cfg->hp_pins[cfg->hp_outs])
923 cfg->hp_outs++;
924 }
925}
926
d88897ea
TI
927/*
928 */
a9111321 929static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
d88897ea
TI
930{
931 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
932 return;
933 spec->mixers[spec->num_mixers++] = mix;
934}
935
936static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
937{
938 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
939 return;
940 spec->init_verbs[spec->num_init_verbs++] = verb;
941}
942
df694daa
KY
943/*
944 * set up from the preset table
945 */
e9c364c0 946static void setup_preset(struct hda_codec *codec,
9c7f852e 947 const struct alc_config_preset *preset)
df694daa 948{
e9c364c0 949 struct alc_spec *spec = codec->spec;
df694daa
KY
950 int i;
951
952 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
d88897ea 953 add_mixer(spec, preset->mixers[i]);
f9e336f6 954 spec->cap_mixer = preset->cap_mixer;
9c7f852e
TI
955 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
956 i++)
d88897ea 957 add_verb(spec, preset->init_verbs[i]);
ea1fb29a 958
df694daa
KY
959 spec->channel_mode = preset->channel_mode;
960 spec->num_channel_mode = preset->num_channel_mode;
4e195a7b 961 spec->need_dac_fix = preset->need_dac_fix;
3b315d70 962 spec->const_channel_count = preset->const_channel_count;
df694daa 963
3b315d70
HM
964 if (preset->const_channel_count)
965 spec->multiout.max_channels = preset->const_channel_count;
966 else
967 spec->multiout.max_channels = spec->channel_mode[0].channels;
968 spec->ext_channel_count = spec->channel_mode[0].channels;
df694daa
KY
969
970 spec->multiout.num_dacs = preset->num_dacs;
971 spec->multiout.dac_nids = preset->dac_nids;
972 spec->multiout.dig_out_nid = preset->dig_out_nid;
b25c9da1 973 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
df694daa 974 spec->multiout.hp_nid = preset->hp_nid;
ea1fb29a 975
a1e8d2da 976 spec->num_mux_defs = preset->num_mux_defs;
f12ab1e0 977 if (!spec->num_mux_defs)
a1e8d2da 978 spec->num_mux_defs = 1;
df694daa
KY
979 spec->input_mux = preset->input_mux;
980
981 spec->num_adc_nids = preset->num_adc_nids;
982 spec->adc_nids = preset->adc_nids;
e1406348 983 spec->capsrc_nids = preset->capsrc_nids;
df694daa 984 spec->dig_in_nid = preset->dig_in_nid;
ae6b813a
TI
985
986 spec->unsol_event = preset->unsol_event;
987 spec->init_hook = preset->init_hook;
cb53c626 988#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 989 spec->power_hook = preset->power_hook;
cb53c626
TI
990 spec->loopback.amplist = preset->loopbacks;
991#endif
e9c364c0
TI
992
993 if (preset->setup)
994 preset->setup(codec);
f6837bbd
TI
995
996 alc_fixup_autocfg_pin_nums(codec);
df694daa
KY
997}
998
bc9f98a9 999/* Enable GPIO mask and set output */
a9111321 1000static const struct hda_verb alc_gpio1_init_verbs[] = {
bc9f98a9
KY
1001 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1002 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1003 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1004 { }
1005};
1006
a9111321 1007static const struct hda_verb alc_gpio2_init_verbs[] = {
bc9f98a9
KY
1008 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1009 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1011 { }
1012};
1013
a9111321 1014static const struct hda_verb alc_gpio3_init_verbs[] = {
bdd148a3
KY
1015 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1016 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1017 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1018 { }
1019};
1020
2c3bf9ab
TI
1021/*
1022 * Fix hardware PLL issue
1023 * On some codecs, the analog PLL gating control must be off while
1024 * the default value is 1.
1025 */
1026static void alc_fix_pll(struct hda_codec *codec)
1027{
1028 struct alc_spec *spec = codec->spec;
1029 unsigned int val;
1030
1031 if (!spec->pll_nid)
1032 return;
1033 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1034 spec->pll_coef_idx);
1035 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1036 AC_VERB_GET_PROC_COEF, 0);
1037 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1038 spec->pll_coef_idx);
1039 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1040 val & ~(1 << spec->pll_coef_bit));
1041}
1042
1043static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1044 unsigned int coef_idx, unsigned int coef_bit)
1045{
1046 struct alc_spec *spec = codec->spec;
1047 spec->pll_nid = nid;
1048 spec->pll_coef_idx = coef_idx;
1049 spec->pll_coef_bit = coef_bit;
1050 alc_fix_pll(codec);
1051}
1052
9ad0e496
KY
1053static int alc_init_jacks(struct hda_codec *codec)
1054{
cd372fb3 1055#ifdef CONFIG_SND_HDA_INPUT_JACK
9ad0e496
KY
1056 struct alc_spec *spec = codec->spec;
1057 int err;
1058 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1059 unsigned int mic_nid = spec->ext_mic.pin;
1060
265a0247 1061 if (hp_nid) {
cd372fb3
TI
1062 err = snd_hda_input_jack_add(codec, hp_nid,
1063 SND_JACK_HEADPHONE, NULL);
265a0247
TI
1064 if (err < 0)
1065 return err;
cd372fb3 1066 snd_hda_input_jack_report(codec, hp_nid);
265a0247 1067 }
9ad0e496 1068
265a0247 1069 if (mic_nid) {
cd372fb3
TI
1070 err = snd_hda_input_jack_add(codec, mic_nid,
1071 SND_JACK_MICROPHONE, NULL);
265a0247
TI
1072 if (err < 0)
1073 return err;
cd372fb3 1074 snd_hda_input_jack_report(codec, mic_nid);
265a0247 1075 }
cd372fb3 1076#endif /* CONFIG_SND_HDA_INPUT_JACK */
9ad0e496
KY
1077 return 0;
1078}
9ad0e496 1079
e6a5e1b7 1080static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
c9b58006 1081{
e6a5e1b7 1082 int i, present = 0;
c9b58006 1083
e6a5e1b7
TI
1084 for (i = 0; i < num_pins; i++) {
1085 hda_nid_t nid = pins[i];
bb35febd
TI
1086 if (!nid)
1087 break;
cd372fb3 1088 snd_hda_input_jack_report(codec, nid);
e6a5e1b7 1089 present |= snd_hda_jack_detect(codec, nid);
bb35febd 1090 }
e6a5e1b7
TI
1091 return present;
1092}
bb35febd 1093
e6a5e1b7 1094static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
e9427969 1095 bool mute, bool hp_out)
e6a5e1b7
TI
1096{
1097 struct alc_spec *spec = codec->spec;
1098 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
e9427969 1099 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
e6a5e1b7
TI
1100 int i;
1101
1102 for (i = 0; i < num_pins; i++) {
1103 hda_nid_t nid = pins[i];
a9fd4f3f
TI
1104 if (!nid)
1105 break;
3b8510ce
TI
1106 switch (spec->automute_mode) {
1107 case ALC_AUTOMUTE_PIN:
bb35febd 1108 snd_hda_codec_write(codec, nid, 0,
e6a5e1b7
TI
1109 AC_VERB_SET_PIN_WIDGET_CONTROL,
1110 pin_bits);
3b8510ce
TI
1111 break;
1112 case ALC_AUTOMUTE_AMP:
bb35febd 1113 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
e6a5e1b7 1114 HDA_AMP_MUTE, mute_bits);
3b8510ce
TI
1115 break;
1116 case ALC_AUTOMUTE_MIXER:
1117 nid = spec->automute_mixer_nid[i];
1118 if (!nid)
1119 break;
1120 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
e6a5e1b7 1121 HDA_AMP_MUTE, mute_bits);
3b8510ce 1122 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
e6a5e1b7 1123 HDA_AMP_MUTE, mute_bits);
3b8510ce 1124 break;
bb35febd 1125 }
a9fd4f3f 1126 }
c9b58006
KY
1127}
1128
e6a5e1b7
TI
1129/* Toggle internal speakers muting */
1130static void update_speakers(struct hda_codec *codec)
1131{
1132 struct alc_spec *spec = codec->spec;
1a1455de 1133 int on;
e6a5e1b7 1134
1a1455de
TI
1135 if (!spec->automute)
1136 on = 0;
1137 else
1138 on = spec->jack_present | spec->line_jack_present;
1139 on |= spec->master_mute;
e6a5e1b7 1140 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1a1455de 1141 spec->autocfg.speaker_pins, on, false);
e6a5e1b7
TI
1142
1143 /* toggle line-out mutes if needed, too */
1a1455de
TI
1144 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1145 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1146 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
e6a5e1b7 1147 return;
1a1455de
TI
1148 if (!spec->automute_lines || !spec->automute)
1149 on = 0;
1150 else
1151 on = spec->jack_present;
1152 on |= spec->master_mute;
e6a5e1b7 1153 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1a1455de 1154 spec->autocfg.line_out_pins, on, false);
e6a5e1b7
TI
1155}
1156
1157static void alc_hp_automute(struct hda_codec *codec)
1158{
1159 struct alc_spec *spec = codec->spec;
1160
1161 if (!spec->automute)
1162 return;
1163 spec->jack_present =
1164 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1165 spec->autocfg.hp_pins);
1166 update_speakers(codec);
1167}
1168
1169static void alc_line_automute(struct hda_codec *codec)
1170{
1171 struct alc_spec *spec = codec->spec;
1172
1173 if (!spec->automute || !spec->detect_line)
1174 return;
1175 spec->line_jack_present =
1176 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1177 spec->autocfg.line_out_pins);
1178 update_speakers(codec);
1179}
1180
6c819492
TI
1181static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1182 hda_nid_t nid)
1183{
1184 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1185 int i, nums;
1186
1187 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1188 for (i = 0; i < nums; i++)
1189 if (conn[i] == nid)
1190 return i;
1191 return -1;
1192}
1193
840b64c0
TI
1194/* switch the current ADC according to the jack state */
1195static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1196{
1197 struct alc_spec *spec = codec->spec;
1198 unsigned int present;
1199 hda_nid_t new_adc;
1200
1201 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1202 if (present)
1203 spec->cur_adc_idx = 1;
1204 else
1205 spec->cur_adc_idx = 0;
1206 new_adc = spec->adc_nids[spec->cur_adc_idx];
1207 if (spec->cur_adc && spec->cur_adc != new_adc) {
1208 /* stream is running, let's swap the current ADC */
f0cea797 1209 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
840b64c0
TI
1210 spec->cur_adc = new_adc;
1211 snd_hda_codec_setup_stream(codec, new_adc,
1212 spec->cur_adc_stream_tag, 0,
1213 spec->cur_adc_format);
1214 }
1215}
1216
7fb0d78f
KY
1217static void alc_mic_automute(struct hda_codec *codec)
1218{
1219 struct alc_spec *spec = codec->spec;
6c819492
TI
1220 struct alc_mic_route *dead, *alive;
1221 unsigned int present, type;
1222 hda_nid_t cap_nid;
1223
b59bdf3b
TI
1224 if (!spec->auto_mic)
1225 return;
6c819492
TI
1226 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1227 return;
1228 if (snd_BUG_ON(!spec->adc_nids))
1229 return;
1230
840b64c0
TI
1231 if (spec->dual_adc_switch) {
1232 alc_dual_mic_adc_auto_switch(codec);
1233 return;
1234 }
1235
6c819492
TI
1236 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1237
864f92be 1238 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
6c819492
TI
1239 if (present) {
1240 alive = &spec->ext_mic;
1241 dead = &spec->int_mic;
1242 } else {
1243 alive = &spec->int_mic;
1244 dead = &spec->ext_mic;
1245 }
1246
6c819492
TI
1247 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1248 if (type == AC_WID_AUD_MIX) {
1249 /* Matrix-mixer style (e.g. ALC882) */
1250 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1251 alive->mux_idx,
1252 HDA_AMP_MUTE, 0);
1253 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1254 dead->mux_idx,
1255 HDA_AMP_MUTE, HDA_AMP_MUTE);
1256 } else {
1257 /* MUX style (e.g. ALC880) */
1258 snd_hda_codec_write_cache(codec, cap_nid, 0,
1259 AC_VERB_SET_CONNECT_SEL,
1260 alive->mux_idx);
1261 }
cd372fb3 1262 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
6c819492
TI
1263
1264 /* FIXME: analog mixer */
7fb0d78f
KY
1265}
1266
c9b58006
KY
1267/* unsolicited event for HP jack sensing */
1268static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1269{
1270 if (codec->vendor_id == 0x10ec0880)
1271 res >>= 28;
1272 else
1273 res >>= 26;
a9fd4f3f
TI
1274 switch (res) {
1275 case ALC880_HP_EVENT:
d922b51d 1276 alc_hp_automute(codec);
a9fd4f3f 1277 break;
e6a5e1b7
TI
1278 case ALC880_FRONT_EVENT:
1279 alc_line_automute(codec);
1280 break;
a9fd4f3f 1281 case ALC880_MIC_EVENT:
7fb0d78f 1282 alc_mic_automute(codec);
a9fd4f3f
TI
1283 break;
1284 }
7fb0d78f
KY
1285}
1286
1287static void alc_inithook(struct hda_codec *codec)
1288{
d922b51d 1289 alc_hp_automute(codec);
e6a5e1b7 1290 alc_line_automute(codec);
7fb0d78f 1291 alc_mic_automute(codec);
c9b58006
KY
1292}
1293
f9423e7a
KY
1294/* additional initialization for ALC888 variants */
1295static void alc888_coef_init(struct hda_codec *codec)
1296{
1297 unsigned int tmp;
1298
1299 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1300 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1301 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
37db623a 1302 if ((tmp & 0xf0) == 0x20)
f9423e7a
KY
1303 /* alc888S-VC */
1304 snd_hda_codec_read(codec, 0x20, 0,
1305 AC_VERB_SET_PROC_COEF, 0x830);
1306 else
1307 /* alc888-VB */
1308 snd_hda_codec_read(codec, 0x20, 0,
1309 AC_VERB_SET_PROC_COEF, 0x3030);
1310}
1311
87a8c370
JK
1312static void alc889_coef_init(struct hda_codec *codec)
1313{
1314 unsigned int tmp;
1315
1316 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1317 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1318 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1319 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1320}
1321
3fb4a508
TI
1322/* turn on/off EAPD control (only if available) */
1323static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1324{
1325 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1326 return;
1327 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1328 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1329 on ? 2 : 0);
1330}
1331
691f1fcc
TI
1332/* turn on/off EAPD controls of the codec */
1333static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1334{
1335 /* We currently only handle front, HP */
1336 switch (codec->vendor_id) {
1337 case 0x10ec0260:
1338 set_eapd(codec, 0x0f, on);
1339 set_eapd(codec, 0x10, on);
1340 break;
1341 case 0x10ec0262:
1342 case 0x10ec0267:
1343 case 0x10ec0268:
1344 case 0x10ec0269:
1345 case 0x10ec0270:
1346 case 0x10ec0272:
1347 case 0x10ec0660:
1348 case 0x10ec0662:
1349 case 0x10ec0663:
1350 case 0x10ec0665:
1351 case 0x10ec0862:
1352 case 0x10ec0889:
1353 case 0x10ec0892:
1354 set_eapd(codec, 0x14, on);
1355 set_eapd(codec, 0x15, on);
1356 break;
1357 }
1358}
1359
1c716153
TI
1360/* generic shutup callback;
1361 * just turning off EPAD and a little pause for avoiding pop-noise
1362 */
1363static void alc_eapd_shutup(struct hda_codec *codec)
1364{
1365 alc_auto_setup_eapd(codec, false);
1366 msleep(200);
1367}
1368
4a79ba34 1369static void alc_auto_init_amp(struct hda_codec *codec, int type)
bc9f98a9 1370{
4a79ba34 1371 unsigned int tmp;
bc9f98a9 1372
4a79ba34
TI
1373 switch (type) {
1374 case ALC_INIT_GPIO1:
bc9f98a9
KY
1375 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1376 break;
4a79ba34 1377 case ALC_INIT_GPIO2:
bc9f98a9
KY
1378 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1379 break;
4a79ba34 1380 case ALC_INIT_GPIO3:
bdd148a3
KY
1381 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1382 break;
4a79ba34 1383 case ALC_INIT_DEFAULT:
691f1fcc 1384 alc_auto_setup_eapd(codec, true);
c9b58006
KY
1385 switch (codec->vendor_id) {
1386 case 0x10ec0260:
1387 snd_hda_codec_write(codec, 0x1a, 0,
1388 AC_VERB_SET_COEF_INDEX, 7);
1389 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1390 AC_VERB_GET_PROC_COEF, 0);
1391 snd_hda_codec_write(codec, 0x1a, 0,
1392 AC_VERB_SET_COEF_INDEX, 7);
1393 snd_hda_codec_write(codec, 0x1a, 0,
1394 AC_VERB_SET_PROC_COEF,
1395 tmp | 0x2010);
1396 break;
1397 case 0x10ec0262:
1398 case 0x10ec0880:
1399 case 0x10ec0882:
1400 case 0x10ec0883:
1401 case 0x10ec0885:
4a5a4c56 1402 case 0x10ec0887:
20b67ddd 1403 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
87a8c370 1404 alc889_coef_init(codec);
c9b58006 1405 break;
f9423e7a 1406 case 0x10ec0888:
4a79ba34 1407 alc888_coef_init(codec);
f9423e7a 1408 break;
0aea778e 1409#if 0 /* XXX: This may cause the silent output on speaker on some machines */
c9b58006
KY
1410 case 0x10ec0267:
1411 case 0x10ec0268:
1412 snd_hda_codec_write(codec, 0x20, 0,
1413 AC_VERB_SET_COEF_INDEX, 7);
1414 tmp = snd_hda_codec_read(codec, 0x20, 0,
1415 AC_VERB_GET_PROC_COEF, 0);
1416 snd_hda_codec_write(codec, 0x20, 0,
ea1fb29a 1417 AC_VERB_SET_COEF_INDEX, 7);
c9b58006
KY
1418 snd_hda_codec_write(codec, 0x20, 0,
1419 AC_VERB_SET_PROC_COEF,
1420 tmp | 0x3000);
1421 break;
0aea778e 1422#endif /* XXX */
bc9f98a9 1423 }
4a79ba34
TI
1424 break;
1425 }
1426}
1427
1a1455de
TI
1428static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1429 struct snd_ctl_elem_info *uinfo)
1430{
ae8a60a5
TI
1431 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1432 struct alc_spec *spec = codec->spec;
1433 static const char * const texts2[] = {
1434 "Disabled", "Enabled"
1435 };
1436 static const char * const texts3[] = {
1a1455de
TI
1437 "Disabled", "Speaker Only", "Line-Out+Speaker"
1438 };
ae8a60a5 1439 const char * const *texts;
1a1455de
TI
1440
1441 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1442 uinfo->count = 1;
ae8a60a5
TI
1443 if (spec->automute_hp_lo) {
1444 uinfo->value.enumerated.items = 3;
1445 texts = texts3;
1446 } else {
1447 uinfo->value.enumerated.items = 2;
1448 texts = texts2;
1449 }
1450 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1451 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1a1455de
TI
1452 strcpy(uinfo->value.enumerated.name,
1453 texts[uinfo->value.enumerated.item]);
1454 return 0;
1455}
1456
1457static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1458 struct snd_ctl_elem_value *ucontrol)
1459{
1460 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1461 struct alc_spec *spec = codec->spec;
1462 unsigned int val;
1463 if (!spec->automute)
1464 val = 0;
1465 else if (!spec->automute_lines)
1466 val = 1;
1467 else
1468 val = 2;
1469 ucontrol->value.enumerated.item[0] = val;
1470 return 0;
1471}
1472
1473static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1474 struct snd_ctl_elem_value *ucontrol)
1475{
1476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1477 struct alc_spec *spec = codec->spec;
1478
1479 switch (ucontrol->value.enumerated.item[0]) {
1480 case 0:
1481 if (!spec->automute)
1482 return 0;
1483 spec->automute = 0;
1484 break;
1485 case 1:
1486 if (spec->automute && !spec->automute_lines)
1487 return 0;
1488 spec->automute = 1;
1489 spec->automute_lines = 0;
1490 break;
1491 case 2:
ae8a60a5
TI
1492 if (!spec->automute_hp_lo)
1493 return -EINVAL;
1a1455de
TI
1494 if (spec->automute && spec->automute_lines)
1495 return 0;
1496 spec->automute = 1;
1497 spec->automute_lines = 1;
1498 break;
1499 default:
1500 return -EINVAL;
1501 }
1502 update_speakers(codec);
1503 return 1;
1504}
1505
a9111321 1506static const struct snd_kcontrol_new alc_automute_mode_enum = {
1a1455de
TI
1507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1508 .name = "Auto-Mute Mode",
1509 .info = alc_automute_mode_info,
1510 .get = alc_automute_mode_get,
1511 .put = alc_automute_mode_put,
1512};
1513
1514static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1515
1516static int alc_add_automute_mode_enum(struct hda_codec *codec)
1517{
1518 struct alc_spec *spec = codec->spec;
1519 struct snd_kcontrol_new *knew;
1520
1521 knew = alc_kcontrol_new(spec);
1522 if (!knew)
1523 return -ENOMEM;
1524 *knew = alc_automute_mode_enum;
1525 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1526 if (!knew->name)
1527 return -ENOMEM;
1528 return 0;
1529}
1530
4a79ba34
TI
1531static void alc_init_auto_hp(struct hda_codec *codec)
1532{
1533 struct alc_spec *spec = codec->spec;
bb35febd 1534 struct auto_pin_cfg *cfg = &spec->autocfg;
1daf5f46 1535 int present = 0;
bb35febd 1536 int i;
4a79ba34 1537
1daf5f46
TI
1538 if (cfg->hp_pins[0])
1539 present++;
1540 if (cfg->line_out_pins[0])
1541 present++;
1542 if (cfg->speaker_pins[0])
1543 present++;
1544 if (present < 2) /* need two different output types */
1545 return;
ae8a60a5
TI
1546 if (present == 3)
1547 spec->automute_hp_lo = 1; /* both HP and LO automute */
4a79ba34 1548
bb35febd 1549 if (!cfg->speaker_pins[0]) {
bb35febd
TI
1550 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1551 sizeof(cfg->speaker_pins));
1552 cfg->speaker_outs = cfg->line_outs;
1553 }
1554
1555 if (!cfg->hp_pins[0]) {
1556 memcpy(cfg->hp_pins, cfg->line_out_pins,
1557 sizeof(cfg->hp_pins));
1558 cfg->hp_outs = cfg->line_outs;
4a79ba34
TI
1559 }
1560
bb35febd 1561 for (i = 0; i < cfg->hp_outs; i++) {
1a1455de
TI
1562 hda_nid_t nid = cfg->hp_pins[i];
1563 if (!(snd_hda_query_pin_caps(codec, nid) &
1564 AC_PINCAP_PRES_DETECT))
1565 continue;
bb35febd 1566 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1a1455de
TI
1567 nid);
1568 snd_hda_codec_write_cache(codec, nid, 0,
4a79ba34
TI
1569 AC_VERB_SET_UNSOLICITED_ENABLE,
1570 AC_USRSP_EN | ALC880_HP_EVENT);
d922b51d
TI
1571 spec->automute = 1;
1572 spec->automute_mode = ALC_AUTOMUTE_PIN;
bb35febd 1573 }
1a1455de
TI
1574 if (spec->automute && cfg->line_out_pins[0] &&
1575 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1576 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1577 for (i = 0; i < cfg->line_outs; i++) {
1578 hda_nid_t nid = cfg->line_out_pins[i];
1579 if (!(snd_hda_query_pin_caps(codec, nid) &
1580 AC_PINCAP_PRES_DETECT))
1581 continue;
1582 snd_printdd("realtek: Enable Line-Out auto-muting "
1583 "on NID 0x%x\n", nid);
1584 snd_hda_codec_write_cache(codec, nid, 0,
1585 AC_VERB_SET_UNSOLICITED_ENABLE,
1586 AC_USRSP_EN | ALC880_FRONT_EVENT);
1587 spec->detect_line = 1;
1588 }
ae8a60a5
TI
1589 spec->automute_lines = 1;
1590 }
1591
1592 if (spec->automute) {
1a1455de
TI
1593 /* create a control for automute mode */
1594 alc_add_automute_mode_enum(codec);
ae8a60a5 1595 spec->unsol_event = alc_sku_unsol_event;
1a1455de 1596 }
4a79ba34
TI
1597}
1598
6c819492
TI
1599static void alc_init_auto_mic(struct hda_codec *codec)
1600{
1601 struct alc_spec *spec = codec->spec;
1602 struct auto_pin_cfg *cfg = &spec->autocfg;
1603 hda_nid_t fixed, ext;
1604 int i;
1605
1606 /* there must be only two mic inputs exclusively */
66ceeb6b 1607 for (i = 0; i < cfg->num_inputs; i++)
86e2959a 1608 if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN)
6c819492
TI
1609 return;
1610
1611 fixed = ext = 0;
66ceeb6b
TI
1612 for (i = 0; i < cfg->num_inputs; i++) {
1613 hda_nid_t nid = cfg->inputs[i].pin;
6c819492 1614 unsigned int defcfg;
6c819492 1615 defcfg = snd_hda_codec_get_pincfg(codec, nid);
99ae28be
TI
1616 switch (snd_hda_get_input_pin_attr(defcfg)) {
1617 case INPUT_PIN_ATTR_INT:
6c819492
TI
1618 if (fixed)
1619 return; /* already occupied */
1620 fixed = nid;
1621 break;
99ae28be
TI
1622 case INPUT_PIN_ATTR_UNUSED:
1623 return; /* invalid entry */
1624 default:
6c819492
TI
1625 if (ext)
1626 return; /* already occupied */
1627 ext = nid;
1628 break;
6c819492
TI
1629 }
1630 }
eaa9b3a7
TI
1631 if (!ext || !fixed)
1632 return;
6c819492
TI
1633 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1634 return; /* no unsol support */
1635 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1636 ext, fixed);
1637 spec->ext_mic.pin = ext;
1638 spec->int_mic.pin = fixed;
1639 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1640 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1641 spec->auto_mic = 1;
1642 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1643 AC_VERB_SET_UNSOLICITED_ENABLE,
1644 AC_USRSP_EN | ALC880_MIC_EVENT);
1645 spec->unsol_event = alc_sku_unsol_event;
1646}
1647
90622917
DH
1648/* Could be any non-zero and even value. When used as fixup, tells
1649 * the driver to ignore any present sku defines.
1650 */
1651#define ALC_FIXUP_SKU_IGNORE (2)
1652
da00c244
KY
1653static int alc_auto_parse_customize_define(struct hda_codec *codec)
1654{
1655 unsigned int ass, tmp, i;
7fb56223 1656 unsigned nid = 0;
da00c244
KY
1657 struct alc_spec *spec = codec->spec;
1658
b6cbe517
TI
1659 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1660
90622917
DH
1661 if (spec->cdefine.fixup) {
1662 ass = spec->cdefine.sku_cfg;
1663 if (ass == ALC_FIXUP_SKU_IGNORE)
1664 return -1;
1665 goto do_sku;
1666 }
1667
da00c244 1668 ass = codec->subsystem_id & 0xffff;
b6cbe517 1669 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
da00c244
KY
1670 goto do_sku;
1671
1672 nid = 0x1d;
1673 if (codec->vendor_id == 0x10ec0260)
1674 nid = 0x17;
1675 ass = snd_hda_codec_get_pincfg(codec, nid);
1676
1677 if (!(ass & 1)) {
1678 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1679 codec->chip_name, ass);
1680 return -1;
1681 }
1682
1683 /* check sum */
1684 tmp = 0;
1685 for (i = 1; i < 16; i++) {
1686 if ((ass >> i) & 1)
1687 tmp++;
1688 }
1689 if (((ass >> 16) & 0xf) != tmp)
1690 return -1;
1691
1692 spec->cdefine.port_connectivity = ass >> 30;
1693 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1694 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1695 spec->cdefine.customization = ass >> 8;
1696do_sku:
1697 spec->cdefine.sku_cfg = ass;
1698 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1699 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1700 spec->cdefine.swap = (ass & 0x2) >> 1;
1701 spec->cdefine.override = ass & 0x1;
1702
1703 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1704 nid, spec->cdefine.sku_cfg);
1705 snd_printd("SKU: port_connectivity=0x%x\n",
1706 spec->cdefine.port_connectivity);
1707 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1708 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1709 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1710 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1711 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1712 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1713 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1714
1715 return 0;
1716}
1717
4a79ba34
TI
1718/* check subsystem ID and set up device-specific initialization;
1719 * return 1 if initialized, 0 if invalid SSID
1720 */
1721/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1722 * 31 ~ 16 : Manufacture ID
1723 * 15 ~ 8 : SKU ID
1724 * 7 ~ 0 : Assembly ID
1725 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1726 */
1727static int alc_subsystem_id(struct hda_codec *codec,
1728 hda_nid_t porta, hda_nid_t porte,
6227cdce 1729 hda_nid_t portd, hda_nid_t porti)
4a79ba34
TI
1730{
1731 unsigned int ass, tmp, i;
1732 unsigned nid;
1733 struct alc_spec *spec = codec->spec;
1734
90622917
DH
1735 if (spec->cdefine.fixup) {
1736 ass = spec->cdefine.sku_cfg;
1737 if (ass == ALC_FIXUP_SKU_IGNORE)
1738 return 0;
1739 goto do_sku;
1740 }
1741
4a79ba34
TI
1742 ass = codec->subsystem_id & 0xffff;
1743 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1744 goto do_sku;
1745
1746 /* invalid SSID, check the special NID pin defcfg instead */
1747 /*
def319f9 1748 * 31~30 : port connectivity
4a79ba34
TI
1749 * 29~21 : reserve
1750 * 20 : PCBEEP input
1751 * 19~16 : Check sum (15:1)
1752 * 15~1 : Custom
1753 * 0 : override
1754 */
1755 nid = 0x1d;
1756 if (codec->vendor_id == 0x10ec0260)
1757 nid = 0x17;
1758 ass = snd_hda_codec_get_pincfg(codec, nid);
1759 snd_printd("realtek: No valid SSID, "
1760 "checking pincfg 0x%08x for NID 0x%x\n",
cb6605c1 1761 ass, nid);
6227cdce 1762 if (!(ass & 1))
4a79ba34
TI
1763 return 0;
1764 if ((ass >> 30) != 1) /* no physical connection */
1765 return 0;
1766
1767 /* check sum */
1768 tmp = 0;
1769 for (i = 1; i < 16; i++) {
1770 if ((ass >> i) & 1)
1771 tmp++;
1772 }
1773 if (((ass >> 16) & 0xf) != tmp)
1774 return 0;
1775do_sku:
1776 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1777 ass & 0xffff, codec->vendor_id);
1778 /*
1779 * 0 : override
1780 * 1 : Swap Jack
1781 * 2 : 0 --> Desktop, 1 --> Laptop
1782 * 3~5 : External Amplifier control
1783 * 7~6 : Reserved
1784 */
1785 tmp = (ass & 0x38) >> 3; /* external Amp control */
1786 switch (tmp) {
1787 case 1:
1788 spec->init_amp = ALC_INIT_GPIO1;
1789 break;
1790 case 3:
1791 spec->init_amp = ALC_INIT_GPIO2;
1792 break;
1793 case 7:
1794 spec->init_amp = ALC_INIT_GPIO3;
1795 break;
1796 case 5:
5a8cfb4e 1797 default:
4a79ba34 1798 spec->init_amp = ALC_INIT_DEFAULT;
bc9f98a9
KY
1799 break;
1800 }
ea1fb29a 1801
8c427226 1802 /* is laptop or Desktop and enable the function "Mute internal speaker
c9b58006
KY
1803 * when the external headphone out jack is plugged"
1804 */
8c427226 1805 if (!(ass & 0x8000))
4a79ba34 1806 return 1;
c9b58006
KY
1807 /*
1808 * 10~8 : Jack location
1809 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1810 * 14~13: Resvered
1811 * 15 : 1 --> enable the function "Mute internal speaker
1812 * when the external headphone out jack is plugged"
1813 */
c9b58006 1814 if (!spec->autocfg.hp_pins[0]) {
01d4825d 1815 hda_nid_t nid;
c9b58006
KY
1816 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1817 if (tmp == 0)
01d4825d 1818 nid = porta;
c9b58006 1819 else if (tmp == 1)
01d4825d 1820 nid = porte;
c9b58006 1821 else if (tmp == 2)
01d4825d 1822 nid = portd;
6227cdce
KY
1823 else if (tmp == 3)
1824 nid = porti;
c9b58006 1825 else
4a79ba34 1826 return 1;
01d4825d
TI
1827 for (i = 0; i < spec->autocfg.line_outs; i++)
1828 if (spec->autocfg.line_out_pins[i] == nid)
1829 return 1;
1830 spec->autocfg.hp_pins[0] = nid;
c9b58006 1831 }
4a79ba34
TI
1832 return 1;
1833}
ea1fb29a 1834
4a79ba34 1835static void alc_ssid_check(struct hda_codec *codec,
6227cdce
KY
1836 hda_nid_t porta, hda_nid_t porte,
1837 hda_nid_t portd, hda_nid_t porti)
4a79ba34 1838{
6227cdce 1839 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
4a79ba34
TI
1840 struct alc_spec *spec = codec->spec;
1841 snd_printd("realtek: "
1842 "Enable default setup for auto mode as fallback\n");
1843 spec->init_amp = ALC_INIT_DEFAULT;
4a79ba34 1844 }
1a1455de
TI
1845
1846 alc_init_auto_hp(codec);
1847 alc_init_auto_mic(codec);
bc9f98a9
KY
1848}
1849
f95474ec 1850/*
f8f25ba3 1851 * Fix-up pin default configurations and add default verbs
f95474ec
TI
1852 */
1853
1854struct alc_pincfg {
1855 hda_nid_t nid;
1856 u32 val;
1857};
1858
e1eb5f10
TB
1859struct alc_model_fixup {
1860 const int id;
1861 const char *name;
1862};
1863
f8f25ba3 1864struct alc_fixup {
b5bfbc67 1865 int type;
361fe6e9
TI
1866 bool chained;
1867 int chain_id;
b5bfbc67
TI
1868 union {
1869 unsigned int sku;
1870 const struct alc_pincfg *pins;
1871 const struct hda_verb *verbs;
1872 void (*func)(struct hda_codec *codec,
1873 const struct alc_fixup *fix,
1874 int action);
1875 } v;
f8f25ba3
TI
1876};
1877
b5bfbc67
TI
1878enum {
1879 ALC_FIXUP_INVALID,
1880 ALC_FIXUP_SKU,
1881 ALC_FIXUP_PINS,
1882 ALC_FIXUP_VERBS,
1883 ALC_FIXUP_FUNC,
1884};
1885
1886enum {
1887 ALC_FIXUP_ACT_PRE_PROBE,
1888 ALC_FIXUP_ACT_PROBE,
58701120 1889 ALC_FIXUP_ACT_INIT,
b5bfbc67
TI
1890};
1891
1892static void alc_apply_fixup(struct hda_codec *codec, int action)
f95474ec 1893{
b5bfbc67
TI
1894 struct alc_spec *spec = codec->spec;
1895 int id = spec->fixup_id;
aa1d0c52 1896#ifdef CONFIG_SND_DEBUG_VERBOSE
b5bfbc67 1897 const char *modelname = spec->fixup_name;
aa1d0c52 1898#endif
b5bfbc67 1899 int depth = 0;
f95474ec 1900
b5bfbc67
TI
1901 if (!spec->fixup_list)
1902 return;
1903
1904 while (id >= 0) {
1905 const struct alc_fixup *fix = spec->fixup_list + id;
1906 const struct alc_pincfg *cfg;
1907
1908 switch (fix->type) {
1909 case ALC_FIXUP_SKU:
1910 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1911 break;;
1912 snd_printdd(KERN_INFO "hda_codec: %s: "
1913 "Apply sku override for %s\n",
1914 codec->chip_name, modelname);
1915 spec->cdefine.sku_cfg = fix->v.sku;
1916 spec->cdefine.fixup = 1;
1917 break;
1918 case ALC_FIXUP_PINS:
1919 cfg = fix->v.pins;
1920 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1921 break;
1922 snd_printdd(KERN_INFO "hda_codec: %s: "
1923 "Apply pincfg for %s\n",
1924 codec->chip_name, modelname);
1925 for (; cfg->nid; cfg++)
1926 snd_hda_codec_set_pincfg(codec, cfg->nid,
1927 cfg->val);
1928 break;
1929 case ALC_FIXUP_VERBS:
1930 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1931 break;
1932 snd_printdd(KERN_INFO "hda_codec: %s: "
1933 "Apply fix-verbs for %s\n",
1934 codec->chip_name, modelname);
1935 add_verb(codec->spec, fix->v.verbs);
1936 break;
1937 case ALC_FIXUP_FUNC:
1938 if (!fix->v.func)
1939 break;
1940 snd_printdd(KERN_INFO "hda_codec: %s: "
1941 "Apply fix-func for %s\n",
1942 codec->chip_name, modelname);
1943 fix->v.func(codec, fix, action);
1944 break;
1945 default:
1946 snd_printk(KERN_ERR "hda_codec: %s: "
1947 "Invalid fixup type %d\n",
1948 codec->chip_name, fix->type);
1949 break;
1950 }
24af2b1c 1951 if (!fix->chained)
b5bfbc67
TI
1952 break;
1953 if (++depth > 10)
1954 break;
24af2b1c 1955 id = fix->chain_id;
9d57883f 1956 }
f95474ec
TI
1957}
1958
e1eb5f10 1959static void alc_pick_fixup(struct hda_codec *codec,
b5bfbc67
TI
1960 const struct alc_model_fixup *models,
1961 const struct snd_pci_quirk *quirk,
1962 const struct alc_fixup *fixlist)
e1eb5f10 1963{
b5bfbc67
TI
1964 struct alc_spec *spec = codec->spec;
1965 int id = -1;
1966 const char *name = NULL;
e1eb5f10 1967
e1eb5f10
TB
1968 if (codec->modelname && models) {
1969 while (models->name) {
1970 if (!strcmp(codec->modelname, models->name)) {
b5bfbc67
TI
1971 id = models->id;
1972 name = models->name;
e1eb5f10
TB
1973 break;
1974 }
1975 models++;
1976 }
b5bfbc67
TI
1977 }
1978 if (id < 0) {
1979 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1980 if (quirk) {
1981 id = quirk->value;
1982#ifdef CONFIG_SND_DEBUG_VERBOSE
1983 name = quirk->name;
1984#endif
1985 }
1986 }
1987
1988 spec->fixup_id = id;
1989 if (id >= 0) {
1990 spec->fixup_list = fixlist;
1991 spec->fixup_name = name;
e1eb5f10 1992 }
f95474ec
TI
1993}
1994
274693f3
KY
1995static int alc_read_coef_idx(struct hda_codec *codec,
1996 unsigned int coef_idx)
1997{
1998 unsigned int val;
1999 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2000 coef_idx);
2001 val = snd_hda_codec_read(codec, 0x20, 0,
2002 AC_VERB_GET_PROC_COEF, 0);
2003 return val;
2004}
2005
977ddd6b
KY
2006static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2007 unsigned int coef_val)
2008{
2009 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2010 coef_idx);
2011 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2012 coef_val);
2013}
2014
757899ac
TI
2015/* set right pin controls for digital I/O */
2016static void alc_auto_init_digital(struct hda_codec *codec)
2017{
2018 struct alc_spec *spec = codec->spec;
2019 int i;
2020 hda_nid_t pin;
2021
2022 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2023 pin = spec->autocfg.dig_out_pins[i];
2024 if (pin) {
2025 snd_hda_codec_write(codec, pin, 0,
2026 AC_VERB_SET_PIN_WIDGET_CONTROL,
2027 PIN_OUT);
2028 }
2029 }
2030 pin = spec->autocfg.dig_in_pin;
2031 if (pin)
2032 snd_hda_codec_write(codec, pin, 0,
2033 AC_VERB_SET_PIN_WIDGET_CONTROL,
2034 PIN_IN);
2035}
2036
2037/* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2038static void alc_auto_parse_digital(struct hda_codec *codec)
2039{
2040 struct alc_spec *spec = codec->spec;
2041 int i, err;
2042 hda_nid_t dig_nid;
2043
2044 /* support multiple SPDIFs; the secondary is set up as a slave */
2045 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2046 err = snd_hda_get_connections(codec,
2047 spec->autocfg.dig_out_pins[i],
2048 &dig_nid, 1);
2049 if (err < 0)
2050 continue;
2051 if (!i) {
2052 spec->multiout.dig_out_nid = dig_nid;
2053 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2054 } else {
2055 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2056 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2057 break;
2058 spec->slave_dig_outs[i - 1] = dig_nid;
2059 }
2060 }
2061
2062 if (spec->autocfg.dig_in_pin) {
01fdf180
TI
2063 dig_nid = codec->start_nid;
2064 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2065 unsigned int wcaps = get_wcaps(codec, dig_nid);
2066 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2067 continue;
2068 if (!(wcaps & AC_WCAP_DIGITAL))
2069 continue;
2070 if (!(wcaps & AC_WCAP_CONN_LIST))
2071 continue;
2072 err = get_connection_index(codec, dig_nid,
2073 spec->autocfg.dig_in_pin);
2074 if (err >= 0) {
2075 spec->dig_in_nid = dig_nid;
2076 break;
2077 }
2078 }
757899ac
TI
2079 }
2080}
2081
ef8ef5fb
VP
2082/*
2083 * ALC888
2084 */
2085
2086/*
2087 * 2ch mode
2088 */
a9111321 2089static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
ef8ef5fb
VP
2090/* Mic-in jack as mic in */
2091 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2092 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2093/* Line-in jack as Line in */
2094 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2095 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2096/* Line-Out as Front */
2097 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2098 { } /* end */
2099};
2100
2101/*
2102 * 4ch mode
2103 */
a9111321 2104static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
ef8ef5fb
VP
2105/* Mic-in jack as mic in */
2106 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2107 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2108/* Line-in jack as Surround */
2109 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2110 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2111/* Line-Out as Front */
2112 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2113 { } /* end */
2114};
2115
2116/*
2117 * 6ch mode
2118 */
a9111321 2119static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
ef8ef5fb
VP
2120/* Mic-in jack as CLFE */
2121 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2122 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2123/* Line-in jack as Surround */
2124 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2125 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2126/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2127 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2128 { } /* end */
2129};
2130
2131/*
2132 * 8ch mode
2133 */
a9111321 2134static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
ef8ef5fb
VP
2135/* Mic-in jack as CLFE */
2136 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2137 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2138/* Line-in jack as Surround */
2139 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2140 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2141/* Line-Out as Side */
2142 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2143 { } /* end */
2144};
2145
a9111321 2146static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
ef8ef5fb
VP
2147 { 2, alc888_4ST_ch2_intel_init },
2148 { 4, alc888_4ST_ch4_intel_init },
2149 { 6, alc888_4ST_ch6_intel_init },
2150 { 8, alc888_4ST_ch8_intel_init },
2151};
2152
2153/*
2154 * ALC888 Fujitsu Siemens Amillo xa3530
2155 */
2156
a9111321 2157static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
ef8ef5fb
VP
2158/* Front Mic: set to PIN_IN (empty by default) */
2159 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2160/* Connect Internal HP to Front */
2161 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2162 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2163 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2164/* Connect Bass HP to Front */
2165 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2166 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2167 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2168/* Connect Line-Out side jack (SPDIF) to Side */
2169 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2170 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2171 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2172/* Connect Mic jack to CLFE */
2173 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2174 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2175 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2176/* Connect Line-in jack to Surround */
2177 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2178 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2179 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2180/* Connect HP out jack to Front */
2181 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2182 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2183 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2184/* Enable unsolicited event for HP jack and Line-out jack */
2185 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2186 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2187 {}
2188};
2189
4f5d1706 2190static void alc889_automute_setup(struct hda_codec *codec)
6732bd0d
WF
2191{
2192 struct alc_spec *spec = codec->spec;
2193
2194 spec->autocfg.hp_pins[0] = 0x15;
2195 spec->autocfg.speaker_pins[0] = 0x14;
2196 spec->autocfg.speaker_pins[1] = 0x16;
2197 spec->autocfg.speaker_pins[2] = 0x17;
2198 spec->autocfg.speaker_pins[3] = 0x19;
2199 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
2200 spec->automute = 1;
2201 spec->automute_mode = ALC_AUTOMUTE_AMP;
6732bd0d
WF
2202}
2203
2204static void alc889_intel_init_hook(struct hda_codec *codec)
2205{
2206 alc889_coef_init(codec);
d922b51d 2207 alc_hp_automute(codec);
6732bd0d
WF
2208}
2209
4f5d1706 2210static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
a9fd4f3f
TI
2211{
2212 struct alc_spec *spec = codec->spec;
2213
2214 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2215 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2216 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2217 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
d922b51d
TI
2218 spec->automute = 1;
2219 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f 2220}
ef8ef5fb 2221
5b2d1eca
VP
2222/*
2223 * ALC888 Acer Aspire 4930G model
2224 */
2225
a9111321 2226static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
5b2d1eca
VP
2227/* Front Mic: set to PIN_IN (empty by default) */
2228 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2229/* Unselect Front Mic by default in input mixer 3 */
2230 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
ef8ef5fb 2231/* Enable unsolicited event for HP jack */
5b2d1eca
VP
2232 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2233/* Connect Internal HP to front */
2234 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2235 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2236 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2237/* Connect HP out to front */
2238 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2239 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2240 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
e2e93296 2241 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5b2d1eca
VP
2242 { }
2243};
2244
d2fd4b09
TV
2245/*
2246 * ALC888 Acer Aspire 6530G model
2247 */
2248
a9111321 2249static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
d1284182
TV
2250/* Route to built-in subwoofer as well as speakers */
2251 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2252 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2253 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2254 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
d2fd4b09
TV
2255/* Bias voltage on for external mic port */
2256 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
320d5920
EL
2257/* Front Mic: set to PIN_IN (empty by default) */
2258 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2259/* Unselect Front Mic by default in input mixer 3 */
2260 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
d2fd4b09
TV
2261/* Enable unsolicited event for HP jack */
2262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2263/* Enable speaker output */
2264 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1284182 2266 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2267/* Enable headphone output */
2268 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2269 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2270 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1284182 2271 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
d2fd4b09
TV
2272 { }
2273};
2274
d9477207
DK
2275/*
2276 *ALC888 Acer Aspire 7730G model
2277 */
2278
a9111321 2279static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
d9477207
DK
2280/* Bias voltage on for external mic port */
2281 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2282/* Front Mic: set to PIN_IN (empty by default) */
2283 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2284/* Unselect Front Mic by default in input mixer 3 */
2285 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2286/* Enable unsolicited event for HP jack */
2287 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2288/* Enable speaker output */
2289 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2290 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2291 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2292/* Enable headphone output */
2293 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2294 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2295 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2296 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2297/*Enable internal subwoofer */
2298 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2299 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2300 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2301 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2302 { }
2303};
2304
3b315d70 2305/*
018df418 2306 * ALC889 Acer Aspire 8930G model
3b315d70
HM
2307 */
2308
a9111321 2309static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
3b315d70
HM
2310/* Front Mic: set to PIN_IN (empty by default) */
2311 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2312/* Unselect Front Mic by default in input mixer 3 */
2313 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2314/* Enable unsolicited event for HP jack */
2315 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2316/* Connect Internal Front to Front */
2317 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2318 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2319 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2320/* Connect Internal Rear to Rear */
2321 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2322 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2324/* Connect Internal CLFE to CLFE */
2325 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2326 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2328/* Connect HP out to Front */
018df418 2329 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
3b315d70
HM
2330 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2332/* Enable all DACs */
2333/* DAC DISABLE/MUTE 1? */
2334/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2335 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2336 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2337/* DAC DISABLE/MUTE 2? */
2338/* some bit here disables the other DACs. Init=0x4900 */
2339 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2340 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
018df418
HM
2341/* DMIC fix
2342 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2343 * which makes the stereo useless. However, either the mic or the ALC889
2344 * makes the signal become a difference/sum signal instead of standard
2345 * stereo, which is annoying. So instead we flip this bit which makes the
2346 * codec replicate the sum signal to both channels, turning it into a
2347 * normal mono mic.
2348 */
2349/* DMIC_CONTROL? Init value = 0x0001 */
2350 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2351 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
3b315d70
HM
2352 { }
2353};
2354
a9111321 2355static const struct hda_input_mux alc888_2_capture_sources[2] = {
5b2d1eca
VP
2356 /* Front mic only available on one ADC */
2357 {
2358 .num_items = 4,
2359 .items = {
2360 { "Mic", 0x0 },
2361 { "Line", 0x2 },
2362 { "CD", 0x4 },
2363 { "Front Mic", 0xb },
2364 },
2365 },
2366 {
2367 .num_items = 3,
2368 .items = {
2369 { "Mic", 0x0 },
2370 { "Line", 0x2 },
2371 { "CD", 0x4 },
2372 },
2373 }
2374};
2375
a9111321 2376static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
d2fd4b09
TV
2377 /* Interal mic only available on one ADC */
2378 {
684a8842 2379 .num_items = 5,
d2fd4b09 2380 .items = {
8607f7c4 2381 { "Mic", 0x0 },
684a8842 2382 { "Line In", 0x2 },
d2fd4b09 2383 { "CD", 0x4 },
684a8842 2384 { "Input Mix", 0xa },
28c4edb7 2385 { "Internal Mic", 0xb },
d2fd4b09
TV
2386 },
2387 },
2388 {
684a8842 2389 .num_items = 4,
d2fd4b09 2390 .items = {
8607f7c4 2391 { "Mic", 0x0 },
684a8842 2392 { "Line In", 0x2 },
d2fd4b09 2393 { "CD", 0x4 },
684a8842 2394 { "Input Mix", 0xa },
d2fd4b09
TV
2395 },
2396 }
2397};
2398
a9111321 2399static const struct hda_input_mux alc889_capture_sources[3] = {
018df418
HM
2400 /* Digital mic only available on first "ADC" */
2401 {
2402 .num_items = 5,
2403 .items = {
2404 { "Mic", 0x0 },
2405 { "Line", 0x2 },
2406 { "CD", 0x4 },
2407 { "Front Mic", 0xb },
2408 { "Input Mix", 0xa },
2409 },
2410 },
2411 {
2412 .num_items = 4,
2413 .items = {
2414 { "Mic", 0x0 },
2415 { "Line", 0x2 },
2416 { "CD", 0x4 },
2417 { "Input Mix", 0xa },
2418 },
2419 },
2420 {
2421 .num_items = 4,
2422 .items = {
2423 { "Mic", 0x0 },
2424 { "Line", 0x2 },
2425 { "CD", 0x4 },
2426 { "Input Mix", 0xa },
2427 },
2428 }
2429};
2430
a9111321 2431static const struct snd_kcontrol_new alc888_base_mixer[] = {
5b2d1eca
VP
2432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2433 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2434 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2435 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2436 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2437 HDA_OUTPUT),
2438 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2439 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2440 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2441 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2442 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2443 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2444 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2445 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2446 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2447 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2448 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
5b2d1eca 2449 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5b2d1eca
VP
2450 { } /* end */
2451};
2452
a9111321 2453static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
460c92fa
ŁW
2454 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2455 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2456 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2457 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
786c51f9 2458 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
460c92fa 2459 HDA_OUTPUT),
786c51f9
ŁW
2460 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2461 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2462 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2463 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2464 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
460c92fa
ŁW
2465 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2466 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2467 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2468 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2469 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2470 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2471 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2472 { } /* end */
2473};
2474
a9111321 2475static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
556eea9a
HM
2476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2481 HDA_OUTPUT),
2482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2486 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2487 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 2488 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
556eea9a
HM
2489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2490 { } /* end */
2491};
2492
2493
4f5d1706 2494static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
5b2d1eca 2495{
a9fd4f3f 2496 struct alc_spec *spec = codec->spec;
5b2d1eca 2497
a9fd4f3f
TI
2498 spec->autocfg.hp_pins[0] = 0x15;
2499 spec->autocfg.speaker_pins[0] = 0x14;
7cef4cf1
ŁW
2500 spec->autocfg.speaker_pins[1] = 0x16;
2501 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2502 spec->automute = 1;
2503 spec->automute_mode = ALC_AUTOMUTE_AMP;
5b2d1eca
VP
2504}
2505
4f5d1706 2506static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
320d5920
EL
2507{
2508 struct alc_spec *spec = codec->spec;
2509
2510 spec->autocfg.hp_pins[0] = 0x15;
2511 spec->autocfg.speaker_pins[0] = 0x14;
2512 spec->autocfg.speaker_pins[1] = 0x16;
2513 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2514 spec->automute = 1;
2515 spec->automute_mode = ALC_AUTOMUTE_AMP;
320d5920
EL
2516}
2517
d9477207
DK
2518static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2519{
2520 struct alc_spec *spec = codec->spec;
2521
2522 spec->autocfg.hp_pins[0] = 0x15;
2523 spec->autocfg.speaker_pins[0] = 0x14;
2524 spec->autocfg.speaker_pins[1] = 0x16;
2525 spec->autocfg.speaker_pins[2] = 0x17;
d922b51d
TI
2526 spec->automute = 1;
2527 spec->automute_mode = ALC_AUTOMUTE_AMP;
d9477207
DK
2528}
2529
4f5d1706 2530static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
3b315d70
HM
2531{
2532 struct alc_spec *spec = codec->spec;
2533
2534 spec->autocfg.hp_pins[0] = 0x15;
2535 spec->autocfg.speaker_pins[0] = 0x14;
2536 spec->autocfg.speaker_pins[1] = 0x16;
2537 spec->autocfg.speaker_pins[2] = 0x1b;
d922b51d
TI
2538 spec->automute = 1;
2539 spec->automute_mode = ALC_AUTOMUTE_AMP;
3b315d70
HM
2540}
2541
1da177e4 2542/*
e9edcee0
TI
2543 * ALC880 3-stack model
2544 *
2545 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
9c7f852e
TI
2546 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2547 * F-Mic = 0x1b, HP = 0x19
1da177e4
LT
2548 */
2549
4c6d72d1 2550static const hda_nid_t alc880_dac_nids[4] = {
e9edcee0
TI
2551 /* front, rear, clfe, rear_surr */
2552 0x02, 0x05, 0x04, 0x03
2553};
2554
4c6d72d1 2555static const hda_nid_t alc880_adc_nids[3] = {
e9edcee0
TI
2556 /* ADC0-2 */
2557 0x07, 0x08, 0x09,
2558};
2559
2560/* The datasheet says the node 0x07 is connected from inputs,
2561 * but it shows zero connection in the real implementation on some devices.
df694daa 2562 * Note: this is a 915GAV bug, fixed on 915GLV
1da177e4 2563 */
4c6d72d1 2564static const hda_nid_t alc880_adc_nids_alt[2] = {
e9edcee0
TI
2565 /* ADC1-2 */
2566 0x08, 0x09,
2567};
2568
2569#define ALC880_DIGOUT_NID 0x06
2570#define ALC880_DIGIN_NID 0x0a
2571
a9111321 2572static const struct hda_input_mux alc880_capture_source = {
e9edcee0
TI
2573 .num_items = 4,
2574 .items = {
2575 { "Mic", 0x0 },
2576 { "Front Mic", 0x3 },
2577 { "Line", 0x2 },
2578 { "CD", 0x4 },
2579 },
2580};
2581
2582/* channel source setting (2/6 channel selection for 3-stack) */
2583/* 2ch mode */
a9111321 2584static const struct hda_verb alc880_threestack_ch2_init[] = {
e9edcee0
TI
2585 /* set line-in to input, mute it */
2586 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2587 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2588 /* set mic-in to input vref 80%, mute it */
2589 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2590 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2591 { } /* end */
2592};
2593
2594/* 6ch mode */
a9111321 2595static const struct hda_verb alc880_threestack_ch6_init[] = {
e9edcee0
TI
2596 /* set line-in to output, unmute it */
2597 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2598 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2599 /* set mic-in to output, unmute it */
2600 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2601 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2602 { } /* end */
2603};
2604
a9111321 2605static const struct hda_channel_mode alc880_threestack_modes[2] = {
e9edcee0
TI
2606 { 2, alc880_threestack_ch2_init },
2607 { 6, alc880_threestack_ch6_init },
2608};
2609
a9111321 2610static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
05acb863 2611 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2612 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 2613 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2614 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
05acb863
TI
2615 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2616 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2617 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2618 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1da177e4
LT
2619 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2620 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2623 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2624 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2625 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2626 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
e9edcee0
TI
2627 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2628 {
2629 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2630 .name = "Channel Mode",
df694daa
KY
2631 .info = alc_ch_mode_info,
2632 .get = alc_ch_mode_get,
2633 .put = alc_ch_mode_put,
e9edcee0
TI
2634 },
2635 { } /* end */
2636};
2637
2638/* capture mixer elements */
f9e336f6
TI
2639static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2640 struct snd_ctl_elem_info *uinfo)
2641{
2642 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2643 struct alc_spec *spec = codec->spec;
2644 int err;
1da177e4 2645
5a9e02e9 2646 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2647 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2648 HDA_INPUT);
2649 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
5a9e02e9 2650 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2651 return err;
2652}
2653
2654static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2655 unsigned int size, unsigned int __user *tlv)
2656{
2657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2658 struct alc_spec *spec = codec->spec;
2659 int err;
1da177e4 2660
5a9e02e9 2661 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2662 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2663 HDA_INPUT);
2664 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
5a9e02e9 2665 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2666 return err;
2667}
2668
2669typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2670 struct snd_ctl_elem_value *ucontrol);
2671
2672static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2673 struct snd_ctl_elem_value *ucontrol,
2674 getput_call_t func)
2675{
2676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2677 struct alc_spec *spec = codec->spec;
2678 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2679 int err;
2680
5a9e02e9 2681 mutex_lock(&codec->control_mutex);
f9e336f6
TI
2682 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2683 3, 0, HDA_INPUT);
2684 err = func(kcontrol, ucontrol);
5a9e02e9 2685 mutex_unlock(&codec->control_mutex);
f9e336f6
TI
2686 return err;
2687}
2688
2689static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2690 struct snd_ctl_elem_value *ucontrol)
2691{
2692 return alc_cap_getput_caller(kcontrol, ucontrol,
2693 snd_hda_mixer_amp_volume_get);
2694}
2695
2696static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2697 struct snd_ctl_elem_value *ucontrol)
2698{
2699 return alc_cap_getput_caller(kcontrol, ucontrol,
2700 snd_hda_mixer_amp_volume_put);
2701}
2702
2703/* capture mixer elements */
2704#define alc_cap_sw_info snd_ctl_boolean_stereo_info
2705
2706static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2707 struct snd_ctl_elem_value *ucontrol)
2708{
2709 return alc_cap_getput_caller(kcontrol, ucontrol,
2710 snd_hda_mixer_amp_switch_get);
2711}
2712
2713static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2714 struct snd_ctl_elem_value *ucontrol)
2715{
2716 return alc_cap_getput_caller(kcontrol, ucontrol,
2717 snd_hda_mixer_amp_switch_put);
2718}
2719
a23b688f 2720#define _DEFINE_CAPMIX(num) \
f9e336f6
TI
2721 { \
2722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2723 .name = "Capture Switch", \
2724 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2725 .count = num, \
2726 .info = alc_cap_sw_info, \
2727 .get = alc_cap_sw_get, \
2728 .put = alc_cap_sw_put, \
2729 }, \
2730 { \
2731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2732 .name = "Capture Volume", \
2733 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2734 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2735 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2736 .count = num, \
2737 .info = alc_cap_vol_info, \
2738 .get = alc_cap_vol_get, \
2739 .put = alc_cap_vol_put, \
2740 .tlv = { .c = alc_cap_vol_tlv }, \
a23b688f
TI
2741 }
2742
2743#define _DEFINE_CAPSRC(num) \
3c3e9892
TI
2744 { \
2745 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2746 /* .name = "Capture Source", */ \
2747 .name = "Input Source", \
2748 .count = num, \
2749 .info = alc_mux_enum_info, \
2750 .get = alc_mux_enum_get, \
2751 .put = alc_mux_enum_put, \
a23b688f
TI
2752 }
2753
2754#define DEFINE_CAPMIX(num) \
a9111321 2755static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
a23b688f
TI
2756 _DEFINE_CAPMIX(num), \
2757 _DEFINE_CAPSRC(num), \
2758 { } /* end */ \
2759}
2760
2761#define DEFINE_CAPMIX_NOSRC(num) \
a9111321 2762static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
a23b688f
TI
2763 _DEFINE_CAPMIX(num), \
2764 { } /* end */ \
f9e336f6
TI
2765}
2766
2767/* up to three ADCs */
2768DEFINE_CAPMIX(1);
2769DEFINE_CAPMIX(2);
2770DEFINE_CAPMIX(3);
a23b688f
TI
2771DEFINE_CAPMIX_NOSRC(1);
2772DEFINE_CAPMIX_NOSRC(2);
2773DEFINE_CAPMIX_NOSRC(3);
e9edcee0
TI
2774
2775/*
2776 * ALC880 5-stack model
2777 *
9c7f852e
TI
2778 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2779 * Side = 0x02 (0xd)
e9edcee0
TI
2780 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2781 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2782 */
2783
2784/* additional mixers to alc880_three_stack_mixer */
a9111321 2785static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
e9edcee0 2786 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2787 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
1da177e4
LT
2788 { } /* end */
2789};
2790
e9edcee0
TI
2791/* channel source setting (6/8 channel selection for 5-stack) */
2792/* 6ch mode */
a9111321 2793static const struct hda_verb alc880_fivestack_ch6_init[] = {
e9edcee0
TI
2794 /* set line-in to input, mute it */
2795 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2796 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
dfc0ff62
TI
2797 { } /* end */
2798};
2799
e9edcee0 2800/* 8ch mode */
a9111321 2801static const struct hda_verb alc880_fivestack_ch8_init[] = {
e9edcee0
TI
2802 /* set line-in to output, unmute it */
2803 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2804 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2805 { } /* end */
2806};
2807
a9111321 2808static const struct hda_channel_mode alc880_fivestack_modes[2] = {
e9edcee0
TI
2809 { 6, alc880_fivestack_ch6_init },
2810 { 8, alc880_fivestack_ch8_init },
2811};
2812
2813
2814/*
2815 * ALC880 6-stack model
2816 *
9c7f852e
TI
2817 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2818 * Side = 0x05 (0x0f)
e9edcee0
TI
2819 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2820 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2821 */
2822
4c6d72d1 2823static const hda_nid_t alc880_6st_dac_nids[4] = {
e9edcee0
TI
2824 /* front, rear, clfe, rear_surr */
2825 0x02, 0x03, 0x04, 0x05
f12ab1e0 2826};
e9edcee0 2827
a9111321 2828static const struct hda_input_mux alc880_6stack_capture_source = {
e9edcee0
TI
2829 .num_items = 4,
2830 .items = {
2831 { "Mic", 0x0 },
2832 { "Front Mic", 0x1 },
2833 { "Line", 0x2 },
2834 { "CD", 0x4 },
2835 },
2836};
2837
2838/* fixed 8-channels */
a9111321 2839static const struct hda_channel_mode alc880_sixstack_modes[1] = {
e9edcee0
TI
2840 { 8, NULL },
2841};
2842
a9111321 2843static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
16ded525 2844 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2845 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2846 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2847 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2848 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2849 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2850 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2851 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525 2852 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 2853 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16ded525
TI
2854 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2855 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2856 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2857 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2858 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2860 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2861 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16ded525
TI
2862 {
2863 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2864 .name = "Channel Mode",
df694daa
KY
2865 .info = alc_ch_mode_info,
2866 .get = alc_ch_mode_get,
2867 .put = alc_ch_mode_put,
16ded525
TI
2868 },
2869 { } /* end */
2870};
2871
e9edcee0
TI
2872
2873/*
2874 * ALC880 W810 model
2875 *
2876 * W810 has rear IO for:
2877 * Front (DAC 02)
2878 * Surround (DAC 03)
2879 * Center/LFE (DAC 04)
2880 * Digital out (06)
2881 *
2882 * The system also has a pair of internal speakers, and a headphone jack.
2883 * These are both connected to Line2 on the codec, hence to DAC 02.
ea1fb29a 2884 *
e9edcee0
TI
2885 * There is a variable resistor to control the speaker or headphone
2886 * volume. This is a hardware-only device without a software API.
2887 *
2888 * Plugging headphones in will disable the internal speakers. This is
2889 * implemented in hardware, not via the driver using jack sense. In
2890 * a similar fashion, plugging into the rear socket marked "front" will
2891 * disable both the speakers and headphones.
2892 *
2893 * For input, there's a microphone jack, and an "audio in" jack.
2894 * These may not do anything useful with this driver yet, because I
2895 * haven't setup any initialization verbs for these yet...
2896 */
2897
4c6d72d1 2898static const hda_nid_t alc880_w810_dac_nids[3] = {
e9edcee0
TI
2899 /* front, rear/surround, clfe */
2900 0x02, 0x03, 0x04
16ded525
TI
2901};
2902
e9edcee0 2903/* fixed 6 channels */
a9111321 2904static const struct hda_channel_mode alc880_w810_modes[1] = {
e9edcee0
TI
2905 { 6, NULL }
2906};
2907
2908/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
a9111321 2909static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
16ded525 2910 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2911 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 2912 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2913 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2914 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2915 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
2916 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2917 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
e9edcee0
TI
2918 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2919 { } /* end */
2920};
2921
2922
2923/*
2924 * Z710V model
2925 *
2926 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
9c7f852e
TI
2927 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2928 * Line = 0x1a
e9edcee0
TI
2929 */
2930
4c6d72d1 2931static const hda_nid_t alc880_z71v_dac_nids[1] = {
e9edcee0
TI
2932 0x02
2933};
2934#define ALC880_Z71V_HP_DAC 0x03
2935
2936/* fixed 2 channels */
a9111321 2937static const struct hda_channel_mode alc880_2_jack_modes[1] = {
e9edcee0
TI
2938 { 2, NULL }
2939};
2940
a9111321 2941static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
e9edcee0 2942 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2943 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
e9edcee0 2944 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 2945 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
2946 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2947 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16ded525
TI
2948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2949 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
2950 { } /* end */
2951};
2952
e9edcee0 2953
e9edcee0
TI
2954/*
2955 * ALC880 F1734 model
2956 *
2957 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
2958 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
2959 */
2960
4c6d72d1 2961static const hda_nid_t alc880_f1734_dac_nids[1] = {
e9edcee0
TI
2962 0x03
2963};
2964#define ALC880_F1734_HP_DAC 0x02
2965
a9111321 2966static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
e9edcee0 2967 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 2968 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
2134ea4f
TI
2969 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2970 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
e9edcee0
TI
2971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
937b4160
TI
2973 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2974 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e9edcee0
TI
2975 { } /* end */
2976};
2977
a9111321 2978static const struct hda_input_mux alc880_f1734_capture_source = {
937b4160
TI
2979 .num_items = 2,
2980 .items = {
2981 { "Mic", 0x1 },
2982 { "CD", 0x4 },
2983 },
2984};
2985
e9edcee0 2986
e9edcee0
TI
2987/*
2988 * ALC880 ASUS model
2989 *
2990 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
2991 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
2992 * Mic = 0x18, Line = 0x1a
2993 */
2994
2995#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
2996#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
2997
a9111321 2998static const struct snd_kcontrol_new alc880_asus_mixer[] = {
16ded525 2999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 3000 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16ded525 3001 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 3002 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16ded525
TI
3003 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3004 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
3005 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3006 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16ded525
TI
3007 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3008 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3009 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3010 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16ded525
TI
3011 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3012 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16ded525
TI
3013 {
3014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3015 .name = "Channel Mode",
df694daa
KY
3016 .info = alc_ch_mode_info,
3017 .get = alc_ch_mode_get,
3018 .put = alc_ch_mode_put,
16ded525
TI
3019 },
3020 { } /* end */
3021};
e9edcee0 3022
e9edcee0
TI
3023/*
3024 * ALC880 ASUS W1V model
3025 *
3026 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3027 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3028 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3029 */
3030
3031/* additional mixers to alc880_asus_mixer */
a9111321 3032static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
e9edcee0
TI
3033 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3034 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3035 { } /* end */
3036};
3037
df694daa 3038/* TCL S700 */
a9111321 3039static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
df694daa
KY
3040 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3041 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3042 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3043 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3044 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3046 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3047 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3048 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
df694daa
KY
3049 { } /* end */
3050};
3051
ccc656ce 3052/* Uniwill */
a9111321 3053static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
2134ea4f
TI
3054 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3055 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3056 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3057 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3058 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3059 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3060 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3061 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3064 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3065 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3066 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3067 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3068 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce
KY
3070 {
3071 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3072 .name = "Channel Mode",
3073 .info = alc_ch_mode_info,
3074 .get = alc_ch_mode_get,
3075 .put = alc_ch_mode_put,
3076 },
3077 { } /* end */
3078};
3079
a9111321 3080static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2cf9f0fc
TD
3081 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3082 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3083 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3084 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3085 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3086 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8607f7c4
DH
3087 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3088 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
3089 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3090 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2cf9f0fc
TD
3091 { } /* end */
3092};
3093
a9111321 3094static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2134ea4f
TI
3095 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3096 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3097 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3098 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
ccc656ce
KY
3099 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3100 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3101 { } /* end */
3102};
3103
2134ea4f
TI
3104/*
3105 * virtual master controls
3106 */
3107
3108/*
3109 * slave controls for virtual master
3110 */
ea734963 3111static const char * const alc_slave_vols[] = {
2134ea4f
TI
3112 "Front Playback Volume",
3113 "Surround Playback Volume",
3114 "Center Playback Volume",
3115 "LFE Playback Volume",
3116 "Side Playback Volume",
3117 "Headphone Playback Volume",
3118 "Speaker Playback Volume",
3119 "Mono Playback Volume",
2134ea4f 3120 "Line-Out Playback Volume",
26f5df26 3121 "PCM Playback Volume",
2134ea4f
TI
3122 NULL,
3123};
3124
ea734963 3125static const char * const alc_slave_sws[] = {
2134ea4f
TI
3126 "Front Playback Switch",
3127 "Surround Playback Switch",
3128 "Center Playback Switch",
3129 "LFE Playback Switch",
3130 "Side Playback Switch",
3131 "Headphone Playback Switch",
3132 "Speaker Playback Switch",
3133 "Mono Playback Switch",
edb54a55 3134 "IEC958 Playback Switch",
23033b2b
TI
3135 "Line-Out Playback Switch",
3136 "PCM Playback Switch",
2134ea4f
TI
3137 NULL,
3138};
3139
1da177e4 3140/*
e9edcee0 3141 * build control elements
1da177e4 3142 */
603c4019 3143
5b0cb1d8
JK
3144#define NID_MAPPING (-1)
3145
3146#define SUBDEV_SPEAKER_ (0 << 6)
3147#define SUBDEV_HP_ (1 << 6)
3148#define SUBDEV_LINE_ (2 << 6)
3149#define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3150#define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3151#define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3152
603c4019
TI
3153static void alc_free_kctls(struct hda_codec *codec);
3154
67d634c0 3155#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1 3156/* additional beep mixers; the actual parameters are overwritten at build */
a9111321 3157static const struct snd_kcontrol_new alc_beep_mixer[] = {
45bdd1c1 3158 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
123c07ae 3159 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
45bdd1c1
TI
3160 { } /* end */
3161};
67d634c0 3162#endif
45bdd1c1 3163
1da177e4
LT
3164static int alc_build_controls(struct hda_codec *codec)
3165{
3166 struct alc_spec *spec = codec->spec;
2f44f847 3167 struct snd_kcontrol *kctl = NULL;
a9111321 3168 const struct snd_kcontrol_new *knew;
5b0cb1d8
JK
3169 int i, j, err;
3170 unsigned int u;
3171 hda_nid_t nid;
1da177e4
LT
3172
3173 for (i = 0; i < spec->num_mixers; i++) {
3174 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3175 if (err < 0)
3176 return err;
3177 }
f9e336f6
TI
3178 if (spec->cap_mixer) {
3179 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3180 if (err < 0)
3181 return err;
3182 }
1da177e4 3183 if (spec->multiout.dig_out_nid) {
9c7f852e
TI
3184 err = snd_hda_create_spdif_out_ctls(codec,
3185 spec->multiout.dig_out_nid);
1da177e4
LT
3186 if (err < 0)
3187 return err;
e64f14f4
TI
3188 if (!spec->no_analog) {
3189 err = snd_hda_create_spdif_share_sw(codec,
3190 &spec->multiout);
3191 if (err < 0)
3192 return err;
3193 spec->multiout.share_spdif = 1;
3194 }
1da177e4
LT
3195 }
3196 if (spec->dig_in_nid) {
3197 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3198 if (err < 0)
3199 return err;
3200 }
2134ea4f 3201
67d634c0 3202#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
3203 /* create beep controls if needed */
3204 if (spec->beep_amp) {
a9111321 3205 const struct snd_kcontrol_new *knew;
45bdd1c1
TI
3206 for (knew = alc_beep_mixer; knew->name; knew++) {
3207 struct snd_kcontrol *kctl;
3208 kctl = snd_ctl_new1(knew, codec);
3209 if (!kctl)
3210 return -ENOMEM;
3211 kctl->private_value = spec->beep_amp;
5e26dfd0 3212 err = snd_hda_ctl_add(codec, 0, kctl);
45bdd1c1
TI
3213 if (err < 0)
3214 return err;
3215 }
3216 }
67d634c0 3217#endif
45bdd1c1 3218
2134ea4f 3219 /* if we have no master control, let's create it */
e64f14f4
TI
3220 if (!spec->no_analog &&
3221 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
1c82ed1b 3222 unsigned int vmaster_tlv[4];
2134ea4f 3223 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1c82ed1b 3224 HDA_OUTPUT, vmaster_tlv);
2134ea4f 3225 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
1c82ed1b 3226 vmaster_tlv, alc_slave_vols);
2134ea4f
TI
3227 if (err < 0)
3228 return err;
3229 }
e64f14f4
TI
3230 if (!spec->no_analog &&
3231 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2134ea4f
TI
3232 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3233 NULL, alc_slave_sws);
3234 if (err < 0)
3235 return err;
3236 }
3237
5b0cb1d8 3238 /* assign Capture Source enums to NID */
fbe618f2
TI
3239 if (spec->capsrc_nids || spec->adc_nids) {
3240 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3241 if (!kctl)
3242 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3243 for (i = 0; kctl && i < kctl->count; i++) {
4c6d72d1 3244 const hda_nid_t *nids = spec->capsrc_nids;
fbe618f2
TI
3245 if (!nids)
3246 nids = spec->adc_nids;
3247 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3248 if (err < 0)
3249 return err;
3250 }
5b0cb1d8
JK
3251 }
3252 if (spec->cap_mixer) {
3253 const char *kname = kctl ? kctl->id.name : NULL;
3254 for (knew = spec->cap_mixer; knew->name; knew++) {
3255 if (kname && strcmp(knew->name, kname) == 0)
3256 continue;
3257 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3258 for (i = 0; kctl && i < kctl->count; i++) {
3259 err = snd_hda_add_nid(codec, kctl, i,
3260 spec->adc_nids[i]);
3261 if (err < 0)
3262 return err;
3263 }
3264 }
3265 }
3266
3267 /* other nid->control mapping */
3268 for (i = 0; i < spec->num_mixers; i++) {
3269 for (knew = spec->mixers[i]; knew->name; knew++) {
3270 if (knew->iface != NID_MAPPING)
3271 continue;
3272 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3273 if (kctl == NULL)
3274 continue;
3275 u = knew->subdevice;
3276 for (j = 0; j < 4; j++, u >>= 8) {
3277 nid = u & 0x3f;
3278 if (nid == 0)
3279 continue;
3280 switch (u & 0xc0) {
3281 case SUBDEV_SPEAKER_:
3282 nid = spec->autocfg.speaker_pins[nid];
3283 break;
3284 case SUBDEV_LINE_:
3285 nid = spec->autocfg.line_out_pins[nid];
3286 break;
3287 case SUBDEV_HP_:
3288 nid = spec->autocfg.hp_pins[nid];
3289 break;
3290 default:
3291 continue;
3292 }
3293 err = snd_hda_add_nid(codec, kctl, 0, nid);
3294 if (err < 0)
3295 return err;
3296 }
3297 u = knew->private_value;
3298 for (j = 0; j < 4; j++, u >>= 8) {
3299 nid = u & 0xff;
3300 if (nid == 0)
3301 continue;
3302 err = snd_hda_add_nid(codec, kctl, 0, nid);
3303 if (err < 0)
3304 return err;
3305 }
3306 }
3307 }
bae84e70
TI
3308
3309 alc_free_kctls(codec); /* no longer needed */
3310
1da177e4
LT
3311 return 0;
3312}
3313
e9edcee0 3314
1da177e4
LT
3315/*
3316 * initialize the codec volumes, etc
3317 */
3318
e9edcee0
TI
3319/*
3320 * generic initialization of ADC, input mixers and output mixers
3321 */
a9111321 3322static const struct hda_verb alc880_volume_init_verbs[] = {
e9edcee0
TI
3323 /*
3324 * Unmute ADC0-2 and set the default input to mic-in
3325 */
71fe7b82 3326 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3327 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3328 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3329 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
71fe7b82 3330 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 3331 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 3332
e9edcee0
TI
3333 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3334 * mixer widget
9c7f852e
TI
3335 * Note: PASD motherboards uses the Line In 2 as the input for front
3336 * panel mic (mic 2)
1da177e4 3337 */
e9edcee0 3338 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
3339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3341 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3342 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3343 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3344 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3345 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
1da177e4 3346
e9edcee0
TI
3347 /*
3348 * Set up output mixers (0x0c - 0x0f)
1da177e4 3349 */
e9edcee0
TI
3350 /* set vol=0 to output mixers */
3351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3353 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3354 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3355 /* set up input amps for analog loopback */
3356 /* Amp Indices: DAC = 0, mixer = 1 */
05acb863
TI
3357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3358 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3361 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3362 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
05acb863
TI
3363 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3364 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
3365
3366 { }
3367};
3368
e9edcee0
TI
3369/*
3370 * 3-stack pin configuration:
3371 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3372 */
a9111321 3373static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
e9edcee0
TI
3374 /*
3375 * preset connection lists of input pins
3376 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3377 */
3378 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3379 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3380 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3381
3382 /*
3383 * Set pin mode and muting
3384 */
3385 /* set front pin widgets 0x14 for output */
05acb863 3386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3387 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3388 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3389 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3390 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3391 /* Mic2 (as headphone out) for HP output */
3392 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3393 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3394 /* Line In pin widget for input */
05acb863 3395 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
3396 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3397 /* Line2 (as front mic) pin widget for input and vref at 80% */
3398 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3399 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3400 /* CD pin widget for input */
05acb863 3401 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 3402
e9edcee0
TI
3403 { }
3404};
1da177e4 3405
e9edcee0
TI
3406/*
3407 * 5-stack pin configuration:
3408 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3409 * line-in/side = 0x1a, f-mic = 0x1b
3410 */
a9111321 3411static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
e9edcee0
TI
3412 /*
3413 * preset connection lists of input pins
3414 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
1da177e4 3415 */
e9edcee0
TI
3416 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3417 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
1da177e4 3418
e9edcee0
TI
3419 /*
3420 * Set pin mode and muting
1da177e4 3421 */
e9edcee0
TI
3422 /* set pin widgets 0x14-0x17 for output */
3423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3424 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3425 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3426 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3427 /* unmute pins for output (no gain on this amp) */
3428 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3429 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3430 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3431 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3432
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},
3439 /* Line In pin widget for input */
3440 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
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},
3445 /* CD pin widget for input */
3446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
3447
3448 { }
3449};
3450
e9edcee0
TI
3451/*
3452 * W810 pin configuration:
3453 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3454 */
a9111321 3455static const struct hda_verb alc880_pin_w810_init_verbs[] = {
e9edcee0
TI
3456 /* hphone/speaker input selector: front DAC */
3457 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
1da177e4 3458
05acb863 3459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3460 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3461 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3462 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3463 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3464 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 3465
e9edcee0 3466 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
05acb863 3467 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1da177e4 3468
1da177e4
LT
3469 { }
3470};
3471
e9edcee0
TI
3472/*
3473 * Z71V pin configuration:
3474 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3475 */
a9111321 3476static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
05acb863 3477 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3478 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
05acb863 3479 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3480 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
dfc0ff62 3481
16ded525 3482 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3483 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525 3484 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3485 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16ded525
TI
3486
3487 { }
3488};
3489
e9edcee0
TI
3490/*
3491 * 6-stack pin configuration:
9c7f852e
TI
3492 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3493 * f-mic = 0x19, line = 0x1a, HP = 0x1b
e9edcee0 3494 */
a9111321 3495static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
e9edcee0
TI
3496 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3497
16ded525 3498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3501 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3502 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3503 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3504 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3505 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506
16ded525 3507 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3508 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3509 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0 3510 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3511 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0 3512 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3513 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3514 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3515 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3516
e9edcee0
TI
3517 { }
3518};
3519
ccc656ce
KY
3520/*
3521 * Uniwill pin configuration:
3522 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3523 * line = 0x1a
3524 */
a9111321 3525static const struct hda_verb alc880_uniwill_init_verbs[] = {
ccc656ce
KY
3526 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3527
3528 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3529 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3533 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3534 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3535 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3536 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3537 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3538 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3539 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3540 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3541 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3542
3543 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3544 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3545 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3546 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3547 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3548 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3549 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3550 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3551 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3552
3553 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3554 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3555
3556 { }
3557};
3558
3559/*
3560* Uniwill P53
ea1fb29a 3561* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
ccc656ce 3562 */
a9111321 3563static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
ccc656ce
KY
3564 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3565
3566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3567 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3568 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3569 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3571 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3572 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3574 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3575 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3576 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3577 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3578
3579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3581 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3582 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3585
3586 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3587 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3588
3589 { }
3590};
3591
a9111321 3592static const struct hda_verb alc880_beep_init_verbs[] = {
2cf9f0fc
TD
3593 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3594 { }
3595};
3596
458a4fab 3597/* auto-toggle front mic */
eeb43387 3598static void alc88x_simple_mic_automute(struct hda_codec *codec)
458a4fab
TI
3599{
3600 unsigned int present;
3601 unsigned char bits;
ccc656ce 3602
864f92be 3603 present = snd_hda_jack_detect(codec, 0x18);
47fd830a
TI
3604 bits = present ? HDA_AMP_MUTE : 0;
3605 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
458a4fab
TI
3606}
3607
4f5d1706 3608static void alc880_uniwill_setup(struct hda_codec *codec)
458a4fab 3609{
a9fd4f3f
TI
3610 struct alc_spec *spec = codec->spec;
3611
3612 spec->autocfg.hp_pins[0] = 0x14;
3613 spec->autocfg.speaker_pins[0] = 0x15;
3614 spec->autocfg.speaker_pins[0] = 0x16;
d922b51d
TI
3615 spec->automute = 1;
3616 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
3617}
3618
3619static void alc880_uniwill_init_hook(struct hda_codec *codec)
3620{
d922b51d 3621 alc_hp_automute(codec);
eeb43387 3622 alc88x_simple_mic_automute(codec);
ccc656ce
KY
3623}
3624
3625static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3626 unsigned int res)
3627{
3628 /* Looks like the unsol event is incompatible with the standard
3629 * definition. 4bit tag is placed at 28 bit!
3630 */
458a4fab 3631 switch (res >> 28) {
458a4fab 3632 case ALC880_MIC_EVENT:
eeb43387 3633 alc88x_simple_mic_automute(codec);
458a4fab 3634 break;
a9fd4f3f 3635 default:
d922b51d 3636 alc_sku_unsol_event(codec, res);
a9fd4f3f 3637 break;
458a4fab 3638 }
ccc656ce
KY
3639}
3640
4f5d1706 3641static void alc880_uniwill_p53_setup(struct hda_codec *codec)
ccc656ce 3642{
a9fd4f3f 3643 struct alc_spec *spec = codec->spec;
ccc656ce 3644
a9fd4f3f
TI
3645 spec->autocfg.hp_pins[0] = 0x14;
3646 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
3647 spec->automute = 1;
3648 spec->automute_mode = ALC_AUTOMUTE_AMP;
ccc656ce
KY
3649}
3650
3651static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3652{
3653 unsigned int present;
ea1fb29a 3654
ccc656ce 3655 present = snd_hda_codec_read(codec, 0x21, 0,
47fd830a
TI
3656 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3657 present &= HDA_AMP_VOLMASK;
3658 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3659 HDA_AMP_VOLMASK, present);
3660 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3661 HDA_AMP_VOLMASK, present);
ccc656ce 3662}
47fd830a 3663
ccc656ce
KY
3664static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3665 unsigned int res)
3666{
3667 /* Looks like the unsol event is incompatible with the standard
3668 * definition. 4bit tag is placed at 28 bit!
3669 */
f12ab1e0 3670 if ((res >> 28) == ALC880_DCVOL_EVENT)
ccc656ce 3671 alc880_uniwill_p53_dcvol_automute(codec);
a9fd4f3f 3672 else
d922b51d 3673 alc_sku_unsol_event(codec, res);
ccc656ce
KY
3674}
3675
e9edcee0
TI
3676/*
3677 * F1734 pin configuration:
3678 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3679 */
a9111321 3680static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
ee7a9c7c 3681 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
16ded525
TI
3682 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3683 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3684 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3685 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3686
e9edcee0 3687 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16ded525 3688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
e9edcee0 3689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16ded525 3690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3691
e9edcee0
TI
3692 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3693 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
ee7a9c7c 3694 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
e9edcee0 3695 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3696 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3697 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3698 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3699 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3700 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
dfc0ff62 3701
937b4160
TI
3702 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3703 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3704
dfc0ff62
TI
3705 { }
3706};
3707
e9edcee0
TI
3708/*
3709 * ASUS pin configuration:
3710 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3711 */
a9111321 3712static const struct hda_verb alc880_pin_asus_init_verbs[] = {
16ded525
TI
3713 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3714 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3715 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3716 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3717
3718 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
e9edcee0 3719 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3720 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3721 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3722 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3723 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3724 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0
TI
3725 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3726
3727 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3728 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3731 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3732 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16ded525 3733 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
e9edcee0 3734 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16ded525 3735 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
ea1fb29a 3736
e9edcee0
TI
3737 { }
3738};
16ded525 3739
e9edcee0 3740/* Enable GPIO mask and set output */
bc9f98a9
KY
3741#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3742#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
64a8be74 3743#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
df694daa
KY
3744
3745/* Clevo m520g init */
a9111321 3746static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
df694daa
KY
3747 /* headphone output */
3748 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3749 /* line-out */
3750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3752 /* Line-in */
3753 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3754 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3755 /* CD */
3756 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3757 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3758 /* Mic1 (rear panel) */
3759 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3760 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3761 /* Mic2 (front panel) */
3762 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3763 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3764 /* headphone */
3765 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3767 /* change to EAPD mode */
3768 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3769 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3770
3771 { }
16ded525
TI
3772};
3773
a9111321 3774static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
4b146cb0
TI
3775 /* change to EAPD mode */
3776 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3777 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3778
df694daa
KY
3779 /* Headphone output */
3780 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3781 /* Front output*/
3782 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3783 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3784
3785 /* Line In pin widget for input */
3786 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3787 /* CD pin widget for input */
3788 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3789 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3790 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3791
3792 /* change to EAPD mode */
3793 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3794 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3795
3796 { }
3797};
16ded525 3798
e9edcee0 3799/*
ae6b813a
TI
3800 * LG m1 express dual
3801 *
3802 * Pin assignment:
3803 * Rear Line-In/Out (blue): 0x14
3804 * Build-in Mic-In: 0x15
3805 * Speaker-out: 0x17
3806 * HP-Out (green): 0x1b
3807 * Mic-In/Out (red): 0x19
3808 * SPDIF-Out: 0x1e
3809 */
3810
3811/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
4c6d72d1 3812static const hda_nid_t alc880_lg_dac_nids[3] = {
ae6b813a
TI
3813 0x05, 0x02, 0x03
3814};
3815
3816/* seems analog CD is not working */
a9111321 3817static const struct hda_input_mux alc880_lg_capture_source = {
ae6b813a
TI
3818 .num_items = 3,
3819 .items = {
3820 { "Mic", 0x1 },
3821 { "Line", 0x5 },
3822 { "Internal Mic", 0x6 },
3823 },
3824};
3825
3826/* 2,4,6 channel modes */
a9111321 3827static const struct hda_verb alc880_lg_ch2_init[] = {
ae6b813a
TI
3828 /* set line-in and mic-in to input */
3829 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3830 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3831 { }
3832};
3833
a9111321 3834static const struct hda_verb alc880_lg_ch4_init[] = {
ae6b813a
TI
3835 /* set line-in to out and mic-in to input */
3836 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3837 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3838 { }
3839};
3840
a9111321 3841static const struct hda_verb alc880_lg_ch6_init[] = {
ae6b813a
TI
3842 /* set line-in and mic-in to output */
3843 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3844 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3845 { }
3846};
3847
a9111321 3848static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
ae6b813a
TI
3849 { 2, alc880_lg_ch2_init },
3850 { 4, alc880_lg_ch4_init },
3851 { 6, alc880_lg_ch6_init },
3852};
3853
a9111321 3854static const struct snd_kcontrol_new alc880_lg_mixer[] = {
2134ea4f
TI
3855 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3856 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
ae6b813a
TI
3857 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3858 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3859 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3860 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3861 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3862 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3863 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3864 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3865 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3866 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3867 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3868 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3869 {
3870 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3871 .name = "Channel Mode",
3872 .info = alc_ch_mode_info,
3873 .get = alc_ch_mode_get,
3874 .put = alc_ch_mode_put,
3875 },
3876 { } /* end */
3877};
3878
a9111321 3879static const struct hda_verb alc880_lg_init_verbs[] = {
ae6b813a
TI
3880 /* set capture source to mic-in */
3881 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3882 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3883 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3884 /* mute all amp mixer inputs */
3885 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
cb53c626
TI
3886 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3887 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
ae6b813a
TI
3888 /* line-in to input */
3889 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3890 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3891 /* built-in mic */
3892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3893 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3894 /* speaker-out */
3895 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3896 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3897 /* mic-in to input */
3898 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3899 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3900 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3901 /* HP-out */
3902 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3903 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3904 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3905 /* jack sense */
a9fd4f3f 3906 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ae6b813a
TI
3907 { }
3908};
3909
3910/* toggle speaker-output according to the hp-jack state */
4f5d1706 3911static void alc880_lg_setup(struct hda_codec *codec)
ae6b813a 3912{
a9fd4f3f 3913 struct alc_spec *spec = codec->spec;
ae6b813a 3914
a9fd4f3f
TI
3915 spec->autocfg.hp_pins[0] = 0x1b;
3916 spec->autocfg.speaker_pins[0] = 0x17;
d922b51d
TI
3917 spec->automute = 1;
3918 spec->automute_mode = ALC_AUTOMUTE_AMP;
ae6b813a
TI
3919}
3920
d681518a
TI
3921/*
3922 * LG LW20
3923 *
3924 * Pin assignment:
3925 * Speaker-out: 0x14
3926 * Mic-In: 0x18
e4f41da9
CM
3927 * Built-in Mic-In: 0x19
3928 * Line-In: 0x1b
3929 * HP-Out: 0x1a
d681518a
TI
3930 * SPDIF-Out: 0x1e
3931 */
3932
a9111321 3933static const struct hda_input_mux alc880_lg_lw_capture_source = {
e4f41da9 3934 .num_items = 3,
d681518a
TI
3935 .items = {
3936 { "Mic", 0x0 },
3937 { "Internal Mic", 0x1 },
e4f41da9 3938 { "Line In", 0x2 },
d681518a
TI
3939 },
3940};
3941
0a8c5da3
CM
3942#define alc880_lg_lw_modes alc880_threestack_modes
3943
a9111321 3944static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
0a8c5da3
CM
3945 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3946 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3947 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3948 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3949 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3950 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3951 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3952 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3953 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3954 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d681518a
TI
3955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3957 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
3958 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
0a8c5da3
CM
3959 {
3960 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3961 .name = "Channel Mode",
3962 .info = alc_ch_mode_info,
3963 .get = alc_ch_mode_get,
3964 .put = alc_ch_mode_put,
3965 },
d681518a
TI
3966 { } /* end */
3967};
3968
a9111321 3969static const struct hda_verb alc880_lg_lw_init_verbs[] = {
0a8c5da3
CM
3970 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3971 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3972 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3973
d681518a
TI
3974 /* set capture source to mic-in */
3975 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3976 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3977 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
cb53c626 3978 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
d681518a
TI
3979 /* speaker-out */
3980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3981 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3982 /* HP-out */
d681518a
TI
3983 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3984 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3985 /* mic-in to input */
3986 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3987 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3988 /* built-in mic */
3989 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3990 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3991 /* jack sense */
a9fd4f3f 3992 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
d681518a
TI
3993 { }
3994};
3995
3996/* toggle speaker-output according to the hp-jack state */
4f5d1706 3997static void alc880_lg_lw_setup(struct hda_codec *codec)
d681518a 3998{
a9fd4f3f 3999 struct alc_spec *spec = codec->spec;
d681518a 4000
a9fd4f3f
TI
4001 spec->autocfg.hp_pins[0] = 0x1b;
4002 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
4003 spec->automute = 1;
4004 spec->automute_mode = ALC_AUTOMUTE_AMP;
d681518a
TI
4005}
4006
a9111321 4007static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
df99cd33
TI
4008 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4009 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4012 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4013 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4014 { } /* end */
4015};
4016
a9111321 4017static const struct hda_input_mux alc880_medion_rim_capture_source = {
df99cd33
TI
4018 .num_items = 2,
4019 .items = {
4020 { "Mic", 0x0 },
4021 { "Internal Mic", 0x1 },
4022 },
4023};
4024
a9111321 4025static const struct hda_verb alc880_medion_rim_init_verbs[] = {
df99cd33
TI
4026 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4027
4028 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4029 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030
4031 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4032 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4033 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4034 /* Mic2 (as headphone out) for HP output */
4035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4036 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4037 /* Internal Speaker */
4038 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4039 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4040
4041 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4042 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4043
4044 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4045 { }
4046};
4047
4048/* toggle speaker-output according to the hp-jack state */
4049static void alc880_medion_rim_automute(struct hda_codec *codec)
4050{
a9fd4f3f 4051 struct alc_spec *spec = codec->spec;
d922b51d 4052 alc_hp_automute(codec);
a9fd4f3f
TI
4053 /* toggle EAPD */
4054 if (spec->jack_present)
df99cd33
TI
4055 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4056 else
4057 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4058}
4059
4060static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4061 unsigned int res)
4062{
4063 /* Looks like the unsol event is incompatible with the standard
4064 * definition. 4bit tag is placed at 28 bit!
4065 */
4066 if ((res >> 28) == ALC880_HP_EVENT)
4067 alc880_medion_rim_automute(codec);
4068}
4069
4f5d1706 4070static void alc880_medion_rim_setup(struct hda_codec *codec)
a9fd4f3f
TI
4071{
4072 struct alc_spec *spec = codec->spec;
4073
4074 spec->autocfg.hp_pins[0] = 0x14;
4075 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
4076 spec->automute = 1;
4077 spec->automute_mode = ALC_AUTOMUTE_AMP;
a9fd4f3f
TI
4078}
4079
cb53c626 4080#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 4081static const struct hda_amp_list alc880_loopbacks[] = {
cb53c626
TI
4082 { 0x0b, HDA_INPUT, 0 },
4083 { 0x0b, HDA_INPUT, 1 },
4084 { 0x0b, HDA_INPUT, 2 },
4085 { 0x0b, HDA_INPUT, 3 },
4086 { 0x0b, HDA_INPUT, 4 },
4087 { } /* end */
4088};
4089
a9111321 4090static const struct hda_amp_list alc880_lg_loopbacks[] = {
cb53c626
TI
4091 { 0x0b, HDA_INPUT, 1 },
4092 { 0x0b, HDA_INPUT, 6 },
4093 { 0x0b, HDA_INPUT, 7 },
4094 { } /* end */
4095};
4096#endif
4097
ae6b813a
TI
4098/*
4099 * Common callbacks
e9edcee0
TI
4100 */
4101
584c0c4c
TI
4102static void alc_init_special_input_src(struct hda_codec *codec);
4103
1da177e4
LT
4104static int alc_init(struct hda_codec *codec)
4105{
4106 struct alc_spec *spec = codec->spec;
e9edcee0
TI
4107 unsigned int i;
4108
2c3bf9ab 4109 alc_fix_pll(codec);
4a79ba34 4110 alc_auto_init_amp(codec, spec->init_amp);
2c3bf9ab 4111
e9edcee0
TI
4112 for (i = 0; i < spec->num_init_verbs; i++)
4113 snd_hda_sequence_write(codec, spec->init_verbs[i]);
584c0c4c 4114 alc_init_special_input_src(codec);
ae6b813a
TI
4115
4116 if (spec->init_hook)
4117 spec->init_hook(codec);
4118
58701120
TI
4119 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4120
9e5341b9 4121 hda_call_check_power_status(codec, 0x01);
1da177e4
LT
4122 return 0;
4123}
4124
ae6b813a
TI
4125static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4126{
4127 struct alc_spec *spec = codec->spec;
4128
4129 if (spec->unsol_event)
4130 spec->unsol_event(codec, res);
4131}
4132
cb53c626
TI
4133#ifdef CONFIG_SND_HDA_POWER_SAVE
4134static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4135{
4136 struct alc_spec *spec = codec->spec;
4137 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4138}
4139#endif
4140
1da177e4
LT
4141/*
4142 * Analog playback callbacks
4143 */
4144static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4145 struct hda_codec *codec,
c8b6bf9b 4146 struct snd_pcm_substream *substream)
1da177e4
LT
4147{
4148 struct alc_spec *spec = codec->spec;
9a08160b
TI
4149 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4150 hinfo);
1da177e4
LT
4151}
4152
4153static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4154 struct hda_codec *codec,
4155 unsigned int stream_tag,
4156 unsigned int format,
c8b6bf9b 4157 struct snd_pcm_substream *substream)
1da177e4
LT
4158{
4159 struct alc_spec *spec = codec->spec;
9c7f852e
TI
4160 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4161 stream_tag, format, substream);
1da177e4
LT
4162}
4163
4164static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4165 struct hda_codec *codec,
c8b6bf9b 4166 struct snd_pcm_substream *substream)
1da177e4
LT
4167{
4168 struct alc_spec *spec = codec->spec;
4169 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4170}
4171
4172/*
4173 * Digital out
4174 */
4175static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4176 struct hda_codec *codec,
c8b6bf9b 4177 struct snd_pcm_substream *substream)
1da177e4
LT
4178{
4179 struct alc_spec *spec = codec->spec;
4180 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4181}
4182
6b97eb45
TI
4183static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4184 struct hda_codec *codec,
4185 unsigned int stream_tag,
4186 unsigned int format,
4187 struct snd_pcm_substream *substream)
4188{
4189 struct alc_spec *spec = codec->spec;
4190 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4191 stream_tag, format, substream);
4192}
4193
9b5f12e5
TI
4194static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4195 struct hda_codec *codec,
4196 struct snd_pcm_substream *substream)
4197{
4198 struct alc_spec *spec = codec->spec;
4199 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4200}
4201
1da177e4
LT
4202static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4203 struct hda_codec *codec,
c8b6bf9b 4204 struct snd_pcm_substream *substream)
1da177e4
LT
4205{
4206 struct alc_spec *spec = codec->spec;
4207 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4208}
4209
4210/*
4211 * Analog capture
4212 */
6330079f 4213static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
1da177e4
LT
4214 struct hda_codec *codec,
4215 unsigned int stream_tag,
4216 unsigned int format,
c8b6bf9b 4217 struct snd_pcm_substream *substream)
1da177e4
LT
4218{
4219 struct alc_spec *spec = codec->spec;
4220
6330079f 4221 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
1da177e4
LT
4222 stream_tag, 0, format);
4223 return 0;
4224}
4225
6330079f 4226static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
1da177e4 4227 struct hda_codec *codec,
c8b6bf9b 4228 struct snd_pcm_substream *substream)
1da177e4
LT
4229{
4230 struct alc_spec *spec = codec->spec;
4231
888afa15
TI
4232 snd_hda_codec_cleanup_stream(codec,
4233 spec->adc_nids[substream->number + 1]);
1da177e4
LT
4234 return 0;
4235}
4236
840b64c0
TI
4237/* analog capture with dynamic dual-adc changes */
4238static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4239 struct hda_codec *codec,
4240 unsigned int stream_tag,
4241 unsigned int format,
4242 struct snd_pcm_substream *substream)
4243{
4244 struct alc_spec *spec = codec->spec;
4245 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4246 spec->cur_adc_stream_tag = stream_tag;
4247 spec->cur_adc_format = format;
4248 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4249 return 0;
4250}
4251
4252static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4253 struct hda_codec *codec,
4254 struct snd_pcm_substream *substream)
4255{
4256 struct alc_spec *spec = codec->spec;
4257 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4258 spec->cur_adc = 0;
4259 return 0;
4260}
4261
a9111321 4262static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
840b64c0
TI
4263 .substreams = 1,
4264 .channels_min = 2,
4265 .channels_max = 2,
4266 .nid = 0, /* fill later */
4267 .ops = {
4268 .prepare = dualmic_capture_pcm_prepare,
4269 .cleanup = dualmic_capture_pcm_cleanup
4270 },
4271};
1da177e4
LT
4272
4273/*
4274 */
a9111321 4275static const struct hda_pcm_stream alc880_pcm_analog_playback = {
1da177e4
LT
4276 .substreams = 1,
4277 .channels_min = 2,
4278 .channels_max = 8,
e9edcee0 4279 /* NID is set in alc_build_pcms */
1da177e4
LT
4280 .ops = {
4281 .open = alc880_playback_pcm_open,
4282 .prepare = alc880_playback_pcm_prepare,
4283 .cleanup = alc880_playback_pcm_cleanup
4284 },
4285};
4286
a9111321 4287static const struct hda_pcm_stream alc880_pcm_analog_capture = {
6330079f
TI
4288 .substreams = 1,
4289 .channels_min = 2,
4290 .channels_max = 2,
4291 /* NID is set in alc_build_pcms */
4292};
4293
a9111321 4294static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
6330079f
TI
4295 .substreams = 1,
4296 .channels_min = 2,
4297 .channels_max = 2,
4298 /* NID is set in alc_build_pcms */
4299};
4300
a9111321 4301static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
6330079f 4302 .substreams = 2, /* can be overridden */
1da177e4
LT
4303 .channels_min = 2,
4304 .channels_max = 2,
e9edcee0 4305 /* NID is set in alc_build_pcms */
1da177e4 4306 .ops = {
6330079f
TI
4307 .prepare = alc880_alt_capture_pcm_prepare,
4308 .cleanup = alc880_alt_capture_pcm_cleanup
1da177e4
LT
4309 },
4310};
4311
a9111321 4312static const struct hda_pcm_stream alc880_pcm_digital_playback = {
1da177e4
LT
4313 .substreams = 1,
4314 .channels_min = 2,
4315 .channels_max = 2,
4316 /* NID is set in alc_build_pcms */
4317 .ops = {
4318 .open = alc880_dig_playback_pcm_open,
6b97eb45 4319 .close = alc880_dig_playback_pcm_close,
9b5f12e5
TI
4320 .prepare = alc880_dig_playback_pcm_prepare,
4321 .cleanup = alc880_dig_playback_pcm_cleanup
1da177e4
LT
4322 },
4323};
4324
a9111321 4325static const struct hda_pcm_stream alc880_pcm_digital_capture = {
1da177e4
LT
4326 .substreams = 1,
4327 .channels_min = 2,
4328 .channels_max = 2,
4329 /* NID is set in alc_build_pcms */
4330};
4331
4c5186ed 4332/* Used by alc_build_pcms to flag that a PCM has no playback stream */
a9111321 4333static const struct hda_pcm_stream alc_pcm_null_stream = {
4c5186ed
JW
4334 .substreams = 0,
4335 .channels_min = 0,
4336 .channels_max = 0,
4337};
4338
1da177e4
LT
4339static int alc_build_pcms(struct hda_codec *codec)
4340{
4341 struct alc_spec *spec = codec->spec;
4342 struct hda_pcm *info = spec->pcm_rec;
4343 int i;
4344
4345 codec->num_pcms = 1;
4346 codec->pcm_info = info;
4347
e64f14f4
TI
4348 if (spec->no_analog)
4349 goto skip_analog;
4350
812a2cca
TI
4351 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4352 "%s Analog", codec->chip_name);
1da177e4 4353 info->name = spec->stream_name_analog;
274693f3 4354
4a471b7d 4355 if (spec->stream_analog_playback) {
da3cec35
TI
4356 if (snd_BUG_ON(!spec->multiout.dac_nids))
4357 return -EINVAL;
4a471b7d
TI
4358 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4359 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4360 }
4361 if (spec->stream_analog_capture) {
da3cec35
TI
4362 if (snd_BUG_ON(!spec->adc_nids))
4363 return -EINVAL;
4a471b7d
TI
4364 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4365 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4366 }
4367
4368 if (spec->channel_mode) {
4369 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4370 for (i = 0; i < spec->num_channel_mode; i++) {
4371 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4372 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4373 }
1da177e4
LT
4374 }
4375 }
4376
e64f14f4 4377 skip_analog:
e08a007d 4378 /* SPDIF for stream index #1 */
1da177e4 4379 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
812a2cca
TI
4380 snprintf(spec->stream_name_digital,
4381 sizeof(spec->stream_name_digital),
4382 "%s Digital", codec->chip_name);
e08a007d 4383 codec->num_pcms = 2;
b25c9da1 4384 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
c06134d7 4385 info = spec->pcm_rec + 1;
1da177e4 4386 info->name = spec->stream_name_digital;
8c441982
TI
4387 if (spec->dig_out_type)
4388 info->pcm_type = spec->dig_out_type;
4389 else
4390 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4a471b7d
TI
4391 if (spec->multiout.dig_out_nid &&
4392 spec->stream_digital_playback) {
1da177e4
LT
4393 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4394 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4395 }
4a471b7d
TI
4396 if (spec->dig_in_nid &&
4397 spec->stream_digital_capture) {
1da177e4
LT
4398 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4399 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4400 }
963f803f
TI
4401 /* FIXME: do we need this for all Realtek codec models? */
4402 codec->spdif_status_reset = 1;
1da177e4
LT
4403 }
4404
e64f14f4
TI
4405 if (spec->no_analog)
4406 return 0;
4407
e08a007d
TI
4408 /* If the use of more than one ADC is requested for the current
4409 * model, configure a second analog capture-only PCM.
4410 */
4411 /* Additional Analaog capture for index #2 */
6330079f
TI
4412 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4413 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
e08a007d 4414 codec->num_pcms = 3;
c06134d7 4415 info = spec->pcm_rec + 2;
e08a007d 4416 info->name = spec->stream_name_analog;
6330079f
TI
4417 if (spec->alt_dac_nid) {
4418 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4419 *spec->stream_analog_alt_playback;
4420 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4421 spec->alt_dac_nid;
4422 } else {
4423 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4424 alc_pcm_null_stream;
4425 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4426 }
ce85c9ac 4427 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
6330079f
TI
4428 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4429 *spec->stream_analog_alt_capture;
4430 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4431 spec->adc_nids[1];
4432 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4433 spec->num_adc_nids - 1;
4434 } else {
4435 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4436 alc_pcm_null_stream;
4437 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
e08a007d
TI
4438 }
4439 }
4440
1da177e4
LT
4441 return 0;
4442}
4443
a4e09aa3
TI
4444static inline void alc_shutup(struct hda_codec *codec)
4445{
1c716153
TI
4446 struct alc_spec *spec = codec->spec;
4447
4448 if (spec && spec->shutup)
4449 spec->shutup(codec);
a4e09aa3
TI
4450 snd_hda_shutup_pins(codec);
4451}
4452
603c4019
TI
4453static void alc_free_kctls(struct hda_codec *codec)
4454{
4455 struct alc_spec *spec = codec->spec;
4456
4457 if (spec->kctls.list) {
4458 struct snd_kcontrol_new *kctl = spec->kctls.list;
4459 int i;
4460 for (i = 0; i < spec->kctls.used; i++)
4461 kfree(kctl[i].name);
4462 }
4463 snd_array_free(&spec->kctls);
4464}
4465
1da177e4
LT
4466static void alc_free(struct hda_codec *codec)
4467{
e9edcee0 4468 struct alc_spec *spec = codec->spec;
e9edcee0 4469
f12ab1e0 4470 if (!spec)
e9edcee0
TI
4471 return;
4472
a4e09aa3 4473 alc_shutup(codec);
cd372fb3 4474 snd_hda_input_jack_free(codec);
603c4019 4475 alc_free_kctls(codec);
e9edcee0 4476 kfree(spec);
680cd536 4477 snd_hda_detach_beep_device(codec);
1da177e4
LT
4478}
4479
f5de24b0 4480#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df
DC
4481static void alc_power_eapd(struct hda_codec *codec)
4482{
691f1fcc 4483 alc_auto_setup_eapd(codec, false);
c97259df
DC
4484}
4485
f5de24b0
HM
4486static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4487{
4488 struct alc_spec *spec = codec->spec;
a4e09aa3 4489 alc_shutup(codec);
f5de24b0 4490 if (spec && spec->power_hook)
c97259df 4491 spec->power_hook(codec);
f5de24b0
HM
4492 return 0;
4493}
4494#endif
4495
e044c39a 4496#ifdef SND_HDA_NEEDS_RESUME
e044c39a
TI
4497static int alc_resume(struct hda_codec *codec)
4498{
1c716153 4499 msleep(150); /* to avoid pop noise */
e044c39a
TI
4500 codec->patch_ops.init(codec);
4501 snd_hda_codec_resume_amp(codec);
4502 snd_hda_codec_resume_cache(codec);
9e5341b9 4503 hda_call_check_power_status(codec, 0x01);
e044c39a
TI
4504 return 0;
4505}
e044c39a
TI
4506#endif
4507
1da177e4
LT
4508/*
4509 */
a9111321 4510static const struct hda_codec_ops alc_patch_ops = {
1da177e4
LT
4511 .build_controls = alc_build_controls,
4512 .build_pcms = alc_build_pcms,
4513 .init = alc_init,
4514 .free = alc_free,
ae6b813a 4515 .unsol_event = alc_unsol_event,
e044c39a
TI
4516#ifdef SND_HDA_NEEDS_RESUME
4517 .resume = alc_resume,
4518#endif
cb53c626 4519#ifdef CONFIG_SND_HDA_POWER_SAVE
f5de24b0 4520 .suspend = alc_suspend,
cb53c626
TI
4521 .check_power_status = alc_check_power_status,
4522#endif
c97259df 4523 .reboot_notify = alc_shutup,
1da177e4
LT
4524};
4525
c027ddcd
KY
4526/* replace the codec chip_name with the given string */
4527static int alc_codec_rename(struct hda_codec *codec, const char *name)
4528{
4529 kfree(codec->chip_name);
4530 codec->chip_name = kstrdup(name, GFP_KERNEL);
4531 if (!codec->chip_name) {
4532 alc_free(codec);
4533 return -ENOMEM;
4534 }
4535 return 0;
4536}
4537
2fa522be
TI
4538/*
4539 * Test configuration for debugging
4540 *
4541 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4542 * enum controls.
4543 */
4544#ifdef CONFIG_SND_DEBUG
4c6d72d1 4545static const hda_nid_t alc880_test_dac_nids[4] = {
2fa522be
TI
4546 0x02, 0x03, 0x04, 0x05
4547};
4548
a9111321 4549static const struct hda_input_mux alc880_test_capture_source = {
ae6b813a 4550 .num_items = 7,
2fa522be
TI
4551 .items = {
4552 { "In-1", 0x0 },
4553 { "In-2", 0x1 },
4554 { "In-3", 0x2 },
4555 { "In-4", 0x3 },
4556 { "CD", 0x4 },
ae6b813a
TI
4557 { "Front", 0x5 },
4558 { "Surround", 0x6 },
2fa522be
TI
4559 },
4560};
4561
a9111321 4562static const struct hda_channel_mode alc880_test_modes[4] = {
2fa522be 4563 { 2, NULL },
fd2c326d 4564 { 4, NULL },
2fa522be 4565 { 6, NULL },
fd2c326d 4566 { 8, NULL },
2fa522be
TI
4567};
4568
9c7f852e
TI
4569static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4570 struct snd_ctl_elem_info *uinfo)
2fa522be 4571{
4c6d72d1 4572 static const char * const texts[] = {
2fa522be
TI
4573 "N/A", "Line Out", "HP Out",
4574 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4575 };
4576 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4577 uinfo->count = 1;
4578 uinfo->value.enumerated.items = 8;
4579 if (uinfo->value.enumerated.item >= 8)
4580 uinfo->value.enumerated.item = 7;
4581 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4582 return 0;
4583}
4584
9c7f852e
TI
4585static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4586 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4587{
4588 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4589 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4590 unsigned int pin_ctl, item = 0;
4591
4592 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4593 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4594 if (pin_ctl & AC_PINCTL_OUT_EN) {
4595 if (pin_ctl & AC_PINCTL_HP_EN)
4596 item = 2;
4597 else
4598 item = 1;
4599 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4600 switch (pin_ctl & AC_PINCTL_VREFEN) {
4601 case AC_PINCTL_VREF_HIZ: item = 3; break;
4602 case AC_PINCTL_VREF_50: item = 4; break;
4603 case AC_PINCTL_VREF_GRD: item = 5; break;
4604 case AC_PINCTL_VREF_80: item = 6; break;
4605 case AC_PINCTL_VREF_100: item = 7; break;
4606 }
4607 }
4608 ucontrol->value.enumerated.item[0] = item;
4609 return 0;
4610}
4611
9c7f852e
TI
4612static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4613 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4614{
4615 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4616 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4c6d72d1 4617 static const unsigned int ctls[] = {
2fa522be
TI
4618 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4619 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4620 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4621 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4622 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4623 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4624 };
4625 unsigned int old_ctl, new_ctl;
4626
4627 old_ctl = snd_hda_codec_read(codec, nid, 0,
4628 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4629 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4630 if (old_ctl != new_ctl) {
82beb8fd
TI
4631 int val;
4632 snd_hda_codec_write_cache(codec, nid, 0,
4633 AC_VERB_SET_PIN_WIDGET_CONTROL,
4634 new_ctl);
47fd830a
TI
4635 val = ucontrol->value.enumerated.item[0] >= 3 ?
4636 HDA_AMP_MUTE : 0;
4637 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4638 HDA_AMP_MUTE, val);
2fa522be
TI
4639 return 1;
4640 }
4641 return 0;
4642}
4643
9c7f852e
TI
4644static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4645 struct snd_ctl_elem_info *uinfo)
2fa522be 4646{
4c6d72d1 4647 static const char * const texts[] = {
2fa522be
TI
4648 "Front", "Surround", "CLFE", "Side"
4649 };
4650 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4651 uinfo->count = 1;
4652 uinfo->value.enumerated.items = 4;
4653 if (uinfo->value.enumerated.item >= 4)
4654 uinfo->value.enumerated.item = 3;
4655 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4656 return 0;
4657}
4658
9c7f852e
TI
4659static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4660 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4661{
4662 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4663 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4664 unsigned int sel;
4665
4666 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4667 ucontrol->value.enumerated.item[0] = sel & 3;
4668 return 0;
4669}
4670
9c7f852e
TI
4671static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4672 struct snd_ctl_elem_value *ucontrol)
2fa522be
TI
4673{
4674 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4675 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4676 unsigned int sel;
4677
4678 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4679 if (ucontrol->value.enumerated.item[0] != sel) {
4680 sel = ucontrol->value.enumerated.item[0] & 3;
82beb8fd
TI
4681 snd_hda_codec_write_cache(codec, nid, 0,
4682 AC_VERB_SET_CONNECT_SEL, sel);
2fa522be
TI
4683 return 1;
4684 }
4685 return 0;
4686}
4687
4688#define PIN_CTL_TEST(xname,nid) { \
4689 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4690 .name = xname, \
5b0cb1d8 4691 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4692 .info = alc_test_pin_ctl_info, \
4693 .get = alc_test_pin_ctl_get, \
4694 .put = alc_test_pin_ctl_put, \
4695 .private_value = nid \
4696 }
4697
4698#define PIN_SRC_TEST(xname,nid) { \
4699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4700 .name = xname, \
5b0cb1d8 4701 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
2fa522be
TI
4702 .info = alc_test_pin_src_info, \
4703 .get = alc_test_pin_src_get, \
4704 .put = alc_test_pin_src_put, \
4705 .private_value = nid \
4706 }
4707
a9111321 4708static const struct snd_kcontrol_new alc880_test_mixer[] = {
05acb863
TI
4709 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4710 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4711 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4712 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b
TI
4713 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4714 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4715 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4716 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2fa522be
TI
4717 PIN_CTL_TEST("Front Pin Mode", 0x14),
4718 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4719 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4720 PIN_CTL_TEST("Side Pin Mode", 0x17),
4721 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4722 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4723 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4724 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4725 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4726 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4727 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4728 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4729 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4730 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4731 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4732 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4733 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4734 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4735 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4736 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4737 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4738 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
2fa522be
TI
4739 {
4740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4741 .name = "Channel Mode",
df694daa
KY
4742 .info = alc_ch_mode_info,
4743 .get = alc_ch_mode_get,
4744 .put = alc_ch_mode_put,
2fa522be
TI
4745 },
4746 { } /* end */
4747};
4748
a9111321 4749static const struct hda_verb alc880_test_init_verbs[] = {
2fa522be 4750 /* Unmute inputs of 0x0c - 0x0f */
05acb863
TI
4751 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4753 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4754 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4755 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4756 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4757 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4758 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2fa522be 4759 /* Vol output for 0x0c-0x0f */
05acb863
TI
4760 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4762 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4763 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2fa522be 4764 /* Set output pins 0x14-0x17 */
05acb863
TI
4765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4768 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2fa522be 4769 /* Unmute output pins 0x14-0x17 */
05acb863
TI
4770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4771 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4772 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4773 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2fa522be 4774 /* Set input pins 0x18-0x1c */
16ded525
TI
4775 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4776 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
05acb863
TI
4777 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4778 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4779 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2fa522be 4780 /* Mute input pins 0x18-0x1b */
05acb863
TI
4781 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4782 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4783 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4784 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
71fe7b82 4785 /* ADC set up */
05acb863 4786 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4787 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4788 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4789 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863 4790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 4791 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
4792 /* Analog input/passthru */
4793 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4795 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4796 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4797 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2fa522be
TI
4798 { }
4799};
4800#endif
4801
1da177e4
LT
4802/*
4803 */
4804
ea734963 4805static const char * const alc880_models[ALC880_MODEL_LAST] = {
f5fcc13c
TI
4806 [ALC880_3ST] = "3stack",
4807 [ALC880_TCL_S700] = "tcl",
4808 [ALC880_3ST_DIG] = "3stack-digout",
4809 [ALC880_CLEVO] = "clevo",
4810 [ALC880_5ST] = "5stack",
4811 [ALC880_5ST_DIG] = "5stack-digout",
4812 [ALC880_W810] = "w810",
4813 [ALC880_Z71V] = "z71v",
4814 [ALC880_6ST] = "6stack",
4815 [ALC880_6ST_DIG] = "6stack-digout",
4816 [ALC880_ASUS] = "asus",
4817 [ALC880_ASUS_W1V] = "asus-w1v",
4818 [ALC880_ASUS_DIG] = "asus-dig",
4819 [ALC880_ASUS_DIG2] = "asus-dig2",
4820 [ALC880_UNIWILL_DIG] = "uniwill",
2cf9f0fc
TD
4821 [ALC880_UNIWILL_P53] = "uniwill-p53",
4822 [ALC880_FUJITSU] = "fujitsu",
f5fcc13c
TI
4823 [ALC880_F1734] = "F1734",
4824 [ALC880_LG] = "lg",
4825 [ALC880_LG_LW] = "lg-lw",
df99cd33 4826 [ALC880_MEDION_RIM] = "medion",
2fa522be 4827#ifdef CONFIG_SND_DEBUG
f5fcc13c 4828 [ALC880_TEST] = "test",
2fa522be 4829#endif
f5fcc13c
TI
4830 [ALC880_AUTO] = "auto",
4831};
4832
a9111321 4833static const struct snd_pci_quirk alc880_cfg_tbl[] = {
ac3e3741 4834 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
f5fcc13c
TI
4835 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4836 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4837 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4838 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4839 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4840 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4841 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4842 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
f5fcc13c
TI
4843 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4844 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
f5fcc13c
TI
4845 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4846 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4847 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4848 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4849 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4850 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4851 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4852 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4853 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4854 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
186c3117 4855 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
f5fcc13c
TI
4856 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4857 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4858 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
dea0a509 4859 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
f5fcc13c 4860 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
ac3e3741
TI
4861 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4862 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
f5fcc13c
TI
4863 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4864 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
f5fcc13c
TI
4865 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4866 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4867 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4868 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
ac3e3741
TI
4869 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4870 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
f5fcc13c 4871 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
ac3e3741 4872 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
f5fcc13c 4873 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
a2e2bc28 4874 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
f5fcc13c
TI
4875 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4876 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
ac3e3741 4877 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
df99cd33 4878 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
ac3e3741 4879 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
f5fcc13c 4880 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
f5fcc13c 4881 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
1d11604e 4882 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
3353541f 4883 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
2cf9f0fc 4884 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
ac3e3741 4885 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
f5fcc13c 4886 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
77c4d5cd 4887 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
f5fcc13c 4888 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
f5fcc13c 4889 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
ac3e3741
TI
4890 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4891 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4892 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4893 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
f5fcc13c
TI
4894 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4895 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
ac3e3741 4896 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c 4897 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
ac3e3741
TI
4898 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4899 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
f5fcc13c
TI
4900 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4901 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4902 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
dea0a509
TI
4903 /* default Intel */
4904 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
ac3e3741
TI
4905 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4906 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
1da177e4
LT
4907 {}
4908};
4909
16ded525 4910/*
df694daa 4911 * ALC880 codec presets
16ded525 4912 */
a9111321 4913static const struct alc_config_preset alc880_presets[] = {
16ded525 4914 [ALC880_3ST] = {
e9edcee0 4915 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4916 .init_verbs = { alc880_volume_init_verbs,
4917 alc880_pin_3stack_init_verbs },
16ded525 4918 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525 4919 .dac_nids = alc880_dac_nids,
16ded525
TI
4920 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4921 .channel_mode = alc880_threestack_modes,
4e195a7b 4922 .need_dac_fix = 1,
16ded525
TI
4923 .input_mux = &alc880_capture_source,
4924 },
4925 [ALC880_3ST_DIG] = {
e9edcee0 4926 .mixers = { alc880_three_stack_mixer },
f12ab1e0
TI
4927 .init_verbs = { alc880_volume_init_verbs,
4928 alc880_pin_3stack_init_verbs },
16ded525 4929 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
16ded525
TI
4930 .dac_nids = alc880_dac_nids,
4931 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4932 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4933 .channel_mode = alc880_threestack_modes,
4e195a7b 4934 .need_dac_fix = 1,
16ded525
TI
4935 .input_mux = &alc880_capture_source,
4936 },
df694daa
KY
4937 [ALC880_TCL_S700] = {
4938 .mixers = { alc880_tcl_s700_mixer },
4939 .init_verbs = { alc880_volume_init_verbs,
4940 alc880_pin_tcl_S700_init_verbs,
4941 alc880_gpio2_init_verbs },
4942 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4943 .dac_nids = alc880_dac_nids,
f9e336f6
TI
4944 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4945 .num_adc_nids = 1, /* single ADC */
df694daa
KY
4946 .hp_nid = 0x03,
4947 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4948 .channel_mode = alc880_2_jack_modes,
4949 .input_mux = &alc880_capture_source,
4950 },
16ded525 4951 [ALC880_5ST] = {
f12ab1e0
TI
4952 .mixers = { alc880_three_stack_mixer,
4953 alc880_five_stack_mixer},
4954 .init_verbs = { alc880_volume_init_verbs,
4955 alc880_pin_5stack_init_verbs },
16ded525
TI
4956 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4957 .dac_nids = alc880_dac_nids,
16ded525
TI
4958 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4959 .channel_mode = alc880_fivestack_modes,
4960 .input_mux = &alc880_capture_source,
4961 },
4962 [ALC880_5ST_DIG] = {
f12ab1e0
TI
4963 .mixers = { alc880_three_stack_mixer,
4964 alc880_five_stack_mixer },
4965 .init_verbs = { alc880_volume_init_verbs,
4966 alc880_pin_5stack_init_verbs },
16ded525
TI
4967 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4968 .dac_nids = alc880_dac_nids,
4969 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4970 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
4971 .channel_mode = alc880_fivestack_modes,
4972 .input_mux = &alc880_capture_source,
4973 },
b6482d48
TI
4974 [ALC880_6ST] = {
4975 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4976 .init_verbs = { alc880_volume_init_verbs,
4977 alc880_pin_6stack_init_verbs },
b6482d48
TI
4978 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4979 .dac_nids = alc880_6st_dac_nids,
4980 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4981 .channel_mode = alc880_sixstack_modes,
4982 .input_mux = &alc880_6stack_capture_source,
4983 },
16ded525 4984 [ALC880_6ST_DIG] = {
e9edcee0 4985 .mixers = { alc880_six_stack_mixer },
f12ab1e0
TI
4986 .init_verbs = { alc880_volume_init_verbs,
4987 alc880_pin_6stack_init_verbs },
16ded525
TI
4988 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
4989 .dac_nids = alc880_6st_dac_nids,
4990 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
4991 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
4992 .channel_mode = alc880_sixstack_modes,
4993 .input_mux = &alc880_6stack_capture_source,
4994 },
4995 [ALC880_W810] = {
e9edcee0 4996 .mixers = { alc880_w810_base_mixer },
f12ab1e0
TI
4997 .init_verbs = { alc880_volume_init_verbs,
4998 alc880_pin_w810_init_verbs,
b0af0de5 4999 alc880_gpio2_init_verbs },
16ded525
TI
5000 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5001 .dac_nids = alc880_w810_dac_nids,
5002 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5003 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5004 .channel_mode = alc880_w810_modes,
5005 .input_mux = &alc880_capture_source,
5006 },
5007 [ALC880_Z71V] = {
e9edcee0 5008 .mixers = { alc880_z71v_mixer },
f12ab1e0
TI
5009 .init_verbs = { alc880_volume_init_verbs,
5010 alc880_pin_z71v_init_verbs },
16ded525
TI
5011 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5012 .dac_nids = alc880_z71v_dac_nids,
5013 .dig_out_nid = ALC880_DIGOUT_NID,
5014 .hp_nid = 0x03,
e9edcee0
TI
5015 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5016 .channel_mode = alc880_2_jack_modes,
16ded525
TI
5017 .input_mux = &alc880_capture_source,
5018 },
5019 [ALC880_F1734] = {
e9edcee0 5020 .mixers = { alc880_f1734_mixer },
f12ab1e0
TI
5021 .init_verbs = { alc880_volume_init_verbs,
5022 alc880_pin_f1734_init_verbs },
e9edcee0
TI
5023 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5024 .dac_nids = alc880_f1734_dac_nids,
5025 .hp_nid = 0x02,
5026 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5027 .channel_mode = alc880_2_jack_modes,
937b4160
TI
5028 .input_mux = &alc880_f1734_capture_source,
5029 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5030 .setup = alc880_uniwill_p53_setup,
d922b51d 5031 .init_hook = alc_hp_automute,
16ded525
TI
5032 },
5033 [ALC880_ASUS] = {
e9edcee0 5034 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5035 .init_verbs = { alc880_volume_init_verbs,
5036 alc880_pin_asus_init_verbs,
e9edcee0
TI
5037 alc880_gpio1_init_verbs },
5038 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5039 .dac_nids = alc880_asus_dac_nids,
5040 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5041 .channel_mode = alc880_asus_modes,
4e195a7b 5042 .need_dac_fix = 1,
16ded525
TI
5043 .input_mux = &alc880_capture_source,
5044 },
5045 [ALC880_ASUS_DIG] = {
e9edcee0 5046 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5047 .init_verbs = { alc880_volume_init_verbs,
5048 alc880_pin_asus_init_verbs,
e9edcee0
TI
5049 alc880_gpio1_init_verbs },
5050 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5051 .dac_nids = alc880_asus_dac_nids,
16ded525 5052 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5053 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5054 .channel_mode = alc880_asus_modes,
4e195a7b 5055 .need_dac_fix = 1,
16ded525
TI
5056 .input_mux = &alc880_capture_source,
5057 },
df694daa
KY
5058 [ALC880_ASUS_DIG2] = {
5059 .mixers = { alc880_asus_mixer },
f12ab1e0
TI
5060 .init_verbs = { alc880_volume_init_verbs,
5061 alc880_pin_asus_init_verbs,
df694daa
KY
5062 alc880_gpio2_init_verbs }, /* use GPIO2 */
5063 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5064 .dac_nids = alc880_asus_dac_nids,
5065 .dig_out_nid = ALC880_DIGOUT_NID,
5066 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5067 .channel_mode = alc880_asus_modes,
4e195a7b 5068 .need_dac_fix = 1,
df694daa
KY
5069 .input_mux = &alc880_capture_source,
5070 },
16ded525 5071 [ALC880_ASUS_W1V] = {
e9edcee0 5072 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
f12ab1e0
TI
5073 .init_verbs = { alc880_volume_init_verbs,
5074 alc880_pin_asus_init_verbs,
e9edcee0
TI
5075 alc880_gpio1_init_verbs },
5076 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5077 .dac_nids = alc880_asus_dac_nids,
16ded525 5078 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5079 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5080 .channel_mode = alc880_asus_modes,
4e195a7b 5081 .need_dac_fix = 1,
16ded525
TI
5082 .input_mux = &alc880_capture_source,
5083 },
5084 [ALC880_UNIWILL_DIG] = {
45bdd1c1 5085 .mixers = { alc880_asus_mixer },
ccc656ce
KY
5086 .init_verbs = { alc880_volume_init_verbs,
5087 alc880_pin_asus_init_verbs },
e9edcee0
TI
5088 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5089 .dac_nids = alc880_asus_dac_nids,
16ded525 5090 .dig_out_nid = ALC880_DIGOUT_NID,
e9edcee0
TI
5091 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5092 .channel_mode = alc880_asus_modes,
4e195a7b 5093 .need_dac_fix = 1,
16ded525
TI
5094 .input_mux = &alc880_capture_source,
5095 },
ccc656ce
KY
5096 [ALC880_UNIWILL] = {
5097 .mixers = { alc880_uniwill_mixer },
5098 .init_verbs = { alc880_volume_init_verbs,
5099 alc880_uniwill_init_verbs },
5100 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5101 .dac_nids = alc880_asus_dac_nids,
5102 .dig_out_nid = ALC880_DIGOUT_NID,
5103 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5104 .channel_mode = alc880_threestack_modes,
5105 .need_dac_fix = 1,
5106 .input_mux = &alc880_capture_source,
5107 .unsol_event = alc880_uniwill_unsol_event,
4f5d1706 5108 .setup = alc880_uniwill_setup,
a9fd4f3f 5109 .init_hook = alc880_uniwill_init_hook,
ccc656ce
KY
5110 },
5111 [ALC880_UNIWILL_P53] = {
5112 .mixers = { alc880_uniwill_p53_mixer },
5113 .init_verbs = { alc880_volume_init_verbs,
5114 alc880_uniwill_p53_init_verbs },
5115 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5116 .dac_nids = alc880_asus_dac_nids,
5117 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2cf9f0fc
TD
5118 .channel_mode = alc880_threestack_modes,
5119 .input_mux = &alc880_capture_source,
5120 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5121 .setup = alc880_uniwill_p53_setup,
d922b51d 5122 .init_hook = alc_hp_automute,
2cf9f0fc
TD
5123 },
5124 [ALC880_FUJITSU] = {
45bdd1c1 5125 .mixers = { alc880_fujitsu_mixer },
2cf9f0fc
TD
5126 .init_verbs = { alc880_volume_init_verbs,
5127 alc880_uniwill_p53_init_verbs,
5128 alc880_beep_init_verbs },
5129 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5130 .dac_nids = alc880_dac_nids,
d53d7d9e 5131 .dig_out_nid = ALC880_DIGOUT_NID,
2cf9f0fc
TD
5132 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5133 .channel_mode = alc880_2_jack_modes,
ccc656ce
KY
5134 .input_mux = &alc880_capture_source,
5135 .unsol_event = alc880_uniwill_p53_unsol_event,
4f5d1706 5136 .setup = alc880_uniwill_p53_setup,
d922b51d 5137 .init_hook = alc_hp_automute,
ccc656ce 5138 },
df694daa
KY
5139 [ALC880_CLEVO] = {
5140 .mixers = { alc880_three_stack_mixer },
5141 .init_verbs = { alc880_volume_init_verbs,
5142 alc880_pin_clevo_init_verbs },
5143 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5144 .dac_nids = alc880_dac_nids,
5145 .hp_nid = 0x03,
5146 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5147 .channel_mode = alc880_threestack_modes,
4e195a7b 5148 .need_dac_fix = 1,
df694daa
KY
5149 .input_mux = &alc880_capture_source,
5150 },
ae6b813a
TI
5151 [ALC880_LG] = {
5152 .mixers = { alc880_lg_mixer },
5153 .init_verbs = { alc880_volume_init_verbs,
5154 alc880_lg_init_verbs },
5155 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5156 .dac_nids = alc880_lg_dac_nids,
5157 .dig_out_nid = ALC880_DIGOUT_NID,
5158 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5159 .channel_mode = alc880_lg_ch_modes,
4e195a7b 5160 .need_dac_fix = 1,
ae6b813a 5161 .input_mux = &alc880_lg_capture_source,
d922b51d 5162 .unsol_event = alc_sku_unsol_event,
4f5d1706 5163 .setup = alc880_lg_setup,
d922b51d 5164 .init_hook = alc_hp_automute,
cb53c626
TI
5165#ifdef CONFIG_SND_HDA_POWER_SAVE
5166 .loopbacks = alc880_lg_loopbacks,
5167#endif
ae6b813a 5168 },
d681518a
TI
5169 [ALC880_LG_LW] = {
5170 .mixers = { alc880_lg_lw_mixer },
5171 .init_verbs = { alc880_volume_init_verbs,
5172 alc880_lg_lw_init_verbs },
0a8c5da3 5173 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
d681518a
TI
5174 .dac_nids = alc880_dac_nids,
5175 .dig_out_nid = ALC880_DIGOUT_NID,
0a8c5da3
CM
5176 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5177 .channel_mode = alc880_lg_lw_modes,
d681518a 5178 .input_mux = &alc880_lg_lw_capture_source,
d922b51d 5179 .unsol_event = alc_sku_unsol_event,
4f5d1706 5180 .setup = alc880_lg_lw_setup,
d922b51d 5181 .init_hook = alc_hp_automute,
d681518a 5182 },
df99cd33
TI
5183 [ALC880_MEDION_RIM] = {
5184 .mixers = { alc880_medion_rim_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_medion_rim_init_verbs,
5187 alc_gpio2_init_verbs },
5188 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5189 .dac_nids = alc880_dac_nids,
5190 .dig_out_nid = ALC880_DIGOUT_NID,
5191 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5192 .channel_mode = alc880_2_jack_modes,
5193 .input_mux = &alc880_medion_rim_capture_source,
5194 .unsol_event = alc880_medion_rim_unsol_event,
4f5d1706
TI
5195 .setup = alc880_medion_rim_setup,
5196 .init_hook = alc880_medion_rim_automute,
df99cd33 5197 },
16ded525
TI
5198#ifdef CONFIG_SND_DEBUG
5199 [ALC880_TEST] = {
e9edcee0
TI
5200 .mixers = { alc880_test_mixer },
5201 .init_verbs = { alc880_test_init_verbs },
16ded525
TI
5202 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5203 .dac_nids = alc880_test_dac_nids,
5204 .dig_out_nid = ALC880_DIGOUT_NID,
16ded525
TI
5205 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5206 .channel_mode = alc880_test_modes,
5207 .input_mux = &alc880_test_capture_source,
5208 },
5209#endif
5210};
5211
e9edcee0
TI
5212/*
5213 * Automatic parse of I/O pins from the BIOS configuration
5214 */
5215
e9edcee0
TI
5216enum {
5217 ALC_CTL_WIDGET_VOL,
5218 ALC_CTL_WIDGET_MUTE,
5219 ALC_CTL_BIND_MUTE,
5220};
a9111321 5221static const struct snd_kcontrol_new alc880_control_templates[] = {
e9edcee0
TI
5222 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5223 HDA_CODEC_MUTE(NULL, 0, 0, 0),
985be54b 5224 HDA_BIND_MUTE(NULL, 0, 0, 0),
e9edcee0
TI
5225};
5226
ce764ab2
TI
5227static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5228{
5229 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5230 return snd_array_new(&spec->kctls);
5231}
5232
e9edcee0 5233/* add dynamic controls */
f12ab1e0 5234static int add_control(struct alc_spec *spec, int type, const char *name,
66ceeb6b 5235 int cidx, unsigned long val)
e9edcee0 5236{
c8b6bf9b 5237 struct snd_kcontrol_new *knew;
e9edcee0 5238
ce764ab2 5239 knew = alc_kcontrol_new(spec);
603c4019
TI
5240 if (!knew)
5241 return -ENOMEM;
e9edcee0 5242 *knew = alc880_control_templates[type];
543537bd 5243 knew->name = kstrdup(name, GFP_KERNEL);
f12ab1e0 5244 if (!knew->name)
e9edcee0 5245 return -ENOMEM;
66ceeb6b 5246 knew->index = cidx;
4d02d1b6 5247 if (get_amp_nid_(val))
5e26dfd0 5248 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
e9edcee0 5249 knew->private_value = val;
e9edcee0
TI
5250 return 0;
5251}
5252
0afe5f89
TI
5253static int add_control_with_pfx(struct alc_spec *spec, int type,
5254 const char *pfx, const char *dir,
66ceeb6b 5255 const char *sfx, int cidx, unsigned long val)
0afe5f89
TI
5256{
5257 char name[32];
5258 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
66ceeb6b 5259 return add_control(spec, type, name, cidx, val);
0afe5f89
TI
5260}
5261
66ceeb6b
TI
5262#define add_pb_vol_ctrl(spec, type, pfx, val) \
5263 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5264#define add_pb_sw_ctrl(spec, type, pfx, val) \
5265 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5266#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5267 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5268#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5269 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
0afe5f89 5270
e9edcee0
TI
5271#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5272#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5273#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5274#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
e9edcee0
TI
5275#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5276#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5277#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5278#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5279#define ALC880_PIN_CD_NID 0x1c
5280
5281/* fill in the dac_nids table from the parsed pin configuration */
f12ab1e0
TI
5282static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5283 const struct auto_pin_cfg *cfg)
e9edcee0
TI
5284{
5285 hda_nid_t nid;
5286 int assigned[4];
5287 int i, j;
5288
5289 memset(assigned, 0, sizeof(assigned));
b0af0de5 5290 spec->multiout.dac_nids = spec->private_dac_nids;
e9edcee0
TI
5291
5292 /* check the pins hardwired to audio widget */
5293 for (i = 0; i < cfg->line_outs; i++) {
5294 nid = cfg->line_out_pins[i];
5295 if (alc880_is_fixed_pin(nid)) {
5296 int idx = alc880_fixed_pin_idx(nid);
dda14410 5297 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
e9edcee0
TI
5298 assigned[idx] = 1;
5299 }
5300 }
5301 /* left pins can be connect to any audio widget */
5302 for (i = 0; i < cfg->line_outs; i++) {
5303 nid = cfg->line_out_pins[i];
5304 if (alc880_is_fixed_pin(nid))
5305 continue;
5306 /* search for an empty channel */
5307 for (j = 0; j < cfg->line_outs; j++) {
f12ab1e0 5308 if (!assigned[j]) {
dda14410 5309 spec->private_dac_nids[i] =
f12ab1e0 5310 alc880_idx_to_dac(j);
e9edcee0
TI
5311 assigned[j] = 1;
5312 break;
5313 }
5314 }
5315 }
5316 spec->multiout.num_dacs = cfg->line_outs;
5317 return 0;
5318}
5319
ce764ab2 5320static const char *alc_get_line_out_pfx(struct alc_spec *spec,
bcb2f0f5
TI
5321 bool can_be_master)
5322{
ce764ab2
TI
5323 struct auto_pin_cfg *cfg = &spec->autocfg;
5324
5325 if (cfg->line_outs == 1 && !spec->multi_ios &&
5326 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
bcb2f0f5
TI
5327 return "Master";
5328
5329 switch (cfg->line_out_type) {
5330 case AUTO_PIN_SPEAKER_OUT:
ebbeb3d6
DH
5331 if (cfg->line_outs == 1)
5332 return "Speaker";
5333 break;
bcb2f0f5
TI
5334 case AUTO_PIN_HP_OUT:
5335 return "Headphone";
5336 default:
ce764ab2 5337 if (cfg->line_outs == 1 && !spec->multi_ios)
bcb2f0f5
TI
5338 return "PCM";
5339 break;
5340 }
5341 return NULL;
5342}
5343
e9edcee0 5344/* add playback controls from the parsed DAC table */
df694daa
KY
5345static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5346 const struct auto_pin_cfg *cfg)
e9edcee0 5347{
ea734963 5348 static const char * const chname[4] = {
f12ab1e0
TI
5349 "Front", "Surround", NULL /*CLFE*/, "Side"
5350 };
ce764ab2 5351 const char *pfx = alc_get_line_out_pfx(spec, false);
e9edcee0 5352 hda_nid_t nid;
ce764ab2 5353 int i, err, noutputs;
e9edcee0 5354
ce764ab2
TI
5355 noutputs = cfg->line_outs;
5356 if (spec->multi_ios > 0)
5357 noutputs += spec->multi_ios;
5358
5359 for (i = 0; i < noutputs; i++) {
f12ab1e0 5360 if (!spec->multiout.dac_nids[i])
e9edcee0
TI
5361 continue;
5362 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
bcb2f0f5 5363 if (!pfx && i == 2) {
e9edcee0 5364 /* Center/LFE */
0afe5f89
TI
5365 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5366 "Center",
f12ab1e0
TI
5367 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5368 HDA_OUTPUT));
5369 if (err < 0)
e9edcee0 5370 return err;
0afe5f89
TI
5371 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5372 "LFE",
f12ab1e0
TI
5373 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5374 HDA_OUTPUT));
5375 if (err < 0)
e9edcee0 5376 return err;
0afe5f89
TI
5377 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5378 "Center",
f12ab1e0
TI
5379 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5380 HDA_INPUT));
5381 if (err < 0)
e9edcee0 5382 return err;
0afe5f89
TI
5383 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5384 "LFE",
f12ab1e0
TI
5385 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5386 HDA_INPUT));
5387 if (err < 0)
e9edcee0
TI
5388 return err;
5389 } else {
bcb2f0f5 5390 const char *name = pfx;
7e59e097
DH
5391 int index = i;
5392 if (!name) {
bcb2f0f5 5393 name = chname[i];
7e59e097
DH
5394 index = 0;
5395 }
bcb2f0f5 5396 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
7e59e097 5397 name, index,
f12ab1e0
TI
5398 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5399 HDA_OUTPUT));
5400 if (err < 0)
e9edcee0 5401 return err;
bcb2f0f5 5402 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
7e59e097 5403 name, index,
f12ab1e0
TI
5404 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5405 HDA_INPUT));
5406 if (err < 0)
e9edcee0
TI
5407 return err;
5408 }
5409 }
e9edcee0
TI
5410 return 0;
5411}
5412
8d88bc3d
TI
5413/* add playback controls for speaker and HP outputs */
5414static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5415 const char *pfx)
e9edcee0
TI
5416{
5417 hda_nid_t nid;
5418 int err;
5419
f12ab1e0 5420 if (!pin)
e9edcee0
TI
5421 return 0;
5422
5423 if (alc880_is_fixed_pin(pin)) {
5424 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
82bc955f 5425 /* specify the DAC as the extra output */
f12ab1e0 5426 if (!spec->multiout.hp_nid)
e9edcee0 5427 spec->multiout.hp_nid = nid;
82bc955f
TI
5428 else
5429 spec->multiout.extra_out_nid[0] = nid;
e9edcee0
TI
5430 /* control HP volume/switch on the output mixer amp */
5431 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
0afe5f89 5432 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
5433 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5434 if (err < 0)
e9edcee0 5435 return err;
0afe5f89 5436 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
5437 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5438 if (err < 0)
e9edcee0
TI
5439 return err;
5440 } else if (alc880_is_multi_pin(pin)) {
5441 /* set manual connection */
e9edcee0 5442 /* we have only a switch on HP-out PIN */
0afe5f89 5443 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
5444 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5445 if (err < 0)
e9edcee0
TI
5446 return err;
5447 }
5448 return 0;
5449}
5450
5451/* create input playback/capture controls for the given pin */
f12ab1e0 5452static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
66ceeb6b 5453 const char *ctlname, int ctlidx,
df694daa 5454 int idx, hda_nid_t mix_nid)
e9edcee0 5455{
df694daa 5456 int err;
e9edcee0 5457
66ceeb6b 5458 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
f12ab1e0
TI
5459 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5460 if (err < 0)
e9edcee0 5461 return err;
66ceeb6b 5462 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
f12ab1e0
TI
5463 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5464 if (err < 0)
e9edcee0
TI
5465 return err;
5466 return 0;
5467}
5468
05f5f477
TI
5469static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5470{
5471 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5472 return (pincap & AC_PINCAP_IN) != 0;
5473}
5474
e9edcee0 5475/* create playback/capture controls for input pins */
05f5f477
TI
5476static int alc_auto_create_input_ctls(struct hda_codec *codec,
5477 const struct auto_pin_cfg *cfg,
5478 hda_nid_t mixer,
5479 hda_nid_t cap1, hda_nid_t cap2)
e9edcee0 5480{
05f5f477 5481 struct alc_spec *spec = codec->spec;
61b9b9b1 5482 struct hda_input_mux *imux = &spec->private_imux[0];
5322bf27
DH
5483 int i, err, idx, type_idx = 0;
5484 const char *prev_label = NULL;
e9edcee0 5485
66ceeb6b 5486 for (i = 0; i < cfg->num_inputs; i++) {
05f5f477 5487 hda_nid_t pin;
10a20af7 5488 const char *label;
05f5f477 5489
66ceeb6b 5490 pin = cfg->inputs[i].pin;
05f5f477
TI
5491 if (!alc_is_input_pin(codec, pin))
5492 continue;
5493
5322bf27
DH
5494 label = hda_get_autocfg_input_label(codec, cfg, i);
5495 if (prev_label && !strcmp(label, prev_label))
66ceeb6b
TI
5496 type_idx++;
5497 else
5498 type_idx = 0;
5322bf27
DH
5499 prev_label = label;
5500
05f5f477
TI
5501 if (mixer) {
5502 idx = get_connection_index(codec, mixer, pin);
5503 if (idx >= 0) {
5504 err = new_analog_input(spec, pin,
10a20af7
TI
5505 label, type_idx,
5506 idx, mixer);
05f5f477
TI
5507 if (err < 0)
5508 return err;
5509 }
5510 }
5511
5512 if (!cap1)
5513 continue;
5514 idx = get_connection_index(codec, cap1, pin);
5515 if (idx < 0 && cap2)
5516 idx = get_connection_index(codec, cap2, pin);
10a20af7
TI
5517 if (idx >= 0)
5518 snd_hda_add_imux_item(imux, label, idx, NULL);
e9edcee0
TI
5519 }
5520 return 0;
5521}
5522
05f5f477
TI
5523static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5524 const struct auto_pin_cfg *cfg)
5525{
5526 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5527}
5528
f6c7e546
TI
5529static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5530 unsigned int pin_type)
5531{
5532 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5533 pin_type);
5534 /* unmute pin */
d260cdf6
TI
5535 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5536 AMP_OUT_UNMUTE);
f6c7e546
TI
5537}
5538
df694daa
KY
5539static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5540 hda_nid_t nid, int pin_type,
e9edcee0
TI
5541 int dac_idx)
5542{
f6c7e546 5543 alc_set_pin_output(codec, nid, pin_type);
e9edcee0
TI
5544 /* need the manual connection? */
5545 if (alc880_is_multi_pin(nid)) {
5546 struct alc_spec *spec = codec->spec;
5547 int idx = alc880_multi_pin_idx(nid);
5548 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5549 AC_VERB_SET_CONNECT_SEL,
5550 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5551 }
5552}
5553
baba8ee9
TI
5554static int get_pin_type(int line_out_type)
5555{
5556 if (line_out_type == AUTO_PIN_HP_OUT)
5557 return PIN_HP;
5558 else
5559 return PIN_OUT;
5560}
5561
e9edcee0
TI
5562static void alc880_auto_init_multi_out(struct hda_codec *codec)
5563{
5564 struct alc_spec *spec = codec->spec;
5565 int i;
ea1fb29a 5566
e9edcee0
TI
5567 for (i = 0; i < spec->autocfg.line_outs; i++) {
5568 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9
TI
5569 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5570 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
e9edcee0
TI
5571 }
5572}
5573
8d88bc3d 5574static void alc880_auto_init_extra_out(struct hda_codec *codec)
e9edcee0
TI
5575{
5576 struct alc_spec *spec = codec->spec;
5577 hda_nid_t pin;
5578
82bc955f 5579 pin = spec->autocfg.speaker_pins[0];
8d88bc3d
TI
5580 if (pin) /* connect to front */
5581 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
eb06ed8f 5582 pin = spec->autocfg.hp_pins[0];
e9edcee0
TI
5583 if (pin) /* connect to front */
5584 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5585}
5586
5587static void alc880_auto_init_analog_input(struct hda_codec *codec)
5588{
5589 struct alc_spec *spec = codec->spec;
66ceeb6b 5590 struct auto_pin_cfg *cfg = &spec->autocfg;
e9edcee0
TI
5591 int i;
5592
66ceeb6b
TI
5593 for (i = 0; i < cfg->num_inputs; i++) {
5594 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 5595 if (alc_is_input_pin(codec, nid)) {
30ea098f 5596 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
5597 if (nid != ALC880_PIN_CD_NID &&
5598 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
5599 snd_hda_codec_write(codec, nid, 0,
5600 AC_VERB_SET_AMP_GAIN_MUTE,
e9edcee0
TI
5601 AMP_OUT_MUTE);
5602 }
5603 }
5604}
5605
7f311a46
TI
5606static void alc880_auto_init_input_src(struct hda_codec *codec)
5607{
5608 struct alc_spec *spec = codec->spec;
5609 int c;
5610
5611 for (c = 0; c < spec->num_adc_nids; c++) {
5612 unsigned int mux_idx;
5613 const struct hda_input_mux *imux;
5614 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5615 imux = &spec->input_mux[mux_idx];
5616 if (!imux->num_items && mux_idx > 0)
5617 imux = &spec->input_mux[0];
5618 if (imux)
5619 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5620 AC_VERB_SET_CONNECT_SEL,
5621 imux->items[0].index);
5622 }
5623}
5624
ce764ab2
TI
5625static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5626
e9edcee0 5627/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
5628/* return 1 if successful, 0 if the proper config is not found,
5629 * or a negative error code
5630 */
e9edcee0
TI
5631static int alc880_parse_auto_config(struct hda_codec *codec)
5632{
5633 struct alc_spec *spec = codec->spec;
757899ac 5634 int err;
4c6d72d1 5635 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
e9edcee0 5636
f12ab1e0
TI
5637 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5638 alc880_ignore);
5639 if (err < 0)
e9edcee0 5640 return err;
f12ab1e0 5641 if (!spec->autocfg.line_outs)
e9edcee0 5642 return 0; /* can't find valid BIOS pin config */
df694daa 5643
f12ab1e0 5644 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
5645 if (err < 0)
5646 return err;
5647 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
5648 if (err < 0)
5649 return err;
5650 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5651 if (err < 0)
5652 return err;
5653 err = alc880_auto_create_extra_out(spec,
5654 spec->autocfg.speaker_pins[0],
5655 "Speaker");
5656 if (err < 0)
5657 return err;
5658 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5659 "Headphone");
5660 if (err < 0)
5661 return err;
05f5f477 5662 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 5663 if (err < 0)
e9edcee0
TI
5664 return err;
5665
5666 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5667
757899ac 5668 alc_auto_parse_digital(codec);
e9edcee0 5669
603c4019 5670 if (spec->kctls.list)
d88897ea 5671 add_mixer(spec, spec->kctls.list);
e9edcee0 5672
d88897ea 5673 add_verb(spec, alc880_volume_init_verbs);
e9edcee0 5674
a1e8d2da 5675 spec->num_mux_defs = 1;
61b9b9b1 5676 spec->input_mux = &spec->private_imux[0];
e9edcee0 5677
6227cdce 5678 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 5679
e9edcee0
TI
5680 return 1;
5681}
5682
ae6b813a
TI
5683/* additional initialization for auto-configuration model */
5684static void alc880_auto_init(struct hda_codec *codec)
e9edcee0 5685{
f6c7e546 5686 struct alc_spec *spec = codec->spec;
e9edcee0 5687 alc880_auto_init_multi_out(codec);
8d88bc3d 5688 alc880_auto_init_extra_out(codec);
e9edcee0 5689 alc880_auto_init_analog_input(codec);
7f311a46 5690 alc880_auto_init_input_src(codec);
757899ac 5691 alc_auto_init_digital(codec);
f6c7e546 5692 if (spec->unsol_event)
7fb0d78f 5693 alc_inithook(codec);
e9edcee0
TI
5694}
5695
b59bdf3b
TI
5696/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5697 * one of two digital mic pins, e.g. on ALC272
5698 */
5699static void fixup_automic_adc(struct hda_codec *codec)
5700{
5701 struct alc_spec *spec = codec->spec;
5702 int i;
5703
5704 for (i = 0; i < spec->num_adc_nids; i++) {
5705 hda_nid_t cap = spec->capsrc_nids ?
5706 spec->capsrc_nids[i] : spec->adc_nids[i];
5707 int iidx, eidx;
5708
5709 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5710 if (iidx < 0)
5711 continue;
5712 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5713 if (eidx < 0)
5714 continue;
5715 spec->int_mic.mux_idx = iidx;
5716 spec->ext_mic.mux_idx = eidx;
5717 if (spec->capsrc_nids)
5718 spec->capsrc_nids += i;
5719 spec->adc_nids += i;
5720 spec->num_adc_nids = 1;
5721 return;
5722 }
5723 snd_printd(KERN_INFO "hda_codec: %s: "
5724 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5725 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5726 spec->auto_mic = 0; /* disable auto-mic to be sure */
5727}
5728
748cce43
TI
5729/* select or unmute the given capsrc route */
5730static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5731 int idx)
5732{
5733 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5734 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5735 HDA_AMP_MUTE, 0);
5736 } else {
5737 snd_hda_codec_write_cache(codec, cap, 0,
5738 AC_VERB_SET_CONNECT_SEL, idx);
5739 }
5740}
5741
840b64c0
TI
5742/* set the default connection to that pin */
5743static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
eaa9b3a7
TI
5744{
5745 struct alc_spec *spec = codec->spec;
eaa9b3a7
TI
5746 int i;
5747
eaa9b3a7
TI
5748 for (i = 0; i < spec->num_adc_nids; i++) {
5749 hda_nid_t cap = spec->capsrc_nids ?
5750 spec->capsrc_nids[i] : spec->adc_nids[i];
5751 int idx;
5752
5753 idx = get_connection_index(codec, cap, pin);
5754 if (idx < 0)
5755 continue;
748cce43 5756 select_or_unmute_capsrc(codec, cap, idx);
840b64c0
TI
5757 return i; /* return the found index */
5758 }
5759 return -1; /* not found */
5760}
5761
5762/* choose the ADC/MUX containing the input pin and initialize the setup */
5763static void fixup_single_adc(struct hda_codec *codec)
5764{
5765 struct alc_spec *spec = codec->spec;
66ceeb6b 5766 struct auto_pin_cfg *cfg = &spec->autocfg;
840b64c0
TI
5767 int i;
5768
5769 /* search for the input pin; there must be only one */
66ceeb6b 5770 if (cfg->num_inputs != 1)
eaa9b3a7 5771 return;
66ceeb6b 5772 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
840b64c0
TI
5773 if (i >= 0) {
5774 /* use only this ADC */
5775 if (spec->capsrc_nids)
5776 spec->capsrc_nids += i;
5777 spec->adc_nids += i;
5778 spec->num_adc_nids = 1;
584c0c4c 5779 spec->single_input_src = 1;
eaa9b3a7
TI
5780 }
5781}
5782
840b64c0
TI
5783/* initialize dual adcs */
5784static void fixup_dual_adc_switch(struct hda_codec *codec)
5785{
5786 struct alc_spec *spec = codec->spec;
5787 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5788 init_capsrc_for_pin(codec, spec->int_mic.pin);
5789}
5790
584c0c4c
TI
5791/* initialize some special cases for input sources */
5792static void alc_init_special_input_src(struct hda_codec *codec)
5793{
5794 struct alc_spec *spec = codec->spec;
5795 if (spec->dual_adc_switch)
5796 fixup_dual_adc_switch(codec);
5797 else if (spec->single_input_src)
5798 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5799}
5800
b59bdf3b 5801static void set_capture_mixer(struct hda_codec *codec)
f9e336f6 5802{
b59bdf3b 5803 struct alc_spec *spec = codec->spec;
a9111321 5804 static const struct snd_kcontrol_new *caps[2][3] = {
a23b688f
TI
5805 { alc_capture_mixer_nosrc1,
5806 alc_capture_mixer_nosrc2,
5807 alc_capture_mixer_nosrc3 },
5808 { alc_capture_mixer1,
5809 alc_capture_mixer2,
5810 alc_capture_mixer3 },
f9e336f6 5811 };
a23b688f 5812 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
eaa9b3a7 5813 int mux = 0;
840b64c0
TI
5814 int num_adcs = spec->num_adc_nids;
5815 if (spec->dual_adc_switch)
584c0c4c 5816 num_adcs = 1;
840b64c0 5817 else if (spec->auto_mic)
b59bdf3b 5818 fixup_automic_adc(codec);
eaa9b3a7
TI
5819 else if (spec->input_mux) {
5820 if (spec->input_mux->num_items > 1)
5821 mux = 1;
5822 else if (spec->input_mux->num_items == 1)
5823 fixup_single_adc(codec);
5824 }
840b64c0 5825 spec->cap_mixer = caps[mux][num_adcs - 1];
a23b688f 5826 }
f9e336f6
TI
5827}
5828
6694635d 5829/* fill adc_nids (and capsrc_nids) containing all active input pins */
4c6d72d1 5830static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
6694635d
TI
5831 int num_nids)
5832{
5833 struct alc_spec *spec = codec->spec;
66ceeb6b 5834 struct auto_pin_cfg *cfg = &spec->autocfg;
6694635d
TI
5835 int n;
5836 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5837
5838 for (n = 0; n < num_nids; n++) {
5839 hda_nid_t adc, cap;
5840 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5841 int nconns, i, j;
5842
5843 adc = nids[n];
5844 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5845 continue;
5846 cap = adc;
5847 nconns = snd_hda_get_connections(codec, cap, conn,
5848 ARRAY_SIZE(conn));
5849 if (nconns == 1) {
5850 cap = conn[0];
5851 nconns = snd_hda_get_connections(codec, cap, conn,
5852 ARRAY_SIZE(conn));
5853 }
5854 if (nconns <= 0)
5855 continue;
5856 if (!fallback_adc) {
5857 fallback_adc = adc;
5858 fallback_cap = cap;
5859 }
66ceeb6b
TI
5860 for (i = 0; i < cfg->num_inputs; i++) {
5861 hda_nid_t nid = cfg->inputs[i].pin;
6694635d
TI
5862 for (j = 0; j < nconns; j++) {
5863 if (conn[j] == nid)
5864 break;
5865 }
5866 if (j >= nconns)
5867 break;
5868 }
66ceeb6b 5869 if (i >= cfg->num_inputs) {
6694635d
TI
5870 int num_adcs = spec->num_adc_nids;
5871 spec->private_adc_nids[num_adcs] = adc;
5872 spec->private_capsrc_nids[num_adcs] = cap;
5873 spec->num_adc_nids++;
5874 spec->adc_nids = spec->private_adc_nids;
5875 if (adc != cap)
5876 spec->capsrc_nids = spec->private_capsrc_nids;
5877 }
5878 }
5879 if (!spec->num_adc_nids) {
5880 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
1f85d72d
TI
5881 " using fallback 0x%x\n",
5882 codec->chip_name, fallback_adc);
6694635d
TI
5883 spec->private_adc_nids[0] = fallback_adc;
5884 spec->adc_nids = spec->private_adc_nids;
5885 if (fallback_adc != fallback_cap) {
5886 spec->private_capsrc_nids[0] = fallback_cap;
5887 spec->capsrc_nids = spec->private_adc_nids;
5888 }
5889 }
5890}
5891
67d634c0 5892#ifdef CONFIG_SND_HDA_INPUT_BEEP
45bdd1c1
TI
5893#define set_beep_amp(spec, nid, idx, dir) \
5894 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
dc1eae25 5895
a9111321 5896static const struct snd_pci_quirk beep_white_list[] = {
dc1eae25 5897 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
080dc7bc 5898 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
a7e985e1 5899 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
e096c8e6 5900 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
dc1eae25
TI
5901 {}
5902};
5903
5904static inline int has_cdefine_beep(struct hda_codec *codec)
5905{
5906 struct alc_spec *spec = codec->spec;
5907 const struct snd_pci_quirk *q;
5908 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5909 if (q)
5910 return q->value;
5911 return spec->cdefine.enable_pcbeep;
5912}
67d634c0
TI
5913#else
5914#define set_beep_amp(spec, nid, idx, dir) /* NOP */
dc1eae25 5915#define has_cdefine_beep(codec) 0
67d634c0 5916#endif
45bdd1c1
TI
5917
5918/*
5919 * OK, here we have finally the patch for ALC880
5920 */
5921
1da177e4
LT
5922static int patch_alc880(struct hda_codec *codec)
5923{
5924 struct alc_spec *spec;
5925 int board_config;
df694daa 5926 int err;
1da177e4 5927
e560d8d8 5928 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
5929 if (spec == NULL)
5930 return -ENOMEM;
5931
5932 codec->spec = spec;
5933
f5fcc13c
TI
5934 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5935 alc880_models,
5936 alc880_cfg_tbl);
5937 if (board_config < 0) {
9a11f1aa
TI
5938 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5939 codec->chip_name);
e9edcee0 5940 board_config = ALC880_AUTO;
1da177e4 5941 }
1da177e4 5942
e9edcee0
TI
5943 if (board_config == ALC880_AUTO) {
5944 /* automatic parse from the BIOS config */
5945 err = alc880_parse_auto_config(codec);
5946 if (err < 0) {
5947 alc_free(codec);
5948 return err;
f12ab1e0 5949 } else if (!err) {
9c7f852e
TI
5950 printk(KERN_INFO
5951 "hda_codec: Cannot set up configuration "
5952 "from BIOS. Using 3-stack mode...\n");
e9edcee0
TI
5953 board_config = ALC880_3ST;
5954 }
1da177e4
LT
5955 }
5956
680cd536
KK
5957 err = snd_hda_attach_beep_device(codec, 0x1);
5958 if (err < 0) {
5959 alc_free(codec);
5960 return err;
5961 }
5962
df694daa 5963 if (board_config != ALC880_AUTO)
e9c364c0 5964 setup_preset(codec, &alc880_presets[board_config]);
1da177e4 5965
1da177e4
LT
5966 spec->stream_analog_playback = &alc880_pcm_analog_playback;
5967 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6330079f 5968 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
1da177e4 5969
1da177e4
LT
5970 spec->stream_digital_playback = &alc880_pcm_digital_playback;
5971 spec->stream_digital_capture = &alc880_pcm_digital_capture;
5972
f12ab1e0 5973 if (!spec->adc_nids && spec->input_mux) {
e9edcee0 5974 /* check whether NID 0x07 is valid */
54d17403 5975 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
f12ab1e0 5976 /* get type */
a22d543a 5977 wcap = get_wcaps_type(wcap);
e9edcee0
TI
5978 if (wcap != AC_WID_AUD_IN) {
5979 spec->adc_nids = alc880_adc_nids_alt;
5980 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
e9edcee0
TI
5981 } else {
5982 spec->adc_nids = alc880_adc_nids;
5983 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
e9edcee0
TI
5984 }
5985 }
b59bdf3b 5986 set_capture_mixer(codec);
45bdd1c1 5987 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
1da177e4 5988
2134ea4f
TI
5989 spec->vmaster_nid = 0x0c;
5990
1da177e4 5991 codec->patch_ops = alc_patch_ops;
e9edcee0 5992 if (board_config == ALC880_AUTO)
ae6b813a 5993 spec->init_hook = alc880_auto_init;
cb53c626
TI
5994#ifdef CONFIG_SND_HDA_POWER_SAVE
5995 if (!spec->loopback.amplist)
5996 spec->loopback.amplist = alc880_loopbacks;
5997#endif
1da177e4
LT
5998
5999 return 0;
6000}
6001
e9edcee0 6002
1da177e4
LT
6003/*
6004 * ALC260 support
6005 */
6006
4c6d72d1 6007static const hda_nid_t alc260_dac_nids[1] = {
e9edcee0
TI
6008 /* front */
6009 0x02,
6010};
6011
4c6d72d1 6012static const hda_nid_t alc260_adc_nids[1] = {
e9edcee0
TI
6013 /* ADC0 */
6014 0x04,
6015};
6016
4c6d72d1 6017static const hda_nid_t alc260_adc_nids_alt[1] = {
e9edcee0
TI
6018 /* ADC1 */
6019 0x05,
6020};
6021
d57fdac0
JW
6022/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6023 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6024 */
4c6d72d1 6025static const hda_nid_t alc260_dual_adc_nids[2] = {
4c5186ed
JW
6026 /* ADC0, ADC1 */
6027 0x04, 0x05
6028};
6029
e9edcee0
TI
6030#define ALC260_DIGOUT_NID 0x03
6031#define ALC260_DIGIN_NID 0x06
6032
a9111321 6033static const struct hda_input_mux alc260_capture_source = {
e9edcee0
TI
6034 .num_items = 4,
6035 .items = {
6036 { "Mic", 0x0 },
6037 { "Front Mic", 0x1 },
6038 { "Line", 0x2 },
6039 { "CD", 0x4 },
6040 },
6041};
6042
17e7aec6 6043/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
a1e8d2da
JW
6044 * headphone jack and the internal CD lines since these are the only pins at
6045 * which audio can appear. For flexibility, also allow the option of
6046 * recording the mixer output on the second ADC (ADC0 doesn't have a
6047 * connection to the mixer output).
a9430dd8 6048 */
a9111321 6049static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
a1e8d2da
JW
6050 {
6051 .num_items = 3,
6052 .items = {
6053 { "Mic/Line", 0x0 },
6054 { "CD", 0x4 },
6055 { "Headphone", 0x2 },
6056 },
a9430dd8 6057 },
a1e8d2da
JW
6058 {
6059 .num_items = 4,
6060 .items = {
6061 { "Mic/Line", 0x0 },
6062 { "CD", 0x4 },
6063 { "Headphone", 0x2 },
6064 { "Mixer", 0x5 },
6065 },
6066 },
6067
a9430dd8
JW
6068};
6069
a1e8d2da
JW
6070/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6071 * the Fujitsu S702x, but jacks are marked differently.
0bfc90e9 6072 */
a9111321 6073static const struct hda_input_mux alc260_acer_capture_sources[2] = {
a1e8d2da
JW
6074 {
6075 .num_items = 4,
6076 .items = {
6077 { "Mic", 0x0 },
6078 { "Line", 0x2 },
6079 { "CD", 0x4 },
6080 { "Headphone", 0x5 },
6081 },
6082 },
6083 {
6084 .num_items = 5,
6085 .items = {
6086 { "Mic", 0x0 },
6087 { "Line", 0x2 },
6088 { "CD", 0x4 },
6089 { "Headphone", 0x6 },
6090 { "Mixer", 0x5 },
6091 },
0bfc90e9
JW
6092 },
6093};
cc959489
MS
6094
6095/* Maxdata Favorit 100XS */
a9111321 6096static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
cc959489
MS
6097 {
6098 .num_items = 2,
6099 .items = {
6100 { "Line/Mic", 0x0 },
6101 { "CD", 0x4 },
6102 },
6103 },
6104 {
6105 .num_items = 3,
6106 .items = {
6107 { "Line/Mic", 0x0 },
6108 { "CD", 0x4 },
6109 { "Mixer", 0x5 },
6110 },
6111 },
6112};
6113
1da177e4
LT
6114/*
6115 * This is just place-holder, so there's something for alc_build_pcms to look
6116 * at when it calculates the maximum number of channels. ALC260 has no mixer
6117 * element which allows changing the channel mode, so the verb list is
6118 * never used.
6119 */
a9111321 6120static const struct hda_channel_mode alc260_modes[1] = {
1da177e4
LT
6121 { 2, NULL },
6122};
6123
df694daa
KY
6124
6125/* Mixer combinations
6126 *
6127 * basic: base_output + input + pc_beep + capture
6128 * HP: base_output + input + capture_alt
6129 * HP_3013: hp_3013 + input + capture
6130 * fujitsu: fujitsu + capture
0bfc90e9 6131 * acer: acer + capture
df694daa
KY
6132 */
6133
a9111321 6134static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
05acb863 6135 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6136 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
05acb863 6137 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
985be54b 6138 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
05acb863 6139 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
985be54b 6140 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
1da177e4 6141 { } /* end */
f12ab1e0 6142};
1da177e4 6143
a9111321 6144static const struct snd_kcontrol_new alc260_input_mixer[] = {
16ded525
TI
6145 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6146 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6147 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6148 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6150 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6151 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6152 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
df694daa
KY
6153 { } /* end */
6154};
6155
bec15c3a 6156/* update HP, line and mono out pins according to the master switch */
e9427969 6157static void alc260_hp_master_update(struct hda_codec *codec)
bec15c3a
TI
6158{
6159 struct alc_spec *spec = codec->spec;
e9427969
TI
6160
6161 /* change HP pins */
6162 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
6163 spec->autocfg.hp_pins, spec->master_mute, true);
6164 update_speakers(codec);
bec15c3a
TI
6165}
6166
6167static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6168 struct snd_ctl_elem_value *ucontrol)
6169{
6170 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6171 struct alc_spec *spec = codec->spec;
e9427969 6172 *ucontrol->value.integer.value = !spec->master_mute;
bec15c3a
TI
6173 return 0;
6174}
6175
6176static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6177 struct snd_ctl_elem_value *ucontrol)
6178{
6179 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6180 struct alc_spec *spec = codec->spec;
e9427969 6181 int val = !*ucontrol->value.integer.value;
bec15c3a 6182
e9427969 6183 if (val == spec->master_mute)
bec15c3a 6184 return 0;
e9427969
TI
6185 spec->master_mute = val;
6186 alc260_hp_master_update(codec);
bec15c3a
TI
6187 return 1;
6188}
6189
a9111321 6190static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
bec15c3a
TI
6191 {
6192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6193 .name = "Master Playback Switch",
5b0cb1d8 6194 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6195 .info = snd_ctl_boolean_mono_info,
6196 .get = alc260_hp_master_sw_get,
6197 .put = alc260_hp_master_sw_put,
bec15c3a
TI
6198 },
6199 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6200 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6201 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6202 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6203 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6204 HDA_OUTPUT),
6205 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6206 { } /* end */
6207};
6208
a9111321 6209static const struct hda_verb alc260_hp_unsol_verbs[] = {
bec15c3a
TI
6210 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6211 {},
6212};
6213
e9427969 6214static void alc260_hp_setup(struct hda_codec *codec)
bec15c3a
TI
6215{
6216 struct alc_spec *spec = codec->spec;
bec15c3a 6217
e9427969
TI
6218 spec->autocfg.hp_pins[0] = 0x0f;
6219 spec->autocfg.speaker_pins[0] = 0x10;
6220 spec->autocfg.speaker_pins[1] = 0x11;
6221 spec->automute = 1;
6222 spec->automute_mode = ALC_AUTOMUTE_PIN;
bec15c3a
TI
6223}
6224
a9111321 6225static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
bec15c3a
TI
6226 {
6227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6228 .name = "Master Playback Switch",
5b0cb1d8 6229 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
bec15c3a
TI
6230 .info = snd_ctl_boolean_mono_info,
6231 .get = alc260_hp_master_sw_get,
6232 .put = alc260_hp_master_sw_put,
bec15c3a 6233 },
df694daa
KY
6234 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6235 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6236 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6237 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6238 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6239 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
86cd9298
TI
6240 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6241 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
16ded525
TI
6242 { } /* end */
6243};
6244
e9427969
TI
6245static void alc260_hp_3013_setup(struct hda_codec *codec)
6246{
6247 struct alc_spec *spec = codec->spec;
6248
6249 spec->autocfg.hp_pins[0] = 0x15;
6250 spec->autocfg.speaker_pins[0] = 0x10;
6251 spec->autocfg.speaker_pins[1] = 0x11;
6252 spec->automute = 1;
6253 spec->automute_mode = ALC_AUTOMUTE_PIN;
6254}
6255
a9111321 6256static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
3f878308
KY
6257 .ops = &snd_hda_bind_vol,
6258 .values = {
6259 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6260 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6261 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6262 0
6263 },
6264};
6265
a9111321 6266static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
3f878308
KY
6267 .ops = &snd_hda_bind_sw,
6268 .values = {
6269 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6270 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6271 0
6272 },
6273};
6274
a9111321 6275static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
3f878308
KY
6276 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6277 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6278 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6279 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6280 { } /* end */
6281};
6282
a9111321 6283static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
bec15c3a
TI
6284 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6285 {},
6286};
6287
e9427969 6288static void alc260_hp_3012_setup(struct hda_codec *codec)
bec15c3a
TI
6289{
6290 struct alc_spec *spec = codec->spec;
bec15c3a 6291
e9427969
TI
6292 spec->autocfg.hp_pins[0] = 0x10;
6293 spec->autocfg.speaker_pins[0] = 0x0f;
6294 spec->autocfg.speaker_pins[1] = 0x11;
6295 spec->autocfg.speaker_pins[2] = 0x15;
6296 spec->automute = 1;
6297 spec->automute_mode = ALC_AUTOMUTE_PIN;
3f878308
KY
6298}
6299
6300/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
a1e8d2da
JW
6301 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6302 */
a9111321 6303static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
a9430dd8 6304 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
985be54b 6305 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
4c5186ed 6306 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
a9430dd8
JW
6307 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6308 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6309 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6310 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
4c5186ed 6311 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
31bffaa9
TI
6312 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6313 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
df694daa
KY
6314 { } /* end */
6315};
6316
a1e8d2da
JW
6317/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6318 * versions of the ALC260 don't act on requests to enable mic bias from NID
6319 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6320 * datasheet doesn't mention this restriction. At this stage it's not clear
6321 * whether this behaviour is intentional or is a hardware bug in chip
6322 * revisions available in early 2006. Therefore for now allow the
6323 * "Headphone Jack Mode" control to span all choices, but if it turns out
6324 * that the lack of mic bias for this NID is intentional we could change the
6325 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6326 *
6327 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6328 * don't appear to make the mic bias available from the "line" jack, even
6329 * though the NID used for this jack (0x14) can supply it. The theory is
6330 * that perhaps Acer have included blocking capacitors between the ALC260
6331 * and the output jack. If this turns out to be the case for all such
6332 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6333 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
bd869485
JW
6334 *
6335 * The C20x Tablet series have a mono internal speaker which is controlled
6336 * via the chip's Mono sum widget and pin complex, so include the necessary
6337 * controls for such models. On models without a "mono speaker" the control
6338 * won't do anything.
a1e8d2da 6339 */
a9111321 6340static const struct snd_kcontrol_new alc260_acer_mixer[] = {
0bfc90e9
JW
6341 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6342 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
a1e8d2da 6343 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
31bffaa9 6344 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
bd869485 6345 HDA_OUTPUT),
31bffaa9 6346 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
bd869485 6347 HDA_INPUT),
0bfc90e9
JW
6348 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6349 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6351 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6352 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6353 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6354 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6355 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
0bfc90e9
JW
6356 { } /* end */
6357};
6358
cc959489
MS
6359/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6360 */
a9111321 6361static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
cc959489
MS
6362 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6363 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6364 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6365 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6366 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6367 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6368 { } /* end */
6369};
6370
bc9f98a9
KY
6371/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6372 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6373 */
a9111321 6374static const struct snd_kcontrol_new alc260_will_mixer[] = {
bc9f98a9
KY
6375 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6376 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6378 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6379 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6380 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6381 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6382 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6383 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6384 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
bc9f98a9
KY
6385 { } /* end */
6386};
6387
6388/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6389 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6390 */
a9111321 6391static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
bc9f98a9
KY
6392 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6393 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6395 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6396 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6397 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6398 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6399 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6400 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6401 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6402 { } /* end */
6403};
6404
df694daa
KY
6405/*
6406 * initialization verbs
6407 */
a9111321 6408static const struct hda_verb alc260_init_verbs[] = {
1da177e4 6409 /* Line In pin widget for input */
05acb863 6410 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6411 /* CD pin widget for input */
05acb863 6412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4 6413 /* Mic1 (rear panel) pin widget for input and vref at 80% */
16ded525 6414 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6415 /* Mic2 (front panel) pin widget for input and vref at 80% */
16ded525 6416 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1da177e4 6417 /* LINE-2 is used for line-out in rear */
05acb863 6418 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6419 /* select line-out */
fd56f2db 6420 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 6421 /* LINE-OUT pin */
05acb863 6422 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1da177e4 6423 /* enable HP */
05acb863 6424 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1da177e4 6425 /* enable Mono */
05acb863
TI
6426 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6427 /* mute capture amp left and right */
16ded525 6428 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4
LT
6429 /* set connection select to line in (default select for this ADC) */
6430 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
16ded525
TI
6431 /* mute capture amp left and right */
6432 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6433 /* set connection select to line in (default select for this ADC) */
6434 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
05acb863
TI
6435 /* set vol=0 Line-Out mixer amp left and right */
6436 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6437 /* unmute pin widget amp left and right (no gain on this amp) */
6438 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6439 /* set vol=0 HP mixer amp left and right */
6440 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6441 /* unmute pin widget amp left and right (no gain on this amp) */
6442 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6443 /* set vol=0 Mono mixer amp left and right */
6444 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6445 /* unmute pin widget amp left and right (no gain on this amp) */
6446 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6447 /* unmute LINE-2 out pin */
6448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f12ab1e0
TI
6449 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6450 * Line In 2 = 0x03
6451 */
cb53c626
TI
6452 /* mute analog inputs */
6453 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6454 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6455 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6456 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6457 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
1da177e4 6458 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
05acb863
TI
6459 /* mute Front out path */
6460 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6461 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6462 /* mute Headphone out path */
6463 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6464 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6465 /* mute Mono out path */
6466 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6467 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4
LT
6468 { }
6469};
6470
474167d6 6471#if 0 /* should be identical with alc260_init_verbs? */
a9111321 6472static const struct hda_verb alc260_hp_init_verbs[] = {
df694daa
KY
6473 /* Headphone and output */
6474 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6475 /* mono output */
6476 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6477 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6478 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6479 /* Mic2 (front panel) pin widget for input and vref at 80% */
6480 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6481 /* Line In pin widget for input */
6482 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6483 /* Line-2 pin widget for output */
6484 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6485 /* CD pin widget for input */
6486 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6487 /* unmute amp left and right */
6488 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6489 /* set connection select to line in (default select for this ADC) */
6490 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6491 /* unmute Line-Out mixer amp left and right (volume = 0) */
6492 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6493 /* mute pin widget amp left and right (no gain on this amp) */
6494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6495 /* unmute HP mixer amp left and right (volume = 0) */
6496 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6497 /* mute pin widget amp left and right (no gain on this amp) */
6498 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6499 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6500 * Line In 2 = 0x03
6501 */
cb53c626
TI
6502 /* mute analog inputs */
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6504 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6505 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6506 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6507 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6508 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6509 /* Unmute Front out path */
6510 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6511 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6512 /* Unmute Headphone out path */
6513 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6514 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6515 /* Unmute Mono out path */
6516 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6517 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6518 { }
6519};
474167d6 6520#endif
df694daa 6521
a9111321 6522static const struct hda_verb alc260_hp_3013_init_verbs[] = {
df694daa
KY
6523 /* Line out and output */
6524 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6525 /* mono output */
6526 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6527 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6528 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6529 /* Mic2 (front panel) pin widget for input and vref at 80% */
6530 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6531 /* Line In pin widget for input */
6532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6533 /* Headphone pin widget for output */
6534 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6535 /* CD pin widget for input */
6536 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6537 /* unmute amp left and right */
6538 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6539 /* set connection select to line in (default select for this ADC) */
6540 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6541 /* unmute Line-Out mixer amp left and right (volume = 0) */
6542 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6543 /* mute pin widget amp left and right (no gain on this amp) */
6544 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6545 /* unmute HP mixer amp left and right (volume = 0) */
6546 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6547 /* mute pin widget amp left and right (no gain on this amp) */
6548 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
f12ab1e0
TI
6549 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6550 * Line In 2 = 0x03
6551 */
cb53c626
TI
6552 /* mute analog inputs */
6553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6554 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6555 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6556 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6557 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
6558 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6559 /* Unmute Front out path */
6560 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6561 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6562 /* Unmute Headphone out path */
6563 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6564 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6565 /* Unmute Mono out path */
6566 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6567 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6568 { }
6569};
6570
a9430dd8 6571/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
a1e8d2da
JW
6572 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6573 * audio = 0x16, internal speaker = 0x10.
a9430dd8 6574 */
a9111321 6575static const struct hda_verb alc260_fujitsu_init_verbs[] = {
a9430dd8
JW
6576 /* Disable all GPIOs */
6577 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6578 /* Internal speaker is connected to headphone pin */
6579 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6580 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6581 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
f7ace40d
JW
6582 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6583 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6584 /* Ensure all other unused pins are disabled and muted. */
6585 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6586 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6587 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d 6588 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a9430dd8 6589 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
f7ace40d
JW
6590 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6593
6594 /* Disable digital (SPDIF) pins */
6595 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6596 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
a9430dd8 6597
ea1fb29a 6598 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
f7ace40d
JW
6599 * when acting as an output.
6600 */
6601 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
4c5186ed 6602
f7ace40d 6603 /* Start with output sum widgets muted and their output gains at min */
8b33a5aa
TI
6604 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6605 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6607 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6608 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6610 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6611 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a9430dd8 6613
f7ace40d
JW
6614 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6615 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6616 /* Unmute Line1 pin widget output buffer since it starts as an output.
6617 * If the pin mode is changed by the user the pin mode control will
6618 * take care of enabling the pin's input/output buffers as needed.
6619 * Therefore there's no need to enable the input buffer at this
6620 * stage.
cdcd9268 6621 */
f7ace40d 6622 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 6623 /* Unmute input buffer of pin widget used for Line-in (no equiv
cdcd9268
JW
6624 * mixer ctrl)
6625 */
f7ace40d
JW
6626 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6627
6628 /* Mute capture amp left and right */
6629 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 6630 /* Set ADC connection select to match default mixer setting - line
f7ace40d
JW
6631 * in (on mic1 pin)
6632 */
6633 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6634
6635 /* Do the same for the second ADC: mute capture input amp and
6636 * set ADC connection to line in (on mic1 pin)
6637 */
6638 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6640
6641 /* Mute all inputs to mixer widget (even unconnected ones) */
6642 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6643 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6644 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6645 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6646 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6647 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6648 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6649 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
4a471b7d
TI
6650
6651 { }
a9430dd8
JW
6652};
6653
0bfc90e9
JW
6654/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6655 * similar laptops (adapted from Fujitsu init verbs).
6656 */
a9111321 6657static const struct hda_verb alc260_acer_init_verbs[] = {
0bfc90e9
JW
6658 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6659 * the headphone jack. Turn this on and rely on the standard mute
6660 * methods whenever the user wants to turn these outputs off.
6661 */
6662 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6663 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6664 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6665 /* Internal speaker/Headphone jack is connected to Line-out pin */
6666 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6667 /* Internal microphone/Mic jack is connected to Mic1 pin */
6668 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6669 /* Line In jack is connected to Line1 pin */
6670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
bd869485
JW
6671 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6672 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
0bfc90e9
JW
6673 /* Ensure all other unused pins are disabled and muted. */
6674 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6675 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
0bfc90e9
JW
6676 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6677 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6678 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6679 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6680 /* Disable digital (SPDIF) pins */
6681 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6682 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6683
ea1fb29a 6684 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
0bfc90e9
JW
6685 * bus when acting as outputs.
6686 */
6687 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6688 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6689
6690 /* Start with output sum widgets muted and their output gains at min */
6691 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6692 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6693 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6694 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6695 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6696 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6697 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6698 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6699 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6700
f12ab1e0
TI
6701 /* Unmute Line-out pin widget amp left and right
6702 * (no equiv mixer ctrl)
6703 */
0bfc90e9 6704 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
bd869485
JW
6705 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6706 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
0bfc90e9
JW
6707 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6708 * inputs. If the pin mode is changed by the user the pin mode control
6709 * will take care of enabling the pin's input/output buffers as needed.
6710 * Therefore there's no need to enable the input buffer at this
6711 * stage.
6712 */
6713 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6715
6716 /* Mute capture amp left and right */
6717 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6718 /* Set ADC connection select to match default mixer setting - mic
6719 * (on mic1 pin)
6720 */
6721 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6722
6723 /* Do similar with the second ADC: mute capture input amp and
a1e8d2da 6724 * set ADC connection to mic to match ALSA's default state.
0bfc90e9
JW
6725 */
6726 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
a1e8d2da 6727 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
0bfc90e9
JW
6728
6729 /* Mute all inputs to mixer widget (even unconnected ones) */
6730 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6731 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6732 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6733 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6734 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6735 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6736 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6737 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6738
6739 { }
6740};
6741
cc959489
MS
6742/* Initialisation sequence for Maxdata Favorit 100XS
6743 * (adapted from Acer init verbs).
6744 */
a9111321 6745static const struct hda_verb alc260_favorit100_init_verbs[] = {
cc959489
MS
6746 /* GPIO 0 enables the output jack.
6747 * Turn this on and rely on the standard mute
6748 * methods whenever the user wants to turn these outputs off.
6749 */
6750 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6751 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6752 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6753 /* Line/Mic input jack is connected to Mic1 pin */
6754 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6755 /* Ensure all other unused pins are disabled and muted. */
6756 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6757 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6759 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6760 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6761 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6762 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6764 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6765 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6766 /* Disable digital (SPDIF) pins */
6767 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6768 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6769
6770 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6771 * bus when acting as outputs.
6772 */
6773 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6774 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6775
6776 /* Start with output sum widgets muted and their output gains at min */
6777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6778 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6779 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6781 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6782 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6783 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6785 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6786
6787 /* Unmute Line-out pin widget amp left and right
6788 * (no equiv mixer ctrl)
6789 */
6790 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6791 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6792 * inputs. If the pin mode is changed by the user the pin mode control
6793 * will take care of enabling the pin's input/output buffers as needed.
6794 * Therefore there's no need to enable the input buffer at this
6795 * stage.
6796 */
6797 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6798
6799 /* Mute capture amp left and right */
6800 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6801 /* Set ADC connection select to match default mixer setting - mic
6802 * (on mic1 pin)
6803 */
6804 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6805
6806 /* Do similar with the second ADC: mute capture input amp and
6807 * set ADC connection to mic to match ALSA's default state.
6808 */
6809 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6811
6812 /* Mute all inputs to mixer widget (even unconnected ones) */
6813 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6814 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6817 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6819 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6820 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6821
6822 { }
6823};
6824
a9111321 6825static const struct hda_verb alc260_will_verbs[] = {
bc9f98a9
KY
6826 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6827 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6828 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6829 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6830 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6831 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6832 {}
6833};
6834
a9111321 6835static const struct hda_verb alc260_replacer_672v_verbs[] = {
bc9f98a9
KY
6836 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6837 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6838 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6839
6840 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6841 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6842 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6843
6844 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6845 {}
6846};
6847
6848/* toggle speaker-output according to the hp-jack state */
6849static void alc260_replacer_672v_automute(struct hda_codec *codec)
6850{
6851 unsigned int present;
6852
6853 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
864f92be 6854 present = snd_hda_jack_detect(codec, 0x0f);
bc9f98a9 6855 if (present) {
82beb8fd
TI
6856 snd_hda_codec_write_cache(codec, 0x01, 0,
6857 AC_VERB_SET_GPIO_DATA, 1);
6858 snd_hda_codec_write_cache(codec, 0x0f, 0,
6859 AC_VERB_SET_PIN_WIDGET_CONTROL,
6860 PIN_HP);
bc9f98a9 6861 } else {
82beb8fd
TI
6862 snd_hda_codec_write_cache(codec, 0x01, 0,
6863 AC_VERB_SET_GPIO_DATA, 0);
6864 snd_hda_codec_write_cache(codec, 0x0f, 0,
6865 AC_VERB_SET_PIN_WIDGET_CONTROL,
6866 PIN_OUT);
bc9f98a9
KY
6867 }
6868}
6869
6870static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6871 unsigned int res)
6872{
6873 if ((res >> 26) == ALC880_HP_EVENT)
6874 alc260_replacer_672v_automute(codec);
6875}
6876
a9111321 6877static const struct hda_verb alc260_hp_dc7600_verbs[] = {
3f878308
KY
6878 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6879 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6880 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6881 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6882 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6883 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6884 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6885 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6886 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6887 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6888 {}
6889};
6890
7cf51e48
JW
6891/* Test configuration for debugging, modelled after the ALC880 test
6892 * configuration.
6893 */
6894#ifdef CONFIG_SND_DEBUG
4c6d72d1 6895static const hda_nid_t alc260_test_dac_nids[1] = {
7cf51e48
JW
6896 0x02,
6897};
4c6d72d1 6898static const hda_nid_t alc260_test_adc_nids[2] = {
7cf51e48
JW
6899 0x04, 0x05,
6900};
a1e8d2da 6901/* For testing the ALC260, each input MUX needs its own definition since
ea1fb29a 6902 * the signal assignments are different. This assumes that the first ADC
a1e8d2da 6903 * is NID 0x04.
17e7aec6 6904 */
a9111321 6905static const struct hda_input_mux alc260_test_capture_sources[2] = {
a1e8d2da
JW
6906 {
6907 .num_items = 7,
6908 .items = {
6909 { "MIC1 pin", 0x0 },
6910 { "MIC2 pin", 0x1 },
6911 { "LINE1 pin", 0x2 },
6912 { "LINE2 pin", 0x3 },
6913 { "CD pin", 0x4 },
6914 { "LINE-OUT pin", 0x5 },
6915 { "HP-OUT pin", 0x6 },
6916 },
6917 },
6918 {
6919 .num_items = 8,
6920 .items = {
6921 { "MIC1 pin", 0x0 },
6922 { "MIC2 pin", 0x1 },
6923 { "LINE1 pin", 0x2 },
6924 { "LINE2 pin", 0x3 },
6925 { "CD pin", 0x4 },
6926 { "Mixer", 0x5 },
6927 { "LINE-OUT pin", 0x6 },
6928 { "HP-OUT pin", 0x7 },
6929 },
7cf51e48
JW
6930 },
6931};
a9111321 6932static const struct snd_kcontrol_new alc260_test_mixer[] = {
7cf51e48
JW
6933 /* Output driver widgets */
6934 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6935 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6936 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6937 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6938 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6939 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6940
a1e8d2da
JW
6941 /* Modes for retasking pin widgets
6942 * Note: the ALC260 doesn't seem to act on requests to enable mic
6943 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6944 * mention this restriction. At this stage it's not clear whether
6945 * this behaviour is intentional or is a hardware bug in chip
6946 * revisions available at least up until early 2006. Therefore for
6947 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6948 * choices, but if it turns out that the lack of mic bias for these
6949 * NIDs is intentional we could change their modes from
6950 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6951 */
7cf51e48
JW
6952 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6953 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6954 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6955 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6956 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6957 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6958
6959 /* Loopback mixer controls */
6960 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6961 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6962 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6963 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6964 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6965 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6966 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6967 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6968 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6969 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7cf51e48
JW
6970 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6971 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6972 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6973 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
5c8f858d
JW
6974
6975 /* Controls for GPIO pins, assuming they are configured as outputs */
6976 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6977 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6978 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6979 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6980
92621f13
JW
6981 /* Switches to allow the digital IO pins to be enabled. The datasheet
6982 * is ambigious as to which NID is which; testing on laptops which
ea1fb29a 6983 * make this output available should provide clarification.
92621f13
JW
6984 */
6985 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6986 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6987
f8225f6d
JW
6988 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6989 * this output to turn on an external amplifier.
6990 */
6991 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6992 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6993
7cf51e48
JW
6994 { } /* end */
6995};
a9111321 6996static const struct hda_verb alc260_test_init_verbs[] = {
5c8f858d
JW
6997 /* Enable all GPIOs as outputs with an initial value of 0 */
6998 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6999 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7000 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7001
7cf51e48
JW
7002 /* Enable retasking pins as output, initially without power amp */
7003 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7004 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7005 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7007 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7008 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7009
92621f13
JW
7010 /* Disable digital (SPDIF) pins initially, but users can enable
7011 * them via a mixer switch. In the case of SPDIF-out, this initverb
7012 * payload also sets the generation to 0, output to be in "consumer"
7013 * PCM format, copyright asserted, no pre-emphasis and no validity
7014 * control.
7015 */
7cf51e48
JW
7016 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7017 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7018
ea1fb29a 7019 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7cf51e48
JW
7020 * OUT1 sum bus when acting as an output.
7021 */
7022 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7023 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7024 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7025 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7026
7027 /* Start with output sum widgets muted and their output gains at min */
7028 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7029 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7030 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7031 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7032 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7033 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7034 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7035 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7036 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7037
cdcd9268
JW
7038 /* Unmute retasking pin widget output buffers since the default
7039 * state appears to be output. As the pin mode is changed by the
7040 * user the pin mode control will take care of enabling the pin's
7041 * input/output buffers as needed.
7042 */
7cf51e48
JW
7043 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7044 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7045 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7046 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7047 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7048 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7049 /* Also unmute the mono-out pin widget */
7050 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7051
7cf51e48
JW
7052 /* Mute capture amp left and right */
7053 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
f7ace40d
JW
7054 /* Set ADC connection select to match default mixer setting (mic1
7055 * pin)
7cf51e48
JW
7056 */
7057 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7058
7059 /* Do the same for the second ADC: mute capture input amp and
f7ace40d 7060 * set ADC connection to mic1 pin
7cf51e48
JW
7061 */
7062 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7063 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7064
7065 /* Mute all inputs to mixer widget (even unconnected ones) */
7066 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7067 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7068 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7069 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7070 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7071 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7072 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7074
7075 { }
7076};
7077#endif
7078
6330079f
TI
7079#define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7080#define alc260_pcm_analog_capture alc880_pcm_analog_capture
1da177e4 7081
a3bcba38
TI
7082#define alc260_pcm_digital_playback alc880_pcm_digital_playback
7083#define alc260_pcm_digital_capture alc880_pcm_digital_capture
7084
df694daa
KY
7085/*
7086 * for BIOS auto-configuration
7087 */
16ded525 7088
df694daa 7089static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
863b4518 7090 const char *pfx, int *vol_bits)
df694daa
KY
7091{
7092 hda_nid_t nid_vol;
7093 unsigned long vol_val, sw_val;
df694daa
KY
7094 int err;
7095
7096 if (nid >= 0x0f && nid < 0x11) {
7097 nid_vol = nid - 0x7;
7098 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7099 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7100 } else if (nid == 0x11) {
7101 nid_vol = nid - 0x7;
7102 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7103 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7104 } else if (nid >= 0x12 && nid <= 0x15) {
7105 nid_vol = 0x08;
7106 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7107 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7108 } else
7109 return 0; /* N/A */
ea1fb29a 7110
863b4518
TI
7111 if (!(*vol_bits & (1 << nid_vol))) {
7112 /* first control for the volume widget */
0afe5f89 7113 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
863b4518
TI
7114 if (err < 0)
7115 return err;
7116 *vol_bits |= (1 << nid_vol);
7117 }
0afe5f89 7118 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
f12ab1e0 7119 if (err < 0)
df694daa
KY
7120 return err;
7121 return 1;
7122}
7123
7124/* add playback controls from the parsed DAC table */
7125static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7126 const struct auto_pin_cfg *cfg)
7127{
7128 hda_nid_t nid;
7129 int err;
863b4518 7130 int vols = 0;
df694daa
KY
7131
7132 spec->multiout.num_dacs = 1;
7133 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 7134 spec->private_dac_nids[0] = 0x02;
df694daa
KY
7135
7136 nid = cfg->line_out_pins[0];
7137 if (nid) {
23112d6d
TI
7138 const char *pfx;
7139 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7140 pfx = "Master";
7141 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7142 pfx = "Speaker";
7143 else
7144 pfx = "Front";
7145 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
df694daa
KY
7146 if (err < 0)
7147 return err;
7148 }
7149
82bc955f 7150 nid = cfg->speaker_pins[0];
df694daa 7151 if (nid) {
863b4518 7152 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
df694daa
KY
7153 if (err < 0)
7154 return err;
7155 }
7156
eb06ed8f 7157 nid = cfg->hp_pins[0];
df694daa 7158 if (nid) {
863b4518
TI
7159 err = alc260_add_playback_controls(spec, nid, "Headphone",
7160 &vols);
df694daa
KY
7161 if (err < 0)
7162 return err;
7163 }
f12ab1e0 7164 return 0;
df694daa
KY
7165}
7166
7167/* create playback/capture controls for input pins */
05f5f477 7168static int alc260_auto_create_input_ctls(struct hda_codec *codec,
df694daa
KY
7169 const struct auto_pin_cfg *cfg)
7170{
05f5f477 7171 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
df694daa
KY
7172}
7173
7174static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7175 hda_nid_t nid, int pin_type,
7176 int sel_idx)
7177{
f6c7e546 7178 alc_set_pin_output(codec, nid, pin_type);
df694daa
KY
7179 /* need the manual connection? */
7180 if (nid >= 0x12) {
7181 int idx = nid - 0x12;
7182 snd_hda_codec_write(codec, idx + 0x0b, 0,
7183 AC_VERB_SET_CONNECT_SEL, sel_idx);
df694daa
KY
7184 }
7185}
7186
7187static void alc260_auto_init_multi_out(struct hda_codec *codec)
7188{
7189 struct alc_spec *spec = codec->spec;
7190 hda_nid_t nid;
7191
f12ab1e0 7192 nid = spec->autocfg.line_out_pins[0];
baba8ee9
TI
7193 if (nid) {
7194 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7195 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7196 }
ea1fb29a 7197
82bc955f 7198 nid = spec->autocfg.speaker_pins[0];
df694daa
KY
7199 if (nid)
7200 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7201
eb06ed8f 7202 nid = spec->autocfg.hp_pins[0];
df694daa 7203 if (nid)
baba8ee9 7204 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
f12ab1e0 7205}
df694daa
KY
7206
7207#define ALC260_PIN_CD_NID 0x16
7208static void alc260_auto_init_analog_input(struct hda_codec *codec)
7209{
7210 struct alc_spec *spec = codec->spec;
66ceeb6b 7211 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
7212 int i;
7213
66ceeb6b
TI
7214 for (i = 0; i < cfg->num_inputs; i++) {
7215 hda_nid_t nid = cfg->inputs[i].pin;
df694daa 7216 if (nid >= 0x12) {
30ea098f 7217 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
7218 if (nid != ALC260_PIN_CD_NID &&
7219 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f12ab1e0
TI
7220 snd_hda_codec_write(codec, nid, 0,
7221 AC_VERB_SET_AMP_GAIN_MUTE,
df694daa
KY
7222 AMP_OUT_MUTE);
7223 }
7224 }
7225}
7226
7f311a46
TI
7227#define alc260_auto_init_input_src alc880_auto_init_input_src
7228
df694daa
KY
7229/*
7230 * generic initialization of ADC, input mixers and output mixers
7231 */
a9111321 7232static const struct hda_verb alc260_volume_init_verbs[] = {
df694daa
KY
7233 /*
7234 * Unmute ADC0-1 and set the default input to mic-in
7235 */
7236 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7237 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7238 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7239 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 7240
df694daa
KY
7241 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7242 * mixer widget
f12ab1e0
TI
7243 * Note: PASD motherboards uses the Line In 2 as the input for
7244 * front panel mic (mic 2)
df694daa
KY
7245 */
7246 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
7247 /* mute analog inputs */
7248 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7249 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7250 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7251 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7252 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
7253
7254 /*
7255 * Set up output mixers (0x08 - 0x0a)
7256 */
7257 /* set vol=0 to output mixers */
7258 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7259 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7260 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7261 /* set up input amps for analog loopback */
7262 /* Amp Indices: DAC = 0, mixer = 1 */
7263 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7264 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7265 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7266 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7267 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7268 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 7269
df694daa
KY
7270 { }
7271};
7272
7273static int alc260_parse_auto_config(struct hda_codec *codec)
7274{
7275 struct alc_spec *spec = codec->spec;
df694daa 7276 int err;
4c6d72d1 7277 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
df694daa 7278
f12ab1e0
TI
7279 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7280 alc260_ignore);
7281 if (err < 0)
df694daa 7282 return err;
f12ab1e0
TI
7283 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7284 if (err < 0)
4a471b7d 7285 return err;
603c4019 7286 if (!spec->kctls.list)
df694daa 7287 return 0; /* can't find valid BIOS pin config */
05f5f477 7288 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 7289 if (err < 0)
df694daa
KY
7290 return err;
7291
7292 spec->multiout.max_channels = 2;
7293
0852d7a6 7294 if (spec->autocfg.dig_outs)
df694daa 7295 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
603c4019 7296 if (spec->kctls.list)
d88897ea 7297 add_mixer(spec, spec->kctls.list);
df694daa 7298
d88897ea 7299 add_verb(spec, alc260_volume_init_verbs);
df694daa 7300
a1e8d2da 7301 spec->num_mux_defs = 1;
61b9b9b1 7302 spec->input_mux = &spec->private_imux[0];
df694daa 7303
6227cdce 7304 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
4a79ba34 7305
df694daa
KY
7306 return 1;
7307}
7308
ae6b813a
TI
7309/* additional initialization for auto-configuration model */
7310static void alc260_auto_init(struct hda_codec *codec)
df694daa 7311{
f6c7e546 7312 struct alc_spec *spec = codec->spec;
df694daa
KY
7313 alc260_auto_init_multi_out(codec);
7314 alc260_auto_init_analog_input(codec);
7f311a46 7315 alc260_auto_init_input_src(codec);
757899ac 7316 alc_auto_init_digital(codec);
f6c7e546 7317 if (spec->unsol_event)
7fb0d78f 7318 alc_inithook(codec);
df694daa
KY
7319}
7320
cb53c626 7321#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 7322static const struct hda_amp_list alc260_loopbacks[] = {
cb53c626
TI
7323 { 0x07, HDA_INPUT, 0 },
7324 { 0x07, HDA_INPUT, 1 },
7325 { 0x07, HDA_INPUT, 2 },
7326 { 0x07, HDA_INPUT, 3 },
7327 { 0x07, HDA_INPUT, 4 },
7328 { } /* end */
7329};
7330#endif
7331
fc091769
TI
7332/*
7333 * Pin config fixes
7334 */
7335enum {
7336 PINFIX_HP_DC5750,
7337};
7338
fc091769
TI
7339static const struct alc_fixup alc260_fixups[] = {
7340 [PINFIX_HP_DC5750] = {
b5bfbc67
TI
7341 .type = ALC_FIXUP_PINS,
7342 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
7343 { 0x11, 0x90130110 }, /* speaker */
7344 { }
7345 }
fc091769
TI
7346 },
7347};
7348
a9111321 7349static const struct snd_pci_quirk alc260_fixup_tbl[] = {
fc091769
TI
7350 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7351 {}
7352};
7353
df694daa
KY
7354/*
7355 * ALC260 configurations
7356 */
ea734963 7357static const char * const alc260_models[ALC260_MODEL_LAST] = {
f5fcc13c
TI
7358 [ALC260_BASIC] = "basic",
7359 [ALC260_HP] = "hp",
7360 [ALC260_HP_3013] = "hp-3013",
2922c9af 7361 [ALC260_HP_DC7600] = "hp-dc7600",
f5fcc13c
TI
7362 [ALC260_FUJITSU_S702X] = "fujitsu",
7363 [ALC260_ACER] = "acer",
bc9f98a9
KY
7364 [ALC260_WILL] = "will",
7365 [ALC260_REPLACER_672V] = "replacer",
cc959489 7366 [ALC260_FAVORIT100] = "favorit100",
7cf51e48 7367#ifdef CONFIG_SND_DEBUG
f5fcc13c 7368 [ALC260_TEST] = "test",
7cf51e48 7369#endif
f5fcc13c
TI
7370 [ALC260_AUTO] = "auto",
7371};
7372
a9111321 7373static const struct snd_pci_quirk alc260_cfg_tbl[] = {
bd869485 7374 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
950200e2 7375 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
f5fcc13c 7376 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
cc959489 7377 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
9720b718 7378 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
4ac55982 7379 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
f5fcc13c 7380 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
34ec8a0a 7381 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
3f878308 7382 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
f5fcc13c
TI
7383 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7384 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7385 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7386 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7387 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7388 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7389 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7390 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7391 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
bc9f98a9 7392 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
ac3e3741 7393 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
df694daa
KY
7394 {}
7395};
7396
a9111321 7397static const struct alc_config_preset alc260_presets[] = {
df694daa
KY
7398 [ALC260_BASIC] = {
7399 .mixers = { alc260_base_output_mixer,
45bdd1c1 7400 alc260_input_mixer },
df694daa
KY
7401 .init_verbs = { alc260_init_verbs },
7402 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7403 .dac_nids = alc260_dac_nids,
f9e336f6 7404 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
9c4cc0bd 7405 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7406 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7407 .channel_mode = alc260_modes,
7408 .input_mux = &alc260_capture_source,
7409 },
7410 [ALC260_HP] = {
bec15c3a 7411 .mixers = { alc260_hp_output_mixer,
f9e336f6 7412 alc260_input_mixer },
bec15c3a
TI
7413 .init_verbs = { alc260_init_verbs,
7414 alc260_hp_unsol_verbs },
df694daa
KY
7415 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7416 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7417 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7418 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7419 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7420 .channel_mode = alc260_modes,
7421 .input_mux = &alc260_capture_source,
e9427969
TI
7422 .unsol_event = alc_sku_unsol_event,
7423 .setup = alc260_hp_setup,
7424 .init_hook = alc_inithook,
df694daa 7425 },
3f878308
KY
7426 [ALC260_HP_DC7600] = {
7427 .mixers = { alc260_hp_dc7600_mixer,
f9e336f6 7428 alc260_input_mixer },
3f878308
KY
7429 .init_verbs = { alc260_init_verbs,
7430 alc260_hp_dc7600_verbs },
7431 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7432 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7433 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7434 .adc_nids = alc260_adc_nids_alt,
3f878308
KY
7435 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7436 .channel_mode = alc260_modes,
7437 .input_mux = &alc260_capture_source,
e9427969
TI
7438 .unsol_event = alc_sku_unsol_event,
7439 .setup = alc260_hp_3012_setup,
7440 .init_hook = alc_inithook,
3f878308 7441 },
df694daa
KY
7442 [ALC260_HP_3013] = {
7443 .mixers = { alc260_hp_3013_mixer,
f9e336f6 7444 alc260_input_mixer },
bec15c3a
TI
7445 .init_verbs = { alc260_hp_3013_init_verbs,
7446 alc260_hp_3013_unsol_verbs },
df694daa
KY
7447 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7448 .dac_nids = alc260_dac_nids,
f9e336f6
TI
7449 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7450 .adc_nids = alc260_adc_nids_alt,
df694daa
KY
7451 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7452 .channel_mode = alc260_modes,
7453 .input_mux = &alc260_capture_source,
e9427969
TI
7454 .unsol_event = alc_sku_unsol_event,
7455 .setup = alc260_hp_3013_setup,
7456 .init_hook = alc_inithook,
df694daa
KY
7457 },
7458 [ALC260_FUJITSU_S702X] = {
f9e336f6 7459 .mixers = { alc260_fujitsu_mixer },
df694daa
KY
7460 .init_verbs = { alc260_fujitsu_init_verbs },
7461 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462 .dac_nids = alc260_dac_nids,
d57fdac0
JW
7463 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7464 .adc_nids = alc260_dual_adc_nids,
df694daa
KY
7465 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7466 .channel_mode = alc260_modes,
a1e8d2da
JW
7467 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7468 .input_mux = alc260_fujitsu_capture_sources,
df694daa 7469 },
0bfc90e9 7470 [ALC260_ACER] = {
f9e336f6 7471 .mixers = { alc260_acer_mixer },
0bfc90e9
JW
7472 .init_verbs = { alc260_acer_init_verbs },
7473 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7474 .dac_nids = alc260_dac_nids,
7475 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7476 .adc_nids = alc260_dual_adc_nids,
7477 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7478 .channel_mode = alc260_modes,
a1e8d2da
JW
7479 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7480 .input_mux = alc260_acer_capture_sources,
0bfc90e9 7481 },
cc959489
MS
7482 [ALC260_FAVORIT100] = {
7483 .mixers = { alc260_favorit100_mixer },
7484 .init_verbs = { alc260_favorit100_init_verbs },
7485 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7486 .dac_nids = alc260_dac_nids,
7487 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7488 .adc_nids = alc260_dual_adc_nids,
7489 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7490 .channel_mode = alc260_modes,
7491 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7492 .input_mux = alc260_favorit100_capture_sources,
7493 },
bc9f98a9 7494 [ALC260_WILL] = {
f9e336f6 7495 .mixers = { alc260_will_mixer },
bc9f98a9
KY
7496 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7497 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7498 .dac_nids = alc260_dac_nids,
7499 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7500 .adc_nids = alc260_adc_nids,
7501 .dig_out_nid = ALC260_DIGOUT_NID,
7502 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7503 .channel_mode = alc260_modes,
7504 .input_mux = &alc260_capture_source,
7505 },
7506 [ALC260_REPLACER_672V] = {
f9e336f6 7507 .mixers = { alc260_replacer_672v_mixer },
bc9f98a9
KY
7508 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7509 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7510 .dac_nids = alc260_dac_nids,
7511 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7512 .adc_nids = alc260_adc_nids,
7513 .dig_out_nid = ALC260_DIGOUT_NID,
7514 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7515 .channel_mode = alc260_modes,
7516 .input_mux = &alc260_capture_source,
7517 .unsol_event = alc260_replacer_672v_unsol_event,
7518 .init_hook = alc260_replacer_672v_automute,
7519 },
7cf51e48
JW
7520#ifdef CONFIG_SND_DEBUG
7521 [ALC260_TEST] = {
f9e336f6 7522 .mixers = { alc260_test_mixer },
7cf51e48
JW
7523 .init_verbs = { alc260_test_init_verbs },
7524 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7525 .dac_nids = alc260_test_dac_nids,
7526 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7527 .adc_nids = alc260_test_adc_nids,
7528 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7529 .channel_mode = alc260_modes,
a1e8d2da
JW
7530 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7531 .input_mux = alc260_test_capture_sources,
7cf51e48
JW
7532 },
7533#endif
df694daa
KY
7534};
7535
7536static int patch_alc260(struct hda_codec *codec)
1da177e4
LT
7537{
7538 struct alc_spec *spec;
df694daa 7539 int err, board_config;
1da177e4 7540
e560d8d8 7541 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1da177e4
LT
7542 if (spec == NULL)
7543 return -ENOMEM;
7544
7545 codec->spec = spec;
7546
f5fcc13c
TI
7547 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7548 alc260_models,
7549 alc260_cfg_tbl);
7550 if (board_config < 0) {
9a11f1aa 7551 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6c627f39 7552 codec->chip_name);
df694daa 7553 board_config = ALC260_AUTO;
16ded525 7554 }
1da177e4 7555
b5bfbc67
TI
7556 if (board_config == ALC260_AUTO) {
7557 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7558 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7559 }
fc091769 7560
df694daa
KY
7561 if (board_config == ALC260_AUTO) {
7562 /* automatic parse from the BIOS config */
7563 err = alc260_parse_auto_config(codec);
7564 if (err < 0) {
7565 alc_free(codec);
7566 return err;
f12ab1e0 7567 } else if (!err) {
9c7f852e
TI
7568 printk(KERN_INFO
7569 "hda_codec: Cannot set up configuration "
7570 "from BIOS. Using base mode...\n");
df694daa
KY
7571 board_config = ALC260_BASIC;
7572 }
a9430dd8 7573 }
e9edcee0 7574
680cd536
KK
7575 err = snd_hda_attach_beep_device(codec, 0x1);
7576 if (err < 0) {
7577 alc_free(codec);
7578 return err;
7579 }
7580
df694daa 7581 if (board_config != ALC260_AUTO)
e9c364c0 7582 setup_preset(codec, &alc260_presets[board_config]);
1da177e4 7583
1da177e4
LT
7584 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7585 spec->stream_analog_capture = &alc260_pcm_analog_capture;
53bacfbb 7586 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
1da177e4 7587
a3bcba38
TI
7588 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7589 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7590
4ef0ef19
TI
7591 if (!spec->adc_nids && spec->input_mux) {
7592 /* check whether NID 0x04 is valid */
7593 unsigned int wcap = get_wcaps(codec, 0x04);
a22d543a 7594 wcap = get_wcaps_type(wcap);
4ef0ef19
TI
7595 /* get type */
7596 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7597 spec->adc_nids = alc260_adc_nids_alt;
7598 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7599 } else {
7600 spec->adc_nids = alc260_adc_nids;
7601 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7602 }
7603 }
b59bdf3b 7604 set_capture_mixer(codec);
45bdd1c1 7605 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
f9e336f6 7606
b5bfbc67 7607 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
fc091769 7608
2134ea4f
TI
7609 spec->vmaster_nid = 0x08;
7610
1da177e4 7611 codec->patch_ops = alc_patch_ops;
df694daa 7612 if (board_config == ALC260_AUTO)
ae6b813a 7613 spec->init_hook = alc260_auto_init;
1c716153 7614 spec->shutup = alc_eapd_shutup;
cb53c626
TI
7615#ifdef CONFIG_SND_HDA_POWER_SAVE
7616 if (!spec->loopback.amplist)
7617 spec->loopback.amplist = alc260_loopbacks;
7618#endif
1da177e4
LT
7619
7620 return 0;
7621}
7622
e9edcee0 7623
1da177e4 7624/*
4953550a 7625 * ALC882/883/885/888/889 support
1da177e4
LT
7626 *
7627 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7628 * configuration. Each pin widget can choose any input DACs and a mixer.
7629 * Each ADC is connected from a mixer of all inputs. This makes possible
7630 * 6-channel independent captures.
7631 *
7632 * In addition, an independent DAC for the multi-playback (not used in this
7633 * driver yet).
7634 */
df694daa
KY
7635#define ALC882_DIGOUT_NID 0x06
7636#define ALC882_DIGIN_NID 0x0a
4953550a
TI
7637#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7638#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7639#define ALC1200_DIGOUT_NID 0x10
7640
1da177e4 7641
a9111321 7642static const struct hda_channel_mode alc882_ch_modes[1] = {
1da177e4
LT
7643 { 8, NULL }
7644};
7645
4953550a 7646/* DACs */
4c6d72d1 7647static const hda_nid_t alc882_dac_nids[4] = {
1da177e4
LT
7648 /* front, rear, clfe, rear_surr */
7649 0x02, 0x03, 0x04, 0x05
7650};
4953550a 7651#define alc883_dac_nids alc882_dac_nids
1da177e4 7652
4953550a 7653/* ADCs */
df694daa
KY
7654#define alc882_adc_nids alc880_adc_nids
7655#define alc882_adc_nids_alt alc880_adc_nids_alt
4953550a 7656#define alc883_adc_nids alc882_adc_nids_alt
4c6d72d1
TI
7657static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7658static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
4953550a 7659#define alc889_adc_nids alc880_adc_nids
1da177e4 7660
4c6d72d1
TI
7661static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7662static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
4953550a 7663#define alc883_capsrc_nids alc882_capsrc_nids_alt
4c6d72d1 7664static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
4953550a 7665#define alc889_capsrc_nids alc882_capsrc_nids
e1406348 7666
1da177e4
LT
7667/* input MUX */
7668/* FIXME: should be a matrix-type input source selection */
7669
a9111321 7670static const struct hda_input_mux alc882_capture_source = {
1da177e4
LT
7671 .num_items = 4,
7672 .items = {
7673 { "Mic", 0x0 },
7674 { "Front Mic", 0x1 },
7675 { "Line", 0x2 },
7676 { "CD", 0x4 },
7677 },
7678};
41d5545d 7679
4953550a
TI
7680#define alc883_capture_source alc882_capture_source
7681
a9111321 7682static const struct hda_input_mux alc889_capture_source = {
87a8c370
JK
7683 .num_items = 3,
7684 .items = {
7685 { "Front Mic", 0x0 },
7686 { "Mic", 0x3 },
7687 { "Line", 0x2 },
7688 },
7689};
7690
a9111321 7691static const struct hda_input_mux mb5_capture_source = {
41d5545d
KS
7692 .num_items = 3,
7693 .items = {
7694 { "Mic", 0x1 },
b8f171e7 7695 { "Line", 0x7 },
41d5545d
KS
7696 { "CD", 0x4 },
7697 },
7698};
7699
a9111321 7700static const struct hda_input_mux macmini3_capture_source = {
e458b1fa
LY
7701 .num_items = 2,
7702 .items = {
7703 { "Line", 0x2 },
7704 { "CD", 0x4 },
7705 },
7706};
7707
a9111321 7708static const struct hda_input_mux alc883_3stack_6ch_intel = {
4953550a
TI
7709 .num_items = 4,
7710 .items = {
7711 { "Mic", 0x1 },
7712 { "Front Mic", 0x0 },
7713 { "Line", 0x2 },
7714 { "CD", 0x4 },
7715 },
7716};
7717
a9111321 7718static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
4953550a
TI
7719 .num_items = 2,
7720 .items = {
7721 { "Mic", 0x1 },
7722 { "Line", 0x2 },
7723 },
7724};
7725
a9111321 7726static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
4953550a
TI
7727 .num_items = 4,
7728 .items = {
7729 { "Mic", 0x0 },
28c4edb7 7730 { "Internal Mic", 0x1 },
4953550a
TI
7731 { "Line", 0x2 },
7732 { "CD", 0x4 },
7733 },
7734};
7735
a9111321 7736static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
4953550a
TI
7737 .num_items = 2,
7738 .items = {
7739 { "Mic", 0x0 },
28c4edb7 7740 { "Internal Mic", 0x1 },
4953550a
TI
7741 },
7742};
7743
a9111321 7744static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
4953550a
TI
7745 .num_items = 3,
7746 .items = {
7747 { "Mic", 0x0 },
7748 { "Front Mic", 0x1 },
7749 { "Line", 0x4 },
7750 },
7751};
7752
a9111321 7753static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
4953550a
TI
7754 .num_items = 2,
7755 .items = {
7756 { "Mic", 0x0 },
7757 { "Line", 0x2 },
7758 },
7759};
7760
a9111321 7761static const struct hda_input_mux alc889A_mb31_capture_source = {
4953550a
TI
7762 .num_items = 2,
7763 .items = {
7764 { "Mic", 0x0 },
7765 /* Front Mic (0x01) unused */
7766 { "Line", 0x2 },
7767 /* Line 2 (0x03) unused */
af901ca1 7768 /* CD (0x04) unused? */
4953550a
TI
7769 },
7770};
7771
a9111321 7772static const struct hda_input_mux alc889A_imac91_capture_source = {
b7cccc52
JM
7773 .num_items = 2,
7774 .items = {
7775 { "Mic", 0x01 },
7776 { "Line", 0x2 }, /* Not sure! */
7777 },
7778};
7779
4953550a
TI
7780/*
7781 * 2ch mode
7782 */
a9111321 7783static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
4953550a
TI
7784 { 2, NULL }
7785};
7786
272a527c
KY
7787/*
7788 * 2ch mode
7789 */
a9111321 7790static const struct hda_verb alc882_3ST_ch2_init[] = {
272a527c
KY
7791 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7792 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7793 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7794 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7795 { } /* end */
7796};
7797
4953550a
TI
7798/*
7799 * 4ch mode
7800 */
a9111321 7801static const struct hda_verb alc882_3ST_ch4_init[] = {
4953550a
TI
7802 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7803 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7804 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7805 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7806 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7807 { } /* end */
7808};
7809
272a527c
KY
7810/*
7811 * 6ch mode
7812 */
a9111321 7813static const struct hda_verb alc882_3ST_ch6_init[] = {
272a527c
KY
7814 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7815 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7816 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7817 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7818 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7819 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7820 { } /* end */
7821};
7822
a9111321 7823static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
272a527c 7824 { 2, alc882_3ST_ch2_init },
4953550a 7825 { 4, alc882_3ST_ch4_init },
272a527c
KY
7826 { 6, alc882_3ST_ch6_init },
7827};
7828
4953550a
TI
7829#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7830
a65cc60f 7831/*
7832 * 2ch mode
7833 */
a9111321 7834static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
a65cc60f 7835 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7836 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7837 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7838 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7839 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7840 { } /* end */
7841};
7842
7843/*
7844 * 4ch mode
7845 */
a9111321 7846static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
a65cc60f 7847 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
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
7856/*
7857 * 6ch mode
7858 */
a9111321 7859static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
a65cc60f 7860 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7862 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7863 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7864 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7865 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7866 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7867 { } /* end */
7868};
7869
a9111321 7870static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
a65cc60f 7871 { 2, alc883_3ST_ch2_clevo_init },
7872 { 4, alc883_3ST_ch4_clevo_init },
7873 { 6, alc883_3ST_ch6_clevo_init },
7874};
7875
7876
df694daa
KY
7877/*
7878 * 6ch mode
7879 */
a9111321 7880static const struct hda_verb alc882_sixstack_ch6_init[] = {
df694daa
KY
7881 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7882 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7883 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7884 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { } /* end */
7886};
7887
7888/*
7889 * 8ch mode
7890 */
a9111321 7891static const struct hda_verb alc882_sixstack_ch8_init[] = {
df694daa
KY
7892 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7893 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7895 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7896 { } /* end */
7897};
7898
a9111321 7899static const struct hda_channel_mode alc882_sixstack_modes[2] = {
df694daa
KY
7900 { 6, alc882_sixstack_ch6_init },
7901 { 8, alc882_sixstack_ch8_init },
7902};
7903
76e6f5a9
RH
7904
7905/* Macbook Air 2,1 */
7906
a9111321 7907static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
76e6f5a9
RH
7908 { 2, NULL },
7909};
7910
87350ad0 7911/*
def319f9 7912 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
87350ad0
TI
7913 */
7914
7915/*
7916 * 2ch mode
7917 */
a9111321 7918static const struct hda_verb alc885_mbp_ch2_init[] = {
87350ad0
TI
7919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7920 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7921 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7922 { } /* end */
7923};
7924
7925/*
a3f730af 7926 * 4ch mode
87350ad0 7927 */
a9111321 7928static const struct hda_verb alc885_mbp_ch4_init[] = {
87350ad0
TI
7929 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7931 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7932 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7933 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7934 { } /* end */
7935};
7936
a9111321 7937static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
87350ad0 7938 { 2, alc885_mbp_ch2_init },
a3f730af 7939 { 4, alc885_mbp_ch4_init },
87350ad0
TI
7940};
7941
92b9de83
KS
7942/*
7943 * 2ch
7944 * Speakers/Woofer/HP = Front
7945 * LineIn = Input
7946 */
a9111321 7947static const struct hda_verb alc885_mb5_ch2_init[] = {
92b9de83
KS
7948 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7949 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7950 { } /* end */
7951};
7952
7953/*
7954 * 6ch mode
7955 * Speakers/HP = Front
7956 * Woofer = LFE
7957 * LineIn = Surround
7958 */
a9111321 7959static const struct hda_verb alc885_mb5_ch6_init[] = {
92b9de83
KS
7960 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7961 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7962 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7963 { } /* end */
7964};
7965
a9111321 7966static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
92b9de83
KS
7967 { 2, alc885_mb5_ch2_init },
7968 { 6, alc885_mb5_ch6_init },
7969};
87350ad0 7970
d01aecdf 7971#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
4953550a
TI
7972
7973/*
7974 * 2ch mode
7975 */
a9111321 7976static const struct hda_verb alc883_4ST_ch2_init[] = {
4953550a
TI
7977 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7978 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7979 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7980 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7981 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7982 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7983 { } /* end */
7984};
7985
7986/*
7987 * 4ch mode
7988 */
a9111321 7989static const struct hda_verb alc883_4ST_ch4_init[] = {
4953550a
TI
7990 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7991 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7992 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7993 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7994 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7995 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7996 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7997 { } /* end */
7998};
7999
8000/*
8001 * 6ch mode
8002 */
a9111321 8003static const struct hda_verb alc883_4ST_ch6_init[] = {
4953550a
TI
8004 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8005 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8006 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8007 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8008 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8009 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8010 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8011 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8012 { } /* end */
8013};
8014
8015/*
8016 * 8ch mode
8017 */
a9111321 8018static const struct hda_verb alc883_4ST_ch8_init[] = {
4953550a
TI
8019 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8020 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8021 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8022 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8023 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8024 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8025 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8026 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8027 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8028 { } /* end */
8029};
8030
a9111321 8031static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
4953550a
TI
8032 { 2, alc883_4ST_ch2_init },
8033 { 4, alc883_4ST_ch4_init },
8034 { 6, alc883_4ST_ch6_init },
8035 { 8, alc883_4ST_ch8_init },
8036};
8037
8038
8039/*
8040 * 2ch mode
8041 */
a9111321 8042static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
4953550a
TI
8043 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8044 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8045 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8046 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8047 { } /* end */
8048};
8049
8050/*
8051 * 4ch mode
8052 */
a9111321 8053static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
4953550a
TI
8054 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8055 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8056 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8057 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8058 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8059 { } /* end */
8060};
8061
8062/*
8063 * 6ch mode
8064 */
a9111321 8065static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
4953550a
TI
8066 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8067 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8068 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8069 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8070 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8071 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8072 { } /* end */
8073};
8074
a9111321 8075static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
4953550a
TI
8076 { 2, alc883_3ST_ch2_intel_init },
8077 { 4, alc883_3ST_ch4_intel_init },
8078 { 6, alc883_3ST_ch6_intel_init },
8079};
8080
dd7714c9
WF
8081/*
8082 * 2ch mode
8083 */
a9111321 8084static const struct hda_verb alc889_ch2_intel_init[] = {
dd7714c9
WF
8085 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8086 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8087 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8088 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8089 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8090 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { } /* end */
8092};
8093
87a8c370
JK
8094/*
8095 * 6ch mode
8096 */
a9111321 8097static const struct hda_verb alc889_ch6_intel_init[] = {
dd7714c9
WF
8098 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8099 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8100 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8101 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
87a8c370
JK
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8104 { } /* end */
8105};
8106
8107/*
8108 * 8ch mode
8109 */
a9111321 8110static const struct hda_verb alc889_ch8_intel_init[] = {
dd7714c9
WF
8111 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8112 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8113 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8114 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8115 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
87a8c370
JK
8116 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8117 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
87a8c370
JK
8118 { } /* end */
8119};
8120
a9111321 8121static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
dd7714c9 8122 { 2, alc889_ch2_intel_init },
87a8c370
JK
8123 { 6, alc889_ch6_intel_init },
8124 { 8, alc889_ch8_intel_init },
8125};
8126
4953550a
TI
8127/*
8128 * 6ch mode
8129 */
a9111321 8130static const struct hda_verb alc883_sixstack_ch6_init[] = {
4953550a
TI
8131 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8132 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8133 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8134 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8135 { } /* end */
8136};
8137
8138/*
8139 * 8ch mode
8140 */
a9111321 8141static const struct hda_verb alc883_sixstack_ch8_init[] = {
4953550a
TI
8142 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8143 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8144 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8145 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8146 { } /* end */
8147};
8148
a9111321 8149static const struct hda_channel_mode alc883_sixstack_modes[2] = {
4953550a
TI
8150 { 6, alc883_sixstack_ch6_init },
8151 { 8, alc883_sixstack_ch8_init },
8152};
8153
8154
1da177e4
LT
8155/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8156 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8157 */
a9111321 8158static const struct snd_kcontrol_new alc882_base_mixer[] = {
05acb863 8159 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
985be54b 8160 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
05acb863 8161 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
985be54b 8162 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
05acb863
TI
8163 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8164 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
985be54b
TI
8165 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8166 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
05acb863 8167 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
985be54b 8168 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1da177e4
LT
8169 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8170 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8171 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8172 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8173 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8174 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8175 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
1da177e4
LT
8176 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8177 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8178 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
1da177e4 8179 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1da177e4
LT
8180 { } /* end */
8181};
8182
76e6f5a9
RH
8183/* Macbook Air 2,1 same control for HP and internal Speaker */
8184
a9111321 8185static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
76e6f5a9
RH
8186 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8187 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8188 { }
8189};
8190
8191
a9111321 8192static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
a3f730af
TI
8193 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8194 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8195 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8196 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8197 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
2134ea4f
TI
8198 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8199 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
87350ad0
TI
8200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8201 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
5f99f86a
DH
8202 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
87350ad0
TI
8204 { } /* end */
8205};
41d5545d 8206
a9111321 8207static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
92b9de83
KS
8208 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8209 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8210 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8211 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8212 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8213 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
a76221d4
AM
8214 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8215 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
b8f171e7
AM
8216 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8217 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
41d5545d
KS
8218 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8219 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
8220 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
41d5545d
KS
8222 { } /* end */
8223};
92b9de83 8224
a9111321 8225static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
e458b1fa
LY
8226 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8227 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8228 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8229 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8230 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8231 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8232 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8234 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8235 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
5f99f86a 8236 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
e458b1fa
LY
8237 { } /* end */
8238};
8239
a9111321 8240static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
b7cccc52
JM
8241 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
4b7e1803
JM
8243 { } /* end */
8244};
8245
8246
a9111321 8247static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
bdd148a3
KY
8248 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8249 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8250 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8251 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8252 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8253 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8254 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8255 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3 8256 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
bdd148a3
KY
8257 { } /* end */
8258};
8259
a9111321 8260static const struct snd_kcontrol_new alc882_targa_mixer[] = {
272a527c
KY
8261 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8262 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8263 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8264 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8265 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8267 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8268 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8269 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8270 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8271 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8272 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 8273 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
272a527c
KY
8274 { } /* end */
8275};
8276
8277/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8278 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8279 */
a9111321 8280static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
272a527c
KY
8281 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8282 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8283 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8284 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8285 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8286 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8287 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8288 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8289 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8290 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8291 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8292 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8293 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
272a527c
KY
8294 { } /* end */
8295};
8296
a9111321 8297static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
914759b7
TI
8298 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8299 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8300 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 8306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
914759b7 8307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
914759b7
TI
8308 { } /* end */
8309};
8310
a9111321 8311static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
df694daa
KY
8312 {
8313 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8314 .name = "Channel Mode",
8315 .info = alc_ch_mode_info,
8316 .get = alc_ch_mode_get,
8317 .put = alc_ch_mode_put,
8318 },
8319 { } /* end */
8320};
8321
a9111321 8322static const struct hda_verb alc882_base_init_verbs[] = {
1da177e4 8323 /* Front mixer: unmute input/output amp left and right (volume = 0) */
05acb863
TI
8324 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8325 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8326 /* Rear mixer */
05acb863
TI
8327 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8328 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8329 /* CLFE mixer */
05acb863
TI
8330 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8331 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8332 /* Side mixer */
05acb863
TI
8333 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8334 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1da177e4 8335
e9edcee0 8336 /* Front Pin: output 0 (0x0c) */
05acb863 8337 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8338 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8339 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
e9edcee0 8340 /* Rear Pin: output 1 (0x0d) */
05acb863 8341 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8342 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8343 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
e9edcee0 8344 /* CLFE Pin: output 2 (0x0e) */
05acb863 8345 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8346 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8347 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
e9edcee0 8348 /* Side Pin: output 3 (0x0f) */
05acb863 8349 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
05acb863 8350 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1da177e4 8351 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
e9edcee0 8352 /* Mic (rear) pin: input vref at 80% */
16ded525 8353 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8354 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8355 /* Front Mic pin: input vref at 80% */
16ded525 8356 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
e9edcee0
TI
8357 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8358 /* Line In pin: input */
05acb863 8359 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
e9edcee0
TI
8360 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8361 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8362 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8363 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8364 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4 8365 /* CD pin widget for input */
05acb863 8366 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1da177e4
LT
8367
8368 /* FIXME: use matrix-type input source selection */
8369 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
1da177e4 8370 /* Input mixer2 */
05acb863 8371 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1da177e4 8372 /* Input mixer3 */
05acb863 8373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
05acb863
TI
8374 /* ADC2: mute amp left and right */
8375 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8376 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
05acb863
TI
8377 /* ADC3: mute amp left and right */
8378 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
71fe7b82 8379 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
1da177e4
LT
8380
8381 { }
8382};
8383
a9111321 8384static const struct hda_verb alc882_adc1_init_verbs[] = {
4953550a
TI
8385 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8386 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8387 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8388 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8389 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8390 /* ADC1: mute amp left and right */
8391 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8392 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8393 { }
8394};
8395
a9111321 8396static const struct hda_verb alc882_eapd_verbs[] = {
4b146cb0
TI
8397 /* change to EAPD mode */
8398 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
b373bdeb 8399 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
f12ab1e0 8400 { }
4b146cb0
TI
8401};
8402
a9111321 8403static const struct hda_verb alc889_eapd_verbs[] = {
87a8c370
JK
8404 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8405 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8406 { }
8407};
8408
a9111321 8409static const struct hda_verb alc_hp15_unsol_verbs[] = {
6732bd0d
WF
8410 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8412 {}
8413};
87a8c370 8414
a9111321 8415static const struct hda_verb alc885_init_verbs[] = {
87a8c370 8416 /* Front mixer: unmute input/output amp left and right (volume = 0) */
88102f3f
KY
8417 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8418 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8419 /* Rear mixer */
88102f3f
KY
8420 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8421 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8422 /* CLFE mixer */
88102f3f
KY
8423 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8424 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370 8425 /* Side mixer */
88102f3f
KY
8426 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8427 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
87a8c370
JK
8428
8429 /* Front HP Pin: output 0 (0x0c) */
6732bd0d 8430 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
87a8c370
JK
8431 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8432 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8433 /* Front Pin: output 0 (0x0c) */
8434 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8435 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8436 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8437 /* Rear Pin: output 1 (0x0d) */
8438 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8439 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8440 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8441 /* CLFE Pin: output 2 (0x0e) */
8442 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8443 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8444 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8445 /* Side Pin: output 3 (0x0f) */
8446 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8447 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8448 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8449 /* Mic (rear) pin: input vref at 80% */
8450 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8451 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8452 /* Front Mic pin: input vref at 80% */
8453 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8454 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8455 /* Line In pin: input */
8456 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8457 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8458
8459 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8460 /* Input mixer1 */
88102f3f 8461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8462 /* Input mixer2 */
8463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370 8464 /* Input mixer3 */
88102f3f 8465 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
87a8c370
JK
8466 /* ADC2: mute amp left and right */
8467 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8468 /* ADC3: mute amp left and right */
8469 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8470
8471 { }
8472};
8473
a9111321 8474static const struct hda_verb alc885_init_input_verbs[] = {
87a8c370
JK
8475 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8476 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8477 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8478 { }
8479};
8480
8481
8482/* Unmute Selector 24h and set the default input to front mic */
a9111321 8483static const struct hda_verb alc889_init_input_verbs[] = {
87a8c370
JK
8484 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8485 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 { }
8487};
8488
8489
4953550a
TI
8490#define alc883_init_verbs alc882_base_init_verbs
8491
9102cd1c 8492/* Mac Pro test */
a9111321 8493static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
9102cd1c
TD
8494 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8495 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8497 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8498 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
45bdd1c1 8499 /* FIXME: this looks suspicious...
d355c82a
JK
8500 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8501 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
45bdd1c1 8502 */
9102cd1c
TD
8503 { } /* end */
8504};
8505
a9111321 8506static const struct hda_verb alc882_macpro_init_verbs[] = {
9102cd1c
TD
8507 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8511 /* Front Pin: output 0 (0x0c) */
8512 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8513 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8514 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8515 /* Front Mic pin: input vref at 80% */
8516 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8517 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8518 /* Speaker: output */
8519 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8520 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8521 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8522 /* Headphone output (output 0 - 0x0c) */
8523 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8524 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8525 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8526
8527 /* FIXME: use matrix-type input source selection */
8528 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8529 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8530 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8532 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8533 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8534 /* Input mixer2 */
8535 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8536 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8537 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8538 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8539 /* Input mixer3 */
8540 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8541 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544 /* ADC1: mute amp left and right */
8545 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8546 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8547 /* ADC2: mute amp left and right */
8548 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8549 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8550 /* ADC3: mute amp left and right */
8551 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8552 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8553
8554 { }
8555};
f12ab1e0 8556
41d5545d 8557/* Macbook 5,1 */
a9111321 8558static const struct hda_verb alc885_mb5_init_verbs[] = {
92b9de83
KS
8559 /* DACs */
8560 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8561 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8562 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8563 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
41d5545d 8564 /* Front mixer */
41d5545d
KS
8565 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8566 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8567 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
92b9de83
KS
8568 /* Surround mixer */
8569 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8570 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8571 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8572 /* LFE mixer */
8573 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8574 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8575 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8576 /* HP mixer */
8577 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8580 /* Front Pin (0x0c) */
41d5545d
KS
8581 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83
KS
8583 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8584 /* LFE Pin (0x0e) */
8585 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8586 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8587 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8588 /* HP Pin (0x0f) */
41d5545d
KS
8589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
92b9de83 8591 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
a76221d4 8592 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
41d5545d
KS
8593 /* Front Mic pin: input vref at 80% */
8594 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8595 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8596 /* Line In pin */
8597 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8598 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8599
b8f171e7
AM
8600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
41d5545d
KS
8603 { }
8604};
8605
e458b1fa 8606/* Macmini 3,1 */
a9111321 8607static const struct hda_verb alc885_macmini3_init_verbs[] = {
e458b1fa
LY
8608 /* DACs */
8609 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8610 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8611 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8613 /* Front mixer */
8614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8616 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8617 /* Surround mixer */
8618 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8619 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8620 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8621 /* LFE mixer */
8622 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8623 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8624 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8625 /* HP mixer */
8626 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8627 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8628 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8629 /* Front Pin (0x0c) */
8630 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8631 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8632 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8633 /* LFE Pin (0x0e) */
8634 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8635 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8636 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8637 /* HP Pin (0x0f) */
8638 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8639 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8640 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8641 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
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
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8649 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8650 { }
8651};
8652
76e6f5a9 8653
a9111321 8654static const struct hda_verb alc885_mba21_init_verbs[] = {
76e6f5a9
RH
8655 /*Internal and HP Speaker Mixer*/
8656 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8657 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8659 /*Internal Speaker Pin (0x0c)*/
8660 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8661 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8662 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8663 /* HP Pin: output 0 (0x0e) */
8664 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8665 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8666 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8667 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8668 /* Line in (is hp when jack connected)*/
8669 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8670 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8671
8672 { }
8673 };
8674
8675
87350ad0 8676/* Macbook Pro rev3 */
a9111321 8677static const struct hda_verb alc885_mbp3_init_verbs[] = {
87350ad0
TI
8678 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8679 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8682 /* Rear mixer */
8683 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8684 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8685 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a3f730af
TI
8686 /* HP mixer */
8687 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
87350ad0
TI
8690 /* Front Pin: output 0 (0x0c) */
8691 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8692 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8693 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
a3f730af 8694 /* HP Pin: output 0 (0x0e) */
87350ad0 8695 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
a3f730af
TI
8696 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8697 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
87350ad0
TI
8698 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8699 /* Mic (rear) pin: input vref at 80% */
8700 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8701 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8702 /* Front Mic pin: input vref at 80% */
8703 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8704 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8705 /* Line In pin: use output 1 when in LineOut mode */
8706 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8707 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8708 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8709
8710 /* FIXME: use matrix-type input source selection */
8711 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8712 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8713 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8714 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8715 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8716 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8717 /* Input mixer2 */
8718 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8719 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8720 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8721 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8722 /* Input mixer3 */
8723 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8724 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8725 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8726 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8727 /* ADC1: mute amp left and right */
8728 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8729 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8730 /* ADC2: mute amp left and right */
8731 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8732 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8733 /* ADC3: mute amp left and right */
8734 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8736
8737 { }
8738};
8739
4b7e1803 8740/* iMac 9,1 */
a9111321 8741static const struct hda_verb alc885_imac91_init_verbs[] = {
b7cccc52
JM
8742 /* Internal Speaker Pin (0x0c) */
8743 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8744 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8745 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8747 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8748 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8749 /* HP Pin: Rear */
4b7e1803
JM
8750 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8751 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8752 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52
JM
8753 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8754 /* Line in Rear */
8755 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
4b7e1803 8756 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4b7e1803
JM
8757 /* Front Mic pin: input vref at 80% */
8758 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8759 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
b7cccc52
JM
8760 /* Rear mixer */
8761 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8762 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8764 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8765 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8766 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8768 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8769 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8773 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8774 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8775 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8776 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8777 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8778 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
4b7e1803
JM
8779 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8780 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8781 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8782 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
b7cccc52 8783 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8784 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8785 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8786 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8787 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8788 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
b7cccc52 8789 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
4b7e1803
JM
8790 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8791 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4b7e1803
JM
8792 { }
8793};
8794
c54728d8 8795/* iMac 24 mixer. */
a9111321 8796static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
c54728d8
NF
8797 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8798 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8799 { } /* end */
8800};
8801
8802/* iMac 24 init verbs. */
a9111321 8803static const struct hda_verb alc885_imac24_init_verbs[] = {
c54728d8
NF
8804 /* Internal speakers: output 0 (0x0c) */
8805 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8806 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8807 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8808 /* Internal speakers: output 0 (0x0c) */
8809 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8810 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8811 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8812 /* Headphone: output 0 (0x0c) */
8813 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8814 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8815 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8816 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8817 /* Front Mic: input vref at 80% */
8818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8819 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8820 { }
8821};
8822
8823/* Toggle speaker-output according to the hp-jack state */
4f5d1706 8824static void alc885_imac24_setup(struct hda_codec *codec)
c54728d8 8825{
a9fd4f3f 8826 struct alc_spec *spec = codec->spec;
c54728d8 8827
a9fd4f3f
TI
8828 spec->autocfg.hp_pins[0] = 0x14;
8829 spec->autocfg.speaker_pins[0] = 0x18;
8830 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8831 spec->automute = 1;
8832 spec->automute_mode = ALC_AUTOMUTE_AMP;
c54728d8
NF
8833}
8834
9d54f08b
TI
8835#define alc885_mb5_setup alc885_imac24_setup
8836#define alc885_macmini3_setup alc885_imac24_setup
8837
76e6f5a9
RH
8838/* Macbook Air 2,1 */
8839static void alc885_mba21_setup(struct hda_codec *codec)
8840{
8841 struct alc_spec *spec = codec->spec;
8842
8843 spec->autocfg.hp_pins[0] = 0x14;
8844 spec->autocfg.speaker_pins[0] = 0x18;
d922b51d
TI
8845 spec->automute = 1;
8846 spec->automute_mode = ALC_AUTOMUTE_AMP;
76e6f5a9
RH
8847}
8848
8849
8850
4f5d1706 8851static void alc885_mbp3_setup(struct hda_codec *codec)
87350ad0 8852{
a9fd4f3f 8853 struct alc_spec *spec = codec->spec;
87350ad0 8854
a9fd4f3f
TI
8855 spec->autocfg.hp_pins[0] = 0x15;
8856 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
8857 spec->automute = 1;
8858 spec->automute_mode = ALC_AUTOMUTE_AMP;
87350ad0
TI
8859}
8860
9d54f08b 8861static void alc885_imac91_setup(struct hda_codec *codec)
a76221d4 8862{
9d54f08b 8863 struct alc_spec *spec = codec->spec;
4b7e1803 8864
9d54f08b 8865 spec->autocfg.hp_pins[0] = 0x14;
b7cccc52 8866 spec->autocfg.speaker_pins[0] = 0x18;
9d54f08b 8867 spec->autocfg.speaker_pins[1] = 0x1a;
d922b51d
TI
8868 spec->automute = 1;
8869 spec->automute_mode = ALC_AUTOMUTE_AMP;
4b7e1803 8870}
87350ad0 8871
a9111321 8872static const struct hda_verb alc882_targa_verbs[] = {
272a527c
KY
8873 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8874 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8875
8876 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8877 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8878
272a527c
KY
8879 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8880 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8881 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8882
8883 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
272a527c
KY
8884 { } /* end */
8885};
8886
8887/* toggle speaker-output according to the hp-jack state */
8888static void alc882_targa_automute(struct hda_codec *codec)
8889{
a9fd4f3f 8890 struct alc_spec *spec = codec->spec;
d922b51d 8891 alc_hp_automute(codec);
82beb8fd 8892 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
a9fd4f3f
TI
8893 spec->jack_present ? 1 : 3);
8894}
8895
4f5d1706 8896static void alc882_targa_setup(struct hda_codec *codec)
a9fd4f3f
TI
8897{
8898 struct alc_spec *spec = codec->spec;
8899
8900 spec->autocfg.hp_pins[0] = 0x14;
8901 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d
TI
8902 spec->automute = 1;
8903 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
8904}
8905
8906static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8907{
a9fd4f3f 8908 if ((res >> 26) == ALC880_HP_EVENT)
272a527c 8909 alc882_targa_automute(codec);
272a527c
KY
8910}
8911
a9111321 8912static const struct hda_verb alc882_asus_a7j_verbs[] = {
272a527c
KY
8913 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8914 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8915
8916 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8917 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8918 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8919
272a527c
KY
8920 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8922 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8923
8924 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8925 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8926 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8927 { } /* end */
8928};
8929
a9111321 8930static const struct hda_verb alc882_asus_a7m_verbs[] = {
914759b7
TI
8931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8933
8934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8935 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8936 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 8937
914759b7
TI
8938 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8939 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8940 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8941
8942 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8943 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8944 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8945 { } /* end */
8946};
8947
9102cd1c
TD
8948static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8949{
8950 unsigned int gpiostate, gpiomask, gpiodir;
8951
8952 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8953 AC_VERB_GET_GPIO_DATA, 0);
8954
8955 if (!muted)
8956 gpiostate |= (1 << pin);
8957 else
8958 gpiostate &= ~(1 << pin);
8959
8960 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8961 AC_VERB_GET_GPIO_MASK, 0);
8962 gpiomask |= (1 << pin);
8963
8964 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8965 AC_VERB_GET_GPIO_DIRECTION, 0);
8966 gpiodir |= (1 << pin);
8967
8968
8969 snd_hda_codec_write(codec, codec->afg, 0,
8970 AC_VERB_SET_GPIO_MASK, gpiomask);
8971 snd_hda_codec_write(codec, codec->afg, 0,
8972 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8973
8974 msleep(1);
8975
8976 snd_hda_codec_write(codec, codec->afg, 0,
8977 AC_VERB_SET_GPIO_DATA, gpiostate);
8978}
8979
7debbe51
TI
8980/* set up GPIO at initialization */
8981static void alc885_macpro_init_hook(struct hda_codec *codec)
8982{
8983 alc882_gpio_mute(codec, 0, 0);
8984 alc882_gpio_mute(codec, 1, 0);
8985}
8986
8987/* set up GPIO and update auto-muting at initialization */
8988static void alc885_imac24_init_hook(struct hda_codec *codec)
8989{
8990 alc885_macpro_init_hook(codec);
d922b51d 8991 alc_hp_automute(codec);
7debbe51
TI
8992}
8993
df694daa
KY
8994/*
8995 * generic initialization of ADC, input mixers and output mixers
8996 */
a9111321 8997static const struct hda_verb alc883_auto_init_verbs[] = {
df694daa
KY
8998 /*
8999 * Unmute ADC0-2 and set the default input to mic-in
9000 */
4953550a
TI
9001 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9003 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9004 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17bba1b7 9005
4953550a
TI
9006 /*
9007 * Set up output mixers (0x0c - 0x0f)
9008 */
9009 /* set vol=0 to output mixers */
9010 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9011 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9012 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9013 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9014 /* set up input amps for analog loopback */
9015 /* Amp Indices: DAC = 0, mixer = 1 */
9016 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9017 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9018 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9019 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9020 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9021 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9022 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9023 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9024 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9025 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9c7f852e 9026
4953550a
TI
9027 /* FIXME: use matrix-type input source selection */
9028 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9029 /* Input mixer2 */
88102f3f 9030 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9031 /* Input mixer3 */
88102f3f 9032 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4953550a 9033 { }
9c7f852e
TI
9034};
9035
eb4c41d3 9036/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
a9111321 9037static const struct hda_verb alc889A_mb31_ch2_init[] = {
eb4c41d3
TS
9038 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9039 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9040 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9041 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9042 { } /* end */
9043};
9044
9045/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
a9111321 9046static const struct hda_verb alc889A_mb31_ch4_init[] = {
eb4c41d3
TS
9047 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9048 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9049 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9050 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9051 { } /* end */
9052};
9053
9054/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
a9111321 9055static const struct hda_verb alc889A_mb31_ch5_init[] = {
eb4c41d3
TS
9056 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9057 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9058 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9059 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9060 { } /* end */
9061};
9062
9063/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
a9111321 9064static const struct hda_verb alc889A_mb31_ch6_init[] = {
eb4c41d3
TS
9065 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9066 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9067 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9068 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9069 { } /* end */
9070};
9071
a9111321 9072static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
eb4c41d3
TS
9073 { 2, alc889A_mb31_ch2_init },
9074 { 4, alc889A_mb31_ch4_init },
9075 { 5, alc889A_mb31_ch5_init },
9076 { 6, alc889A_mb31_ch6_init },
9077};
9078
a9111321 9079static const struct hda_verb alc883_medion_eapd_verbs[] = {
b373bdeb
AN
9080 /* eanable EAPD on medion laptop */
9081 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9082 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9083 { }
9084};
9085
4953550a 9086#define alc883_base_mixer alc882_base_mixer
834be88d 9087
a9111321 9088static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
a8848bd6
AS
9089 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9090 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9091 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9092 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9093 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9094 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9095 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9097 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
a8848bd6
AS
9098 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9099 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9100 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
a8848bd6 9101 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
a8848bd6
AS
9102 { } /* end */
9103};
9104
a9111321 9105static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
368c7a95
J
9106 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9107 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9108 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9109 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9111 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
368c7a95 9112 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9113 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9114 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9115 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
368c7a95
J
9116 { } /* end */
9117};
9118
a9111321 9119static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
fb97dc67
J
9120 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9121 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9122 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9123 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
fb97dc67 9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9129 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
fb97dc67
J
9130 { } /* end */
9131};
9132
a9111321 9133static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9c7f852e
TI
9134 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9136 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9137 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9138 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9139 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9140 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9141 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9142 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9143 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9145 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9146 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9147 { } /* end */
9148};
df694daa 9149
a9111321 9150static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9c7f852e
TI
9151 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9152 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9153 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9154 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9155 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9156 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9157 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9158 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9159 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9163 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9164 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9165 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
9166 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9167 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9168 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e 9169 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9c7f852e
TI
9170 { } /* end */
9171};
9172
a9111321 9173static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
17bba1b7
J
9174 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9175 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9176 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9177 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9178 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9179 HDA_OUTPUT),
9180 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9182 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9183 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9186 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9189 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
17bba1b7
J
9190 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9191 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9192 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
17bba1b7 9193 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17bba1b7
J
9194 { } /* end */
9195};
9196
a9111321 9197static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
87a8c370
JK
9198 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9199 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9200 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9201 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9202 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9203 HDA_OUTPUT),
9204 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9205 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9206 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9207 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9208 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9209 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9210 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
5f99f86a 9213 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
87a8c370
JK
9214 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9215 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9216 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
87a8c370
JK
9217 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9218 { } /* end */
9219};
9220
a9111321 9221static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
c07584c8 9222 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
0701e064 9223 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
c07584c8 9224 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
0701e064 9225 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
c07584c8
TD
9226 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9227 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
0701e064
TI
9228 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9229 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
c07584c8
TD
9230 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9231 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9232 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
c07584c8
TD
9237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9238 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9239 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
c07584c8 9240 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
c07584c8
TD
9241 { } /* end */
9242};
9243
a9111321 9244static const struct snd_kcontrol_new alc883_targa_mixer[] = {
ccc656ce 9245 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9246 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9247 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9249 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9250 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9251 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9252 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9253 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9254 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9255 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9256 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9257 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9258 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9260 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9261 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
ccc656ce 9262 { } /* end */
f12ab1e0 9263};
ccc656ce 9264
a9111321 9265static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
ccc656ce 9266 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
b99dba34 9267 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
ccc656ce 9268 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
b99dba34 9269 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ccc656ce
KY
9270 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9271 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ccc656ce 9274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7 9275 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9276 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9277 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ccc656ce 9278 { } /* end */
f12ab1e0 9279};
ccc656ce 9280
a9111321 9281static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
b99dba34
TI
9282 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9283 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
28c4edb7 9284 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9285 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7 9286 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
b99dba34
TI
9287 { } /* end */
9288};
9289
a9111321 9290static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
bc9f98a9
KY
9291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
86cd9298
TI
9293 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9294 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
bc9f98a9
KY
9295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9296 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9297 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bc9f98a9 9298 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9 9299 { } /* end */
f12ab1e0 9300};
bc9f98a9 9301
a9111321 9302static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
272a527c
KY
9303 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9304 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9305 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9306 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9307 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9308 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9309 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
28c4edb7
DH
9310 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9311 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c 9312 { } /* end */
ea1fb29a 9313};
272a527c 9314
a9111321 9315static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
7ad7b218
MC
9316 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9317 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9318 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9319 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9320 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9321 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9322 { } /* end */
9323};
9324
a9111321 9325static const struct hda_verb alc883_medion_wim2160_verbs[] = {
7ad7b218
MC
9326 /* Unmute front mixer */
9327 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9328 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9329
9330 /* Set speaker pin to front mixer */
9331 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9332
9333 /* Init headphone pin */
9334 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9335 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9336 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9337 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9338
9339 { } /* end */
9340};
9341
9342/* toggle speaker-output according to the hp-jack state */
9343static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9344{
9345 struct alc_spec *spec = codec->spec;
9346
9347 spec->autocfg.hp_pins[0] = 0x1a;
9348 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9349 spec->automute = 1;
9350 spec->automute_mode = ALC_AUTOMUTE_AMP;
7ad7b218
MC
9351}
9352
a9111321 9353static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
d1a991a6
KY
9354 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9355 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2880a867 9356 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
2880a867
TD
9357 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9358 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d1a991a6 9359 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9360 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d1a991a6 9361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2880a867 9362 { } /* end */
d1a991a6 9363};
2880a867 9364
a9111321 9365static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
d2fd4b09 9366 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
d2fd4b09 9367 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
684a8842
TV
9368 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9369 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
d2fd4b09
TV
9370 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9371 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9372 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9373 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
d2fd4b09
TV
9374 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9375 { } /* end */
9376};
9377
a9111321 9378static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
e2757d5e
KY
9379 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9380 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9381 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9382 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9383 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9384 0x0d, 1, 0x0, HDA_OUTPUT),
9385 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9386 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9387 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9388 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9389 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
e2757d5e
KY
9390 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9391 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9392 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9393 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9394 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9395 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e2757d5e
KY
9396 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9397 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9398 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
e2757d5e 9399 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
e2757d5e
KY
9400 { } /* end */
9401};
9402
a9111321 9403static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
eb4c41d3
TS
9404 /* Output mixers */
9405 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9406 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9407 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9408 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9409 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9410 HDA_OUTPUT),
9411 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9412 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9413 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9414 /* Output switches */
9415 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9416 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9417 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9418 /* Boost mixers */
5f99f86a
DH
9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9420 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
eb4c41d3
TS
9421 /* Input mixers */
9422 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9423 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9424 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9425 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9426 { } /* end */
9427};
9428
a9111321 9429static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
3e1647c5
GG
9430 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9431 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9432 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9433 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5f99f86a 9434 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
3e1647c5
GG
9435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9436 { } /* end */
9437};
9438
a9111321 9439static const struct hda_bind_ctls alc883_bind_cap_vol = {
e2757d5e
KY
9440 .ops = &snd_hda_bind_vol,
9441 .values = {
9442 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9443 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9444 0
9445 },
9446};
9447
a9111321 9448static const struct hda_bind_ctls alc883_bind_cap_switch = {
e2757d5e
KY
9449 .ops = &snd_hda_bind_sw,
9450 .values = {
9451 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9452 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9453 0
9454 },
9455};
9456
a9111321 9457static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
e2757d5e
KY
9458 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9459 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9463 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5f99f86a 9464 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
4953550a
TI
9465 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9466 { } /* end */
9467};
df694daa 9468
a9111321 9469static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
4953550a
TI
9470 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9471 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9472 {
9473 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9474 /* .name = "Capture Source", */
9475 .name = "Input Source",
9476 .count = 1,
9477 .info = alc_mux_enum_info,
9478 .get = alc_mux_enum_get,
9479 .put = alc_mux_enum_put,
9480 },
9481 { } /* end */
9482};
9c7f852e 9483
a9111321 9484static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
4953550a
TI
9485 {
9486 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9487 .name = "Channel Mode",
9488 .info = alc_ch_mode_info,
9489 .get = alc_ch_mode_get,
9490 .put = alc_ch_mode_put,
9491 },
9492 { } /* end */
9c7f852e
TI
9493};
9494
a8848bd6 9495/* toggle speaker-output according to the hp-jack state */
4f5d1706 9496static void alc883_mitac_setup(struct hda_codec *codec)
a8848bd6 9497{
a9fd4f3f 9498 struct alc_spec *spec = codec->spec;
a8848bd6 9499
a9fd4f3f
TI
9500 spec->autocfg.hp_pins[0] = 0x15;
9501 spec->autocfg.speaker_pins[0] = 0x14;
9502 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9503 spec->automute = 1;
9504 spec->automute_mode = ALC_AUTOMUTE_AMP;
a8848bd6
AS
9505}
9506
a9111321 9507static const struct hda_verb alc883_mitac_verbs[] = {
a8848bd6
AS
9508 /* HP */
9509 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9510 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9511 /* Subwoofer */
9512 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9513 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9514
9515 /* enable unsolicited event */
9516 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9517 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9518
9519 { } /* end */
9520};
9521
a9111321 9522static const struct hda_verb alc883_clevo_m540r_verbs[] = {
a65cc60f 9523 /* HP */
9524 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9525 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9526 /* Int speaker */
9527 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9528
9529 /* enable unsolicited event */
9530 /*
9531 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9532 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9533 */
9534
9535 { } /* end */
9536};
9537
a9111321 9538static const struct hda_verb alc883_clevo_m720_verbs[] = {
368c7a95
J
9539 /* HP */
9540 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9541 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9542 /* Int speaker */
9543 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9544 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9545
9546 /* enable unsolicited event */
9547 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
0c4cc443 9548 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
368c7a95
J
9549
9550 { } /* end */
9551};
9552
a9111321 9553static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
fb97dc67
J
9554 /* HP */
9555 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9556 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9557 /* Subwoofer */
9558 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9559 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9560
9561 /* enable unsolicited event */
9562 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9563
9564 { } /* end */
9565};
9566
a9111321 9567static const struct hda_verb alc883_targa_verbs[] = {
ccc656ce
KY
9568 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9569 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9570
9571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
ea1fb29a 9573
64a8be74
DH
9574/* Connect Line-Out side jack (SPDIF) to Side */
9575 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9576 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9577 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9578/* Connect Mic jack to CLFE */
9579 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9580 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9581 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9582/* Connect Line-in jack to Surround */
9583 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9585 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9586/* Connect HP out jack to Front */
9587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9588 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9589 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
ccc656ce
KY
9590
9591 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
ccc656ce
KY
9592
9593 { } /* end */
9594};
9595
a9111321 9596static const struct hda_verb alc883_lenovo_101e_verbs[] = {
bc9f98a9
KY
9597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9598 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9599 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9600 { } /* end */
9601};
9602
a9111321 9603static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
272a527c
KY
9604 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9606 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9607 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9608 { } /* end */
9609};
9610
a9111321 9611static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
272a527c
KY
9612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9614 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9615 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9616 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9617 { } /* end */
9618};
9619
a9111321 9620static const struct hda_verb alc883_haier_w66_verbs[] = {
189609ae
KY
9621 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9622 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9623
9624 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9625
9626 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9627 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9628 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9629 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9630 { } /* end */
9631};
9632
a9111321 9633static const struct hda_verb alc888_lenovo_sky_verbs[] = {
e2757d5e
KY
9634 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9635 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9636 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9637 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9638 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9639 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9640 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9641 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9642 { } /* end */
9643};
9644
a9111321 9645static const struct hda_verb alc888_6st_dell_verbs[] = {
8718b700
HRK
9646 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9647 { }
9648};
9649
a9111321 9650static const struct hda_verb alc883_vaiott_verbs[] = {
3e1647c5
GG
9651 /* HP */
9652 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9653 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9654
9655 /* enable unsolicited event */
9656 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9657
9658 { } /* end */
9659};
9660
4f5d1706 9661static void alc888_3st_hp_setup(struct hda_codec *codec)
8718b700 9662{
a9fd4f3f 9663 struct alc_spec *spec = codec->spec;
8718b700 9664
a9fd4f3f
TI
9665 spec->autocfg.hp_pins[0] = 0x1b;
9666 spec->autocfg.speaker_pins[0] = 0x14;
9667 spec->autocfg.speaker_pins[1] = 0x16;
9668 spec->autocfg.speaker_pins[2] = 0x18;
d922b51d
TI
9669 spec->automute = 1;
9670 spec->automute_mode = ALC_AUTOMUTE_AMP;
8718b700
HRK
9671}
9672
a9111321 9673static const struct hda_verb alc888_3st_hp_verbs[] = {
8341de60 9674 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
f32a19e3
HRK
9675 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9676 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
5795b9e6 9677 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8718b700 9678 { } /* end */
5795b9e6
CM
9679};
9680
3ea0d7cf
HRK
9681/*
9682 * 2ch mode
9683 */
a9111321 9684static const struct hda_verb alc888_3st_hp_2ch_init[] = {
8341de60
CM
9685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9687 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9688 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
3ea0d7cf 9689 { } /* end */
8341de60
CM
9690};
9691
3ea0d7cf
HRK
9692/*
9693 * 4ch mode
9694 */
a9111321 9695static const struct hda_verb alc888_3st_hp_4ch_init[] = {
3ea0d7cf
HRK
9696 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9697 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9698 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9699 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9700 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9701 { } /* end */
9702};
9703
9704/*
9705 * 6ch mode
9706 */
a9111321 9707static const struct hda_verb alc888_3st_hp_6ch_init[] = {
8341de60
CM
9708 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9709 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf 9710 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8341de60
CM
9711 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9712 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
3ea0d7cf
HRK
9713 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9714 { } /* end */
8341de60
CM
9715};
9716
a9111321 9717static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
4723c022 9718 { 2, alc888_3st_hp_2ch_init },
3ea0d7cf 9719 { 4, alc888_3st_hp_4ch_init },
4723c022 9720 { 6, alc888_3st_hp_6ch_init },
8341de60
CM
9721};
9722
e6a5e1b7 9723static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
272a527c 9724{
e6a5e1b7 9725 struct alc_spec *spec = codec->spec;
47fd830a 9726
e6a5e1b7
TI
9727 spec->autocfg.hp_pins[0] = 0x1b;
9728 spec->autocfg.line_out_pins[0] = 0x14;
9729 spec->autocfg.speaker_pins[0] = 0x15;
9730 spec->automute = 1;
9731 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9732}
9733
272a527c 9734/* toggle speaker-output according to the hp-jack state */
dc427170 9735static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
272a527c 9736{
a9fd4f3f 9737 struct alc_spec *spec = codec->spec;
272a527c 9738
a9fd4f3f
TI
9739 spec->autocfg.hp_pins[0] = 0x14;
9740 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9741 spec->automute = 1;
9742 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
9743}
9744
ccc656ce 9745/* toggle speaker-output according to the hp-jack state */
c259249f
SA
9746#define alc883_targa_init_hook alc882_targa_init_hook
9747#define alc883_targa_unsol_event alc882_targa_unsol_event
368c7a95 9748
4f5d1706 9749static void alc883_clevo_m720_setup(struct hda_codec *codec)
0c4cc443 9750{
a9fd4f3f
TI
9751 struct alc_spec *spec = codec->spec;
9752
9753 spec->autocfg.hp_pins[0] = 0x15;
9754 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9755 spec->automute = 1;
9756 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
9757}
9758
9759static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9760{
d922b51d 9761 alc_hp_automute(codec);
eeb43387 9762 alc88x_simple_mic_automute(codec);
0c4cc443
HRK
9763}
9764
9765static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
368c7a95
J
9766 unsigned int res)
9767{
0c4cc443 9768 switch (res >> 26) {
0c4cc443 9769 case ALC880_MIC_EVENT:
eeb43387 9770 alc88x_simple_mic_automute(codec);
0c4cc443 9771 break;
a9fd4f3f 9772 default:
d922b51d 9773 alc_sku_unsol_event(codec, res);
a9fd4f3f 9774 break;
0c4cc443 9775 }
368c7a95
J
9776}
9777
fb97dc67 9778/* toggle speaker-output according to the hp-jack state */
4f5d1706 9779static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
fb97dc67 9780{
a9fd4f3f 9781 struct alc_spec *spec = codec->spec;
fb97dc67 9782
a9fd4f3f
TI
9783 spec->autocfg.hp_pins[0] = 0x14;
9784 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
9785 spec->automute = 1;
9786 spec->automute_mode = ALC_AUTOMUTE_AMP;
fb97dc67
J
9787}
9788
4f5d1706 9789static void alc883_haier_w66_setup(struct hda_codec *codec)
fb97dc67 9790{
a9fd4f3f 9791 struct alc_spec *spec = codec->spec;
189609ae 9792
a9fd4f3f
TI
9793 spec->autocfg.hp_pins[0] = 0x1b;
9794 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
9795 spec->automute = 1;
9796 spec->automute_mode = ALC_AUTOMUTE_AMP;
189609ae
KY
9797}
9798
e6a5e1b7 9799static void alc883_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 9800{
e6a5e1b7 9801 struct alc_spec *spec = codec->spec;
bc9f98a9 9802
e6a5e1b7
TI
9803 spec->autocfg.hp_pins[0] = 0x1b;
9804 spec->autocfg.line_out_pins[0] = 0x14;
9805 spec->autocfg.speaker_pins[0] = 0x15;
9806 spec->automute = 1;
9807 spec->detect_line = 1;
9808 spec->automute_lines = 1;
9809 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
9810}
9811
676a9b53 9812/* toggle speaker-output according to the hp-jack state */
4f5d1706 9813static void alc883_acer_aspire_setup(struct hda_codec *codec)
676a9b53 9814{
a9fd4f3f 9815 struct alc_spec *spec = codec->spec;
676a9b53 9816
a9fd4f3f
TI
9817 spec->autocfg.hp_pins[0] = 0x14;
9818 spec->autocfg.speaker_pins[0] = 0x15;
9819 spec->autocfg.speaker_pins[1] = 0x16;
d922b51d
TI
9820 spec->automute = 1;
9821 spec->automute_mode = ALC_AUTOMUTE_AMP;
676a9b53
TI
9822}
9823
a9111321 9824static const struct hda_verb alc883_acer_eapd_verbs[] = {
d1a991a6
KY
9825 /* HP Pin: output 0 (0x0c) */
9826 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9827 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9828 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9829 /* Front Pin: output 0 (0x0c) */
676a9b53
TI
9830 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9831 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
d1a991a6 9832 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
d1a991a6
KY
9833 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9834 /* eanable EAPD on medion laptop */
9835 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9836 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
676a9b53
TI
9837 /* enable unsolicited event */
9838 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
d1a991a6
KY
9839 { }
9840};
9841
4f5d1706 9842static void alc888_6st_dell_setup(struct hda_codec *codec)
5795b9e6 9843{
a9fd4f3f 9844 struct alc_spec *spec = codec->spec;
5795b9e6 9845
a9fd4f3f
TI
9846 spec->autocfg.hp_pins[0] = 0x1b;
9847 spec->autocfg.speaker_pins[0] = 0x14;
9848 spec->autocfg.speaker_pins[1] = 0x15;
9849 spec->autocfg.speaker_pins[2] = 0x16;
9850 spec->autocfg.speaker_pins[3] = 0x17;
d922b51d
TI
9851 spec->automute = 1;
9852 spec->automute_mode = ALC_AUTOMUTE_AMP;
5795b9e6
CM
9853}
9854
4f5d1706 9855static void alc888_lenovo_sky_setup(struct hda_codec *codec)
e2757d5e 9856{
a9fd4f3f 9857 struct alc_spec *spec = codec->spec;
e2757d5e 9858
a9fd4f3f
TI
9859 spec->autocfg.hp_pins[0] = 0x1b;
9860 spec->autocfg.speaker_pins[0] = 0x14;
9861 spec->autocfg.speaker_pins[1] = 0x15;
9862 spec->autocfg.speaker_pins[2] = 0x16;
9863 spec->autocfg.speaker_pins[3] = 0x17;
9864 spec->autocfg.speaker_pins[4] = 0x1a;
d922b51d
TI
9865 spec->automute = 1;
9866 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9867}
9868
4f5d1706 9869static void alc883_vaiott_setup(struct hda_codec *codec)
3e1647c5
GG
9870{
9871 struct alc_spec *spec = codec->spec;
9872
9873 spec->autocfg.hp_pins[0] = 0x15;
9874 spec->autocfg.speaker_pins[0] = 0x14;
9875 spec->autocfg.speaker_pins[1] = 0x17;
d922b51d
TI
9876 spec->automute = 1;
9877 spec->automute_mode = ALC_AUTOMUTE_AMP;
3e1647c5
GG
9878}
9879
a9111321 9880static const struct hda_verb alc888_asus_m90v_verbs[] = {
e2757d5e
KY
9881 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9882 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9883 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9884 /* enable unsolicited event */
9885 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9886 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9887 { } /* end */
9888};
9889
4f5d1706 9890static void alc883_mode2_setup(struct hda_codec *codec)
e2757d5e 9891{
a9fd4f3f 9892 struct alc_spec *spec = codec->spec;
e2757d5e 9893
a9fd4f3f
TI
9894 spec->autocfg.hp_pins[0] = 0x1b;
9895 spec->autocfg.speaker_pins[0] = 0x14;
9896 spec->autocfg.speaker_pins[1] = 0x15;
9897 spec->autocfg.speaker_pins[2] = 0x16;
4f5d1706
TI
9898 spec->ext_mic.pin = 0x18;
9899 spec->int_mic.pin = 0x19;
9900 spec->ext_mic.mux_idx = 0;
9901 spec->int_mic.mux_idx = 1;
9902 spec->auto_mic = 1;
d922b51d
TI
9903 spec->automute = 1;
9904 spec->automute_mode = ALC_AUTOMUTE_AMP;
e2757d5e
KY
9905}
9906
a9111321 9907static const struct hda_verb alc888_asus_eee1601_verbs[] = {
e2757d5e
KY
9908 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9910 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9911 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9912 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9913 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9914 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9915 /* enable unsolicited event */
9916 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9917 { } /* end */
9918};
9919
e2757d5e
KY
9920static void alc883_eee1601_inithook(struct hda_codec *codec)
9921{
a9fd4f3f
TI
9922 struct alc_spec *spec = codec->spec;
9923
9924 spec->autocfg.hp_pins[0] = 0x14;
9925 spec->autocfg.speaker_pins[0] = 0x1b;
d922b51d 9926 alc_hp_automute(codec);
e2757d5e
KY
9927}
9928
a9111321 9929static const struct hda_verb alc889A_mb31_verbs[] = {
eb4c41d3
TS
9930 /* Init rear pin (used as headphone output) */
9931 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9932 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9933 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9934 /* Init line pin (used as output in 4ch and 6ch mode) */
9935 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9936 /* Init line 2 pin (used as headphone out by default) */
9937 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9938 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9939 { } /* end */
9940};
9941
9942/* Mute speakers according to the headphone jack state */
9943static void alc889A_mb31_automute(struct hda_codec *codec)
9944{
9945 unsigned int present;
9946
9947 /* Mute only in 2ch or 4ch mode */
9948 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9949 == 0x00) {
864f92be 9950 present = snd_hda_jack_detect(codec, 0x15);
eb4c41d3
TS
9951 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9952 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9953 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9954 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9955 }
9956}
9957
9958static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9959{
9960 if ((res >> 26) == ALC880_HP_EVENT)
9961 alc889A_mb31_automute(codec);
9962}
9963
4953550a 9964
cb53c626 9965#ifdef CONFIG_SND_HDA_POWER_SAVE
4953550a 9966#define alc882_loopbacks alc880_loopbacks
cb53c626
TI
9967#endif
9968
def319f9 9969/* pcm configuration: identical with ALC880 */
4953550a
TI
9970#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9971#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9972#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9973#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9974
4c6d72d1 9975static const hda_nid_t alc883_slave_dig_outs[] = {
4953550a
TI
9976 ALC1200_DIGOUT_NID, 0,
9977};
9978
4c6d72d1 9979static const hda_nid_t alc1200_slave_dig_outs[] = {
4953550a
TI
9980 ALC883_DIGOUT_NID, 0,
9981};
9c7f852e
TI
9982
9983/*
9984 * configuration and preset
9985 */
ea734963 9986static const char * const alc882_models[ALC882_MODEL_LAST] = {
4953550a
TI
9987 [ALC882_3ST_DIG] = "3stack-dig",
9988 [ALC882_6ST_DIG] = "6stack-dig",
9989 [ALC882_ARIMA] = "arima",
9990 [ALC882_W2JC] = "w2jc",
9991 [ALC882_TARGA] = "targa",
9992 [ALC882_ASUS_A7J] = "asus-a7j",
9993 [ALC882_ASUS_A7M] = "asus-a7m",
9994 [ALC885_MACPRO] = "macpro",
9995 [ALC885_MB5] = "mb5",
e458b1fa 9996 [ALC885_MACMINI3] = "macmini3",
76e6f5a9 9997 [ALC885_MBA21] = "mba21",
4953550a
TI
9998 [ALC885_MBP3] = "mbp3",
9999 [ALC885_IMAC24] = "imac24",
4b7e1803 10000 [ALC885_IMAC91] = "imac91",
4953550a 10001 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
f5fcc13c
TI
10002 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10003 [ALC883_3ST_6ch] = "3stack-6ch",
4953550a 10004 [ALC883_6ST_DIG] = "alc883-6stack-dig",
f5fcc13c
TI
10005 [ALC883_TARGA_DIG] = "targa-dig",
10006 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
64a8be74 10007 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
f5fcc13c 10008 [ALC883_ACER] = "acer",
2880a867 10009 [ALC883_ACER_ASPIRE] = "acer-aspire",
5b2d1eca 10010 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
b1a91469 10011 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
3b315d70 10012 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
fc86f954 10013 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
f5fcc13c 10014 [ALC883_MEDION] = "medion",
7ad7b218 10015 [ALC883_MEDION_WIM2160] = "medion-wim2160",
f5fcc13c 10016 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
bc9f98a9 10017 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
272a527c
KY
10018 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10019 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
e2757d5e 10020 [ALC888_LENOVO_SKY] = "lenovo-sky",
189609ae 10021 [ALC883_HAIER_W66] = "haier-w66",
4723c022 10022 [ALC888_3ST_HP] = "3stack-hp",
5795b9e6 10023 [ALC888_6ST_DELL] = "6stack-dell",
a8848bd6 10024 [ALC883_MITAC] = "mitac",
a65cc60f 10025 [ALC883_CLEVO_M540R] = "clevo-m540r",
0c4cc443 10026 [ALC883_CLEVO_M720] = "clevo-m720",
fb97dc67 10027 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
ef8ef5fb 10028 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
17bba1b7 10029 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
87a8c370
JK
10030 [ALC889A_INTEL] = "intel-alc889a",
10031 [ALC889_INTEL] = "intel-x58",
3ab90935 10032 [ALC1200_ASUS_P5Q] = "asus-p5q",
eb4c41d3 10033 [ALC889A_MB31] = "mb31",
3e1647c5 10034 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
4953550a 10035 [ALC882_AUTO] = "auto",
f5fcc13c
TI
10036};
10037
a9111321 10038static const struct snd_pci_quirk alc882_cfg_tbl[] = {
4953550a
TI
10039 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10040
ac3e3741 10041 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
69e50282 10042 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9b6682ff 10043 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
ac3e3741
TI
10044 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10045 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
0b18cb18 10046 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
5b2d1eca
VP
10047 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10048 ALC888_ACER_ASPIRE_4930G),
a8e4f9dd 10049 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
83dd7408 10050 ALC888_ACER_ASPIRE_4930G),
3b315d70
HM
10051 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10052 ALC888_ACER_ASPIRE_8930G),
e46b0c8c
TI
10053 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10054 ALC888_ACER_ASPIRE_8930G),
4953550a
TI
10055 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10056 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
a8e4f9dd 10057 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
dde65356 10058 ALC888_ACER_ASPIRE_6530G),
cc374c47 10059 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
d2fd4b09 10060 ALC888_ACER_ASPIRE_6530G),
fc86f954
DK
10061 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10062 ALC888_ACER_ASPIRE_7730G),
22b530e0
TI
10063 /* default Acer -- disabled as it causes more problems.
10064 * model=auto should work fine now
10065 */
10066 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
4953550a 10067
5795b9e6 10068 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
4953550a 10069
25985edc 10070 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
ac3e3741
TI
10071 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10072 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
5d85f8d0 10073 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
06bf3e15 10074 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
7ec30f0e 10075 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
4953550a
TI
10076
10077 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10078 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10079 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
a01c30cb 10080 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
4953550a
TI
10081 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10082 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10083 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
ac3e3741 10084 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
44a678d0 10085 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
3ab90935 10086 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
e2757d5e 10087 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
4953550a
TI
10088
10089 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
97ec710c 10090 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
4953550a 10091 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
2de686d2 10092 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
ac3e3741
TI
10093 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10094 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
e2757d5e 10095 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
ac3e3741 10096 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
ebb47241 10097 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
4953550a 10098
6f3bf657 10099 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
bba8dee7 10100 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10101 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10102 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
2fef62c8 10103 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
4953550a 10104 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
dd146a60 10105 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
82808236 10106 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
f5fcc13c 10107 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
ac3e3741 10108 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10109 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10110 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
ac3e3741 10111 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
64ca1c29 10112 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
b1e4422f 10113 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
f5fcc13c
TI
10114 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10115 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10116 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
b43f6e5e 10117 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
64a8be74 10118 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
ac3e3741
TI
10119 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10120 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10121 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
ee09543c 10122 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
86d34b7e 10123 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
ac3e3741
TI
10124 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10125 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
df01b8af 10126 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
b43f6e5e 10127 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
f5fcc13c 10128 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
b1e4422f 10129 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
4953550a 10130
ac3e3741 10131 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
d1501ea8 10132 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
0c4cc443
HRK
10133 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10134 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
a65cc60f 10135 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
dea0a509 10136 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
e60623b4 10137 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
4953550a 10138 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
f5fcc13c 10139 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
bfb53037 10140 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
f67d8176 10141 ALC883_FUJITSU_PI2515),
bfb53037 10142 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
ef8ef5fb 10143 ALC888_FUJITSU_XA3530),
272a527c 10144 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
272a527c 10145 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
ac3e3741
TI
10146 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10147 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
e2757d5e 10148 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
959973b9 10149 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
0b167bf4 10150 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
189609ae 10151 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
4953550a 10152
17bba1b7
J
10153 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10154 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
2de686d2 10155 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
87a8c370
JK
10156 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10157 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10158 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
572c0e3c 10159 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
9c7f852e 10160
4953550a 10161 {}
f3cd3f5d
WF
10162};
10163
4953550a 10164/* codec SSID table for Intel Mac */
a9111321 10165static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
4953550a
TI
10166 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10167 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10168 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10169 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10170 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10171 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10172 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
26fd74fc 10173 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
ab669967 10174 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
f53dae28 10175 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
6e12970b 10176 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
4953550a
TI
10177 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10178 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10179 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
4b7e1803 10180 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
4953550a 10181 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
3bfea98f 10182 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
46ef6ec9
DC
10183 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10184 * so apparently no perfect solution yet
4953550a
TI
10185 */
10186 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
46ef6ec9 10187 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
e458b1fa 10188 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
4953550a 10189 {} /* terminator */
b25c9da1
WF
10190};
10191
a9111321 10192static const struct alc_config_preset alc882_presets[] = {
4953550a
TI
10193 [ALC882_3ST_DIG] = {
10194 .mixers = { alc882_base_mixer },
8ab9e0af
TI
10195 .init_verbs = { alc882_base_init_verbs,
10196 alc882_adc1_init_verbs },
4953550a
TI
10197 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10198 .dac_nids = alc882_dac_nids,
10199 .dig_out_nid = ALC882_DIGOUT_NID,
10200 .dig_in_nid = ALC882_DIGIN_NID,
10201 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10202 .channel_mode = alc882_ch_modes,
10203 .need_dac_fix = 1,
10204 .input_mux = &alc882_capture_source,
10205 },
10206 [ALC882_6ST_DIG] = {
10207 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10208 .init_verbs = { alc882_base_init_verbs,
10209 alc882_adc1_init_verbs },
4953550a
TI
10210 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10211 .dac_nids = alc882_dac_nids,
10212 .dig_out_nid = ALC882_DIGOUT_NID,
10213 .dig_in_nid = ALC882_DIGIN_NID,
10214 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10215 .channel_mode = alc882_sixstack_modes,
10216 .input_mux = &alc882_capture_source,
10217 },
10218 [ALC882_ARIMA] = {
10219 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10220 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10221 alc882_eapd_verbs },
4953550a
TI
10222 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10223 .dac_nids = alc882_dac_nids,
10224 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10225 .channel_mode = alc882_sixstack_modes,
10226 .input_mux = &alc882_capture_source,
10227 },
10228 [ALC882_W2JC] = {
10229 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10230 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10231 alc882_eapd_verbs, alc880_gpio1_init_verbs },
4953550a
TI
10232 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10233 .dac_nids = alc882_dac_nids,
10234 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10235 .channel_mode = alc880_threestack_modes,
10236 .need_dac_fix = 1,
10237 .input_mux = &alc882_capture_source,
10238 .dig_out_nid = ALC882_DIGOUT_NID,
10239 },
76e6f5a9
RH
10240 [ALC885_MBA21] = {
10241 .mixers = { alc885_mba21_mixer },
10242 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10243 .num_dacs = 2,
10244 .dac_nids = alc882_dac_nids,
10245 .channel_mode = alc885_mba21_ch_modes,
10246 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10247 .input_mux = &alc882_capture_source,
d922b51d 10248 .unsol_event = alc_sku_unsol_event,
76e6f5a9 10249 .setup = alc885_mba21_setup,
d922b51d 10250 .init_hook = alc_hp_automute,
76e6f5a9 10251 },
4953550a
TI
10252 [ALC885_MBP3] = {
10253 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10254 .init_verbs = { alc885_mbp3_init_verbs,
10255 alc880_gpio1_init_verbs },
be0ae923 10256 .num_dacs = 2,
4953550a 10257 .dac_nids = alc882_dac_nids,
be0ae923
TI
10258 .hp_nid = 0x04,
10259 .channel_mode = alc885_mbp_4ch_modes,
10260 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
4953550a
TI
10261 .input_mux = &alc882_capture_source,
10262 .dig_out_nid = ALC882_DIGOUT_NID,
10263 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10264 .unsol_event = alc_sku_unsol_event,
4f5d1706 10265 .setup = alc885_mbp3_setup,
d922b51d 10266 .init_hook = alc_hp_automute,
4953550a
TI
10267 },
10268 [ALC885_MB5] = {
10269 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10270 .init_verbs = { alc885_mb5_init_verbs,
10271 alc880_gpio1_init_verbs },
10272 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10273 .dac_nids = alc882_dac_nids,
10274 .channel_mode = alc885_mb5_6ch_modes,
10275 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10276 .input_mux = &mb5_capture_source,
10277 .dig_out_nid = ALC882_DIGOUT_NID,
10278 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10279 .unsol_event = alc_sku_unsol_event,
9d54f08b 10280 .setup = alc885_mb5_setup,
d922b51d 10281 .init_hook = alc_hp_automute,
4953550a 10282 },
e458b1fa
LY
10283 [ALC885_MACMINI3] = {
10284 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10285 .init_verbs = { alc885_macmini3_init_verbs,
10286 alc880_gpio1_init_verbs },
10287 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10288 .dac_nids = alc882_dac_nids,
10289 .channel_mode = alc885_macmini3_6ch_modes,
10290 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10291 .input_mux = &macmini3_capture_source,
10292 .dig_out_nid = ALC882_DIGOUT_NID,
10293 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10294 .unsol_event = alc_sku_unsol_event,
9d54f08b 10295 .setup = alc885_macmini3_setup,
d922b51d 10296 .init_hook = alc_hp_automute,
e458b1fa 10297 },
4953550a
TI
10298 [ALC885_MACPRO] = {
10299 .mixers = { alc882_macpro_mixer },
10300 .init_verbs = { alc882_macpro_init_verbs },
10301 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10302 .dac_nids = alc882_dac_nids,
10303 .dig_out_nid = ALC882_DIGOUT_NID,
10304 .dig_in_nid = ALC882_DIGIN_NID,
10305 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10306 .channel_mode = alc882_ch_modes,
10307 .input_mux = &alc882_capture_source,
10308 .init_hook = alc885_macpro_init_hook,
10309 },
10310 [ALC885_IMAC24] = {
10311 .mixers = { alc885_imac24_mixer },
10312 .init_verbs = { alc885_imac24_init_verbs },
10313 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10314 .dac_nids = alc882_dac_nids,
10315 .dig_out_nid = ALC882_DIGOUT_NID,
10316 .dig_in_nid = ALC882_DIGIN_NID,
10317 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10318 .channel_mode = alc882_ch_modes,
10319 .input_mux = &alc882_capture_source,
d922b51d 10320 .unsol_event = alc_sku_unsol_event,
4f5d1706 10321 .setup = alc885_imac24_setup,
4953550a
TI
10322 .init_hook = alc885_imac24_init_hook,
10323 },
4b7e1803 10324 [ALC885_IMAC91] = {
b7cccc52 10325 .mixers = {alc885_imac91_mixer},
4b7e1803
JM
10326 .init_verbs = { alc885_imac91_init_verbs,
10327 alc880_gpio1_init_verbs },
10328 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10329 .dac_nids = alc882_dac_nids,
b7cccc52
JM
10330 .channel_mode = alc885_mba21_ch_modes,
10331 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10332 .input_mux = &alc889A_imac91_capture_source,
4b7e1803
JM
10333 .dig_out_nid = ALC882_DIGOUT_NID,
10334 .dig_in_nid = ALC882_DIGIN_NID,
d922b51d 10335 .unsol_event = alc_sku_unsol_event,
9d54f08b 10336 .setup = alc885_imac91_setup,
d922b51d 10337 .init_hook = alc_hp_automute,
4b7e1803 10338 },
4953550a
TI
10339 [ALC882_TARGA] = {
10340 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8ab9e0af 10341 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
31909b83 10342 alc880_gpio3_init_verbs, alc882_targa_verbs},
4953550a
TI
10343 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10344 .dac_nids = alc882_dac_nids,
10345 .dig_out_nid = ALC882_DIGOUT_NID,
10346 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10347 .adc_nids = alc882_adc_nids,
10348 .capsrc_nids = alc882_capsrc_nids,
10349 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10350 .channel_mode = alc882_3ST_6ch_modes,
10351 .need_dac_fix = 1,
10352 .input_mux = &alc882_capture_source,
d922b51d 10353 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
10354 .setup = alc882_targa_setup,
10355 .init_hook = alc882_targa_automute,
4953550a
TI
10356 },
10357 [ALC882_ASUS_A7J] = {
10358 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10359 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10360 alc882_asus_a7j_verbs},
4953550a
TI
10361 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10362 .dac_nids = alc882_dac_nids,
10363 .dig_out_nid = ALC882_DIGOUT_NID,
10364 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10365 .adc_nids = alc882_adc_nids,
10366 .capsrc_nids = alc882_capsrc_nids,
10367 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10368 .channel_mode = alc882_3ST_6ch_modes,
10369 .need_dac_fix = 1,
10370 .input_mux = &alc882_capture_source,
10371 },
10372 [ALC882_ASUS_A7M] = {
10373 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
8ab9e0af
TI
10374 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10375 alc882_eapd_verbs, alc880_gpio1_init_verbs,
4953550a
TI
10376 alc882_asus_a7m_verbs },
10377 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10378 .dac_nids = alc882_dac_nids,
10379 .dig_out_nid = ALC882_DIGOUT_NID,
10380 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10381 .channel_mode = alc880_threestack_modes,
10382 .need_dac_fix = 1,
10383 .input_mux = &alc882_capture_source,
10384 },
9c7f852e
TI
10385 [ALC883_3ST_2ch_DIG] = {
10386 .mixers = { alc883_3ST_2ch_mixer },
10387 .init_verbs = { alc883_init_verbs },
10388 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10389 .dac_nids = alc883_dac_nids,
10390 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10391 .dig_in_nid = ALC883_DIGIN_NID,
10392 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10393 .channel_mode = alc883_3ST_2ch_modes,
10394 .input_mux = &alc883_capture_source,
10395 },
10396 [ALC883_3ST_6ch_DIG] = {
10397 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10398 .init_verbs = { alc883_init_verbs },
10399 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10400 .dac_nids = alc883_dac_nids,
10401 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10402 .dig_in_nid = ALC883_DIGIN_NID,
10403 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10404 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10405 .need_dac_fix = 1,
9c7f852e 10406 .input_mux = &alc883_capture_source,
f12ab1e0 10407 },
9c7f852e
TI
10408 [ALC883_3ST_6ch] = {
10409 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10410 .init_verbs = { alc883_init_verbs },
10411 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10412 .dac_nids = alc883_dac_nids,
9c7f852e
TI
10413 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10414 .channel_mode = alc883_3ST_6ch_modes,
4e195a7b 10415 .need_dac_fix = 1,
9c7f852e 10416 .input_mux = &alc883_capture_source,
f12ab1e0 10417 },
17bba1b7
J
10418 [ALC883_3ST_6ch_INTEL] = {
10419 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10420 .init_verbs = { alc883_init_verbs },
10421 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10422 .dac_nids = alc883_dac_nids,
10423 .dig_out_nid = ALC883_DIGOUT_NID,
10424 .dig_in_nid = ALC883_DIGIN_NID,
f3cd3f5d 10425 .slave_dig_outs = alc883_slave_dig_outs,
17bba1b7
J
10426 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10427 .channel_mode = alc883_3ST_6ch_intel_modes,
10428 .need_dac_fix = 1,
10429 .input_mux = &alc883_3stack_6ch_intel,
10430 },
87a8c370
JK
10431 [ALC889A_INTEL] = {
10432 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
6732bd0d
WF
10433 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10434 alc_hp15_unsol_verbs },
87a8c370
JK
10435 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10436 .dac_nids = alc883_dac_nids,
10437 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10438 .adc_nids = alc889_adc_nids,
10439 .dig_out_nid = ALC883_DIGOUT_NID,
10440 .dig_in_nid = ALC883_DIGIN_NID,
10441 .slave_dig_outs = alc883_slave_dig_outs,
10442 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10443 .channel_mode = alc889_8ch_intel_modes,
10444 .capsrc_nids = alc889_capsrc_nids,
10445 .input_mux = &alc889_capture_source,
4f5d1706 10446 .setup = alc889_automute_setup,
d922b51d
TI
10447 .init_hook = alc_hp_automute,
10448 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10449 .need_dac_fix = 1,
10450 },
10451 [ALC889_INTEL] = {
10452 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10453 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
6732bd0d 10454 alc889_eapd_verbs, alc_hp15_unsol_verbs},
87a8c370
JK
10455 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10456 .dac_nids = alc883_dac_nids,
10457 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10458 .adc_nids = alc889_adc_nids,
10459 .dig_out_nid = ALC883_DIGOUT_NID,
10460 .dig_in_nid = ALC883_DIGIN_NID,
10461 .slave_dig_outs = alc883_slave_dig_outs,
10462 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10463 .channel_mode = alc889_8ch_intel_modes,
10464 .capsrc_nids = alc889_capsrc_nids,
10465 .input_mux = &alc889_capture_source,
4f5d1706 10466 .setup = alc889_automute_setup,
6732bd0d 10467 .init_hook = alc889_intel_init_hook,
d922b51d 10468 .unsol_event = alc_sku_unsol_event,
87a8c370
JK
10469 .need_dac_fix = 1,
10470 },
9c7f852e
TI
10471 [ALC883_6ST_DIG] = {
10472 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10473 .init_verbs = { alc883_init_verbs },
10474 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10475 .dac_nids = alc883_dac_nids,
10476 .dig_out_nid = ALC883_DIGOUT_NID,
9c7f852e
TI
10477 .dig_in_nid = ALC883_DIGIN_NID,
10478 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10479 .channel_mode = alc883_sixstack_modes,
10480 .input_mux = &alc883_capture_source,
10481 },
ccc656ce 10482 [ALC883_TARGA_DIG] = {
c259249f 10483 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
005b1076
DH
10484 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10485 alc883_targa_verbs},
ccc656ce
KY
10486 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10487 .dac_nids = alc883_dac_nids,
10488 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10489 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10490 .channel_mode = alc883_3ST_6ch_modes,
10491 .need_dac_fix = 1,
10492 .input_mux = &alc883_capture_source,
c259249f 10493 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10494 .setup = alc882_targa_setup,
10495 .init_hook = alc882_targa_automute,
ccc656ce
KY
10496 },
10497 [ALC883_TARGA_2ch_DIG] = {
c259249f 10498 .mixers = { alc883_targa_2ch_mixer},
005b1076
DH
10499 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10500 alc883_targa_verbs},
ccc656ce
KY
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10503 .adc_nids = alc883_adc_nids_alt,
10504 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10505 .capsrc_nids = alc883_capsrc_nids,
ccc656ce 10506 .dig_out_nid = ALC883_DIGOUT_NID,
ccc656ce
KY
10507 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10508 .channel_mode = alc883_3ST_2ch_modes,
10509 .input_mux = &alc883_capture_source,
c259249f 10510 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10511 .setup = alc882_targa_setup,
10512 .init_hook = alc882_targa_automute,
ccc656ce 10513 },
64a8be74 10514 [ALC883_TARGA_8ch_DIG] = {
b99dba34
TI
10515 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10516 alc883_chmode_mixer },
64a8be74 10517 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
c259249f 10518 alc883_targa_verbs },
64a8be74
DH
10519 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10520 .dac_nids = alc883_dac_nids,
10521 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10522 .adc_nids = alc883_adc_nids_rev,
10523 .capsrc_nids = alc883_capsrc_nids_rev,
10524 .dig_out_nid = ALC883_DIGOUT_NID,
10525 .dig_in_nid = ALC883_DIGIN_NID,
10526 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10527 .channel_mode = alc883_4ST_8ch_modes,
10528 .need_dac_fix = 1,
10529 .input_mux = &alc883_capture_source,
c259249f 10530 .unsol_event = alc883_targa_unsol_event,
4f5d1706
TI
10531 .setup = alc882_targa_setup,
10532 .init_hook = alc882_targa_automute,
64a8be74 10533 },
bab282b9 10534 [ALC883_ACER] = {
676a9b53 10535 .mixers = { alc883_base_mixer },
bab282b9
VA
10536 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10537 * and the headphone jack. Turn this on and rely on the
10538 * standard mute methods whenever the user wants to turn
10539 * these outputs off.
10540 */
10541 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10542 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10543 .dac_nids = alc883_dac_nids,
bab282b9
VA
10544 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10545 .channel_mode = alc883_3ST_2ch_modes,
10546 .input_mux = &alc883_capture_source,
10547 },
2880a867 10548 [ALC883_ACER_ASPIRE] = {
676a9b53 10549 .mixers = { alc883_acer_aspire_mixer },
d1a991a6 10550 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
2880a867
TD
10551 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10552 .dac_nids = alc883_dac_nids,
10553 .dig_out_nid = ALC883_DIGOUT_NID,
2880a867
TD
10554 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10555 .channel_mode = alc883_3ST_2ch_modes,
10556 .input_mux = &alc883_capture_source,
d922b51d 10557 .unsol_event = alc_sku_unsol_event,
4f5d1706 10558 .setup = alc883_acer_aspire_setup,
d922b51d 10559 .init_hook = alc_hp_automute,
d1a991a6 10560 },
5b2d1eca 10561 [ALC888_ACER_ASPIRE_4930G] = {
460c92fa 10562 .mixers = { alc888_acer_aspire_4930g_mixer,
5b2d1eca
VP
10563 alc883_chmode_mixer },
10564 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10565 alc888_acer_aspire_4930g_verbs },
10566 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10567 .dac_nids = alc883_dac_nids,
10568 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10569 .adc_nids = alc883_adc_nids_rev,
10570 .capsrc_nids = alc883_capsrc_nids_rev,
10571 .dig_out_nid = ALC883_DIGOUT_NID,
10572 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10573 .channel_mode = alc883_3ST_6ch_modes,
10574 .need_dac_fix = 1,
973b8cb0 10575 .const_channel_count = 6,
5b2d1eca 10576 .num_mux_defs =
ef8ef5fb
VP
10577 ARRAY_SIZE(alc888_2_capture_sources),
10578 .input_mux = alc888_2_capture_sources,
d922b51d 10579 .unsol_event = alc_sku_unsol_event,
4f5d1706 10580 .setup = alc888_acer_aspire_4930g_setup,
d922b51d 10581 .init_hook = alc_hp_automute,
d2fd4b09
TV
10582 },
10583 [ALC888_ACER_ASPIRE_6530G] = {
10584 .mixers = { alc888_acer_aspire_6530_mixer },
10585 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10586 alc888_acer_aspire_6530g_verbs },
10587 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10588 .dac_nids = alc883_dac_nids,
10589 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10590 .adc_nids = alc883_adc_nids_rev,
10591 .capsrc_nids = alc883_capsrc_nids_rev,
10592 .dig_out_nid = ALC883_DIGOUT_NID,
10593 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10594 .channel_mode = alc883_3ST_2ch_modes,
10595 .num_mux_defs =
10596 ARRAY_SIZE(alc888_2_capture_sources),
10597 .input_mux = alc888_acer_aspire_6530_sources,
d922b51d 10598 .unsol_event = alc_sku_unsol_event,
4f5d1706 10599 .setup = alc888_acer_aspire_6530g_setup,
d922b51d 10600 .init_hook = alc_hp_automute,
5b2d1eca 10601 },
3b315d70 10602 [ALC888_ACER_ASPIRE_8930G] = {
556eea9a 10603 .mixers = { alc889_acer_aspire_8930g_mixer,
3b315d70
HM
10604 alc883_chmode_mixer },
10605 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
0f86a228
HM
10606 alc889_acer_aspire_8930g_verbs,
10607 alc889_eapd_verbs},
3b315d70
HM
10608 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10609 .dac_nids = alc883_dac_nids,
018df418
HM
10610 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10611 .adc_nids = alc889_adc_nids,
10612 .capsrc_nids = alc889_capsrc_nids,
3b315d70
HM
10613 .dig_out_nid = ALC883_DIGOUT_NID,
10614 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10615 .channel_mode = alc883_3ST_6ch_modes,
10616 .need_dac_fix = 1,
10617 .const_channel_count = 6,
10618 .num_mux_defs =
018df418
HM
10619 ARRAY_SIZE(alc889_capture_sources),
10620 .input_mux = alc889_capture_sources,
d922b51d 10621 .unsol_event = alc_sku_unsol_event,
4f5d1706 10622 .setup = alc889_acer_aspire_8930g_setup,
d922b51d 10623 .init_hook = alc_hp_automute,
f5de24b0 10624#ifdef CONFIG_SND_HDA_POWER_SAVE
c97259df 10625 .power_hook = alc_power_eapd,
f5de24b0 10626#endif
3b315d70 10627 },
fc86f954
DK
10628 [ALC888_ACER_ASPIRE_7730G] = {
10629 .mixers = { alc883_3ST_6ch_mixer,
10630 alc883_chmode_mixer },
10631 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10632 alc888_acer_aspire_7730G_verbs },
10633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10634 .dac_nids = alc883_dac_nids,
10635 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10636 .adc_nids = alc883_adc_nids_rev,
10637 .capsrc_nids = alc883_capsrc_nids_rev,
10638 .dig_out_nid = ALC883_DIGOUT_NID,
10639 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10640 .channel_mode = alc883_3ST_6ch_modes,
10641 .need_dac_fix = 1,
10642 .const_channel_count = 6,
10643 .input_mux = &alc883_capture_source,
d922b51d 10644 .unsol_event = alc_sku_unsol_event,
d9477207 10645 .setup = alc888_acer_aspire_7730g_setup,
d922b51d 10646 .init_hook = alc_hp_automute,
fc86f954 10647 },
c07584c8
TD
10648 [ALC883_MEDION] = {
10649 .mixers = { alc883_fivestack_mixer,
10650 alc883_chmode_mixer },
10651 .init_verbs = { alc883_init_verbs,
b373bdeb 10652 alc883_medion_eapd_verbs },
c07584c8
TD
10653 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10654 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10655 .adc_nids = alc883_adc_nids_alt,
10656 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10657 .capsrc_nids = alc883_capsrc_nids,
c07584c8
TD
10658 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10659 .channel_mode = alc883_sixstack_modes,
10660 .input_mux = &alc883_capture_source,
b373bdeb 10661 },
7ad7b218
MC
10662 [ALC883_MEDION_WIM2160] = {
10663 .mixers = { alc883_medion_wim2160_mixer },
10664 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10665 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10666 .dac_nids = alc883_dac_nids,
10667 .dig_out_nid = ALC883_DIGOUT_NID,
10668 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10669 .adc_nids = alc883_adc_nids,
10670 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10671 .channel_mode = alc883_3ST_2ch_modes,
10672 .input_mux = &alc883_capture_source,
d922b51d 10673 .unsol_event = alc_sku_unsol_event,
7ad7b218 10674 .setup = alc883_medion_wim2160_setup,
d922b51d 10675 .init_hook = alc_hp_automute,
7ad7b218 10676 },
b373bdeb 10677 [ALC883_LAPTOP_EAPD] = {
676a9b53 10678 .mixers = { alc883_base_mixer },
b373bdeb
AN
10679 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10680 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10681 .dac_nids = alc883_dac_nids,
b373bdeb
AN
10682 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10683 .channel_mode = alc883_3ST_2ch_modes,
10684 .input_mux = &alc883_capture_source,
10685 },
a65cc60f 10686 [ALC883_CLEVO_M540R] = {
10687 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10688 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10689 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10690 .dac_nids = alc883_dac_nids,
10691 .dig_out_nid = ALC883_DIGOUT_NID,
10692 .dig_in_nid = ALC883_DIGIN_NID,
10693 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10694 .channel_mode = alc883_3ST_6ch_clevo_modes,
10695 .need_dac_fix = 1,
10696 .input_mux = &alc883_capture_source,
10697 /* This machine has the hardware HP auto-muting, thus
10698 * we need no software mute via unsol event
10699 */
10700 },
0c4cc443
HRK
10701 [ALC883_CLEVO_M720] = {
10702 .mixers = { alc883_clevo_m720_mixer },
10703 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
368c7a95
J
10704 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10705 .dac_nids = alc883_dac_nids,
10706 .dig_out_nid = ALC883_DIGOUT_NID,
10707 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10708 .channel_mode = alc883_3ST_2ch_modes,
10709 .input_mux = &alc883_capture_source,
0c4cc443 10710 .unsol_event = alc883_clevo_m720_unsol_event,
4f5d1706 10711 .setup = alc883_clevo_m720_setup,
a9fd4f3f 10712 .init_hook = alc883_clevo_m720_init_hook,
368c7a95 10713 },
bc9f98a9
KY
10714 [ALC883_LENOVO_101E_2ch] = {
10715 .mixers = { alc883_lenovo_101e_2ch_mixer},
10716 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10717 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10718 .dac_nids = alc883_dac_nids,
f9e336f6
TI
10719 .adc_nids = alc883_adc_nids_alt,
10720 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
035eb0cf 10721 .capsrc_nids = alc883_capsrc_nids,
bc9f98a9
KY
10722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10723 .channel_mode = alc883_3ST_2ch_modes,
10724 .input_mux = &alc883_lenovo_101e_capture_source,
e6a5e1b7
TI
10725 .setup = alc883_lenovo_101e_setup,
10726 .unsol_event = alc_sku_unsol_event,
10727 .init_hook = alc_inithook,
bc9f98a9 10728 },
272a527c
KY
10729 [ALC883_LENOVO_NB0763] = {
10730 .mixers = { alc883_lenovo_nb0763_mixer },
10731 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10732 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10733 .dac_nids = alc883_dac_nids,
272a527c
KY
10734 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10735 .channel_mode = alc883_3ST_2ch_modes,
10736 .need_dac_fix = 1,
10737 .input_mux = &alc883_lenovo_nb0763_capture_source,
d922b51d 10738 .unsol_event = alc_sku_unsol_event,
dc427170 10739 .setup = alc883_lenovo_nb0763_setup,
d922b51d 10740 .init_hook = alc_hp_automute,
272a527c
KY
10741 },
10742 [ALC888_LENOVO_MS7195_DIG] = {
10743 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10744 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10745 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10746 .dac_nids = alc883_dac_nids,
10747 .dig_out_nid = ALC883_DIGOUT_NID,
272a527c
KY
10748 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10749 .channel_mode = alc883_3ST_6ch_modes,
10750 .need_dac_fix = 1,
10751 .input_mux = &alc883_capture_source,
e6a5e1b7
TI
10752 .unsol_event = alc_sku_unsol_event,
10753 .setup = alc888_lenovo_ms7195_setup,
10754 .init_hook = alc_inithook,
189609ae
KY
10755 },
10756 [ALC883_HAIER_W66] = {
c259249f 10757 .mixers = { alc883_targa_2ch_mixer},
189609ae
KY
10758 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10759 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10760 .dac_nids = alc883_dac_nids,
10761 .dig_out_nid = ALC883_DIGOUT_NID,
189609ae
KY
10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10763 .channel_mode = alc883_3ST_2ch_modes,
10764 .input_mux = &alc883_capture_source,
d922b51d 10765 .unsol_event = alc_sku_unsol_event,
4f5d1706 10766 .setup = alc883_haier_w66_setup,
d922b51d 10767 .init_hook = alc_hp_automute,
eea6419e 10768 },
4723c022 10769 [ALC888_3ST_HP] = {
eea6419e 10770 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
4723c022 10771 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
8341de60
CM
10772 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10773 .dac_nids = alc883_dac_nids,
4723c022
CM
10774 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10775 .channel_mode = alc888_3st_hp_modes,
8341de60
CM
10776 .need_dac_fix = 1,
10777 .input_mux = &alc883_capture_source,
d922b51d 10778 .unsol_event = alc_sku_unsol_event,
4f5d1706 10779 .setup = alc888_3st_hp_setup,
d922b51d 10780 .init_hook = alc_hp_automute,
8341de60 10781 },
5795b9e6 10782 [ALC888_6ST_DELL] = {
f24dbdc6 10783 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5795b9e6
CM
10784 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10785 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10786 .dac_nids = alc883_dac_nids,
10787 .dig_out_nid = ALC883_DIGOUT_NID,
5795b9e6
CM
10788 .dig_in_nid = ALC883_DIGIN_NID,
10789 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10790 .channel_mode = alc883_sixstack_modes,
10791 .input_mux = &alc883_capture_source,
d922b51d 10792 .unsol_event = alc_sku_unsol_event,
4f5d1706 10793 .setup = alc888_6st_dell_setup,
d922b51d 10794 .init_hook = alc_hp_automute,
5795b9e6 10795 },
a8848bd6
AS
10796 [ALC883_MITAC] = {
10797 .mixers = { alc883_mitac_mixer },
10798 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10799 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10800 .dac_nids = alc883_dac_nids,
a8848bd6
AS
10801 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10802 .channel_mode = alc883_3ST_2ch_modes,
10803 .input_mux = &alc883_capture_source,
d922b51d 10804 .unsol_event = alc_sku_unsol_event,
4f5d1706 10805 .setup = alc883_mitac_setup,
d922b51d 10806 .init_hook = alc_hp_automute,
a8848bd6 10807 },
fb97dc67
J
10808 [ALC883_FUJITSU_PI2515] = {
10809 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10810 .init_verbs = { alc883_init_verbs,
10811 alc883_2ch_fujitsu_pi2515_verbs},
10812 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10813 .dac_nids = alc883_dac_nids,
10814 .dig_out_nid = ALC883_DIGOUT_NID,
10815 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10816 .channel_mode = alc883_3ST_2ch_modes,
10817 .input_mux = &alc883_fujitsu_pi2515_capture_source,
d922b51d 10818 .unsol_event = alc_sku_unsol_event,
4f5d1706 10819 .setup = alc883_2ch_fujitsu_pi2515_setup,
d922b51d 10820 .init_hook = alc_hp_automute,
fb97dc67 10821 },
ef8ef5fb
VP
10822 [ALC888_FUJITSU_XA3530] = {
10823 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10824 .init_verbs = { alc883_init_verbs,
10825 alc888_fujitsu_xa3530_verbs },
10826 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10827 .dac_nids = alc883_dac_nids,
10828 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10829 .adc_nids = alc883_adc_nids_rev,
10830 .capsrc_nids = alc883_capsrc_nids_rev,
10831 .dig_out_nid = ALC883_DIGOUT_NID,
10832 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10833 .channel_mode = alc888_4ST_8ch_intel_modes,
10834 .num_mux_defs =
10835 ARRAY_SIZE(alc888_2_capture_sources),
10836 .input_mux = alc888_2_capture_sources,
d922b51d 10837 .unsol_event = alc_sku_unsol_event,
4f5d1706 10838 .setup = alc888_fujitsu_xa3530_setup,
d922b51d 10839 .init_hook = alc_hp_automute,
ef8ef5fb 10840 },
e2757d5e
KY
10841 [ALC888_LENOVO_SKY] = {
10842 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10843 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10844 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10845 .dac_nids = alc883_dac_nids,
10846 .dig_out_nid = ALC883_DIGOUT_NID,
e2757d5e
KY
10847 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10848 .channel_mode = alc883_sixstack_modes,
10849 .need_dac_fix = 1,
10850 .input_mux = &alc883_lenovo_sky_capture_source,
d922b51d 10851 .unsol_event = alc_sku_unsol_event,
4f5d1706 10852 .setup = alc888_lenovo_sky_setup,
d922b51d 10853 .init_hook = alc_hp_automute,
e2757d5e
KY
10854 },
10855 [ALC888_ASUS_M90V] = {
10856 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10857 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859 .dac_nids = alc883_dac_nids,
10860 .dig_out_nid = ALC883_DIGOUT_NID,
10861 .dig_in_nid = ALC883_DIGIN_NID,
10862 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10863 .channel_mode = alc883_3ST_6ch_modes,
10864 .need_dac_fix = 1,
10865 .input_mux = &alc883_fujitsu_pi2515_capture_source,
4f5d1706
TI
10866 .unsol_event = alc_sku_unsol_event,
10867 .setup = alc883_mode2_setup,
10868 .init_hook = alc_inithook,
e2757d5e
KY
10869 },
10870 [ALC888_ASUS_EEE1601] = {
10871 .mixers = { alc883_asus_eee1601_mixer },
f9e336f6 10872 .cap_mixer = alc883_asus_eee1601_cap_mixer,
e2757d5e
KY
10873 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10874 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10875 .dac_nids = alc883_dac_nids,
10876 .dig_out_nid = ALC883_DIGOUT_NID,
10877 .dig_in_nid = ALC883_DIGIN_NID,
10878 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10879 .channel_mode = alc883_3ST_2ch_modes,
10880 .need_dac_fix = 1,
10881 .input_mux = &alc883_asus_eee1601_capture_source,
a9fd4f3f 10882 .unsol_event = alc_sku_unsol_event,
e2757d5e
KY
10883 .init_hook = alc883_eee1601_inithook,
10884 },
3ab90935
WF
10885 [ALC1200_ASUS_P5Q] = {
10886 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10887 .init_verbs = { alc883_init_verbs },
10888 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10889 .dac_nids = alc883_dac_nids,
10890 .dig_out_nid = ALC1200_DIGOUT_NID,
10891 .dig_in_nid = ALC883_DIGIN_NID,
b25c9da1 10892 .slave_dig_outs = alc1200_slave_dig_outs,
3ab90935
WF
10893 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10894 .channel_mode = alc883_sixstack_modes,
10895 .input_mux = &alc883_capture_source,
10896 },
eb4c41d3
TS
10897 [ALC889A_MB31] = {
10898 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10899 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10900 alc880_gpio1_init_verbs },
10901 .adc_nids = alc883_adc_nids,
10902 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
035eb0cf 10903 .capsrc_nids = alc883_capsrc_nids,
eb4c41d3
TS
10904 .dac_nids = alc883_dac_nids,
10905 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10906 .channel_mode = alc889A_mb31_6ch_modes,
10907 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10908 .input_mux = &alc889A_mb31_capture_source,
10909 .dig_out_nid = ALC883_DIGOUT_NID,
10910 .unsol_event = alc889A_mb31_unsol_event,
10911 .init_hook = alc889A_mb31_automute,
10912 },
3e1647c5
GG
10913 [ALC883_SONY_VAIO_TT] = {
10914 .mixers = { alc883_vaiott_mixer },
10915 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10916 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10917 .dac_nids = alc883_dac_nids,
10918 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10919 .channel_mode = alc883_3ST_2ch_modes,
10920 .input_mux = &alc883_capture_source,
d922b51d 10921 .unsol_event = alc_sku_unsol_event,
4f5d1706 10922 .setup = alc883_vaiott_setup,
d922b51d 10923 .init_hook = alc_hp_automute,
3e1647c5 10924 },
9c7f852e
TI
10925};
10926
10927
4953550a
TI
10928/*
10929 * Pin config fixes
10930 */
10931enum {
954a29c8 10932 PINFIX_ABIT_AW9D_MAX,
32eea388 10933 PINFIX_LENOVO_Y530,
954a29c8 10934 PINFIX_PB_M5210,
c3d226ab 10935 PINFIX_ACER_ASPIRE_7736,
4953550a
TI
10936};
10937
f8f25ba3
TI
10938static const struct alc_fixup alc882_fixups[] = {
10939 [PINFIX_ABIT_AW9D_MAX] = {
b5bfbc67
TI
10940 .type = ALC_FIXUP_PINS,
10941 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
10942 { 0x15, 0x01080104 }, /* side */
10943 { 0x16, 0x01011012 }, /* rear */
10944 { 0x17, 0x01016011 }, /* clfe */
10945 { }
10946 }
f8f25ba3 10947 },
32eea388
DH
10948 [PINFIX_LENOVO_Y530] = {
10949 .type = ALC_FIXUP_PINS,
10950 .v.pins = (const struct alc_pincfg[]) {
10951 { 0x15, 0x99130112 }, /* rear int speakers */
10952 { 0x16, 0x99130111 }, /* subwoofer */
10953 { }
10954 }
10955 },
954a29c8 10956 [PINFIX_PB_M5210] = {
b5bfbc67
TI
10957 .type = ALC_FIXUP_VERBS,
10958 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
10959 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10960 {}
10961 }
954a29c8 10962 },
c3d226ab 10963 [PINFIX_ACER_ASPIRE_7736] = {
b5bfbc67
TI
10964 .type = ALC_FIXUP_SKU,
10965 .v.sku = ALC_FIXUP_SKU_IGNORE,
c3d226ab 10966 },
4953550a
TI
10967};
10968
a9111321 10969static const struct snd_pci_quirk alc882_fixup_tbl[] = {
954a29c8 10970 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
32eea388 10971 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
4953550a 10972 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
c3d226ab 10973 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
4953550a
TI
10974 {}
10975};
10976
9c7f852e
TI
10977/*
10978 * BIOS auto configuration
10979 */
05f5f477
TI
10980static int alc882_auto_create_input_ctls(struct hda_codec *codec,
10981 const struct auto_pin_cfg *cfg)
10982{
10983 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
10984}
10985
4953550a 10986static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9c7f852e 10987 hda_nid_t nid, int pin_type,
489008cd 10988 hda_nid_t dac)
9c7f852e 10989{
f12ab1e0
TI
10990 int idx;
10991
489008cd 10992 /* set as output */
f6c7e546 10993 alc_set_pin_output(codec, nid, pin_type);
489008cd
TI
10994
10995 if (dac == 0x25)
9c7f852e 10996 idx = 4;
489008cd
TI
10997 else if (dac >= 0x02 && dac <= 0x05)
10998 idx = dac - 2;
f9700d5a 10999 else
489008cd 11000 return;
9c7f852e 11001 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
9c7f852e
TI
11002}
11003
4953550a 11004static void alc882_auto_init_multi_out(struct hda_codec *codec)
9c7f852e
TI
11005{
11006 struct alc_spec *spec = codec->spec;
11007 int i;
11008
11009 for (i = 0; i <= HDA_SIDE; i++) {
f12ab1e0 11010 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 11011 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9c7f852e 11012 if (nid)
4953550a 11013 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
489008cd 11014 spec->multiout.dac_nids[i]);
9c7f852e
TI
11015 }
11016}
11017
4953550a 11018static void alc882_auto_init_hp_out(struct hda_codec *codec)
9c7f852e
TI
11019{
11020 struct alc_spec *spec = codec->spec;
489008cd 11021 hda_nid_t pin, dac;
5855fb80 11022 int i;
9c7f852e 11023
0a3fabe3
DH
11024 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11025 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11026 pin = spec->autocfg.hp_pins[i];
11027 if (!pin)
11028 break;
11029 dac = spec->multiout.hp_nid;
11030 if (!dac)
11031 dac = spec->multiout.dac_nids[0]; /* to front */
11032 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11033 }
489008cd 11034 }
0a3fabe3
DH
11035
11036 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11037 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11038 pin = spec->autocfg.speaker_pins[i];
11039 if (!pin)
11040 break;
11041 dac = spec->multiout.extra_out_nid[0];
11042 if (!dac)
11043 dac = spec->multiout.dac_nids[0]; /* to front */
11044 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11045 }
489008cd 11046 }
9c7f852e
TI
11047}
11048
4953550a 11049static void alc882_auto_init_analog_input(struct hda_codec *codec)
9c7f852e
TI
11050{
11051 struct alc_spec *spec = codec->spec;
66ceeb6b 11052 struct auto_pin_cfg *cfg = &spec->autocfg;
9c7f852e
TI
11053 int i;
11054
66ceeb6b
TI
11055 for (i = 0; i < cfg->num_inputs; i++) {
11056 hda_nid_t nid = cfg->inputs[i].pin;
30ea098f 11057 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
4953550a
TI
11058 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11059 snd_hda_codec_write(codec, nid, 0,
11060 AC_VERB_SET_AMP_GAIN_MUTE,
11061 AMP_OUT_MUTE);
11062 }
11063}
11064
11065static void alc882_auto_init_input_src(struct hda_codec *codec)
11066{
11067 struct alc_spec *spec = codec->spec;
11068 int c;
11069
11070 for (c = 0; c < spec->num_adc_nids; c++) {
11071 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11072 hda_nid_t nid = spec->capsrc_nids[c];
11073 unsigned int mux_idx;
11074 const struct hda_input_mux *imux;
11075 int conns, mute, idx, item;
11076
10696aa0
TI
11077 /* mute ADC */
11078 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11079 AC_VERB_SET_AMP_GAIN_MUTE,
11080 AMP_IN_MUTE(0));
11081
4953550a
TI
11082 conns = snd_hda_get_connections(codec, nid, conn_list,
11083 ARRAY_SIZE(conn_list));
11084 if (conns < 0)
11085 continue;
11086 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11087 imux = &spec->input_mux[mux_idx];
5311114d
TI
11088 if (!imux->num_items && mux_idx > 0)
11089 imux = &spec->input_mux[0];
4953550a
TI
11090 for (idx = 0; idx < conns; idx++) {
11091 /* if the current connection is the selected one,
11092 * unmute it as default - otherwise mute it
11093 */
11094 mute = AMP_IN_MUTE(idx);
11095 for (item = 0; item < imux->num_items; item++) {
11096 if (imux->items[item].index == idx) {
11097 if (spec->cur_mux[c] == item)
11098 mute = AMP_IN_UNMUTE(idx);
11099 break;
11100 }
11101 }
11102 /* check if we have a selector or mixer
11103 * we could check for the widget type instead, but
11104 * just check for Amp-In presence (in case of mixer
11105 * without amp-in there is something wrong, this
11106 * function shouldn't be used or capsrc nid is wrong)
11107 */
11108 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9c7f852e
TI
11109 snd_hda_codec_write(codec, nid, 0,
11110 AC_VERB_SET_AMP_GAIN_MUTE,
4953550a
TI
11111 mute);
11112 else if (mute != AMP_IN_MUTE(idx))
11113 snd_hda_codec_write(codec, nid, 0,
11114 AC_VERB_SET_CONNECT_SEL,
11115 idx);
9c7f852e
TI
11116 }
11117 }
11118}
11119
4953550a
TI
11120/* add mic boosts if needed */
11121static int alc_auto_add_mic_boost(struct hda_codec *codec)
11122{
11123 struct alc_spec *spec = codec->spec;
66ceeb6b 11124 struct auto_pin_cfg *cfg = &spec->autocfg;
5322bf27 11125 int i, err;
53e8c323 11126 int type_idx = 0;
4953550a 11127 hda_nid_t nid;
5322bf27 11128 const char *prev_label = NULL;
4953550a 11129
66ceeb6b 11130 for (i = 0; i < cfg->num_inputs; i++) {
86e2959a 11131 if (cfg->inputs[i].type > AUTO_PIN_MIC)
66ceeb6b
TI
11132 break;
11133 nid = cfg->inputs[i].pin;
11134 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
5322bf27
DH
11135 const char *label;
11136 char boost_label[32];
11137
11138 label = hda_get_autocfg_input_label(codec, cfg, i);
11139 if (prev_label && !strcmp(label, prev_label))
53e8c323
TI
11140 type_idx++;
11141 else
11142 type_idx = 0;
5322bf27
DH
11143 prev_label = label;
11144
11145 snprintf(boost_label, sizeof(boost_label),
11146 "%s Boost Volume", label);
11147 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11148 boost_label, type_idx,
4953550a 11149 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
66ceeb6b
TI
11150 if (err < 0)
11151 return err;
11152 }
4953550a
TI
11153 }
11154 return 0;
11155}
f511b01c 11156
9c7f852e 11157/* almost identical with ALC880 parser... */
4953550a 11158static int alc882_parse_auto_config(struct hda_codec *codec)
9c7f852e
TI
11159{
11160 struct alc_spec *spec = codec->spec;
4c6d72d1 11161 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
757899ac 11162 int err;
9c7f852e 11163
05f5f477
TI
11164 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11165 alc882_ignore);
9c7f852e
TI
11166 if (err < 0)
11167 return err;
05f5f477
TI
11168 if (!spec->autocfg.line_outs)
11169 return 0; /* can't find valid BIOS pin config */
776e184e 11170
05f5f477 11171 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
11172 if (err < 0)
11173 return err;
11174 err = alc_auto_add_multi_channel_mode(codec);
05f5f477
TI
11175 if (err < 0)
11176 return err;
569ed348 11177 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
489008cd
TI
11178 if (err < 0)
11179 return err;
11180 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11181 "Headphone");
05f5f477
TI
11182 if (err < 0)
11183 return err;
11184 err = alc880_auto_create_extra_out(spec,
11185 spec->autocfg.speaker_pins[0],
11186 "Speaker");
11187 if (err < 0)
11188 return err;
05f5f477 11189 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
776e184e
TI
11190 if (err < 0)
11191 return err;
11192
05f5f477
TI
11193 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11194
757899ac 11195 alc_auto_parse_digital(codec);
05f5f477
TI
11196
11197 if (spec->kctls.list)
11198 add_mixer(spec, spec->kctls.list);
11199
11200 add_verb(spec, alc883_auto_init_verbs);
4953550a 11201 /* if ADC 0x07 is available, initialize it, too */
05f5f477 11202 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
4953550a 11203 add_verb(spec, alc882_adc1_init_verbs);
776e184e 11204
05f5f477
TI
11205 spec->num_mux_defs = 1;
11206 spec->input_mux = &spec->private_imux[0];
11207
6227cdce 11208 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
05f5f477
TI
11209
11210 err = alc_auto_add_mic_boost(codec);
11211 if (err < 0)
11212 return err;
61b9b9b1 11213
776e184e 11214 return 1; /* config found */
9c7f852e
TI
11215}
11216
11217/* additional initialization for auto-configuration model */
4953550a 11218static void alc882_auto_init(struct hda_codec *codec)
9c7f852e 11219{
f6c7e546 11220 struct alc_spec *spec = codec->spec;
4953550a
TI
11221 alc882_auto_init_multi_out(codec);
11222 alc882_auto_init_hp_out(codec);
11223 alc882_auto_init_analog_input(codec);
11224 alc882_auto_init_input_src(codec);
757899ac 11225 alc_auto_init_digital(codec);
f6c7e546 11226 if (spec->unsol_event)
7fb0d78f 11227 alc_inithook(codec);
9c7f852e
TI
11228}
11229
4953550a 11230static int patch_alc882(struct hda_codec *codec)
9c7f852e
TI
11231{
11232 struct alc_spec *spec;
11233 int err, board_config;
11234
11235 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11236 if (spec == NULL)
11237 return -ENOMEM;
11238
11239 codec->spec = spec;
11240
4953550a
TI
11241 switch (codec->vendor_id) {
11242 case 0x10ec0882:
11243 case 0x10ec0885:
11244 break;
11245 default:
11246 /* ALC883 and variants */
11247 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11248 break;
11249 }
2c3bf9ab 11250
4953550a
TI
11251 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11252 alc882_models,
11253 alc882_cfg_tbl);
11254
11255 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11256 board_config = snd_hda_check_board_codec_sid_config(codec,
11257 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11258
11259 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9a11f1aa 11260 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4953550a
TI
11261 codec->chip_name);
11262 board_config = ALC882_AUTO;
9c7f852e
TI
11263 }
11264
b5bfbc67
TI
11265 if (board_config == ALC882_AUTO) {
11266 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11267 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11268 }
4953550a 11269
90622917
DH
11270 alc_auto_parse_customize_define(codec);
11271
4953550a 11272 if (board_config == ALC882_AUTO) {
9c7f852e 11273 /* automatic parse from the BIOS config */
4953550a 11274 err = alc882_parse_auto_config(codec);
9c7f852e
TI
11275 if (err < 0) {
11276 alc_free(codec);
11277 return err;
f12ab1e0 11278 } else if (!err) {
9c7f852e
TI
11279 printk(KERN_INFO
11280 "hda_codec: Cannot set up configuration "
11281 "from BIOS. Using base mode...\n");
4953550a 11282 board_config = ALC882_3ST_DIG;
9c7f852e
TI
11283 }
11284 }
11285
dc1eae25 11286 if (has_cdefine_beep(codec)) {
8af2591d
TI
11287 err = snd_hda_attach_beep_device(codec, 0x1);
11288 if (err < 0) {
11289 alc_free(codec);
11290 return err;
11291 }
680cd536
KK
11292 }
11293
4953550a 11294 if (board_config != ALC882_AUTO)
e9c364c0 11295 setup_preset(codec, &alc882_presets[board_config]);
9c7f852e 11296
4953550a
TI
11297 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11298 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11299 /* FIXME: setup DAC5 */
11300 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11301 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11302
11303 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11304 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11305
4953550a 11306 if (!spec->adc_nids && spec->input_mux) {
d11f74c6 11307 int i, j;
4953550a
TI
11308 spec->num_adc_nids = 0;
11309 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
d11f74c6 11310 const struct hda_input_mux *imux = spec->input_mux;
4953550a 11311 hda_nid_t cap;
d11f74c6 11312 hda_nid_t items[16];
4953550a
TI
11313 hda_nid_t nid = alc882_adc_nids[i];
11314 unsigned int wcap = get_wcaps(codec, nid);
11315 /* get type */
a22d543a 11316 wcap = get_wcaps_type(wcap);
4953550a
TI
11317 if (wcap != AC_WID_AUD_IN)
11318 continue;
11319 spec->private_adc_nids[spec->num_adc_nids] = nid;
11320 err = snd_hda_get_connections(codec, nid, &cap, 1);
11321 if (err < 0)
11322 continue;
d11f74c6
TI
11323 err = snd_hda_get_connections(codec, cap, items,
11324 ARRAY_SIZE(items));
11325 if (err < 0)
11326 continue;
11327 for (j = 0; j < imux->num_items; j++)
11328 if (imux->items[j].index >= err)
11329 break;
11330 if (j < imux->num_items)
11331 continue;
4953550a
TI
11332 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11333 spec->num_adc_nids++;
61b9b9b1 11334 }
4953550a
TI
11335 spec->adc_nids = spec->private_adc_nids;
11336 spec->capsrc_nids = spec->private_capsrc_nids;
2f893286
KY
11337 }
11338
b59bdf3b 11339 set_capture_mixer(codec);
da00c244 11340
dc1eae25 11341 if (has_cdefine_beep(codec))
da00c244 11342 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9c7f852e 11343
b5bfbc67 11344 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 11345
2134ea4f
TI
11346 spec->vmaster_nid = 0x0c;
11347
9c7f852e 11348 codec->patch_ops = alc_patch_ops;
4953550a
TI
11349 if (board_config == ALC882_AUTO)
11350 spec->init_hook = alc882_auto_init;
bf1b0225
KY
11351
11352 alc_init_jacks(codec);
cb53c626
TI
11353#ifdef CONFIG_SND_HDA_POWER_SAVE
11354 if (!spec->loopback.amplist)
4953550a 11355 spec->loopback.amplist = alc882_loopbacks;
cb53c626 11356#endif
9c7f852e
TI
11357
11358 return 0;
11359}
11360
4953550a 11361
9c7f852e
TI
11362/*
11363 * ALC262 support
11364 */
11365
11366#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11367#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11368
11369#define alc262_dac_nids alc260_dac_nids
11370#define alc262_adc_nids alc882_adc_nids
11371#define alc262_adc_nids_alt alc882_adc_nids_alt
88c71a99
TI
11372#define alc262_capsrc_nids alc882_capsrc_nids
11373#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
9c7f852e
TI
11374
11375#define alc262_modes alc260_modes
11376#define alc262_capture_source alc882_capture_source
11377
4c6d72d1 11378static const hda_nid_t alc262_dmic_adc_nids[1] = {
4e555fe5
KY
11379 /* ADC0 */
11380 0x09
11381};
11382
4c6d72d1 11383static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
4e555fe5 11384
a9111321 11385static const struct snd_kcontrol_new alc262_base_mixer[] = {
9c7f852e
TI
11386 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11387 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11388 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11389 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11390 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11391 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11392 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11393 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11394 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11395 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11396 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11397 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11398 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11399 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11400 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11401 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11402 { } /* end */
11403};
11404
ce875f07 11405/* update HP, line and mono-out pins according to the master switch */
e9427969 11406#define alc262_hp_master_update alc260_hp_master_update
ce875f07 11407
e9427969 11408static void alc262_hp_bpc_setup(struct hda_codec *codec)
ce875f07
TI
11409{
11410 struct alc_spec *spec = codec->spec;
864f92be 11411
e9427969
TI
11412 spec->autocfg.hp_pins[0] = 0x1b;
11413 spec->autocfg.speaker_pins[0] = 0x16;
11414 spec->automute = 1;
11415 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11416}
11417
e9427969 11418static void alc262_hp_wildwest_setup(struct hda_codec *codec)
ce875f07
TI
11419{
11420 struct alc_spec *spec = codec->spec;
864f92be 11421
e9427969
TI
11422 spec->autocfg.hp_pins[0] = 0x15;
11423 spec->autocfg.speaker_pins[0] = 0x16;
11424 spec->automute = 1;
11425 spec->automute_mode = ALC_AUTOMUTE_PIN;
ce875f07
TI
11426}
11427
b72519b5 11428#define alc262_hp_master_sw_get alc260_hp_master_sw_get
e9427969 11429#define alc262_hp_master_sw_put alc260_hp_master_sw_put
ce875f07 11430
b72519b5
TI
11431#define ALC262_HP_MASTER_SWITCH \
11432 { \
11433 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11434 .name = "Master Playback Switch", \
11435 .info = snd_ctl_boolean_mono_info, \
11436 .get = alc262_hp_master_sw_get, \
11437 .put = alc262_hp_master_sw_put, \
5b0cb1d8
JK
11438 }, \
11439 { \
11440 .iface = NID_MAPPING, \
11441 .name = "Master Playback Switch", \
11442 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
b72519b5
TI
11443 }
11444
5b0cb1d8 11445
a9111321 11446static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
b72519b5 11447 ALC262_HP_MASTER_SWITCH,
9c7f852e
TI
11448 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11449 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
ce875f07
TI
11451 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11452 HDA_OUTPUT),
11453 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11454 HDA_OUTPUT),
9c7f852e
TI
11455 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11457 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9c7f852e
TI
11458 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11460 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9c7f852e
TI
11461 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11462 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11463 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11464 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9c7f852e
TI
11465 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11466 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11467 { } /* end */
11468};
11469
a9111321 11470static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
b72519b5 11471 ALC262_HP_MASTER_SWITCH,
cd7509a4
KY
11472 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11473 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11474 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11475 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
ce875f07
TI
11476 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11477 HDA_OUTPUT),
11478 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11479 HDA_OUTPUT),
cd7509a4
KY
11480 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5f99f86a 11482 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
cd7509a4
KY
11483 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11484 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11485 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11486 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
cd7509a4
KY
11487 { } /* end */
11488};
11489
a9111321 11490static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
cd7509a4
KY
11491 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11492 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11493 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
cd7509a4
KY
11494 { } /* end */
11495};
11496
66d2a9d6 11497/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11498static void alc262_hp_t5735_setup(struct hda_codec *codec)
66d2a9d6
KY
11499{
11500 struct alc_spec *spec = codec->spec;
66d2a9d6 11501
a9fd4f3f 11502 spec->autocfg.hp_pins[0] = 0x15;
dc99be47 11503 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
11504 spec->automute = 1;
11505 spec->automute_mode = ALC_AUTOMUTE_PIN;
66d2a9d6
KY
11506}
11507
a9111321 11508static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
86cd9298
TI
11509 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11510 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
66d2a9d6
KY
11511 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11512 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11514 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11515 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
66d2a9d6
KY
11516 { } /* end */
11517};
11518
a9111321 11519static const struct hda_verb alc262_hp_t5735_verbs[] = {
66d2a9d6
KY
11520 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11522
11523 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11524 { }
11525};
11526
a9111321 11527static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
f2f48e18
TI
11528 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11529 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
86cd9298
TI
11530 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11531 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8c427226
KY
11532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11534 { } /* end */
11535};
11536
a9111321 11537static const struct hda_verb alc262_hp_rp5700_verbs[] = {
8c427226
KY
11538 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11539 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11540 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11541 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11542 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11543 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11544 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11545 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11546 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11547 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11548 {}
11549};
11550
a9111321 11551static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
8c427226
KY
11552 .num_items = 1,
11553 .items = {
11554 { "Line", 0x1 },
11555 },
11556};
11557
42171c17 11558/* bind hp and internal speaker mute (with plug check) as master switch */
e9427969 11559#define alc262_hippo_master_update alc262_hp_master_update
42171c17 11560#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
e9427969 11561#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
42171c17
TI
11562
11563#define ALC262_HIPPO_MASTER_SWITCH \
11564 { \
11565 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11566 .name = "Master Playback Switch", \
11567 .info = snd_ctl_boolean_mono_info, \
11568 .get = alc262_hippo_master_sw_get, \
11569 .put = alc262_hippo_master_sw_put, \
5b0cb1d8
JK
11570 }, \
11571 { \
11572 .iface = NID_MAPPING, \
11573 .name = "Master Playback Switch", \
11574 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11575 (SUBDEV_SPEAKER(0) << 16), \
0724ea2a 11576 }
42171c17 11577
a9111321 11578static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
42171c17
TI
11579 ALC262_HIPPO_MASTER_SWITCH,
11580 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11581 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11582 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11583 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11584 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11587 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11588 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11589 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11590 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11591 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11592 { } /* end */
11593};
11594
a9111321 11595static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
42171c17
TI
11596 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11597 ALC262_HIPPO_MASTER_SWITCH,
11598 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11599 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11600 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11601 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11602 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11603 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11604 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
42171c17
TI
11605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11607 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
42171c17
TI
11608 { } /* end */
11609};
11610
11611/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 11612static void alc262_hippo_setup(struct hda_codec *codec)
42171c17
TI
11613{
11614 struct alc_spec *spec = codec->spec;
11615
11616 spec->autocfg.hp_pins[0] = 0x15;
11617 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11618 spec->automute = 1;
11619 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11620}
11621
4f5d1706 11622static void alc262_hippo1_setup(struct hda_codec *codec)
42171c17
TI
11623{
11624 struct alc_spec *spec = codec->spec;
11625
11626 spec->autocfg.hp_pins[0] = 0x1b;
11627 spec->autocfg.speaker_pins[0] = 0x14;
e9427969
TI
11628 spec->automute = 1;
11629 spec->automute_mode = ALC_AUTOMUTE_AMP;
42171c17
TI
11630}
11631
11632
a9111321 11633static const struct snd_kcontrol_new alc262_sony_mixer[] = {
0724ea2a 11634 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
42171c17 11635 ALC262_HIPPO_MASTER_SWITCH,
272a527c
KY
11636 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11637 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11638 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11639 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11640 { } /* end */
11641};
11642
a9111321 11643static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
42171c17
TI
11644 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11645 ALC262_HIPPO_MASTER_SWITCH,
83c34218
KY
11646 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11647 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11648 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11650 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11651 { } /* end */
11652};
272a527c 11653
a9111321 11654static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
ba340e82
TV
11655 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11656 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11657 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11658 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11659 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11660 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11663 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
ba340e82
TV
11664 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11665 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 11666 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
ba340e82
TV
11667 { } /* end */
11668};
11669
a9111321 11670static const struct hda_verb alc262_tyan_verbs[] = {
ba340e82
TV
11671 /* Headphone automute */
11672 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11674 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11675
11676 /* P11 AUX_IN, white 4-pin connector */
11677 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11678 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11679 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11680 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11681
11682 {}
11683};
11684
11685/* unsolicited event for HP jack sensing */
4f5d1706 11686static void alc262_tyan_setup(struct hda_codec *codec)
ba340e82 11687{
a9fd4f3f 11688 struct alc_spec *spec = codec->spec;
ba340e82 11689
a9fd4f3f
TI
11690 spec->autocfg.hp_pins[0] = 0x1b;
11691 spec->autocfg.speaker_pins[0] = 0x15;
d922b51d
TI
11692 spec->automute = 1;
11693 spec->automute_mode = ALC_AUTOMUTE_AMP;
ba340e82
TV
11694}
11695
ba340e82 11696
9c7f852e
TI
11697#define alc262_capture_mixer alc882_capture_mixer
11698#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11699
11700/*
11701 * generic initialization of ADC, input mixers and output mixers
11702 */
a9111321 11703static const struct hda_verb alc262_init_verbs[] = {
9c7f852e
TI
11704 /*
11705 * Unmute ADC0-2 and set the default input to mic-in
11706 */
11707 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11709 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11710 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11711 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11712 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11713
cb53c626 11714 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 11715 * mixer widget
f12ab1e0
TI
11716 * Note: PASD motherboards uses the Line In 2 as the input for
11717 * front panel mic (mic 2)
9c7f852e
TI
11718 */
11719 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
11720 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
9c7f852e
TI
11725
11726 /*
df694daa
KY
11727 * Set up output mixers (0x0c - 0x0e)
11728 */
11729 /* set vol=0 to output mixers */
11730 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11732 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11733 /* set up input amps for analog loopback */
11734 /* Amp Indices: DAC = 0, mixer = 1 */
11735 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11736 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11737 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11738 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11739 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11740 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11741
11742 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11743 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11744 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11745 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11746 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11747 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11748
11749 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11751 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11752 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
ea1fb29a 11754
df694daa
KY
11755 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11756 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
ea1fb29a 11757
df694daa
KY
11758 /* FIXME: use matrix-type input source selection */
11759 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11760 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11763 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11764 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11765 /* Input mixer2 */
11766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11768 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11769 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11770 /* Input mixer3 */
11771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11773 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
f12ab1e0 11774 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
df694daa
KY
11775
11776 { }
11777};
1da177e4 11778
a9111321 11779static const struct hda_verb alc262_eapd_verbs[] = {
4e555fe5
KY
11780 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11781 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11782 { }
11783};
11784
a9111321 11785static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
ccc656ce
KY
11786 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11787 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11789
11790 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11791 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11792 {}
11793};
11794
a9111321 11795static const struct hda_verb alc262_sony_unsol_verbs[] = {
272a527c
KY
11796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11797 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11798 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11799
11800 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7b1e8795 11802 {}
272a527c
KY
11803};
11804
a9111321 11805static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
4e555fe5
KY
11806 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11807 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11808 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4e555fe5
KY
11811 { } /* end */
11812};
11813
a9111321 11814static const struct hda_verb alc262_toshiba_s06_verbs[] = {
4e555fe5
KY
11815 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11816 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11817 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11818 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11819 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11820 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11821 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11822 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11823 {}
11824};
11825
4f5d1706 11826static void alc262_toshiba_s06_setup(struct hda_codec *codec)
4e555fe5 11827{
a9fd4f3f
TI
11828 struct alc_spec *spec = codec->spec;
11829
11830 spec->autocfg.hp_pins[0] = 0x15;
11831 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
11832 spec->ext_mic.pin = 0x18;
11833 spec->ext_mic.mux_idx = 0;
11834 spec->int_mic.pin = 0x12;
11835 spec->int_mic.mux_idx = 9;
11836 spec->auto_mic = 1;
d922b51d
TI
11837 spec->automute = 1;
11838 spec->automute_mode = ALC_AUTOMUTE_PIN;
4e555fe5
KY
11839}
11840
e8f9ae2a
PT
11841/*
11842 * nec model
11843 * 0x15 = headphone
11844 * 0x16 = internal speaker
11845 * 0x18 = external mic
11846 */
11847
a9111321 11848static const struct snd_kcontrol_new alc262_nec_mixer[] = {
e8f9ae2a
PT
11849 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11850 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11851
11852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11853 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11854 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
e8f9ae2a
PT
11855
11856 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11857 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11858 { } /* end */
11859};
11860
a9111321 11861static const struct hda_verb alc262_nec_verbs[] = {
e8f9ae2a
PT
11862 /* Unmute Speaker */
11863 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11864
11865 /* Headphone */
11866 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11867 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11868
11869 /* External mic to headphone */
11870 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11871 /* External mic to speaker */
11872 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11873 {}
11874};
11875
834be88d
TI
11876/*
11877 * fujitsu model
5d9fab2d
TV
11878 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11879 * 0x1b = port replicator headphone out
834be88d
TI
11880 */
11881
11882#define ALC_HP_EVENT 0x37
11883
a9111321 11884static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
834be88d
TI
11885 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11886 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5d9fab2d
TV
11887 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11888 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
834be88d
TI
11889 {}
11890};
11891
a9111321 11892static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
0e31daf7
J
11893 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11895 {}
11896};
11897
a9111321 11898static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
e2595322
DC
11899 /* Front Mic pin: input vref at 50% */
11900 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11901 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11902 {}
11903};
11904
a9111321 11905static const struct hda_input_mux alc262_fujitsu_capture_source = {
39d3ed38 11906 .num_items = 3,
834be88d
TI
11907 .items = {
11908 { "Mic", 0x0 },
28c4edb7 11909 { "Internal Mic", 0x1 },
834be88d
TI
11910 { "CD", 0x4 },
11911 },
11912};
11913
a9111321 11914static const struct hda_input_mux alc262_HP_capture_source = {
9c7f852e
TI
11915 .num_items = 5,
11916 .items = {
11917 { "Mic", 0x0 },
accbe498 11918 { "Front Mic", 0x1 },
9c7f852e
TI
11919 { "Line", 0x2 },
11920 { "CD", 0x4 },
11921 { "AUX IN", 0x6 },
11922 },
11923};
11924
a9111321 11925static const struct hda_input_mux alc262_HP_D7000_capture_source = {
accbe498 11926 .num_items = 4,
11927 .items = {
11928 { "Mic", 0x0 },
11929 { "Front Mic", 0x2 },
11930 { "Line", 0x1 },
11931 { "CD", 0x4 },
11932 },
11933};
11934
0f0f391c 11935static void alc262_fujitsu_setup(struct hda_codec *codec)
834be88d
TI
11936{
11937 struct alc_spec *spec = codec->spec;
834be88d 11938
0f0f391c
TI
11939 spec->autocfg.hp_pins[0] = 0x14;
11940 spec->autocfg.hp_pins[1] = 0x1b;
11941 spec->autocfg.speaker_pins[0] = 0x15;
11942 spec->automute = 1;
11943 spec->automute_mode = ALC_AUTOMUTE_AMP;
ebc7a406
TI
11944}
11945
834be88d 11946/* bind volumes of both NID 0x0c and 0x0d */
a9111321 11947static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
cca3b371
TI
11948 .ops = &snd_hda_bind_vol,
11949 .values = {
11950 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11951 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11952 0
11953 },
11954};
834be88d 11955
a9111321 11956static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
cca3b371 11957 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
834be88d
TI
11958 {
11959 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11960 .name = "Master Playback Switch",
0f0f391c
TI
11961 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11962 .info = snd_ctl_boolean_mono_info,
11963 .get = alc262_hp_master_sw_get,
11964 .put = alc262_hp_master_sw_put,
834be88d 11965 },
5b0cb1d8
JK
11966 {
11967 .iface = NID_MAPPING,
11968 .name = "Master Playback Switch",
11969 .private_value = 0x1b,
11970 },
834be88d
TI
11971 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11972 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 11973 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
834be88d
TI
11974 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11975 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 11976 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
11977 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11978 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
834be88d
TI
11979 { } /* end */
11980};
11981
0f0f391c 11982static void alc262_lenovo_3000_setup(struct hda_codec *codec)
0e31daf7 11983{
0f0f391c 11984 struct alc_spec *spec = codec->spec;
0e31daf7 11985
0f0f391c
TI
11986 spec->autocfg.hp_pins[0] = 0x1b;
11987 spec->autocfg.speaker_pins[0] = 0x14;
11988 spec->autocfg.speaker_pins[1] = 0x16;
11989 spec->automute = 1;
11990 spec->automute_mode = ALC_AUTOMUTE_AMP;
0e31daf7
J
11991}
11992
a9111321 11993static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
0e31daf7
J
11994 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11995 {
11996 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11997 .name = "Master Playback Switch",
0f0f391c
TI
11998 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11999 .info = snd_ctl_boolean_mono_info,
12000 .get = alc262_hp_master_sw_get,
12001 .put = alc262_hp_master_sw_put,
0e31daf7
J
12002 },
12003 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12004 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5f99f86a 12005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
0e31daf7
J
12006 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12007 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12008 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
12009 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12010 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
0e31daf7
J
12011 { } /* end */
12012};
12013
a9111321 12014static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
9f99a638 12015 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
42171c17 12016 ALC262_HIPPO_MASTER_SWITCH,
9f99a638
HM
12017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 12019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9f99a638
HM
12020 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 12022 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9f99a638
HM
12023 { } /* end */
12024};
12025
304dcaac 12026/* additional init verbs for Benq laptops */
a9111321 12027static const struct hda_verb alc262_EAPD_verbs[] = {
304dcaac
TI
12028 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12029 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12030 {}
12031};
12032
a9111321 12033static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
83c34218
KY
12034 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12035 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12036
12037 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12038 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12039 {}
12040};
12041
f651b50b 12042/* Samsung Q1 Ultra Vista model setup */
a9111321 12043static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
bb9f76cd
TI
12044 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12045 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
f651b50b
TD
12046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12047 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a
DH
12048 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12049 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
f651b50b
TD
12050 { } /* end */
12051};
12052
a9111321 12053static const struct hda_verb alc262_ultra_verbs[] = {
bb9f76cd
TI
12054 /* output mixer */
12055 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12057 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12058 /* speaker */
12059 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12060 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12061 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12062 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12063 /* HP */
f651b50b 12064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
bb9f76cd
TI
12065 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12066 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12067 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12068 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12069 /* internal mic */
12070 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12071 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12072 /* ADC, choose mic */
12073 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12074 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12075 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12076 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12077 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12078 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12079 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12080 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12081 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12082 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
f651b50b
TD
12083 {}
12084};
12085
f651b50b
TD
12086/* mute/unmute internal speaker according to the hp jack and mute state */
12087static void alc262_ultra_automute(struct hda_codec *codec)
12088{
12089 struct alc_spec *spec = codec->spec;
12090 unsigned int mute;
f651b50b 12091
bb9f76cd
TI
12092 mute = 0;
12093 /* auto-mute only when HP is used as HP */
12094 if (!spec->cur_mux[0]) {
864f92be 12095 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
bb9f76cd
TI
12096 if (spec->jack_present)
12097 mute = HDA_AMP_MUTE;
f651b50b 12098 }
bb9f76cd
TI
12099 /* mute/unmute internal speaker */
12100 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12101 HDA_AMP_MUTE, mute);
12102 /* mute/unmute HP */
12103 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12104 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
f651b50b
TD
12105}
12106
12107/* unsolicited event for HP jack sensing */
12108static void alc262_ultra_unsol_event(struct hda_codec *codec,
12109 unsigned int res)
12110{
12111 if ((res >> 26) != ALC880_HP_EVENT)
12112 return;
12113 alc262_ultra_automute(codec);
12114}
12115
a9111321 12116static const struct hda_input_mux alc262_ultra_capture_source = {
bb9f76cd
TI
12117 .num_items = 2,
12118 .items = {
12119 { "Mic", 0x1 },
12120 { "Headphone", 0x7 },
12121 },
12122};
12123
12124static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12125 struct snd_ctl_elem_value *ucontrol)
12126{
12127 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12128 struct alc_spec *spec = codec->spec;
12129 int ret;
12130
54cbc9ab 12131 ret = alc_mux_enum_put(kcontrol, ucontrol);
bb9f76cd
TI
12132 if (!ret)
12133 return 0;
12134 /* reprogram the HP pin as mic or HP according to the input source */
12135 snd_hda_codec_write_cache(codec, 0x15, 0,
12136 AC_VERB_SET_PIN_WIDGET_CONTROL,
12137 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12138 alc262_ultra_automute(codec); /* mute/unmute HP */
12139 return ret;
12140}
12141
a9111321 12142static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
bb9f76cd
TI
12143 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12144 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12145 {
12146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12147 .name = "Capture Source",
54cbc9ab
TI
12148 .info = alc_mux_enum_info,
12149 .get = alc_mux_enum_get,
bb9f76cd
TI
12150 .put = alc262_ultra_mux_enum_put,
12151 },
5b0cb1d8
JK
12152 {
12153 .iface = NID_MAPPING,
12154 .name = "Capture Source",
12155 .private_value = 0x15,
12156 },
bb9f76cd
TI
12157 { } /* end */
12158};
12159
c3fc1f50
TI
12160/* We use two mixers depending on the output pin; 0x16 is a mono output
12161 * and thus it's bound with a different mixer.
12162 * This function returns which mixer amp should be used.
12163 */
12164static int alc262_check_volbit(hda_nid_t nid)
12165{
12166 if (!nid)
12167 return 0;
12168 else if (nid == 0x16)
12169 return 2;
12170 else
12171 return 1;
12172}
12173
12174static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12175 const char *pfx, int *vbits, int idx)
c3fc1f50 12176{
c3fc1f50
TI
12177 unsigned long val;
12178 int vbit;
12179
12180 vbit = alc262_check_volbit(nid);
12181 if (!vbit)
12182 return 0;
12183 if (*vbits & vbit) /* a volume control for this mixer already there */
12184 return 0;
12185 *vbits |= vbit;
c3fc1f50
TI
12186 if (vbit == 2)
12187 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12188 else
12189 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
033688a5 12190 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
c3fc1f50
TI
12191}
12192
12193static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
033688a5 12194 const char *pfx, int idx)
c3fc1f50 12195{
c3fc1f50
TI
12196 unsigned long val;
12197
12198 if (!nid)
12199 return 0;
c3fc1f50
TI
12200 if (nid == 0x16)
12201 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12202 else
12203 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
033688a5 12204 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
c3fc1f50
TI
12205}
12206
df694daa 12207/* add playback controls from the parsed DAC table */
f12ab1e0
TI
12208static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12209 const struct auto_pin_cfg *cfg)
df694daa 12210{
c3fc1f50
TI
12211 const char *pfx;
12212 int vbits;
033688a5 12213 int i, err;
df694daa
KY
12214
12215 spec->multiout.num_dacs = 1; /* only use one dac */
12216 spec->multiout.dac_nids = spec->private_dac_nids;
dda14410 12217 spec->private_dac_nids[0] = 2;
df694daa 12218
ce764ab2 12219 pfx = alc_get_line_out_pfx(spec, true);
bcb2f0f5 12220 if (!pfx)
c3fc1f50 12221 pfx = "Front";
033688a5
TI
12222 for (i = 0; i < 2; i++) {
12223 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12224 if (err < 0)
12225 return err;
12226 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12227 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12228 "Speaker", i);
12229 if (err < 0)
12230 return err;
12231 }
12232 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12233 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12234 "Headphone", i);
12235 if (err < 0)
12236 return err;
12237 }
12238 }
df694daa 12239
c3fc1f50
TI
12240 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12241 alc262_check_volbit(cfg->speaker_pins[0]) |
12242 alc262_check_volbit(cfg->hp_pins[0]);
12243 if (vbits == 1 || vbits == 2)
12244 pfx = "Master"; /* only one mixer is used */
c3fc1f50 12245 vbits = 0;
033688a5
TI
12246 for (i = 0; i < 2; i++) {
12247 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12248 &vbits, i);
12249 if (err < 0)
12250 return err;
12251 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12252 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12253 "Speaker", &vbits, i);
12254 if (err < 0)
12255 return err;
12256 }
12257 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12258 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12259 "Headphone", &vbits, i);
12260 if (err < 0)
12261 return err;
12262 }
12263 }
f12ab1e0 12264 return 0;
df694daa
KY
12265}
12266
05f5f477 12267#define alc262_auto_create_input_ctls \
eaa9b3a7 12268 alc882_auto_create_input_ctls
df694daa
KY
12269
12270/*
12271 * generic initialization of ADC, input mixers and output mixers
12272 */
a9111321 12273static const struct hda_verb alc262_volume_init_verbs[] = {
df694daa
KY
12274 /*
12275 * Unmute ADC0-2 and set the default input to mic-in
12276 */
12277 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12278 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12279 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12280 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12281 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12282 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12283
cb53c626 12284 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
df694daa 12285 * mixer widget
f12ab1e0
TI
12286 * Note: PASD motherboards uses the Line In 2 as the input for
12287 * front panel mic (mic 2)
df694daa
KY
12288 */
12289 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12290 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12291 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12292 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12293 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12294 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
df694daa
KY
12295
12296 /*
12297 * Set up output mixers (0x0c - 0x0f)
12298 */
12299 /* set vol=0 to output mixers */
12300 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12301 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12302 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
ea1fb29a 12303
df694daa
KY
12304 /* set up input amps for analog loopback */
12305 /* Amp Indices: DAC = 0, mixer = 1 */
12306 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12307 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12308 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12309 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12310 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12311 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12312
12313 /* FIXME: use matrix-type input source selection */
12314 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12315 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12316 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12317 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12318 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12319 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12320 /* Input mixer2 */
12321 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12322 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12323 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12324 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12325 /* Input mixer3 */
12326 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12327 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12328 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12330
12331 { }
12332};
12333
a9111321 12334static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
9c7f852e
TI
12335 /*
12336 * Unmute ADC0-2 and set the default input to mic-in
12337 */
12338 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12339 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12340 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12341 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12342 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12343 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12344
cb53c626 12345 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
9c7f852e 12346 * mixer widget
f12ab1e0
TI
12347 * Note: PASD motherboards uses the Line In 2 as the input for
12348 * front panel mic (mic 2)
9c7f852e
TI
12349 */
12350 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12351 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12352 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12353 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12354 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12355 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12356 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12357 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
ea1fb29a 12358
9c7f852e
TI
12359 /*
12360 * Set up output mixers (0x0c - 0x0e)
12361 */
12362 /* set vol=0 to output mixers */
12363 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12365 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12366
12367 /* set up input amps for analog loopback */
12368 /* Amp Indices: DAC = 0, mixer = 1 */
12369 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12371 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12372 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12373 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12374 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12375
ce875f07 12376 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9c7f852e
TI
12377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12378 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12379
12380 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12382
12383 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12384 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12385
12386 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12387 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12388 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12389 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12390 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12391
0e4835c1 12392 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12393 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12394 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
0e4835c1 12395 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
9c7f852e
TI
12396 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12397 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12398
12399
12400 /* FIXME: use matrix-type input source selection */
0e4835c1
JK
12401 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12402 /* Input mixer1: only unmute Mic */
9c7f852e 12403 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12404 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12405 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12406 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12407 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12408 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12409 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12410 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12411 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12412 /* Input mixer2 */
12413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12421 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e
TI
12422 /* Input mixer3 */
12423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
0e4835c1
JK
12424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12426 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12427 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12428 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12429 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12430 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
9c7f852e 12432
ce875f07
TI
12433 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12434
9c7f852e
TI
12435 { }
12436};
12437
a9111321 12438static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
cd7509a4
KY
12439 /*
12440 * Unmute ADC0-2 and set the default input to mic-in
12441 */
12442 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12443 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12444 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12445 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12446 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12447 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12448
cb53c626 12449 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
cd7509a4
KY
12450 * mixer widget
12451 * Note: PASD motherboards uses the Line In 2 as the input for front
12452 * panel mic (mic 2)
12453 */
12454 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
12455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12458 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12459 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12460 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12461 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12462 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
cd7509a4
KY
12463 /*
12464 * Set up output mixers (0x0c - 0x0e)
12465 */
12466 /* set vol=0 to output mixers */
12467 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12468 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12470
12471 /* set up input amps for analog loopback */
12472 /* Amp Indices: DAC = 0, mixer = 1 */
12473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12476 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12479
12480
12481 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12482 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12483 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12485 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12486 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12487 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12488
12489 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12490 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12491
12492 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12493 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12494
12495 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12496 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12497 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12498 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12499 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12500 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12501
12502 /* FIXME: use matrix-type input source selection */
12503 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12504 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12505 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12506 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12508 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12509 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12510 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12511 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12512 /* Input mixer2 */
12513 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12514 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12515 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12516 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12517 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12518 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12519 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12520 /* Input mixer3 */
12521 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12522 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12524 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12525 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12526 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12527 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12528
ce875f07
TI
12529 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12530
cd7509a4
KY
12531 { }
12532};
12533
a9111321 12534static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
9f99a638
HM
12535
12536 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12537 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12538 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12539
12540 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12541 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12543 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12544
12545 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12546 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12547 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12548 {}
12549};
12550
18675e42
TI
12551/*
12552 * Pin config fixes
12553 */
12554enum {
12555 PINFIX_FSC_H270,
12556};
12557
12558static const struct alc_fixup alc262_fixups[] = {
12559 [PINFIX_FSC_H270] = {
b5bfbc67
TI
12560 .type = ALC_FIXUP_PINS,
12561 .v.pins = (const struct alc_pincfg[]) {
18675e42
TI
12562 { 0x14, 0x99130110 }, /* speaker */
12563 { 0x15, 0x0221142f }, /* front HP */
12564 { 0x1b, 0x0121141f }, /* rear HP */
12565 { }
12566 }
12567 },
18675e42
TI
12568};
12569
a9111321 12570static const struct snd_pci_quirk alc262_fixup_tbl[] = {
18675e42
TI
12571 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12572 {}
12573};
12574
9f99a638 12575
cb53c626
TI
12576#ifdef CONFIG_SND_HDA_POWER_SAVE
12577#define alc262_loopbacks alc880_loopbacks
12578#endif
12579
def319f9 12580/* pcm configuration: identical with ALC880 */
df694daa
KY
12581#define alc262_pcm_analog_playback alc880_pcm_analog_playback
12582#define alc262_pcm_analog_capture alc880_pcm_analog_capture
12583#define alc262_pcm_digital_playback alc880_pcm_digital_playback
12584#define alc262_pcm_digital_capture alc880_pcm_digital_capture
12585
12586/*
12587 * BIOS auto configuration
12588 */
12589static int alc262_parse_auto_config(struct hda_codec *codec)
12590{
12591 struct alc_spec *spec = codec->spec;
12592 int err;
4c6d72d1 12593 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
df694daa 12594
f12ab1e0
TI
12595 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12596 alc262_ignore);
12597 if (err < 0)
df694daa 12598 return err;
e64f14f4 12599 if (!spec->autocfg.line_outs) {
0852d7a6 12600 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
e64f14f4
TI
12601 spec->multiout.max_channels = 2;
12602 spec->no_analog = 1;
12603 goto dig_only;
12604 }
df694daa 12605 return 0; /* can't find valid BIOS pin config */
e64f14f4 12606 }
f12ab1e0
TI
12607 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12608 if (err < 0)
12609 return err;
05f5f477 12610 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 12611 if (err < 0)
df694daa
KY
12612 return err;
12613
12614 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12615
e64f14f4 12616 dig_only:
757899ac 12617 alc_auto_parse_digital(codec);
df694daa 12618
603c4019 12619 if (spec->kctls.list)
d88897ea 12620 add_mixer(spec, spec->kctls.list);
df694daa 12621
d88897ea 12622 add_verb(spec, alc262_volume_init_verbs);
a1e8d2da 12623 spec->num_mux_defs = 1;
61b9b9b1 12624 spec->input_mux = &spec->private_imux[0];
df694daa 12625
776e184e
TI
12626 err = alc_auto_add_mic_boost(codec);
12627 if (err < 0)
12628 return err;
12629
6227cdce 12630 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 12631
df694daa
KY
12632 return 1;
12633}
12634
12635#define alc262_auto_init_multi_out alc882_auto_init_multi_out
12636#define alc262_auto_init_hp_out alc882_auto_init_hp_out
12637#define alc262_auto_init_analog_input alc882_auto_init_analog_input
f511b01c 12638#define alc262_auto_init_input_src alc882_auto_init_input_src
df694daa
KY
12639
12640
12641/* init callback for auto-configuration model -- overriding the default init */
ae6b813a 12642static void alc262_auto_init(struct hda_codec *codec)
df694daa 12643{
f6c7e546 12644 struct alc_spec *spec = codec->spec;
df694daa
KY
12645 alc262_auto_init_multi_out(codec);
12646 alc262_auto_init_hp_out(codec);
12647 alc262_auto_init_analog_input(codec);
f511b01c 12648 alc262_auto_init_input_src(codec);
757899ac 12649 alc_auto_init_digital(codec);
f6c7e546 12650 if (spec->unsol_event)
7fb0d78f 12651 alc_inithook(codec);
df694daa
KY
12652}
12653
12654/*
12655 * configuration and preset
12656 */
ea734963 12657static const char * const alc262_models[ALC262_MODEL_LAST] = {
f5fcc13c
TI
12658 [ALC262_BASIC] = "basic",
12659 [ALC262_HIPPO] = "hippo",
12660 [ALC262_HIPPO_1] = "hippo_1",
12661 [ALC262_FUJITSU] = "fujitsu",
12662 [ALC262_HP_BPC] = "hp-bpc",
cd7509a4 12663 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
61dc35de 12664 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8c427226 12665 [ALC262_HP_RP5700] = "hp-rp5700",
f5fcc13c 12666 [ALC262_BENQ_ED8] = "benq",
0f40502e
TI
12667 [ALC262_BENQ_T31] = "benq-t31",
12668 [ALC262_SONY_ASSAMD] = "sony-assamd",
2922c9af 12669 [ALC262_TOSHIBA_S06] = "toshiba-s06",
9f99a638 12670 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
f651b50b 12671 [ALC262_ULTRA] = "ultra",
0e31daf7 12672 [ALC262_LENOVO_3000] = "lenovo-3000",
e8f9ae2a 12673 [ALC262_NEC] = "nec",
ba340e82 12674 [ALC262_TYAN] = "tyan",
f5fcc13c
TI
12675 [ALC262_AUTO] = "auto",
12676};
12677
a9111321 12678static const struct snd_pci_quirk alc262_cfg_tbl[] = {
f5fcc13c 12679 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
e8f9ae2a 12680 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
dea0a509
TI
12681 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12682 ALC262_HP_BPC),
12683 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12684 ALC262_HP_BPC),
5734a07c
TI
12685 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12686 ALC262_HP_BPC),
53eff7e1
TI
12687 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12688 ALC262_HP_BPC),
cd7509a4 12689 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12690 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12691 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12692 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12693 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12694 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741 12695 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
cd7509a4 12696 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
ac3e3741
TI
12697 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12698 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12699 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
66d2a9d6
KY
12700 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12701 ALC262_HP_TC_T5735),
8c427226 12702 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
ac3e3741 12703 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
f5fcc13c 12704 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
5b31954e 12705 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
bd6afe3f 12706 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
376b508f 12707 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
95491d90 12708 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12929bae 12709 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
c5b5165c 12710#if 0 /* disable the quirk since model=auto works better in recent versions */
f872a919
TI
12711 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12712 ALC262_SONY_ASSAMD),
c5b5165c 12713#endif
36ca6e13 12714 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
9f99a638 12715 ALC262_TOSHIBA_RX1),
80ffe869 12716 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
ac3e3741 12717 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
3f1eeaed 12718 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
ba340e82 12719 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
dea0a509
TI
12720 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12721 ALC262_ULTRA),
3e420e78 12722 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
0e31daf7 12723 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
ac3e3741
TI
12724 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12725 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12726 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
df694daa
KY
12727 {}
12728};
12729
a9111321 12730static const struct alc_config_preset alc262_presets[] = {
df694daa
KY
12731 [ALC262_BASIC] = {
12732 .mixers = { alc262_base_mixer },
12733 .init_verbs = { alc262_init_verbs },
12734 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12735 .dac_nids = alc262_dac_nids,
12736 .hp_nid = 0x03,
12737 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12738 .channel_mode = alc262_modes,
a3bcba38 12739 .input_mux = &alc262_capture_source,
df694daa 12740 },
ccc656ce 12741 [ALC262_HIPPO] = {
42171c17 12742 .mixers = { alc262_hippo_mixer },
6732bd0d 12743 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
ccc656ce
KY
12744 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12745 .dac_nids = alc262_dac_nids,
12746 .hp_nid = 0x03,
12747 .dig_out_nid = ALC262_DIGOUT_NID,
12748 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12749 .channel_mode = alc262_modes,
12750 .input_mux = &alc262_capture_source,
e9427969 12751 .unsol_event = alc_sku_unsol_event,
4f5d1706 12752 .setup = alc262_hippo_setup,
e9427969 12753 .init_hook = alc_inithook,
ccc656ce
KY
12754 },
12755 [ALC262_HIPPO_1] = {
12756 .mixers = { alc262_hippo1_mixer },
12757 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12758 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12759 .dac_nids = alc262_dac_nids,
12760 .hp_nid = 0x02,
12761 .dig_out_nid = ALC262_DIGOUT_NID,
12762 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12763 .channel_mode = alc262_modes,
12764 .input_mux = &alc262_capture_source,
e9427969 12765 .unsol_event = alc_sku_unsol_event,
4f5d1706 12766 .setup = alc262_hippo1_setup,
e9427969 12767 .init_hook = alc_inithook,
ccc656ce 12768 },
834be88d
TI
12769 [ALC262_FUJITSU] = {
12770 .mixers = { alc262_fujitsu_mixer },
39d3ed38
TI
12771 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12772 alc262_fujitsu_unsol_verbs },
834be88d
TI
12773 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12774 .dac_nids = alc262_dac_nids,
12775 .hp_nid = 0x03,
12776 .dig_out_nid = ALC262_DIGOUT_NID,
12777 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12778 .channel_mode = alc262_modes,
12779 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12780 .unsol_event = alc_sku_unsol_event,
12781 .setup = alc262_fujitsu_setup,
12782 .init_hook = alc_inithook,
834be88d 12783 },
9c7f852e
TI
12784 [ALC262_HP_BPC] = {
12785 .mixers = { alc262_HP_BPC_mixer },
12786 .init_verbs = { alc262_HP_BPC_init_verbs },
12787 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12788 .dac_nids = alc262_dac_nids,
12789 .hp_nid = 0x03,
12790 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12791 .channel_mode = alc262_modes,
12792 .input_mux = &alc262_HP_capture_source,
e9427969
TI
12793 .unsol_event = alc_sku_unsol_event,
12794 .setup = alc262_hp_bpc_setup,
12795 .init_hook = alc_inithook,
f12ab1e0 12796 },
cd7509a4
KY
12797 [ALC262_HP_BPC_D7000_WF] = {
12798 .mixers = { alc262_HP_BPC_WildWest_mixer },
12799 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12800 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12801 .dac_nids = alc262_dac_nids,
12802 .hp_nid = 0x03,
12803 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12804 .channel_mode = alc262_modes,
accbe498 12805 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12806 .unsol_event = alc_sku_unsol_event,
12807 .setup = alc262_hp_wildwest_setup,
12808 .init_hook = alc_inithook,
f12ab1e0 12809 },
cd7509a4
KY
12810 [ALC262_HP_BPC_D7000_WL] = {
12811 .mixers = { alc262_HP_BPC_WildWest_mixer,
12812 alc262_HP_BPC_WildWest_option_mixer },
12813 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12814 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12815 .dac_nids = alc262_dac_nids,
12816 .hp_nid = 0x03,
12817 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12818 .channel_mode = alc262_modes,
accbe498 12819 .input_mux = &alc262_HP_D7000_capture_source,
e9427969
TI
12820 .unsol_event = alc_sku_unsol_event,
12821 .setup = alc262_hp_wildwest_setup,
12822 .init_hook = alc_inithook,
f12ab1e0 12823 },
66d2a9d6
KY
12824 [ALC262_HP_TC_T5735] = {
12825 .mixers = { alc262_hp_t5735_mixer },
12826 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12827 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12828 .dac_nids = alc262_dac_nids,
12829 .hp_nid = 0x03,
12830 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12831 .channel_mode = alc262_modes,
12832 .input_mux = &alc262_capture_source,
dc99be47 12833 .unsol_event = alc_sku_unsol_event,
4f5d1706 12834 .setup = alc262_hp_t5735_setup,
dc99be47 12835 .init_hook = alc_inithook,
8c427226
KY
12836 },
12837 [ALC262_HP_RP5700] = {
12838 .mixers = { alc262_hp_rp5700_mixer },
12839 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12840 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12841 .dac_nids = alc262_dac_nids,
12842 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12843 .channel_mode = alc262_modes,
12844 .input_mux = &alc262_hp_rp5700_capture_source,
66d2a9d6 12845 },
304dcaac
TI
12846 [ALC262_BENQ_ED8] = {
12847 .mixers = { alc262_base_mixer },
12848 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12849 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12850 .dac_nids = alc262_dac_nids,
12851 .hp_nid = 0x03,
12852 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12853 .channel_mode = alc262_modes,
12854 .input_mux = &alc262_capture_source,
f12ab1e0 12855 },
272a527c
KY
12856 [ALC262_SONY_ASSAMD] = {
12857 .mixers = { alc262_sony_mixer },
12858 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12859 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12860 .dac_nids = alc262_dac_nids,
12861 .hp_nid = 0x02,
12862 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12863 .channel_mode = alc262_modes,
12864 .input_mux = &alc262_capture_source,
e9427969 12865 .unsol_event = alc_sku_unsol_event,
4f5d1706 12866 .setup = alc262_hippo_setup,
e9427969 12867 .init_hook = alc_inithook,
83c34218
KY
12868 },
12869 [ALC262_BENQ_T31] = {
12870 .mixers = { alc262_benq_t31_mixer },
6732bd0d
WF
12871 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12872 alc_hp15_unsol_verbs },
83c34218
KY
12873 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12874 .dac_nids = alc262_dac_nids,
12875 .hp_nid = 0x03,
12876 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12877 .channel_mode = alc262_modes,
12878 .input_mux = &alc262_capture_source,
e9427969 12879 .unsol_event = alc_sku_unsol_event,
4f5d1706 12880 .setup = alc262_hippo_setup,
e9427969 12881 .init_hook = alc_inithook,
ea1fb29a 12882 },
f651b50b 12883 [ALC262_ULTRA] = {
f9e336f6
TI
12884 .mixers = { alc262_ultra_mixer },
12885 .cap_mixer = alc262_ultra_capture_mixer,
bb9f76cd 12886 .init_verbs = { alc262_ultra_verbs },
f651b50b
TD
12887 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12888 .dac_nids = alc262_dac_nids,
f651b50b
TD
12889 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12890 .channel_mode = alc262_modes,
12891 .input_mux = &alc262_ultra_capture_source,
bb9f76cd
TI
12892 .adc_nids = alc262_adc_nids, /* ADC0 */
12893 .capsrc_nids = alc262_capsrc_nids,
12894 .num_adc_nids = 1, /* single ADC */
f651b50b
TD
12895 .unsol_event = alc262_ultra_unsol_event,
12896 .init_hook = alc262_ultra_automute,
12897 },
0e31daf7
J
12898 [ALC262_LENOVO_3000] = {
12899 .mixers = { alc262_lenovo_3000_mixer },
12900 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
e2595322
DC
12901 alc262_lenovo_3000_unsol_verbs,
12902 alc262_lenovo_3000_init_verbs },
0e31daf7
J
12903 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12904 .dac_nids = alc262_dac_nids,
12905 .hp_nid = 0x03,
12906 .dig_out_nid = ALC262_DIGOUT_NID,
12907 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12908 .channel_mode = alc262_modes,
12909 .input_mux = &alc262_fujitsu_capture_source,
0f0f391c
TI
12910 .unsol_event = alc_sku_unsol_event,
12911 .setup = alc262_lenovo_3000_setup,
12912 .init_hook = alc_inithook,
0e31daf7 12913 },
e8f9ae2a
PT
12914 [ALC262_NEC] = {
12915 .mixers = { alc262_nec_mixer },
12916 .init_verbs = { alc262_nec_verbs },
12917 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12918 .dac_nids = alc262_dac_nids,
12919 .hp_nid = 0x03,
12920 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12921 .channel_mode = alc262_modes,
12922 .input_mux = &alc262_capture_source,
12923 },
4e555fe5
KY
12924 [ALC262_TOSHIBA_S06] = {
12925 .mixers = { alc262_toshiba_s06_mixer },
12926 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12927 alc262_eapd_verbs },
12928 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12929 .capsrc_nids = alc262_dmic_capsrc_nids,
12930 .dac_nids = alc262_dac_nids,
12931 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
ae14ef68 12932 .num_adc_nids = 1, /* single ADC */
4e555fe5
KY
12933 .dig_out_nid = ALC262_DIGOUT_NID,
12934 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12935 .channel_mode = alc262_modes,
4f5d1706
TI
12936 .unsol_event = alc_sku_unsol_event,
12937 .setup = alc262_toshiba_s06_setup,
12938 .init_hook = alc_inithook,
4e555fe5 12939 },
9f99a638
HM
12940 [ALC262_TOSHIBA_RX1] = {
12941 .mixers = { alc262_toshiba_rx1_mixer },
12942 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12943 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12944 .dac_nids = alc262_dac_nids,
12945 .hp_nid = 0x03,
12946 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12947 .channel_mode = alc262_modes,
12948 .input_mux = &alc262_capture_source,
e9427969 12949 .unsol_event = alc_sku_unsol_event,
4f5d1706 12950 .setup = alc262_hippo_setup,
e9427969 12951 .init_hook = alc_inithook,
9f99a638 12952 },
ba340e82
TV
12953 [ALC262_TYAN] = {
12954 .mixers = { alc262_tyan_mixer },
12955 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12956 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12957 .dac_nids = alc262_dac_nids,
12958 .hp_nid = 0x02,
12959 .dig_out_nid = ALC262_DIGOUT_NID,
12960 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12961 .channel_mode = alc262_modes,
12962 .input_mux = &alc262_capture_source,
d922b51d 12963 .unsol_event = alc_sku_unsol_event,
4f5d1706 12964 .setup = alc262_tyan_setup,
d922b51d 12965 .init_hook = alc_hp_automute,
ba340e82 12966 },
df694daa
KY
12967};
12968
12969static int patch_alc262(struct hda_codec *codec)
12970{
12971 struct alc_spec *spec;
12972 int board_config;
12973 int err;
12974
dc041e0b 12975 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
12976 if (spec == NULL)
12977 return -ENOMEM;
12978
12979 codec->spec = spec;
12980#if 0
f12ab1e0
TI
12981 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
12982 * under-run
12983 */
df694daa
KY
12984 {
12985 int tmp;
12986 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12987 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
12988 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
12989 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
12990 }
12991#endif
da00c244 12992 alc_auto_parse_customize_define(codec);
df694daa 12993
2c3bf9ab
TI
12994 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12995
f5fcc13c
TI
12996 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
12997 alc262_models,
12998 alc262_cfg_tbl);
cd7509a4 12999
f5fcc13c 13000 if (board_config < 0) {
9a11f1aa
TI
13001 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13002 codec->chip_name);
df694daa
KY
13003 board_config = ALC262_AUTO;
13004 }
13005
b5bfbc67
TI
13006 if (board_config == ALC262_AUTO) {
13007 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13008 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13009 }
18675e42 13010
df694daa
KY
13011 if (board_config == ALC262_AUTO) {
13012 /* automatic parse from the BIOS config */
13013 err = alc262_parse_auto_config(codec);
13014 if (err < 0) {
13015 alc_free(codec);
13016 return err;
f12ab1e0 13017 } else if (!err) {
9c7f852e
TI
13018 printk(KERN_INFO
13019 "hda_codec: Cannot set up configuration "
13020 "from BIOS. Using base mode...\n");
df694daa
KY
13021 board_config = ALC262_BASIC;
13022 }
13023 }
13024
dc1eae25 13025 if (!spec->no_analog && has_cdefine_beep(codec)) {
07eba61d
TI
13026 err = snd_hda_attach_beep_device(codec, 0x1);
13027 if (err < 0) {
13028 alc_free(codec);
13029 return err;
13030 }
680cd536
KK
13031 }
13032
df694daa 13033 if (board_config != ALC262_AUTO)
e9c364c0 13034 setup_preset(codec, &alc262_presets[board_config]);
df694daa 13035
df694daa
KY
13036 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13037 spec->stream_analog_capture = &alc262_pcm_analog_capture;
ea1fb29a 13038
df694daa
KY
13039 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13040 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13041
f12ab1e0 13042 if (!spec->adc_nids && spec->input_mux) {
8c927b4a
TI
13043 int i;
13044 /* check whether the digital-mic has to be supported */
13045 for (i = 0; i < spec->input_mux->num_items; i++) {
13046 if (spec->input_mux->items[i].index >= 9)
13047 break;
13048 }
13049 if (i < spec->input_mux->num_items) {
13050 /* use only ADC0 */
13051 spec->adc_nids = alc262_dmic_adc_nids;
13052 spec->num_adc_nids = 1;
13053 spec->capsrc_nids = alc262_dmic_capsrc_nids;
df694daa 13054 } else {
8c927b4a
TI
13055 /* all analog inputs */
13056 /* check whether NID 0x07 is valid */
13057 unsigned int wcap = get_wcaps(codec, 0x07);
13058
13059 /* get type */
a22d543a 13060 wcap = get_wcaps_type(wcap);
8c927b4a
TI
13061 if (wcap != AC_WID_AUD_IN) {
13062 spec->adc_nids = alc262_adc_nids_alt;
13063 spec->num_adc_nids =
13064 ARRAY_SIZE(alc262_adc_nids_alt);
13065 spec->capsrc_nids = alc262_capsrc_nids_alt;
13066 } else {
13067 spec->adc_nids = alc262_adc_nids;
13068 spec->num_adc_nids =
13069 ARRAY_SIZE(alc262_adc_nids);
13070 spec->capsrc_nids = alc262_capsrc_nids;
13071 }
df694daa
KY
13072 }
13073 }
e64f14f4 13074 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 13075 set_capture_mixer(codec);
dc1eae25 13076 if (!spec->no_analog && has_cdefine_beep(codec))
07eba61d 13077 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
df694daa 13078
b5bfbc67 13079 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18675e42 13080
2134ea4f
TI
13081 spec->vmaster_nid = 0x0c;
13082
df694daa
KY
13083 codec->patch_ops = alc_patch_ops;
13084 if (board_config == ALC262_AUTO)
ae6b813a 13085 spec->init_hook = alc262_auto_init;
1c716153 13086 spec->shutup = alc_eapd_shutup;
bf1b0225
KY
13087
13088 alc_init_jacks(codec);
cb53c626
TI
13089#ifdef CONFIG_SND_HDA_POWER_SAVE
13090 if (!spec->loopback.amplist)
13091 spec->loopback.amplist = alc262_loopbacks;
13092#endif
ea1fb29a 13093
df694daa
KY
13094 return 0;
13095}
13096
a361d84b
KY
13097/*
13098 * ALC268 channel source setting (2 channel)
13099 */
13100#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13101#define alc268_modes alc260_modes
ea1fb29a 13102
4c6d72d1 13103static const hda_nid_t alc268_dac_nids[2] = {
a361d84b
KY
13104 /* front, hp */
13105 0x02, 0x03
13106};
13107
4c6d72d1 13108static const hda_nid_t alc268_adc_nids[2] = {
a361d84b
KY
13109 /* ADC0-1 */
13110 0x08, 0x07
13111};
13112
4c6d72d1 13113static const hda_nid_t alc268_adc_nids_alt[1] = {
a361d84b
KY
13114 /* ADC0 */
13115 0x08
13116};
13117
4c6d72d1 13118static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
e1406348 13119
a9111321 13120static const struct snd_kcontrol_new alc268_base_mixer[] = {
a361d84b
KY
13121 /* output mixer control */
13122 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13123 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13124 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13125 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13126 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13127 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13128 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
a361d84b
KY
13129 { }
13130};
13131
a9111321 13132static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
42171c17
TI
13133 /* output mixer control */
13134 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13135 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13136 ALC262_HIPPO_MASTER_SWITCH,
5f99f86a
DH
13137 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13138 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13139 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
42171c17
TI
13140 { }
13141};
13142
aef9d318 13143/* bind Beep switches of both NID 0x0f and 0x10 */
a9111321 13144static const struct hda_bind_ctls alc268_bind_beep_sw = {
aef9d318
TI
13145 .ops = &snd_hda_bind_sw,
13146 .values = {
13147 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13148 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13149 0
13150 },
13151};
13152
a9111321 13153static const struct snd_kcontrol_new alc268_beep_mixer[] = {
aef9d318
TI
13154 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13155 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13156 { }
13157};
13158
a9111321 13159static const struct hda_verb alc268_eapd_verbs[] = {
d1a991a6
KY
13160 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13161 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13162 { }
13163};
13164
d273809e 13165/* Toshiba specific */
a9111321 13166static const struct hda_verb alc268_toshiba_verbs[] = {
d273809e
TI
13167 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13168 { } /* end */
13169};
13170
13171/* Acer specific */
889c4395 13172/* bind volumes of both NID 0x02 and 0x03 */
a9111321 13173static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
6bc96857
TI
13174 .ops = &snd_hda_bind_vol,
13175 .values = {
13176 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13177 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13178 0
13179 },
13180};
13181
0f0f391c 13182static void alc268_acer_setup(struct hda_codec *codec)
889c4395
TI
13183{
13184 struct alc_spec *spec = codec->spec;
889c4395 13185
0f0f391c
TI
13186 spec->autocfg.hp_pins[0] = 0x14;
13187 spec->autocfg.speaker_pins[0] = 0x15;
13188 spec->automute = 1;
13189 spec->automute_mode = ALC_AUTOMUTE_AMP;
889c4395
TI
13190}
13191
0f0f391c
TI
13192#define alc268_acer_master_sw_get alc262_hp_master_sw_get
13193#define alc268_acer_master_sw_put alc262_hp_master_sw_put
d273809e 13194
a9111321 13195static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
8ef355da
KY
13196 /* output mixer control */
13197 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13198 {
13199 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13200 .name = "Master Playback Switch",
0f0f391c
TI
13201 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13202 .info = snd_ctl_boolean_mono_info,
13203 .get = alc268_acer_master_sw_get,
8ef355da 13204 .put = alc268_acer_master_sw_put,
8ef355da
KY
13205 },
13206 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13207 { }
13208};
13209
a9111321 13210static const struct snd_kcontrol_new alc268_acer_mixer[] = {
d273809e
TI
13211 /* output mixer control */
13212 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13213 {
13214 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13215 .name = "Master Playback Switch",
0f0f391c
TI
13216 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13217 .info = snd_ctl_boolean_mono_info,
13218 .get = alc268_acer_master_sw_get,
d273809e 13219 .put = alc268_acer_master_sw_put,
d273809e 13220 },
5f99f86a
DH
13221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13222 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13223 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
d273809e
TI
13224 { }
13225};
13226
a9111321 13227static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
c238b4f4
TI
13228 /* output mixer control */
13229 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13230 {
13231 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13232 .name = "Master Playback Switch",
0f0f391c
TI
13233 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13234 .info = snd_ctl_boolean_mono_info,
13235 .get = alc268_acer_master_sw_get,
c238b4f4 13236 .put = alc268_acer_master_sw_put,
c238b4f4 13237 },
5f99f86a
DH
13238 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13239 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
c238b4f4
TI
13240 { }
13241};
13242
a9111321 13243static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
8ef355da
KY
13244 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13245 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13246 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13247 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13248 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13249 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13250 { }
13251};
13252
a9111321 13253static const struct hda_verb alc268_acer_verbs[] = {
0ccb541c
TI
13254 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13255 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d273809e
TI
13256 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13257 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
0ccb541c
TI
13258 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13259 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
d273809e
TI
13260 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13261 { }
13262};
13263
13264/* unsolicited event for HP jack sensing */
4f5d1706 13265#define alc268_toshiba_setup alc262_hippo_setup
d273809e 13266
4f5d1706
TI
13267static void alc268_acer_lc_setup(struct hda_codec *codec)
13268{
13269 struct alc_spec *spec = codec->spec;
3b8510ce
TI
13270 spec->autocfg.hp_pins[0] = 0x15;
13271 spec->autocfg.speaker_pins[0] = 0x14;
13272 spec->automute_mixer_nid[0] = 0x0f;
13273 spec->automute = 1;
13274 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
13275 spec->ext_mic.pin = 0x18;
13276 spec->ext_mic.mux_idx = 0;
13277 spec->int_mic.pin = 0x12;
13278 spec->int_mic.mux_idx = 6;
13279 spec->auto_mic = 1;
8ef355da
KY
13280}
13281
a9111321 13282static const struct snd_kcontrol_new alc268_dell_mixer[] = {
3866f0b0
TI
13283 /* output mixer control */
13284 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13285 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13286 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13287 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5f99f86a
DH
13288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
3866f0b0
TI
13290 { }
13291};
13292
a9111321 13293static const struct hda_verb alc268_dell_verbs[] = {
3866f0b0
TI
13294 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13295 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13296 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
4f5d1706 13297 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
3866f0b0
TI
13298 { }
13299};
13300
13301/* mute/unmute internal speaker according to the hp jack and mute state */
4f5d1706 13302static void alc268_dell_setup(struct hda_codec *codec)
3866f0b0 13303{
a9fd4f3f 13304 struct alc_spec *spec = codec->spec;
3866f0b0 13305
a9fd4f3f
TI
13306 spec->autocfg.hp_pins[0] = 0x15;
13307 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13308 spec->ext_mic.pin = 0x18;
13309 spec->ext_mic.mux_idx = 0;
13310 spec->int_mic.pin = 0x19;
13311 spec->int_mic.mux_idx = 1;
13312 spec->auto_mic = 1;
d922b51d
TI
13313 spec->automute = 1;
13314 spec->automute_mode = ALC_AUTOMUTE_PIN;
3866f0b0
TI
13315}
13316
a9111321 13317static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
eb5a6621
HRK
13318 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13319 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13320 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13321 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13322 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13323 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
5f99f86a
DH
13324 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13325 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
eb5a6621
HRK
13326 { }
13327};
13328
a9111321 13329static const struct hda_verb alc267_quanta_il1_verbs[] = {
eb5a6621
HRK
13330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13331 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13332 { }
13333};
13334
4f5d1706 13335static void alc267_quanta_il1_setup(struct hda_codec *codec)
eb5a6621 13336{
a9fd4f3f 13337 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
13338 spec->autocfg.hp_pins[0] = 0x15;
13339 spec->autocfg.speaker_pins[0] = 0x14;
4f5d1706
TI
13340 spec->ext_mic.pin = 0x18;
13341 spec->ext_mic.mux_idx = 0;
13342 spec->int_mic.pin = 0x19;
13343 spec->int_mic.mux_idx = 1;
13344 spec->auto_mic = 1;
d922b51d
TI
13345 spec->automute = 1;
13346 spec->automute_mode = ALC_AUTOMUTE_PIN;
eb5a6621
HRK
13347}
13348
a361d84b
KY
13349/*
13350 * generic initialization of ADC, input mixers and output mixers
13351 */
a9111321 13352static const struct hda_verb alc268_base_init_verbs[] = {
a361d84b
KY
13353 /* Unmute DAC0-1 and set vol = 0 */
13354 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b 13355 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13356
13357 /*
13358 * Set up output mixers (0x0c - 0x0e)
13359 */
13360 /* set vol=0 to output mixers */
13361 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13362 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13363
13364 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13365 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13366
13367 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13368 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13369 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13370 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13371 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13372 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13373 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13374 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13375
13376 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13377 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13378 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13379 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13380 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
aef9d318
TI
13381
13382 /* set PCBEEP vol = 0, mute connections */
13383 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13384 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13385 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b 13386
a9b3aa8a 13387 /* Unmute Selector 23h,24h and set the default input to mic-in */
ea1fb29a 13388
a9b3aa8a
JZ
13389 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13390 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13391 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13392 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
a361d84b 13393
a361d84b
KY
13394 { }
13395};
13396
13397/*
13398 * generic initialization of ADC, input mixers and output mixers
13399 */
a9111321 13400static const struct hda_verb alc268_volume_init_verbs[] = {
a361d84b 13401 /* set output DAC */
4cfb91c6
TI
13402 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13403 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
a361d84b
KY
13404
13405 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13406 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13407 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13408 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13409 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13410
a361d84b 13411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
a361d84b
KY
13412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13413 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13414
13415 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13416 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
a361d84b 13417
aef9d318
TI
13418 /* set PCBEEP vol = 0, mute connections */
13419 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13420 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13421 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
a361d84b
KY
13422
13423 { }
13424};
13425
a9111321 13426static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
fdbc6626
TI
13427 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13428 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13429 { } /* end */
13430};
13431
a9111321 13432static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
a361d84b
KY
13433 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
fdbc6626 13435 _DEFINE_CAPSRC(1),
a361d84b
KY
13436 { } /* end */
13437};
13438
a9111321 13439static const struct snd_kcontrol_new alc268_capture_mixer[] = {
a361d84b
KY
13440 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13441 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13442 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13443 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
fdbc6626 13444 _DEFINE_CAPSRC(2),
a361d84b
KY
13445 { } /* end */
13446};
13447
a9111321 13448static const struct hda_input_mux alc268_capture_source = {
a361d84b
KY
13449 .num_items = 4,
13450 .items = {
13451 { "Mic", 0x0 },
13452 { "Front Mic", 0x1 },
13453 { "Line", 0x2 },
13454 { "CD", 0x3 },
13455 },
13456};
13457
a9111321 13458static const struct hda_input_mux alc268_acer_capture_source = {
c238b4f4
TI
13459 .num_items = 3,
13460 .items = {
13461 { "Mic", 0x0 },
13462 { "Internal Mic", 0x1 },
13463 { "Line", 0x2 },
13464 },
13465};
13466
a9111321 13467static const struct hda_input_mux alc268_acer_dmic_capture_source = {
0ccb541c
TI
13468 .num_items = 3,
13469 .items = {
13470 { "Mic", 0x0 },
13471 { "Internal Mic", 0x6 },
13472 { "Line", 0x2 },
13473 },
13474};
13475
86c53bd2 13476#ifdef CONFIG_SND_DEBUG
a9111321 13477static const struct snd_kcontrol_new alc268_test_mixer[] = {
86c53bd2
JW
13478 /* Volume widgets */
13479 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13480 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13481 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13482 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13483 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13484 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13485 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13486 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13488 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13489 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13490 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13491 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
f0747ee6
TI
13492 /* The below appears problematic on some hardwares */
13493 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
86c53bd2
JW
13494 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13495 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13496 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13497 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13498
13499 /* Modes for retasking pin widgets */
13500 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13501 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13502 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13503 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13504
13505 /* Controls for GPIO pins, assuming they are configured as outputs */
13506 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13507 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13508 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13509 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13510
13511 /* Switches to allow the digital SPDIF output pin to be enabled.
13512 * The ALC268 does not have an SPDIF input.
13513 */
13514 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13515
13516 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13517 * this output to turn on an external amplifier.
13518 */
13519 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13520 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13521
13522 { } /* end */
13523};
13524#endif
13525
a361d84b
KY
13526/* create input playback/capture controls for the given pin */
13527static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13528 const char *ctlname, int idx)
13529{
3f3b7c1a 13530 hda_nid_t dac;
a361d84b
KY
13531 int err;
13532
3f3b7c1a
TI
13533 switch (nid) {
13534 case 0x14:
13535 case 0x16:
13536 dac = 0x02;
13537 break;
13538 case 0x15:
b08b1637
TI
13539 case 0x1a: /* ALC259/269 only */
13540 case 0x1b: /* ALC259/269 only */
531d8791 13541 case 0x21: /* ALC269vb has this pin, too */
3f3b7c1a
TI
13542 dac = 0x03;
13543 break;
13544 default:
c7a9434d
TI
13545 snd_printd(KERN_WARNING "hda_codec: "
13546 "ignoring pin 0x%x as unknown\n", nid);
3f3b7c1a
TI
13547 return 0;
13548 }
13549 if (spec->multiout.dac_nids[0] != dac &&
13550 spec->multiout.dac_nids[1] != dac) {
0afe5f89 13551 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
3f3b7c1a 13552 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
a361d84b
KY
13553 HDA_OUTPUT));
13554 if (err < 0)
13555 return err;
dda14410 13556 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3f3b7c1a
TI
13557 }
13558
3f3b7c1a 13559 if (nid != 0x16)
0afe5f89 13560 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
a361d84b 13561 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
3f3b7c1a 13562 else /* mono */
0afe5f89 13563 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
3f3b7c1a 13564 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
a361d84b
KY
13565 if (err < 0)
13566 return err;
13567 return 0;
13568}
13569
13570/* add playback controls from the parsed DAC table */
13571static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13572 const struct auto_pin_cfg *cfg)
13573{
13574 hda_nid_t nid;
13575 int err;
13576
a361d84b 13577 spec->multiout.dac_nids = spec->private_dac_nids;
a361d84b
KY
13578
13579 nid = cfg->line_out_pins[0];
3f3b7c1a
TI
13580 if (nid) {
13581 const char *name;
13582 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13583 name = "Speaker";
13584 else
13585 name = "Front";
13586 err = alc268_new_analog_output(spec, nid, name, 0);
13587 if (err < 0)
13588 return err;
13589 }
a361d84b
KY
13590
13591 nid = cfg->speaker_pins[0];
13592 if (nid == 0x1d) {
0afe5f89 13593 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
a361d84b
KY
13594 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13595 if (err < 0)
13596 return err;
7bfb9c03 13597 } else if (nid) {
3f3b7c1a
TI
13598 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13599 if (err < 0)
13600 return err;
a361d84b
KY
13601 }
13602 nid = cfg->hp_pins[0];
3f3b7c1a
TI
13603 if (nid) {
13604 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13605 if (err < 0)
13606 return err;
13607 }
a361d84b
KY
13608
13609 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13610 if (nid == 0x16) {
0afe5f89 13611 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
3f3b7c1a 13612 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
a361d84b
KY
13613 if (err < 0)
13614 return err;
13615 }
ea1fb29a 13616 return 0;
a361d84b
KY
13617}
13618
13619/* create playback/capture controls for input pins */
05f5f477 13620static int alc268_auto_create_input_ctls(struct hda_codec *codec,
a361d84b
KY
13621 const struct auto_pin_cfg *cfg)
13622{
05f5f477 13623 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
a361d84b
KY
13624}
13625
e9af4f36
TI
13626static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13627 hda_nid_t nid, int pin_type)
13628{
13629 int idx;
13630
13631 alc_set_pin_output(codec, nid, pin_type);
13632 if (nid == 0x14 || nid == 0x16)
13633 idx = 0;
13634 else
13635 idx = 1;
13636 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13637}
13638
13639static void alc268_auto_init_multi_out(struct hda_codec *codec)
13640{
13641 struct alc_spec *spec = codec->spec;
e1ca7b4e
TI
13642 int i;
13643
13644 for (i = 0; i < spec->autocfg.line_outs; i++) {
13645 hda_nid_t nid = spec->autocfg.line_out_pins[i];
e9af4f36
TI
13646 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13647 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13648 }
13649}
13650
13651static void alc268_auto_init_hp_out(struct hda_codec *codec)
13652{
13653 struct alc_spec *spec = codec->spec;
13654 hda_nid_t pin;
e1ca7b4e 13655 int i;
e9af4f36 13656
e1ca7b4e
TI
13657 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13658 pin = spec->autocfg.hp_pins[i];
e9af4f36 13659 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
e1ca7b4e
TI
13660 }
13661 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13662 pin = spec->autocfg.speaker_pins[i];
e9af4f36 13663 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
e1ca7b4e
TI
13664 }
13665 if (spec->autocfg.mono_out_pin)
13666 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13667 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36
TI
13668}
13669
a361d84b
KY
13670static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13671{
13672 struct alc_spec *spec = codec->spec;
13673 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13674 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13675 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13676 unsigned int dac_vol1, dac_vol2;
13677
e9af4f36 13678 if (line_nid == 0x1d || speaker_nid == 0x1d) {
a361d84b
KY
13679 snd_hda_codec_write(codec, speaker_nid, 0,
13680 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
e9af4f36 13681 /* mute mixer inputs from 0x1d */
a361d84b
KY
13682 snd_hda_codec_write(codec, 0x0f, 0,
13683 AC_VERB_SET_AMP_GAIN_MUTE,
13684 AMP_IN_UNMUTE(1));
13685 snd_hda_codec_write(codec, 0x10, 0,
13686 AC_VERB_SET_AMP_GAIN_MUTE,
13687 AMP_IN_UNMUTE(1));
13688 } else {
e9af4f36 13689 /* unmute mixer inputs from 0x1d */
a361d84b
KY
13690 snd_hda_codec_write(codec, 0x0f, 0,
13691 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13692 snd_hda_codec_write(codec, 0x10, 0,
13693 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13694 }
13695
13696 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
ea1fb29a 13697 if (line_nid == 0x14)
a361d84b
KY
13698 dac_vol2 = AMP_OUT_ZERO;
13699 else if (line_nid == 0x15)
13700 dac_vol1 = AMP_OUT_ZERO;
ea1fb29a 13701 if (hp_nid == 0x14)
a361d84b
KY
13702 dac_vol2 = AMP_OUT_ZERO;
13703 else if (hp_nid == 0x15)
13704 dac_vol1 = AMP_OUT_ZERO;
13705 if (line_nid != 0x16 || hp_nid != 0x16 ||
13706 spec->autocfg.line_out_pins[1] != 0x16 ||
13707 spec->autocfg.line_out_pins[2] != 0x16)
13708 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13709
13710 snd_hda_codec_write(codec, 0x02, 0,
13711 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13712 snd_hda_codec_write(codec, 0x03, 0,
13713 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13714}
13715
def319f9 13716/* pcm configuration: identical with ALC880 */
a361d84b
KY
13717#define alc268_pcm_analog_playback alc880_pcm_analog_playback
13718#define alc268_pcm_analog_capture alc880_pcm_analog_capture
6330079f 13719#define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
a361d84b
KY
13720#define alc268_pcm_digital_playback alc880_pcm_digital_playback
13721
13722/*
13723 * BIOS auto configuration
13724 */
13725static int alc268_parse_auto_config(struct hda_codec *codec)
13726{
13727 struct alc_spec *spec = codec->spec;
13728 int err;
4c6d72d1 13729 static const hda_nid_t alc268_ignore[] = { 0 };
a361d84b
KY
13730
13731 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13732 alc268_ignore);
13733 if (err < 0)
13734 return err;
7e0e44d4
TI
13735 if (!spec->autocfg.line_outs) {
13736 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13737 spec->multiout.max_channels = 2;
13738 spec->no_analog = 1;
13739 goto dig_only;
13740 }
a361d84b 13741 return 0; /* can't find valid BIOS pin config */
7e0e44d4 13742 }
a361d84b
KY
13743 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13744 if (err < 0)
13745 return err;
05f5f477 13746 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
a361d84b
KY
13747 if (err < 0)
13748 return err;
13749
13750 spec->multiout.max_channels = 2;
13751
7e0e44d4 13752 dig_only:
a361d84b 13753 /* digital only support output */
757899ac 13754 alc_auto_parse_digital(codec);
603c4019 13755 if (spec->kctls.list)
d88897ea 13756 add_mixer(spec, spec->kctls.list);
a361d84b 13757
892981ff 13758 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
d88897ea 13759 add_mixer(spec, alc268_beep_mixer);
aef9d318 13760
d88897ea 13761 add_verb(spec, alc268_volume_init_verbs);
5908589f 13762 spec->num_mux_defs = 2;
61b9b9b1 13763 spec->input_mux = &spec->private_imux[0];
a361d84b 13764
776e184e
TI
13765 err = alc_auto_add_mic_boost(codec);
13766 if (err < 0)
13767 return err;
13768
6227cdce 13769 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
1d955ebd 13770
a361d84b
KY
13771 return 1;
13772}
13773
a361d84b 13774#define alc268_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 13775#define alc268_auto_init_input_src alc882_auto_init_input_src
a361d84b
KY
13776
13777/* init callback for auto-configuration model -- overriding the default init */
13778static void alc268_auto_init(struct hda_codec *codec)
13779{
f6c7e546 13780 struct alc_spec *spec = codec->spec;
a361d84b
KY
13781 alc268_auto_init_multi_out(codec);
13782 alc268_auto_init_hp_out(codec);
13783 alc268_auto_init_mono_speaker_out(codec);
13784 alc268_auto_init_analog_input(codec);
ae0ebbf7 13785 alc268_auto_init_input_src(codec);
757899ac 13786 alc_auto_init_digital(codec);
f6c7e546 13787 if (spec->unsol_event)
7fb0d78f 13788 alc_inithook(codec);
a361d84b
KY
13789}
13790
13791/*
13792 * configuration and preset
13793 */
ea734963 13794static const char * const alc268_models[ALC268_MODEL_LAST] = {
eb5a6621 13795 [ALC267_QUANTA_IL1] = "quanta-il1",
a361d84b 13796 [ALC268_3ST] = "3stack",
983f8ae4 13797 [ALC268_TOSHIBA] = "toshiba",
d273809e 13798 [ALC268_ACER] = "acer",
c238b4f4 13799 [ALC268_ACER_DMIC] = "acer-dmic",
8ef355da 13800 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
3866f0b0 13801 [ALC268_DELL] = "dell",
f12462c5 13802 [ALC268_ZEPTO] = "zepto",
86c53bd2
JW
13803#ifdef CONFIG_SND_DEBUG
13804 [ALC268_TEST] = "test",
13805#endif
a361d84b
KY
13806 [ALC268_AUTO] = "auto",
13807};
13808
a9111321 13809static const struct snd_pci_quirk alc268_cfg_tbl[] = {
a0b8f7d8 13810 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
ac3e3741 13811 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
dafc8357 13812 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
ac3e3741 13813 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
29a52c24 13814 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
8ef355da
KY
13815 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13816 ALC268_ACER_ASPIRE_ONE),
3866f0b0 13817 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
a1bf8088
DC
13818 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13819 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
33d78674
TI
13820 /* almost compatible with toshiba but with optional digital outs;
13821 * auto-probing seems working fine
13822 */
8871e5b9 13823 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
33d78674 13824 ALC268_AUTO),
a361d84b 13825 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
8871e5b9 13826 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
378bd6a5 13827 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
b875bf3a 13828 SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER),
eb5a6621 13829 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
a361d84b
KY
13830 {}
13831};
13832
3abf2f36 13833/* Toshiba laptops have no unique PCI SSID but only codec SSID */
a9111321 13834static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
3abf2f36
TI
13835 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13836 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13837 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13838 ALC268_TOSHIBA),
13839 {}
13840};
13841
a9111321 13842static const struct alc_config_preset alc268_presets[] = {
eb5a6621 13843 [ALC267_QUANTA_IL1] = {
fdbc6626
TI
13844 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13845 alc268_capture_nosrc_mixer },
eb5a6621
HRK
13846 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13847 alc267_quanta_il1_verbs },
13848 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13849 .dac_nids = alc268_dac_nids,
13850 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13851 .adc_nids = alc268_adc_nids_alt,
13852 .hp_nid = 0x03,
13853 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13854 .channel_mode = alc268_modes,
4f5d1706
TI
13855 .unsol_event = alc_sku_unsol_event,
13856 .setup = alc267_quanta_il1_setup,
13857 .init_hook = alc_inithook,
eb5a6621 13858 },
a361d84b 13859 [ALC268_3ST] = {
aef9d318
TI
13860 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13861 alc268_beep_mixer },
a361d84b
KY
13862 .init_verbs = { alc268_base_init_verbs },
13863 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13864 .dac_nids = alc268_dac_nids,
13865 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13866 .adc_nids = alc268_adc_nids_alt,
e1406348 13867 .capsrc_nids = alc268_capsrc_nids,
a361d84b
KY
13868 .hp_nid = 0x03,
13869 .dig_out_nid = ALC268_DIGOUT_NID,
13870 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13871 .channel_mode = alc268_modes,
13872 .input_mux = &alc268_capture_source,
13873 },
d1a991a6 13874 [ALC268_TOSHIBA] = {
42171c17 13875 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
aef9d318 13876 alc268_beep_mixer },
d273809e
TI
13877 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13878 alc268_toshiba_verbs },
d1a991a6
KY
13879 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13880 .dac_nids = alc268_dac_nids,
13881 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13882 .adc_nids = alc268_adc_nids_alt,
e1406348 13883 .capsrc_nids = alc268_capsrc_nids,
d1a991a6
KY
13884 .hp_nid = 0x03,
13885 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13886 .channel_mode = alc268_modes,
13887 .input_mux = &alc268_capture_source,
e9427969 13888 .unsol_event = alc_sku_unsol_event,
4f5d1706 13889 .setup = alc268_toshiba_setup,
e9427969 13890 .init_hook = alc_inithook,
d273809e
TI
13891 },
13892 [ALC268_ACER] = {
432fd133 13893 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
aef9d318 13894 alc268_beep_mixer },
d273809e
TI
13895 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13896 alc268_acer_verbs },
13897 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13898 .dac_nids = alc268_dac_nids,
13899 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13900 .adc_nids = alc268_adc_nids_alt,
e1406348 13901 .capsrc_nids = alc268_capsrc_nids,
d273809e
TI
13902 .hp_nid = 0x02,
13903 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13904 .channel_mode = alc268_modes,
0ccb541c 13905 .input_mux = &alc268_acer_capture_source,
0f0f391c
TI
13906 .unsol_event = alc_sku_unsol_event,
13907 .setup = alc268_acer_setup,
13908 .init_hook = alc_inithook,
d1a991a6 13909 },
c238b4f4
TI
13910 [ALC268_ACER_DMIC] = {
13911 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13912 alc268_beep_mixer },
13913 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13914 alc268_acer_verbs },
13915 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13916 .dac_nids = alc268_dac_nids,
13917 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13918 .adc_nids = alc268_adc_nids_alt,
13919 .capsrc_nids = alc268_capsrc_nids,
13920 .hp_nid = 0x02,
13921 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13922 .channel_mode = alc268_modes,
13923 .input_mux = &alc268_acer_dmic_capture_source,
0f0f391c
TI
13924 .unsol_event = alc_sku_unsol_event,
13925 .setup = alc268_acer_setup,
13926 .init_hook = alc_inithook,
c238b4f4 13927 },
8ef355da
KY
13928 [ALC268_ACER_ASPIRE_ONE] = {
13929 .mixers = { alc268_acer_aspire_one_mixer,
22971e3a 13930 alc268_beep_mixer,
fdbc6626 13931 alc268_capture_nosrc_mixer },
8ef355da
KY
13932 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13933 alc268_acer_aspire_one_verbs },
13934 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13935 .dac_nids = alc268_dac_nids,
13936 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13937 .adc_nids = alc268_adc_nids_alt,
13938 .capsrc_nids = alc268_capsrc_nids,
13939 .hp_nid = 0x03,
13940 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13941 .channel_mode = alc268_modes,
3b8510ce 13942 .unsol_event = alc_sku_unsol_event,
4f5d1706 13943 .setup = alc268_acer_lc_setup,
3b8510ce 13944 .init_hook = alc_inithook,
8ef355da 13945 },
3866f0b0 13946 [ALC268_DELL] = {
fdbc6626
TI
13947 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13948 alc268_capture_nosrc_mixer },
3866f0b0
TI
13949 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13950 alc268_dell_verbs },
13951 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13952 .dac_nids = alc268_dac_nids,
fdbc6626
TI
13953 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13954 .adc_nids = alc268_adc_nids_alt,
13955 .capsrc_nids = alc268_capsrc_nids,
3866f0b0
TI
13956 .hp_nid = 0x02,
13957 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13958 .channel_mode = alc268_modes,
a9fd4f3f 13959 .unsol_event = alc_sku_unsol_event,
4f5d1706
TI
13960 .setup = alc268_dell_setup,
13961 .init_hook = alc_inithook,
3866f0b0 13962 },
f12462c5 13963 [ALC268_ZEPTO] = {
aef9d318
TI
13964 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13965 alc268_beep_mixer },
f12462c5
MT
13966 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13967 alc268_toshiba_verbs },
13968 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13969 .dac_nids = alc268_dac_nids,
13970 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13971 .adc_nids = alc268_adc_nids_alt,
e1406348 13972 .capsrc_nids = alc268_capsrc_nids,
f12462c5
MT
13973 .hp_nid = 0x03,
13974 .dig_out_nid = ALC268_DIGOUT_NID,
13975 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13976 .channel_mode = alc268_modes,
13977 .input_mux = &alc268_capture_source,
e9427969 13978 .unsol_event = alc_sku_unsol_event,
4f5d1706 13979 .setup = alc268_toshiba_setup,
e9427969 13980 .init_hook = alc_inithook,
f12462c5 13981 },
86c53bd2
JW
13982#ifdef CONFIG_SND_DEBUG
13983 [ALC268_TEST] = {
13984 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13985 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13986 alc268_volume_init_verbs },
13987 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13988 .dac_nids = alc268_dac_nids,
13989 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13990 .adc_nids = alc268_adc_nids_alt,
e1406348 13991 .capsrc_nids = alc268_capsrc_nids,
86c53bd2
JW
13992 .hp_nid = 0x03,
13993 .dig_out_nid = ALC268_DIGOUT_NID,
13994 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13995 .channel_mode = alc268_modes,
13996 .input_mux = &alc268_capture_source,
13997 },
13998#endif
a361d84b
KY
13999};
14000
14001static int patch_alc268(struct hda_codec *codec)
14002{
14003 struct alc_spec *spec;
14004 int board_config;
22971e3a 14005 int i, has_beep, err;
a361d84b 14006
ef86f581 14007 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
a361d84b
KY
14008 if (spec == NULL)
14009 return -ENOMEM;
14010
14011 codec->spec = spec;
14012
14013 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14014 alc268_models,
14015 alc268_cfg_tbl);
14016
3abf2f36
TI
14017 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14018 board_config = snd_hda_check_board_codec_sid_config(codec,
50ae0aa8 14019 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
3abf2f36 14020
a361d84b 14021 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
9a11f1aa
TI
14022 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14023 codec->chip_name);
a361d84b
KY
14024 board_config = ALC268_AUTO;
14025 }
14026
14027 if (board_config == ALC268_AUTO) {
14028 /* automatic parse from the BIOS config */
14029 err = alc268_parse_auto_config(codec);
14030 if (err < 0) {
14031 alc_free(codec);
14032 return err;
14033 } else if (!err) {
14034 printk(KERN_INFO
14035 "hda_codec: Cannot set up configuration "
14036 "from BIOS. Using base mode...\n");
14037 board_config = ALC268_3ST;
14038 }
14039 }
14040
14041 if (board_config != ALC268_AUTO)
e9c364c0 14042 setup_preset(codec, &alc268_presets[board_config]);
a361d84b 14043
a361d84b
KY
14044 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14045 spec->stream_analog_capture = &alc268_pcm_analog_capture;
6330079f 14046 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
a361d84b 14047
a361d84b
KY
14048 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14049
22971e3a
TI
14050 has_beep = 0;
14051 for (i = 0; i < spec->num_mixers; i++) {
14052 if (spec->mixers[i] == alc268_beep_mixer) {
14053 has_beep = 1;
14054 break;
14055 }
14056 }
14057
14058 if (has_beep) {
14059 err = snd_hda_attach_beep_device(codec, 0x1);
14060 if (err < 0) {
14061 alc_free(codec);
14062 return err;
14063 }
14064 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14065 /* override the amp caps for beep generator */
14066 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
aef9d318
TI
14067 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14068 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14069 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14070 (0 << AC_AMPCAP_MUTE_SHIFT));
22971e3a 14071 }
aef9d318 14072
7e0e44d4 14073 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
3866f0b0
TI
14074 /* check whether NID 0x07 is valid */
14075 unsigned int wcap = get_wcaps(codec, 0x07);
14076
defb5ab2 14077 spec->capsrc_nids = alc268_capsrc_nids;
3866f0b0 14078 /* get type */
a22d543a 14079 wcap = get_wcaps_type(wcap);
fdbc6626
TI
14080 if (spec->auto_mic ||
14081 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
3866f0b0
TI
14082 spec->adc_nids = alc268_adc_nids_alt;
14083 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
defb5ab2
TI
14084 if (spec->auto_mic)
14085 fixup_automic_adc(codec);
fdbc6626
TI
14086 if (spec->auto_mic || spec->input_mux->num_items == 1)
14087 add_mixer(spec, alc268_capture_nosrc_mixer);
14088 else
14089 add_mixer(spec, alc268_capture_alt_mixer);
3866f0b0
TI
14090 } else {
14091 spec->adc_nids = alc268_adc_nids;
14092 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
d88897ea 14093 add_mixer(spec, alc268_capture_mixer);
a361d84b
KY
14094 }
14095 }
2134ea4f
TI
14096
14097 spec->vmaster_nid = 0x02;
14098
a361d84b
KY
14099 codec->patch_ops = alc_patch_ops;
14100 if (board_config == ALC268_AUTO)
14101 spec->init_hook = alc268_auto_init;
1c716153 14102 spec->shutup = alc_eapd_shutup;
ea1fb29a 14103
bf1b0225
KY
14104 alc_init_jacks(codec);
14105
a361d84b
KY
14106 return 0;
14107}
14108
f6a92248
KY
14109/*
14110 * ALC269 channel source setting (2 channel)
14111 */
14112#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14113
14114#define alc269_dac_nids alc260_dac_nids
14115
4c6d72d1 14116static const hda_nid_t alc269_adc_nids[1] = {
f6a92248 14117 /* ADC1 */
f53281e6
KY
14118 0x08,
14119};
14120
4c6d72d1 14121static const hda_nid_t alc269_capsrc_nids[1] = {
e01bf509
TI
14122 0x23,
14123};
14124
4c6d72d1 14125static const hda_nid_t alc269vb_adc_nids[1] = {
84898e87
KY
14126 /* ADC1 */
14127 0x09,
14128};
14129
4c6d72d1 14130static const hda_nid_t alc269vb_capsrc_nids[1] = {
84898e87
KY
14131 0x22,
14132};
14133
4c6d72d1 14134static const hda_nid_t alc269_adc_candidates[] = {
262ac22d 14135 0x08, 0x09, 0x07, 0x11,
6694635d 14136};
e01bf509 14137
f6a92248
KY
14138#define alc269_modes alc260_modes
14139#define alc269_capture_source alc880_lg_lw_capture_source
14140
a9111321 14141static const struct snd_kcontrol_new alc269_base_mixer[] = {
f6a92248
KY
14142 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14143 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14144 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14145 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14146 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14147 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14148 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f6a92248
KY
14149 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14150 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14151 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f6a92248
KY
14152 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14153 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14154 { } /* end */
14155};
14156
a9111321 14157static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
60db6b53
KY
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,
60db6b53
KY
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),
60db6b53
KY
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),
60db6b53
KY
14175 { }
14176};
14177
a9111321 14178static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
64154835
TV
14179 /* output mixer control */
14180 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14181 {
14182 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14183 .name = "Master Playback Switch",
5e26dfd0 14184 .subdevice = HDA_SUBDEV_AMP_FLAG,
64154835
TV
14185 .info = snd_hda_mixer_amp_switch_info,
14186 .get = snd_hda_mixer_amp_switch_get,
14187 .put = alc268_acer_master_sw_put,
14188 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14189 },
14190 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 14192 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
64154835
TV
14193 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14194 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5f99f86a 14195 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
64154835
TV
14196 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14197 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
5f99f86a 14198 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
64154835
TV
14199 { }
14200};
14201
a9111321 14202static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
aa202455 14203 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
508f7110 14204 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
aa202455 14205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
508f7110 14206 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
f53281e6
KY
14207 { } /* end */
14208};
14209
a9111321 14210static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
84898e87
KY
14211 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14212 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14214 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14215 { } /* end */
14216};
14217
a9111321 14218static const struct snd_kcontrol_new alc269_asus_mixer[] = {
fe3eb0a7
KY
14219 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14220 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14221 { } /* end */
14222};
14223
f53281e6 14224/* capture mixer elements */
a9111321 14225static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
84898e87
KY
14226 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14227 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a
DH
14228 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14229 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14230 { } /* end */
14231};
14232
a9111321 14233static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
f53281e6
KY
14234 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14235 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5f99f86a 14236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
26f5df26
TI
14237 { } /* end */
14238};
14239
a9111321 14240static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
84898e87
KY
14241 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14242 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a
DH
14243 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14244 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
84898e87
KY
14245 { } /* end */
14246};
14247
a9111321 14248static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
84898e87
KY
14249 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14250 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
5f99f86a 14251 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
84898e87
KY
14252 { } /* end */
14253};
14254
26f5df26 14255/* FSC amilo */
84898e87 14256#define alc269_fujitsu_mixer alc269_laptop_mixer
f53281e6 14257
a9111321 14258static const struct hda_verb alc269_quanta_fl1_verbs[] = {
60db6b53
KY
14259 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14260 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14261 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14262 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14263 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14264 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14265 { }
14266};
f6a92248 14267
a9111321 14268static const struct hda_verb alc269_lifebook_verbs[] = {
64154835
TV
14269 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14270 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14271 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14272 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14273 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14274 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14275 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14276 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14277 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14278 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14279 { }
14280};
14281
60db6b53
KY
14282/* toggle speaker-output according to the hp-jack state */
14283static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14284{
3b8510ce 14285 alc_hp_automute(codec);
f6a92248 14286
60db6b53
KY
14287 snd_hda_codec_write(codec, 0x20, 0,
14288 AC_VERB_SET_COEF_INDEX, 0x0c);
14289 snd_hda_codec_write(codec, 0x20, 0,
14290 AC_VERB_SET_PROC_COEF, 0x680);
f6a92248 14291
60db6b53
KY
14292 snd_hda_codec_write(codec, 0x20, 0,
14293 AC_VERB_SET_COEF_INDEX, 0x0c);
14294 snd_hda_codec_write(codec, 0x20, 0,
14295 AC_VERB_SET_PROC_COEF, 0x480);
14296}
f6a92248 14297
3b8510ce
TI
14298#define alc269_lifebook_speaker_automute \
14299 alc269_quanta_fl1_speaker_automute
64154835 14300
64154835
TV
14301static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14302{
14303 unsigned int present_laptop;
14304 unsigned int present_dock;
14305
864f92be
WF
14306 present_laptop = snd_hda_jack_detect(codec, 0x18);
14307 present_dock = snd_hda_jack_detect(codec, 0x1b);
64154835
TV
14308
14309 /* Laptop mic port overrides dock mic port, design decision */
14310 if (present_dock)
14311 snd_hda_codec_write(codec, 0x23, 0,
14312 AC_VERB_SET_CONNECT_SEL, 0x3);
14313 if (present_laptop)
14314 snd_hda_codec_write(codec, 0x23, 0,
14315 AC_VERB_SET_CONNECT_SEL, 0x0);
14316 if (!present_dock && !present_laptop)
14317 snd_hda_codec_write(codec, 0x23, 0,
14318 AC_VERB_SET_CONNECT_SEL, 0x1);
14319}
14320
60db6b53
KY
14321static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14322 unsigned int res)
14323{
4f5d1706
TI
14324 switch (res >> 26) {
14325 case ALC880_HP_EVENT:
60db6b53 14326 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706
TI
14327 break;
14328 case ALC880_MIC_EVENT:
14329 alc_mic_automute(codec);
14330 break;
14331 }
60db6b53 14332}
f6a92248 14333
64154835
TV
14334static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14335 unsigned int res)
14336{
14337 if ((res >> 26) == ALC880_HP_EVENT)
14338 alc269_lifebook_speaker_automute(codec);
14339 if ((res >> 26) == ALC880_MIC_EVENT)
14340 alc269_lifebook_mic_autoswitch(codec);
14341}
14342
4f5d1706
TI
14343static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14344{
14345 struct alc_spec *spec = codec->spec;
20645d70
TI
14346 spec->autocfg.hp_pins[0] = 0x15;
14347 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14348 spec->automute_mixer_nid[0] = 0x0c;
14349 spec->automute = 1;
14350 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14351 spec->ext_mic.pin = 0x18;
14352 spec->ext_mic.mux_idx = 0;
14353 spec->int_mic.pin = 0x19;
14354 spec->int_mic.mux_idx = 1;
14355 spec->auto_mic = 1;
14356}
14357
60db6b53
KY
14358static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14359{
14360 alc269_quanta_fl1_speaker_automute(codec);
4f5d1706 14361 alc_mic_automute(codec);
60db6b53 14362}
f6a92248 14363
3b8510ce
TI
14364static void alc269_lifebook_setup(struct hda_codec *codec)
14365{
14366 struct alc_spec *spec = codec->spec;
14367 spec->autocfg.hp_pins[0] = 0x15;
14368 spec->autocfg.hp_pins[1] = 0x1a;
14369 spec->autocfg.speaker_pins[0] = 0x14;
14370 spec->automute_mixer_nid[0] = 0x0c;
14371 spec->automute = 1;
14372 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14373}
14374
64154835
TV
14375static void alc269_lifebook_init_hook(struct hda_codec *codec)
14376{
14377 alc269_lifebook_speaker_automute(codec);
14378 alc269_lifebook_mic_autoswitch(codec);
14379}
14380
a9111321 14381static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
f53281e6
KY
14382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14383 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14384 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14385 {0x08, 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 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14389 {}
14390};
14391
a9111321 14392static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
f53281e6
KY
14393 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14394 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14395 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14396 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14398 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14399 {}
14400};
14401
a9111321 14402static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
84898e87
KY
14403 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14404 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14405 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14406 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14407 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14408 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14409 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14410 {}
14411};
14412
a9111321 14413static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
84898e87
KY
14414 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14415 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14416 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14417 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14418 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14419 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14420 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14421 {}
14422};
14423
a9111321 14424static const struct hda_verb alc271_acer_dmic_verbs[] = {
fe3eb0a7
KY
14425 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14426 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14427 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14429 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14430 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14431 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14432 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14433 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14434 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14435 { }
14436};
14437
226b1ec8 14438static void alc269_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14439{
4f5d1706 14440 struct alc_spec *spec = codec->spec;
20645d70
TI
14441 spec->autocfg.hp_pins[0] = 0x15;
14442 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14443 spec->automute_mixer_nid[0] = 0x0c;
14444 spec->automute = 1;
14445 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14446 spec->ext_mic.pin = 0x18;
14447 spec->ext_mic.mux_idx = 0;
226b1ec8
KY
14448 spec->int_mic.pin = 0x19;
14449 spec->int_mic.mux_idx = 1;
4f5d1706 14450 spec->auto_mic = 1;
f53281e6
KY
14451}
14452
226b1ec8 14453static void alc269_laptop_dmic_setup(struct hda_codec *codec)
84898e87
KY
14454{
14455 struct alc_spec *spec = codec->spec;
20645d70
TI
14456 spec->autocfg.hp_pins[0] = 0x15;
14457 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14458 spec->automute_mixer_nid[0] = 0x0c;
14459 spec->automute = 1;
14460 spec->automute_mode = ALC_AUTOMUTE_MIXER;
84898e87
KY
14461 spec->ext_mic.pin = 0x18;
14462 spec->ext_mic.mux_idx = 0;
14463 spec->int_mic.pin = 0x12;
226b1ec8 14464 spec->int_mic.mux_idx = 5;
84898e87
KY
14465 spec->auto_mic = 1;
14466}
14467
226b1ec8 14468static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
f53281e6 14469{
4f5d1706 14470 struct alc_spec *spec = codec->spec;
226b1ec8 14471 spec->autocfg.hp_pins[0] = 0x21;
20645d70 14472 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14473 spec->automute_mixer_nid[0] = 0x0c;
14474 spec->automute = 1;
14475 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
14476 spec->ext_mic.pin = 0x18;
14477 spec->ext_mic.mux_idx = 0;
14478 spec->int_mic.pin = 0x19;
14479 spec->int_mic.mux_idx = 1;
14480 spec->auto_mic = 1;
f53281e6
KY
14481}
14482
226b1ec8
KY
14483static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14484{
14485 struct alc_spec *spec = codec->spec;
14486 spec->autocfg.hp_pins[0] = 0x21;
14487 spec->autocfg.speaker_pins[0] = 0x14;
3b8510ce
TI
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
226b1ec8
KY
14491 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0;
14493 spec->int_mic.pin = 0x12;
14494 spec->int_mic.mux_idx = 6;
14495 spec->auto_mic = 1;
14496}
14497
60db6b53
KY
14498/*
14499 * generic initialization of ADC, input mixers and output mixers
14500 */
a9111321 14501static const struct hda_verb alc269_init_verbs[] = {
60db6b53
KY
14502 /*
14503 * Unmute ADC0 and set the default input to mic-in
14504 */
84898e87 14505 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
60db6b53
KY
14506
14507 /*
84898e87 14508 * Set up output mixers (0x02 - 0x03)
60db6b53
KY
14509 */
14510 /* set vol=0 to output mixers */
14511 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14512 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14513
14514 /* set up input amps for analog loopback */
14515 /* Amp Indices: DAC = 0, mixer = 1 */
14516 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14517 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14518 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14519 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14520 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14521 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14522
14523 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14524 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14525 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14526 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14527 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14529 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14530
14531 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14532 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
60db6b53 14533
84898e87
KY
14534 /* FIXME: use Mux-type input source selection */
14535 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14536 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14537 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53 14538
84898e87
KY
14539 /* set EAPD */
14540 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14541 { }
14542};
14543
a9111321 14544static const struct hda_verb alc269vb_init_verbs[] = {
84898e87
KY
14545 /*
14546 * Unmute ADC0 and set the default input to mic-in
14547 */
14548 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14549
14550 /*
14551 * Set up output mixers (0x02 - 0x03)
14552 */
14553 /* set vol=0 to output mixers */
14554 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14555 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14556
14557 /* set up input amps for analog loopback */
14558 /* Amp Indices: DAC = 0, mixer = 1 */
14559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565
14566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14567 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14570 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14571 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14573
14574 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14575 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14576
14577 /* FIXME: use Mux-type input source selection */
60db6b53
KY
14578 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14579 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
84898e87 14580 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
60db6b53
KY
14581
14582 /* set EAPD */
14583 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
60db6b53
KY
14584 { }
14585};
14586
9d0b71b1
TI
14587#define alc269_auto_create_multi_out_ctls \
14588 alc268_auto_create_multi_out_ctls
05f5f477
TI
14589#define alc269_auto_create_input_ctls \
14590 alc268_auto_create_input_ctls
f6a92248
KY
14591
14592#ifdef CONFIG_SND_HDA_POWER_SAVE
14593#define alc269_loopbacks alc880_loopbacks
14594#endif
14595
def319f9 14596/* pcm configuration: identical with ALC880 */
f6a92248
KY
14597#define alc269_pcm_analog_playback alc880_pcm_analog_playback
14598#define alc269_pcm_analog_capture alc880_pcm_analog_capture
14599#define alc269_pcm_digital_playback alc880_pcm_digital_playback
14600#define alc269_pcm_digital_capture alc880_pcm_digital_capture
14601
a9111321 14602static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
f03d3115
TI
14603 .substreams = 1,
14604 .channels_min = 2,
14605 .channels_max = 8,
14606 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14607 /* NID is set in alc_build_pcms */
14608 .ops = {
14609 .open = alc880_playback_pcm_open,
14610 .prepare = alc880_playback_pcm_prepare,
14611 .cleanup = alc880_playback_pcm_cleanup
14612 },
14613};
14614
a9111321 14615static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
f03d3115
TI
14616 .substreams = 1,
14617 .channels_min = 2,
14618 .channels_max = 2,
14619 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14620 /* NID is set in alc_build_pcms */
14621};
14622
ad35879a
TI
14623#ifdef CONFIG_SND_HDA_POWER_SAVE
14624static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14625{
14626 switch (codec->subsystem_id) {
14627 case 0x103c1586:
14628 return 1;
14629 }
14630 return 0;
14631}
14632
14633static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14634{
14635 /* update mute-LED according to the speaker mute state */
14636 if (nid == 0x01 || nid == 0x14) {
14637 int pinval;
14638 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14639 HDA_AMP_MUTE)
14640 pinval = 0x24;
14641 else
14642 pinval = 0x20;
14643 /* mic2 vref pin is used for mute LED control */
a68d5a54
TI
14644 snd_hda_codec_update_cache(codec, 0x19, 0,
14645 AC_VERB_SET_PIN_WIDGET_CONTROL,
14646 pinval);
ad35879a
TI
14647 }
14648 return alc_check_power_status(codec, nid);
14649}
14650#endif /* CONFIG_SND_HDA_POWER_SAVE */
14651
840b64c0
TI
14652static int alc275_setup_dual_adc(struct hda_codec *codec)
14653{
14654 struct alc_spec *spec = codec->spec;
14655
14656 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14657 return 0;
14658 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14659 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14660 if (spec->ext_mic.pin <= 0x12) {
14661 spec->private_adc_nids[0] = 0x08;
14662 spec->private_adc_nids[1] = 0x11;
14663 spec->private_capsrc_nids[0] = 0x23;
14664 spec->private_capsrc_nids[1] = 0x22;
14665 } else {
14666 spec->private_adc_nids[0] = 0x11;
14667 spec->private_adc_nids[1] = 0x08;
14668 spec->private_capsrc_nids[0] = 0x22;
14669 spec->private_capsrc_nids[1] = 0x23;
14670 }
14671 spec->adc_nids = spec->private_adc_nids;
14672 spec->capsrc_nids = spec->private_capsrc_nids;
14673 spec->num_adc_nids = 2;
14674 spec->dual_adc_switch = 1;
14675 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14676 spec->adc_nids[0], spec->adc_nids[1]);
14677 return 1;
14678 }
14679 return 0;
14680}
14681
d433a678
TI
14682/* different alc269-variants */
14683enum {
14684 ALC269_TYPE_NORMAL,
48c88e82 14685 ALC269_TYPE_ALC258,
d433a678 14686 ALC269_TYPE_ALC259,
48c88e82
KY
14687 ALC269_TYPE_ALC269VB,
14688 ALC269_TYPE_ALC270,
d433a678
TI
14689 ALC269_TYPE_ALC271X,
14690};
14691
f6a92248
KY
14692/*
14693 * BIOS auto configuration
14694 */
14695static int alc269_parse_auto_config(struct hda_codec *codec)
14696{
14697 struct alc_spec *spec = codec->spec;
cfb9fb55 14698 int err;
4c6d72d1 14699 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
f6a92248
KY
14700
14701 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14702 alc269_ignore);
14703 if (err < 0)
14704 return err;
14705
14706 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14707 if (err < 0)
14708 return err;
f3550d1b
TI
14709 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14710 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14711 else
14712 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14713 0x22, 0);
f6a92248
KY
14714 if (err < 0)
14715 return err;
14716
14717 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14718
757899ac 14719 alc_auto_parse_digital(codec);
f6a92248 14720
603c4019 14721 if (spec->kctls.list)
d88897ea 14722 add_mixer(spec, spec->kctls.list);
f6a92248 14723
d433a678 14724 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
84898e87 14725 add_verb(spec, alc269vb_init_verbs);
6227cdce 14726 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
84898e87
KY
14727 } else {
14728 add_verb(spec, alc269_init_verbs);
6227cdce 14729 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
84898e87
KY
14730 }
14731
f6a92248 14732 spec->num_mux_defs = 1;
61b9b9b1 14733 spec->input_mux = &spec->private_imux[0];
840b64c0
TI
14734
14735 if (!alc275_setup_dual_adc(codec))
14736 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14737 sizeof(alc269_adc_candidates));
6694635d 14738
f6a92248
KY
14739 err = alc_auto_add_mic_boost(codec);
14740 if (err < 0)
14741 return err;
14742
7e0e44d4 14743 if (!spec->cap_mixer && !spec->no_analog)
b59bdf3b 14744 set_capture_mixer(codec);
f53281e6 14745
f6a92248
KY
14746 return 1;
14747}
14748
e9af4f36
TI
14749#define alc269_auto_init_multi_out alc268_auto_init_multi_out
14750#define alc269_auto_init_hp_out alc268_auto_init_hp_out
f6a92248 14751#define alc269_auto_init_analog_input alc882_auto_init_analog_input
ae0ebbf7 14752#define alc269_auto_init_input_src alc882_auto_init_input_src
f6a92248
KY
14753
14754
14755/* init callback for auto-configuration model -- overriding the default init */
14756static void alc269_auto_init(struct hda_codec *codec)
14757{
f6c7e546 14758 struct alc_spec *spec = codec->spec;
f6a92248
KY
14759 alc269_auto_init_multi_out(codec);
14760 alc269_auto_init_hp_out(codec);
14761 alc269_auto_init_analog_input(codec);
ae0ebbf7
TI
14762 if (!spec->dual_adc_switch)
14763 alc269_auto_init_input_src(codec);
757899ac 14764 alc_auto_init_digital(codec);
f6c7e546 14765 if (spec->unsol_event)
7fb0d78f 14766 alc_inithook(codec);
f6a92248
KY
14767}
14768
0ec33d1f
TI
14769static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14770{
14771 int val = alc_read_coef_idx(codec, 0x04);
14772 if (power_up)
14773 val |= 1 << 11;
14774 else
14775 val &= ~(1 << 11);
14776 alc_write_coef_idx(codec, 0x04, val);
14777}
14778
5402e4cb 14779static void alc269_shutup(struct hda_codec *codec)
977ddd6b 14780{
0ec33d1f
TI
14781 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14782 alc269_toggle_power_output(codec, 0);
977ddd6b 14783 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14784 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14785 msleep(150);
14786 }
977ddd6b 14787}
0ec33d1f 14788
5402e4cb 14789#ifdef SND_HDA_NEEDS_RESUME
977ddd6b
KY
14790static int alc269_resume(struct hda_codec *codec)
14791{
977ddd6b 14792 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
0ec33d1f 14793 alc269_toggle_power_output(codec, 0);
977ddd6b
KY
14794 msleep(150);
14795 }
14796
14797 codec->patch_ops.init(codec);
14798
14799 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
0ec33d1f 14800 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14801 msleep(200);
14802 }
14803
0ec33d1f
TI
14804 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14805 alc269_toggle_power_output(codec, 1);
977ddd6b
KY
14806
14807 snd_hda_codec_resume_amp(codec);
14808 snd_hda_codec_resume_cache(codec);
9e5341b9 14809 hda_call_check_power_status(codec, 0x01);
977ddd6b
KY
14810 return 0;
14811}
0ec33d1f 14812#endif /* SND_HDA_NEEDS_RESUME */
977ddd6b 14813
1a99d4a4 14814static void alc269_fixup_hweq(struct hda_codec *codec,
b5bfbc67 14815 const struct alc_fixup *fix, int action)
1a99d4a4
KY
14816{
14817 int coef;
14818
58701120 14819 if (action != ALC_FIXUP_ACT_INIT)
9fb1ef25 14820 return;
1a99d4a4
KY
14821 coef = alc_read_coef_idx(codec, 0x1e);
14822 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14823}
14824
6981d184
TI
14825static void alc271_fixup_dmic(struct hda_codec *codec,
14826 const struct alc_fixup *fix, int action)
14827{
a9111321 14828 static const struct hda_verb verbs[] = {
6981d184
TI
14829 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14830 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14831 {}
14832 };
14833 unsigned int cfg;
14834
14835 if (strcmp(codec->chip_name, "ALC271X"))
14836 return;
14837 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14838 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14839 snd_hda_sequence_write(codec, verbs);
14840}
14841
ff818c24
TI
14842enum {
14843 ALC269_FIXUP_SONY_VAIO,
74dc8909 14844 ALC275_FIXUP_SONY_VAIO_GPIO2,
145a902b 14845 ALC269_FIXUP_DELL_M101Z,
022c92be 14846 ALC269_FIXUP_SKU_IGNORE,
ac612407 14847 ALC269_FIXUP_ASUS_G73JW,
357f915e 14848 ALC269_FIXUP_LENOVO_EAPD,
1a99d4a4 14849 ALC275_FIXUP_SONY_HWEQ,
6981d184 14850 ALC271_FIXUP_DMIC,
ff818c24
TI
14851};
14852
ff818c24
TI
14853static const struct alc_fixup alc269_fixups[] = {
14854 [ALC269_FIXUP_SONY_VAIO] = {
b5bfbc67
TI
14855 .type = ALC_FIXUP_VERBS,
14856 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
14857 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14858 {}
14859 }
ff818c24 14860 },
74dc8909 14861 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
b5bfbc67
TI
14862 .type = ALC_FIXUP_VERBS,
14863 .v.verbs = (const struct hda_verb[]) {
2785591a
KY
14864 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14865 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14866 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14867 { }
b5bfbc67
TI
14868 },
14869 .chained = true,
14870 .chain_id = ALC269_FIXUP_SONY_VAIO
2785591a 14871 },
145a902b 14872 [ALC269_FIXUP_DELL_M101Z] = {
b5bfbc67
TI
14873 .type = ALC_FIXUP_VERBS,
14874 .v.verbs = (const struct hda_verb[]) {
145a902b
DH
14875 /* Enables internal speaker */
14876 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14877 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14878 {}
14879 }
14880 },
022c92be 14881 [ALC269_FIXUP_SKU_IGNORE] = {
b5bfbc67
TI
14882 .type = ALC_FIXUP_SKU,
14883 .v.sku = ALC_FIXUP_SKU_IGNORE,
fe67b240 14884 },
ac612407 14885 [ALC269_FIXUP_ASUS_G73JW] = {
b5bfbc67
TI
14886 .type = ALC_FIXUP_PINS,
14887 .v.pins = (const struct alc_pincfg[]) {
ac612407
DH
14888 { 0x17, 0x99130111 }, /* subwoofer */
14889 { }
14890 }
14891 },
357f915e 14892 [ALC269_FIXUP_LENOVO_EAPD] = {
b5bfbc67
TI
14893 .type = ALC_FIXUP_VERBS,
14894 .v.verbs = (const struct hda_verb[]) {
357f915e
KY
14895 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14896 {}
14897 }
14898 },
1a99d4a4 14899 [ALC275_FIXUP_SONY_HWEQ] = {
b5bfbc67
TI
14900 .type = ALC_FIXUP_FUNC,
14901 .v.func = alc269_fixup_hweq,
14902 .chained = true,
14903 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
6981d184
TI
14904 },
14905 [ALC271_FIXUP_DMIC] = {
14906 .type = ALC_FIXUP_FUNC,
14907 .v.func = alc271_fixup_dmic,
14908 },
ff818c24
TI
14909};
14910
a9111321 14911static const struct snd_pci_quirk alc269_fixup_tbl[] = {
74dc8909 14912 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
1a99d4a4
KY
14913 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14914 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
7039c74c 14915 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
145a902b 14916 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
6981d184 14917 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
022c92be 14918 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
ded9f523
DH
14919 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14920 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14921 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14922 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
ac612407 14923 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
357f915e 14924 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
ff818c24
TI
14925 {}
14926};
14927
14928
f6a92248
KY
14929/*
14930 * configuration and preset
14931 */
ea734963 14932static const char * const alc269_models[ALC269_MODEL_LAST] = {
60db6b53 14933 [ALC269_BASIC] = "basic",
2922c9af 14934 [ALC269_QUANTA_FL1] = "quanta",
84898e87
KY
14935 [ALC269_AMIC] = "laptop-amic",
14936 [ALC269_DMIC] = "laptop-dmic",
64154835 14937 [ALC269_FUJITSU] = "fujitsu",
3d3792cb
TI
14938 [ALC269_LIFEBOOK] = "lifebook",
14939 [ALC269_AUTO] = "auto",
f6a92248
KY
14940};
14941
a9111321 14942static const struct snd_pci_quirk alc269_cfg_tbl[] = {
60db6b53 14943 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
fe3eb0a7 14944 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
f53281e6 14945 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
84898e87
KY
14946 ALC269_AMIC),
14947 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14948 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14949 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14950 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14951 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14952 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14953 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14954 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14955 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
c790ad31 14956 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
84898e87
KY
14957 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14958 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14959 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14960 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14961 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14962 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14963 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14964 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14965 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14966 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14967 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14968 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14969 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14970 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14971 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14972 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14973 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14974 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14975 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14976 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14977 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14978 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14979 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14980 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14981 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14982 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
f53281e6 14983 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
84898e87 14984 ALC269_DMIC),
60db6b53 14985 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
84898e87
KY
14986 ALC269_DMIC),
14987 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14988 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
ff818c24 14989 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
64154835 14990 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
61c2d2b5
KY
14991 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14992 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14993 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14994 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14995 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14996 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
f6a92248
KY
14997 {}
14998};
14999
a9111321 15000static const struct alc_config_preset alc269_presets[] = {
f6a92248 15001 [ALC269_BASIC] = {
f9e336f6 15002 .mixers = { alc269_base_mixer },
f6a92248
KY
15003 .init_verbs = { alc269_init_verbs },
15004 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15005 .dac_nids = alc269_dac_nids,
15006 .hp_nid = 0x03,
15007 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15008 .channel_mode = alc269_modes,
15009 .input_mux = &alc269_capture_source,
15010 },
60db6b53
KY
15011 [ALC269_QUANTA_FL1] = {
15012 .mixers = { alc269_quanta_fl1_mixer },
15013 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15014 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15015 .dac_nids = alc269_dac_nids,
15016 .hp_nid = 0x03,
15017 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15018 .channel_mode = alc269_modes,
15019 .input_mux = &alc269_capture_source,
15020 .unsol_event = alc269_quanta_fl1_unsol_event,
4f5d1706 15021 .setup = alc269_quanta_fl1_setup,
60db6b53
KY
15022 .init_hook = alc269_quanta_fl1_init_hook,
15023 },
84898e87
KY
15024 [ALC269_AMIC] = {
15025 .mixers = { alc269_laptop_mixer },
15026 .cap_mixer = alc269_laptop_analog_capture_mixer,
f53281e6 15027 .init_verbs = { alc269_init_verbs,
84898e87 15028 alc269_laptop_amic_init_verbs },
f53281e6
KY
15029 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15030 .dac_nids = alc269_dac_nids,
15031 .hp_nid = 0x03,
15032 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15033 .channel_mode = alc269_modes,
3b8510ce 15034 .unsol_event = alc_sku_unsol_event,
84898e87 15035 .setup = alc269_laptop_amic_setup,
3b8510ce 15036 .init_hook = alc_inithook,
f53281e6 15037 },
84898e87
KY
15038 [ALC269_DMIC] = {
15039 .mixers = { alc269_laptop_mixer },
15040 .cap_mixer = alc269_laptop_digital_capture_mixer,
f53281e6 15041 .init_verbs = { alc269_init_verbs,
84898e87
KY
15042 alc269_laptop_dmic_init_verbs },
15043 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15044 .dac_nids = alc269_dac_nids,
15045 .hp_nid = 0x03,
15046 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15047 .channel_mode = alc269_modes,
3b8510ce 15048 .unsol_event = alc_sku_unsol_event,
84898e87 15049 .setup = alc269_laptop_dmic_setup,
3b8510ce 15050 .init_hook = alc_inithook,
84898e87
KY
15051 },
15052 [ALC269VB_AMIC] = {
15053 .mixers = { alc269vb_laptop_mixer },
15054 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15055 .init_verbs = { alc269vb_init_verbs,
15056 alc269vb_laptop_amic_init_verbs },
f53281e6
KY
15057 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15058 .dac_nids = alc269_dac_nids,
15059 .hp_nid = 0x03,
15060 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15061 .channel_mode = alc269_modes,
3b8510ce 15062 .unsol_event = alc_sku_unsol_event,
226b1ec8 15063 .setup = alc269vb_laptop_amic_setup,
3b8510ce 15064 .init_hook = alc_inithook,
84898e87
KY
15065 },
15066 [ALC269VB_DMIC] = {
15067 .mixers = { alc269vb_laptop_mixer },
15068 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15069 .init_verbs = { alc269vb_init_verbs,
15070 alc269vb_laptop_dmic_init_verbs },
15071 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15072 .dac_nids = alc269_dac_nids,
15073 .hp_nid = 0x03,
15074 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15075 .channel_mode = alc269_modes,
3b8510ce 15076 .unsol_event = alc_sku_unsol_event,
84898e87 15077 .setup = alc269vb_laptop_dmic_setup,
3b8510ce 15078 .init_hook = alc_inithook,
f53281e6 15079 },
26f5df26 15080 [ALC269_FUJITSU] = {
45bdd1c1 15081 .mixers = { alc269_fujitsu_mixer },
84898e87 15082 .cap_mixer = alc269_laptop_digital_capture_mixer,
26f5df26 15083 .init_verbs = { alc269_init_verbs,
84898e87 15084 alc269_laptop_dmic_init_verbs },
26f5df26
TI
15085 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15086 .dac_nids = alc269_dac_nids,
15087 .hp_nid = 0x03,
15088 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15089 .channel_mode = alc269_modes,
3b8510ce 15090 .unsol_event = alc_sku_unsol_event,
84898e87 15091 .setup = alc269_laptop_dmic_setup,
3b8510ce 15092 .init_hook = alc_inithook,
26f5df26 15093 },
64154835
TV
15094 [ALC269_LIFEBOOK] = {
15095 .mixers = { alc269_lifebook_mixer },
15096 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15097 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15098 .dac_nids = alc269_dac_nids,
15099 .hp_nid = 0x03,
15100 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15101 .channel_mode = alc269_modes,
15102 .input_mux = &alc269_capture_source,
15103 .unsol_event = alc269_lifebook_unsol_event,
3b8510ce 15104 .setup = alc269_lifebook_setup,
64154835
TV
15105 .init_hook = alc269_lifebook_init_hook,
15106 },
fe3eb0a7
KY
15107 [ALC271_ACER] = {
15108 .mixers = { alc269_asus_mixer },
15109 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15110 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15111 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15112 .dac_nids = alc269_dac_nids,
15113 .adc_nids = alc262_dmic_adc_nids,
15114 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15115 .capsrc_nids = alc262_dmic_capsrc_nids,
15116 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15117 .channel_mode = alc269_modes,
15118 .input_mux = &alc269_capture_source,
15119 .dig_out_nid = ALC880_DIGOUT_NID,
15120 .unsol_event = alc_sku_unsol_event,
15121 .setup = alc269vb_laptop_dmic_setup,
15122 .init_hook = alc_inithook,
15123 },
f6a92248
KY
15124};
15125
977ddd6b
KY
15126static int alc269_fill_coef(struct hda_codec *codec)
15127{
15128 int val;
15129
15130 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15131 alc_write_coef_idx(codec, 0xf, 0x960b);
15132 alc_write_coef_idx(codec, 0xe, 0x8817);
15133 }
15134
15135 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15136 alc_write_coef_idx(codec, 0xf, 0x960b);
15137 alc_write_coef_idx(codec, 0xe, 0x8814);
15138 }
15139
15140 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15141 val = alc_read_coef_idx(codec, 0x04);
15142 /* Power up output pin */
15143 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15144 }
15145
15146 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15147 val = alc_read_coef_idx(codec, 0xd);
15148 if ((val & 0x0c00) >> 10 != 0x1) {
15149 /* Capless ramp up clock control */
15150 alc_write_coef_idx(codec, 0xd, val | 1<<10);
15151 }
15152 val = alc_read_coef_idx(codec, 0x17);
15153 if ((val & 0x01c0) >> 6 != 0x4) {
15154 /* Class D power on reset */
15155 alc_write_coef_idx(codec, 0x17, val | 1<<7);
15156 }
15157 }
15158 return 0;
15159}
15160
f6a92248
KY
15161static int patch_alc269(struct hda_codec *codec)
15162{
15163 struct alc_spec *spec;
48c88e82 15164 int board_config, coef;
f6a92248
KY
15165 int err;
15166
15167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15168 if (spec == NULL)
15169 return -ENOMEM;
15170
15171 codec->spec = spec;
15172
da00c244
KY
15173 alc_auto_parse_customize_define(codec);
15174
c793bec5
KY
15175 if (codec->vendor_id == 0x10ec0269) {
15176 coef = alc_read_coef_idx(codec, 0);
15177 if ((coef & 0x00f0) == 0x0010) {
15178 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15179 spec->cdefine.platform_type == 1) {
15180 alc_codec_rename(codec, "ALC271X");
15181 spec->codec_variant = ALC269_TYPE_ALC271X;
15182 } else if ((coef & 0xf000) == 0x1000) {
15183 spec->codec_variant = ALC269_TYPE_ALC270;
15184 } else if ((coef & 0xf000) == 0x2000) {
15185 alc_codec_rename(codec, "ALC259");
15186 spec->codec_variant = ALC269_TYPE_ALC259;
15187 } else if ((coef & 0xf000) == 0x3000) {
15188 alc_codec_rename(codec, "ALC258");
15189 spec->codec_variant = ALC269_TYPE_ALC258;
15190 } else {
15191 alc_codec_rename(codec, "ALC269VB");
15192 spec->codec_variant = ALC269_TYPE_ALC269VB;
15193 }
15194 } else
15195 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15196 alc269_fill_coef(codec);
15197 }
977ddd6b 15198
f6a92248
KY
15199 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15200 alc269_models,
15201 alc269_cfg_tbl);
15202
15203 if (board_config < 0) {
9a11f1aa
TI
15204 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15205 codec->chip_name);
f6a92248
KY
15206 board_config = ALC269_AUTO;
15207 }
15208
b5bfbc67
TI
15209 if (board_config == ALC269_AUTO) {
15210 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15211 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15212 }
ff818c24 15213
f6a92248
KY
15214 if (board_config == ALC269_AUTO) {
15215 /* automatic parse from the BIOS config */
15216 err = alc269_parse_auto_config(codec);
15217 if (err < 0) {
15218 alc_free(codec);
15219 return err;
15220 } else if (!err) {
15221 printk(KERN_INFO
15222 "hda_codec: Cannot set up configuration "
15223 "from BIOS. Using base mode...\n");
15224 board_config = ALC269_BASIC;
15225 }
15226 }
15227
dc1eae25 15228 if (has_cdefine_beep(codec)) {
8af2591d
TI
15229 err = snd_hda_attach_beep_device(codec, 0x1);
15230 if (err < 0) {
15231 alc_free(codec);
15232 return err;
15233 }
680cd536
KK
15234 }
15235
f6a92248 15236 if (board_config != ALC269_AUTO)
e9c364c0 15237 setup_preset(codec, &alc269_presets[board_config]);
f6a92248 15238
84898e87 15239 if (board_config == ALC269_QUANTA_FL1) {
f03d3115
TI
15240 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15241 * fix the sample rate of analog I/O to 44.1kHz
15242 */
15243 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15244 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
840b64c0
TI
15245 } else if (spec->dual_adc_switch) {
15246 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15247 /* switch ADC dynamically */
15248 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
f03d3115
TI
15249 } else {
15250 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15251 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15252 }
f6a92248
KY
15253 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15254 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15255
6694635d 15256 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
1657cbd8 15257 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
6694635d
TI
15258 spec->adc_nids = alc269_adc_nids;
15259 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15260 spec->capsrc_nids = alc269_capsrc_nids;
15261 } else {
15262 spec->adc_nids = alc269vb_adc_nids;
15263 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15264 spec->capsrc_nids = alc269vb_capsrc_nids;
15265 }
84898e87
KY
15266 }
15267
f9e336f6 15268 if (!spec->cap_mixer)
b59bdf3b 15269 set_capture_mixer(codec);
dc1eae25 15270 if (has_cdefine_beep(codec))
da00c244 15271 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
f6a92248 15272
b5bfbc67 15273 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
ff818c24 15274
100d5eb3
TI
15275 spec->vmaster_nid = 0x02;
15276
f6a92248 15277 codec->patch_ops = alc_patch_ops;
977ddd6b
KY
15278#ifdef SND_HDA_NEEDS_RESUME
15279 codec->patch_ops.resume = alc269_resume;
15280#endif
f6a92248
KY
15281 if (board_config == ALC269_AUTO)
15282 spec->init_hook = alc269_auto_init;
5402e4cb 15283 spec->shutup = alc269_shutup;
bf1b0225
KY
15284
15285 alc_init_jacks(codec);
f6a92248
KY
15286#ifdef CONFIG_SND_HDA_POWER_SAVE
15287 if (!spec->loopback.amplist)
15288 spec->loopback.amplist = alc269_loopbacks;
ad35879a
TI
15289 if (alc269_mic2_for_mute_led(codec))
15290 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
f6a92248
KY
15291#endif
15292
15293 return 0;
15294}
15295
df694daa
KY
15296/*
15297 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15298 */
15299
15300/*
15301 * set the path ways for 2 channel output
15302 * need to set the codec line out and mic 1 pin widgets to inputs
15303 */
a9111321 15304static const struct hda_verb alc861_threestack_ch2_init[] = {
df694daa
KY
15305 /* set pin widget 1Ah (line in) for input */
15306 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15307 /* set pin widget 18h (mic1/2) for input, for mic also enable
15308 * the vref
15309 */
df694daa
KY
15310 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15311
9c7f852e
TI
15312 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15313#if 0
15314 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15315 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15316#endif
df694daa
KY
15317 { } /* end */
15318};
15319/*
15320 * 6ch mode
15321 * need to set the codec line out and mic 1 pin widgets to outputs
15322 */
a9111321 15323static const struct hda_verb alc861_threestack_ch6_init[] = {
df694daa
KY
15324 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15325 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15326 /* set pin widget 18h (mic1) for output (CLFE)*/
15327 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15328
15329 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
9c7f852e 15330 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa 15331
9c7f852e
TI
15332 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15333#if 0
15334 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15335 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15336#endif
df694daa
KY
15337 { } /* end */
15338};
15339
a9111321 15340static const struct hda_channel_mode alc861_threestack_modes[2] = {
df694daa
KY
15341 { 2, alc861_threestack_ch2_init },
15342 { 6, alc861_threestack_ch6_init },
15343};
22309c3e 15344/* Set mic1 as input and unmute the mixer */
a9111321 15345static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
22309c3e
TI
15346 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15347 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15348 { } /* end */
15349};
15350/* Set mic1 as output and mute mixer */
a9111321 15351static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
22309c3e
TI
15352 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15353 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15354 { } /* end */
15355};
15356
a9111321 15357static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
22309c3e
TI
15358 { 2, alc861_uniwill_m31_ch2_init },
15359 { 4, alc861_uniwill_m31_ch4_init },
15360};
df694daa 15361
7cdbff94 15362/* Set mic1 and line-in as input and unmute the mixer */
a9111321 15363static const struct hda_verb alc861_asus_ch2_init[] = {
7cdbff94
MD
15364 /* set pin widget 1Ah (line in) for input */
15365 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
f12ab1e0
TI
15366 /* set pin widget 18h (mic1/2) for input, for mic also enable
15367 * the vref
15368 */
7cdbff94
MD
15369 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15370
15371 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15372#if 0
15373 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15374 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15375#endif
15376 { } /* end */
15377};
15378/* Set mic1 nad line-in as output and mute mixer */
a9111321 15379static const struct hda_verb alc861_asus_ch6_init[] = {
7cdbff94
MD
15380 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15381 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15382 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15383 /* set pin widget 18h (mic1) for output (CLFE)*/
15384 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15385 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15386 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15387 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15388
15389 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15390#if 0
15391 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15392 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15393#endif
15394 { } /* end */
15395};
15396
a9111321 15397static const struct hda_channel_mode alc861_asus_modes[2] = {
7cdbff94
MD
15398 { 2, alc861_asus_ch2_init },
15399 { 6, alc861_asus_ch6_init },
15400};
15401
df694daa
KY
15402/* patch-ALC861 */
15403
a9111321 15404static const struct snd_kcontrol_new alc861_base_mixer[] = {
df694daa
KY
15405 /* output mixer control */
15406 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15407 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15408 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15409 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15410 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15411
15412 /*Input mixer control */
15413 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15414 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15415 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15416 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15417 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15418 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15419 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15420 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15421 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15422 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15423
df694daa
KY
15424 { } /* end */
15425};
15426
a9111321 15427static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
df694daa
KY
15428 /* output mixer control */
15429 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15430 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15431 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15432 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15433 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15434
15435 /* Input mixer control */
15436 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15437 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15438 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15439 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15440 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15441 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15442 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15443 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15444 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15446
df694daa
KY
15447 {
15448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15449 .name = "Channel Mode",
15450 .info = alc_ch_mode_info,
15451 .get = alc_ch_mode_get,
15452 .put = alc_ch_mode_put,
15453 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15454 },
15455 { } /* end */
a53d1aec
TD
15456};
15457
a9111321 15458static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
a53d1aec
TD
15459 /* output mixer control */
15460 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15462 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
ea1fb29a 15463
a53d1aec 15464 { } /* end */
f12ab1e0 15465};
a53d1aec 15466
a9111321 15467static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
22309c3e
TI
15468 /* output mixer control */
15469 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15470 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15471 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15472 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15473 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15474
15475 /* Input mixer control */
15476 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15477 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15478 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15479 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15480 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15481 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15482 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15483 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15484 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
f12ab1e0 15486
22309c3e
TI
15487 {
15488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15489 .name = "Channel Mode",
15490 .info = alc_ch_mode_info,
15491 .get = alc_ch_mode_get,
15492 .put = alc_ch_mode_put,
15493 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15494 },
15495 { } /* end */
f12ab1e0 15496};
7cdbff94 15497
a9111321 15498static const struct snd_kcontrol_new alc861_asus_mixer[] = {
7cdbff94
MD
15499 /* output mixer control */
15500 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15501 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15502 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15503 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15504 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15505
15506 /* Input mixer control */
15507 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15508 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15509 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15510 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15511 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15512 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15515 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
f12ab1e0
TI
15516 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15517
7cdbff94
MD
15518 {
15519 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15520 .name = "Channel Mode",
15521 .info = alc_ch_mode_info,
15522 .get = alc_ch_mode_get,
15523 .put = alc_ch_mode_put,
15524 .private_value = ARRAY_SIZE(alc861_asus_modes),
15525 },
15526 { }
56bb0cab
TI
15527};
15528
15529/* additional mixer */
a9111321 15530static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
56bb0cab
TI
15531 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
56bb0cab
TI
15533 { }
15534};
7cdbff94 15535
df694daa
KY
15536/*
15537 * generic initialization of ADC, input mixers and output mixers
15538 */
a9111321 15539static const struct hda_verb alc861_base_init_verbs[] = {
df694daa
KY
15540 /*
15541 * Unmute ADC0 and set the default input to mic-in
15542 */
15543 /* port-A for surround (rear panel) */
15544 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15545 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15546 /* port-B for mic-in (rear panel) with vref */
15547 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15548 /* port-C for line-in (rear panel) */
15549 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15550 /* port-D for Front */
15551 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15552 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15553 /* port-E for HP out (front panel) */
15554 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15555 /* route front PCM to HP */
9dece1d7 15556 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15557 /* port-F for mic-in (front panel) with vref */
15558 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15559 /* port-G for CLFE (rear panel) */
15560 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15561 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15562 /* port-H for side (rear panel) */
15563 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15564 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15565 /* CD-in */
15566 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15567 /* route front mic to ADC1*/
15568 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15569 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15570
df694daa
KY
15571 /* Unmute DAC0~3 & spdif out*/
15572 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15573 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15574 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15575 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15577
df694daa
KY
15578 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15579 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15580 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15581 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15582 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15583
df694daa
KY
15584 /* Unmute Stereo Mixer 15 */
15585 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15586 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15587 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15588 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15589
15590 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15591 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15592 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15593 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15594 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15596 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15597 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15598 /* hp used DAC 3 (Front) */
15599 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15600 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15601
15602 { }
15603};
15604
a9111321 15605static const struct hda_verb alc861_threestack_init_verbs[] = {
df694daa
KY
15606 /*
15607 * Unmute ADC0 and set the default input to mic-in
15608 */
15609 /* port-A for surround (rear panel) */
15610 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15611 /* port-B for mic-in (rear panel) with vref */
15612 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15613 /* port-C for line-in (rear panel) */
15614 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15615 /* port-D for Front */
15616 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15617 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15618 /* port-E for HP out (front panel) */
15619 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15620 /* route front PCM to HP */
9dece1d7 15621 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
df694daa
KY
15622 /* port-F for mic-in (front panel) with vref */
15623 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15624 /* port-G for CLFE (rear panel) */
15625 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15626 /* port-H for side (rear panel) */
15627 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15628 /* CD-in */
15629 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15630 /* route front mic to ADC1*/
15631 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15632 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15633 /* Unmute DAC0~3 & spdif out*/
15634 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15635 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15636 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15637 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15638 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15639
df694daa
KY
15640 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15641 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15642 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15643 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15644 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15645
df694daa
KY
15646 /* Unmute Stereo Mixer 15 */
15647 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15648 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15649 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
df694daa
KY
15651
15652 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15653 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15654 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15655 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15657 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15659 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15660 /* hp used DAC 3 (Front) */
15661 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
df694daa
KY
15662 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15663 { }
15664};
22309c3e 15665
a9111321 15666static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
22309c3e
TI
15667 /*
15668 * Unmute ADC0 and set the default input to mic-in
15669 */
15670 /* port-A for surround (rear panel) */
15671 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15672 /* port-B for mic-in (rear panel) with vref */
15673 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15674 /* port-C for line-in (rear panel) */
15675 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15676 /* port-D for Front */
15677 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15678 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15679 /* port-E for HP out (front panel) */
f12ab1e0
TI
15680 /* this has to be set to VREF80 */
15681 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
22309c3e 15682 /* route front PCM to HP */
9dece1d7 15683 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
22309c3e
TI
15684 /* port-F for mic-in (front panel) with vref */
15685 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15686 /* port-G for CLFE (rear panel) */
15687 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15688 /* port-H for side (rear panel) */
15689 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15690 /* CD-in */
15691 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15692 /* route front mic to ADC1*/
15693 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15694 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15695 /* Unmute DAC0~3 & spdif out*/
15696 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15697 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15698 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15699 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15700 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15701
22309c3e
TI
15702 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15703 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15704 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15705 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15706 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15707
22309c3e
TI
15708 /* Unmute Stereo Mixer 15 */
15709 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15710 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15711 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
22309c3e
TI
15713
15714 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15715 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15716 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15717 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15718 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15720 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15721 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15722 /* hp used DAC 3 (Front) */
15723 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
22309c3e
TI
15724 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15725 { }
15726};
15727
a9111321 15728static const struct hda_verb alc861_asus_init_verbs[] = {
7cdbff94
MD
15729 /*
15730 * Unmute ADC0 and set the default input to mic-in
15731 */
f12ab1e0
TI
15732 /* port-A for surround (rear panel)
15733 * according to codec#0 this is the HP jack
15734 */
7cdbff94
MD
15735 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15736 /* route front PCM to HP */
15737 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15738 /* port-B for mic-in (rear panel) with vref */
15739 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15740 /* port-C for line-in (rear panel) */
15741 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15742 /* port-D for Front */
15743 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15744 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15745 /* port-E for HP out (front panel) */
f12ab1e0
TI
15746 /* this has to be set to VREF80 */
15747 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7cdbff94 15748 /* route front PCM to HP */
9dece1d7 15749 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7cdbff94
MD
15750 /* port-F for mic-in (front panel) with vref */
15751 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15752 /* port-G for CLFE (rear panel) */
15753 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15754 /* port-H for side (rear panel) */
15755 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15756 /* CD-in */
15757 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15758 /* route front mic to ADC1*/
15759 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15760 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15761 /* Unmute DAC0~3 & spdif out*/
15762 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15763 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15764 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15765 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15766 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15767 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15768 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15772
7cdbff94
MD
15773 /* Unmute Stereo Mixer 15 */
15774 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15775 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15776 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f12ab1e0 15777 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
7cdbff94
MD
15778
15779 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15780 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15781 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15782 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15783 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15784 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15785 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15786 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
f12ab1e0
TI
15787 /* hp used DAC 3 (Front) */
15788 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7cdbff94
MD
15789 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15790 { }
15791};
15792
56bb0cab 15793/* additional init verbs for ASUS laptops */
a9111321 15794static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
56bb0cab
TI
15795 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15796 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15797 { }
15798};
7cdbff94 15799
df694daa
KY
15800/*
15801 * generic initialization of ADC, input mixers and output mixers
15802 */
a9111321 15803static const struct hda_verb alc861_auto_init_verbs[] = {
df694daa
KY
15804 /*
15805 * Unmute ADC0 and set the default input to mic-in
15806 */
f12ab1e0 15807 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
df694daa 15808 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
ea1fb29a 15809
df694daa
KY
15810 /* Unmute DAC0~3 & spdif out*/
15811 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15812 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15813 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15814 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15815 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
ea1fb29a 15816
df694daa
KY
15817 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15818 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15819 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15820 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
ea1fb29a 15822
df694daa
KY
15823 /* Unmute Stereo Mixer 15 */
15824 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15825 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15828
1c20930a
TI
15829 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15830 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15831 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15832 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15833 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15834 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15835 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15836 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
df694daa
KY
15837
15838 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15839 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa
KY
15842 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15843 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1c20930a
TI
15844 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15845 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
df694daa 15846
f12ab1e0 15847 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
df694daa
KY
15848
15849 { }
15850};
15851
a9111321 15852static const struct hda_verb alc861_toshiba_init_verbs[] = {
a53d1aec 15853 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f12ab1e0 15854
a53d1aec
TD
15855 { }
15856};
15857
15858/* toggle speaker-output according to the hp-jack state */
15859static void alc861_toshiba_automute(struct hda_codec *codec)
15860{
864f92be 15861 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
a53d1aec 15862
47fd830a
TI
15863 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15864 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15865 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15866 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
a53d1aec
TD
15867}
15868
15869static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15870 unsigned int res)
15871{
a53d1aec
TD
15872 if ((res >> 26) == ALC880_HP_EVENT)
15873 alc861_toshiba_automute(codec);
15874}
15875
def319f9 15876/* pcm configuration: identical with ALC880 */
df694daa
KY
15877#define alc861_pcm_analog_playback alc880_pcm_analog_playback
15878#define alc861_pcm_analog_capture alc880_pcm_analog_capture
15879#define alc861_pcm_digital_playback alc880_pcm_digital_playback
15880#define alc861_pcm_digital_capture alc880_pcm_digital_capture
15881
15882
15883#define ALC861_DIGOUT_NID 0x07
15884
a9111321 15885static const struct hda_channel_mode alc861_8ch_modes[1] = {
df694daa
KY
15886 { 8, NULL }
15887};
15888
4c6d72d1 15889static const hda_nid_t alc861_dac_nids[4] = {
df694daa
KY
15890 /* front, surround, clfe, side */
15891 0x03, 0x06, 0x05, 0x04
15892};
15893
4c6d72d1 15894static const hda_nid_t alc660_dac_nids[3] = {
9c7f852e
TI
15895 /* front, clfe, surround */
15896 0x03, 0x05, 0x06
15897};
15898
4c6d72d1 15899static const hda_nid_t alc861_adc_nids[1] = {
df694daa
KY
15900 /* ADC0-2 */
15901 0x08,
15902};
15903
a9111321 15904static const struct hda_input_mux alc861_capture_source = {
df694daa
KY
15905 .num_items = 5,
15906 .items = {
15907 { "Mic", 0x0 },
15908 { "Front Mic", 0x3 },
15909 { "Line", 0x1 },
15910 { "CD", 0x4 },
15911 { "Mixer", 0x5 },
15912 },
15913};
15914
1c20930a
TI
15915static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15916{
15917 struct alc_spec *spec = codec->spec;
15918 hda_nid_t mix, srcs[5];
15919 int i, j, num;
15920
15921 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15922 return 0;
15923 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15924 if (num < 0)
15925 return 0;
15926 for (i = 0; i < num; i++) {
15927 unsigned int type;
a22d543a 15928 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
1c20930a
TI
15929 if (type != AC_WID_AUD_OUT)
15930 continue;
15931 for (j = 0; j < spec->multiout.num_dacs; j++)
15932 if (spec->multiout.dac_nids[j] == srcs[i])
15933 break;
15934 if (j >= spec->multiout.num_dacs)
15935 return srcs[i];
15936 }
15937 return 0;
15938}
15939
df694daa 15940/* fill in the dac_nids table from the parsed pin configuration */
1c20930a 15941static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
f12ab1e0 15942 const struct auto_pin_cfg *cfg)
df694daa 15943{
1c20930a 15944 struct alc_spec *spec = codec->spec;
df694daa 15945 int i;
1c20930a 15946 hda_nid_t nid, dac;
df694daa
KY
15947
15948 spec->multiout.dac_nids = spec->private_dac_nids;
15949 for (i = 0; i < cfg->line_outs; i++) {
15950 nid = cfg->line_out_pins[i];
1c20930a
TI
15951 dac = alc861_look_for_dac(codec, nid);
15952 if (!dac)
15953 continue;
dda14410 15954 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
df694daa 15955 }
df694daa
KY
15956 return 0;
15957}
15958
bcb2f0f5
TI
15959static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15960 hda_nid_t nid, int idx, unsigned int chs)
1c20930a 15961{
bcb2f0f5 15962 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
1c20930a
TI
15963 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15964}
15965
bcb2f0f5
TI
15966#define alc861_create_out_sw(codec, pfx, nid, chs) \
15967 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15968
df694daa 15969/* add playback controls from the parsed DAC table */
1c20930a 15970static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
df694daa
KY
15971 const struct auto_pin_cfg *cfg)
15972{
1c20930a 15973 struct alc_spec *spec = codec->spec;
ea734963 15974 static const char * const chname[4] = {
f12ab1e0
TI
15975 "Front", "Surround", NULL /*CLFE*/, "Side"
15976 };
ce764ab2 15977 const char *pfx = alc_get_line_out_pfx(spec, true);
df694daa 15978 hda_nid_t nid;
ce764ab2 15979 int i, err, noutputs;
1c20930a 15980
ce764ab2
TI
15981 noutputs = cfg->line_outs;
15982 if (spec->multi_ios > 0)
15983 noutputs += spec->multi_ios;
15984
15985 for (i = 0; i < noutputs; i++) {
df694daa 15986 nid = spec->multiout.dac_nids[i];
f12ab1e0 15987 if (!nid)
df694daa 15988 continue;
bcb2f0f5 15989 if (!pfx && i == 2) {
df694daa 15990 /* Center/LFE */
1c20930a 15991 err = alc861_create_out_sw(codec, "Center", nid, 1);
f12ab1e0 15992 if (err < 0)
df694daa 15993 return err;
1c20930a 15994 err = alc861_create_out_sw(codec, "LFE", nid, 2);
f12ab1e0 15995 if (err < 0)
df694daa
KY
15996 return err;
15997 } else {
bcb2f0f5 15998 const char *name = pfx;
5a882646
DH
15999 int index = i;
16000 if (!name) {
bcb2f0f5 16001 name = chname[i];
5a882646
DH
16002 index = 0;
16003 }
16004 err = __alc861_create_out_sw(codec, name, nid, index, 3);
f12ab1e0 16005 if (err < 0)
df694daa
KY
16006 return err;
16007 }
16008 }
16009 return 0;
16010}
16011
1c20930a 16012static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
df694daa 16013{
1c20930a 16014 struct alc_spec *spec = codec->spec;
df694daa
KY
16015 int err;
16016 hda_nid_t nid;
16017
f12ab1e0 16018 if (!pin)
df694daa
KY
16019 return 0;
16020
16021 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
1c20930a
TI
16022 nid = alc861_look_for_dac(codec, pin);
16023 if (nid) {
16024 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16025 if (err < 0)
16026 return err;
16027 spec->multiout.hp_nid = nid;
16028 }
df694daa
KY
16029 }
16030 return 0;
16031}
16032
16033/* create playback/capture controls for input pins */
05f5f477 16034static int alc861_auto_create_input_ctls(struct hda_codec *codec,
f12ab1e0 16035 const struct auto_pin_cfg *cfg)
df694daa 16036{
05f5f477 16037 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
df694daa
KY
16038}
16039
f12ab1e0
TI
16040static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16041 hda_nid_t nid,
1c20930a 16042 int pin_type, hda_nid_t dac)
df694daa 16043{
1c20930a
TI
16044 hda_nid_t mix, srcs[5];
16045 int i, num;
16046
564c5bea
JL
16047 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16048 pin_type);
1c20930a 16049 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
564c5bea 16050 AMP_OUT_UNMUTE);
1c20930a
TI
16051 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16052 return;
16053 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16054 if (num < 0)
16055 return;
16056 for (i = 0; i < num; i++) {
16057 unsigned int mute;
16058 if (srcs[i] == dac || srcs[i] == 0x15)
16059 mute = AMP_IN_UNMUTE(i);
16060 else
16061 mute = AMP_IN_MUTE(i);
16062 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16063 mute);
16064 }
df694daa
KY
16065}
16066
16067static void alc861_auto_init_multi_out(struct hda_codec *codec)
16068{
16069 struct alc_spec *spec = codec->spec;
16070 int i;
16071
16072 for (i = 0; i < spec->autocfg.line_outs; i++) {
16073 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 16074 int pin_type = get_pin_type(spec->autocfg.line_out_type);
df694daa 16075 if (nid)
baba8ee9 16076 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
f12ab1e0 16077 spec->multiout.dac_nids[i]);
df694daa
KY
16078 }
16079}
16080
16081static void alc861_auto_init_hp_out(struct hda_codec *codec)
16082{
16083 struct alc_spec *spec = codec->spec;
df694daa 16084
15870f05
TI
16085 if (spec->autocfg.hp_outs)
16086 alc861_auto_set_output_and_unmute(codec,
16087 spec->autocfg.hp_pins[0],
16088 PIN_HP,
1c20930a 16089 spec->multiout.hp_nid);
15870f05
TI
16090 if (spec->autocfg.speaker_outs)
16091 alc861_auto_set_output_and_unmute(codec,
16092 spec->autocfg.speaker_pins[0],
16093 PIN_OUT,
1c20930a 16094 spec->multiout.dac_nids[0]);
df694daa
KY
16095}
16096
16097static void alc861_auto_init_analog_input(struct hda_codec *codec)
16098{
16099 struct alc_spec *spec = codec->spec;
66ceeb6b 16100 struct auto_pin_cfg *cfg = &spec->autocfg;
df694daa
KY
16101 int i;
16102
66ceeb6b
TI
16103 for (i = 0; i < cfg->num_inputs; i++) {
16104 hda_nid_t nid = cfg->inputs[i].pin;
23f0c048 16105 if (nid >= 0x0c && nid <= 0x11)
30ea098f 16106 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
df694daa
KY
16107 }
16108}
16109
16110/* parse the BIOS configuration and set up the alc_spec */
f12ab1e0
TI
16111/* return 1 if successful, 0 if the proper config is not found,
16112 * or a negative error code
16113 */
df694daa
KY
16114static int alc861_parse_auto_config(struct hda_codec *codec)
16115{
16116 struct alc_spec *spec = codec->spec;
16117 int err;
4c6d72d1 16118 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
df694daa 16119
f12ab1e0
TI
16120 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16121 alc861_ignore);
16122 if (err < 0)
df694daa 16123 return err;
f12ab1e0 16124 if (!spec->autocfg.line_outs)
df694daa
KY
16125 return 0; /* can't find valid BIOS pin config */
16126
1c20930a 16127 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
16128 if (err < 0)
16129 return err;
16130 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
16131 if (err < 0)
16132 return err;
1c20930a 16133 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
16134 if (err < 0)
16135 return err;
1c20930a 16136 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
f12ab1e0
TI
16137 if (err < 0)
16138 return err;
05f5f477 16139 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 16140 if (err < 0)
df694daa
KY
16141 return err;
16142
16143 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16144
757899ac 16145 alc_auto_parse_digital(codec);
df694daa 16146
603c4019 16147 if (spec->kctls.list)
d88897ea 16148 add_mixer(spec, spec->kctls.list);
df694daa 16149
d88897ea 16150 add_verb(spec, alc861_auto_init_verbs);
df694daa 16151
a1e8d2da 16152 spec->num_mux_defs = 1;
61b9b9b1 16153 spec->input_mux = &spec->private_imux[0];
df694daa
KY
16154
16155 spec->adc_nids = alc861_adc_nids;
16156 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
b59bdf3b 16157 set_capture_mixer(codec);
df694daa 16158
6227cdce 16159 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
4a79ba34 16160
df694daa
KY
16161 return 1;
16162}
16163
ae6b813a
TI
16164/* additional initialization for auto-configuration model */
16165static void alc861_auto_init(struct hda_codec *codec)
df694daa 16166{
f6c7e546 16167 struct alc_spec *spec = codec->spec;
df694daa
KY
16168 alc861_auto_init_multi_out(codec);
16169 alc861_auto_init_hp_out(codec);
16170 alc861_auto_init_analog_input(codec);
757899ac 16171 alc_auto_init_digital(codec);
f6c7e546 16172 if (spec->unsol_event)
7fb0d78f 16173 alc_inithook(codec);
df694daa
KY
16174}
16175
cb53c626 16176#ifdef CONFIG_SND_HDA_POWER_SAVE
a9111321 16177static const struct hda_amp_list alc861_loopbacks[] = {
cb53c626
TI
16178 { 0x15, HDA_INPUT, 0 },
16179 { 0x15, HDA_INPUT, 1 },
16180 { 0x15, HDA_INPUT, 2 },
16181 { 0x15, HDA_INPUT, 3 },
16182 { } /* end */
16183};
16184#endif
16185
df694daa
KY
16186
16187/*
16188 * configuration and preset
16189 */
ea734963 16190static const char * const alc861_models[ALC861_MODEL_LAST] = {
f5fcc13c
TI
16191 [ALC861_3ST] = "3stack",
16192 [ALC660_3ST] = "3stack-660",
16193 [ALC861_3ST_DIG] = "3stack-dig",
16194 [ALC861_6ST_DIG] = "6stack-dig",
16195 [ALC861_UNIWILL_M31] = "uniwill-m31",
16196 [ALC861_TOSHIBA] = "toshiba",
16197 [ALC861_ASUS] = "asus",
16198 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16199 [ALC861_AUTO] = "auto",
16200};
16201
a9111321 16202static const struct snd_pci_quirk alc861_cfg_tbl[] = {
687a47bd 16203 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
f5fcc13c
TI
16204 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16205 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16206 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
ac3e3741 16207 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
83c34218 16208 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
ad5e7737 16209 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
341d4eb0
TI
16210 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16211 * Any other models that need this preset?
16212 */
16213 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
ac3e3741
TI
16214 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16215 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
4147dab6 16216 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
ac3e3741
TI
16217 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16218 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16219 /* FIXME: the below seems conflict */
16220 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
07e038b3 16221 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
f5fcc13c 16222 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
df694daa
KY
16223 {}
16224};
16225
a9111321 16226static const struct alc_config_preset alc861_presets[] = {
df694daa
KY
16227 [ALC861_3ST] = {
16228 .mixers = { alc861_3ST_mixer },
16229 .init_verbs = { alc861_threestack_init_verbs },
16230 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16231 .dac_nids = alc861_dac_nids,
16232 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16233 .channel_mode = alc861_threestack_modes,
4e195a7b 16234 .need_dac_fix = 1,
df694daa
KY
16235 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16236 .adc_nids = alc861_adc_nids,
16237 .input_mux = &alc861_capture_source,
16238 },
16239 [ALC861_3ST_DIG] = {
16240 .mixers = { alc861_base_mixer },
16241 .init_verbs = { alc861_threestack_init_verbs },
16242 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16243 .dac_nids = alc861_dac_nids,
16244 .dig_out_nid = ALC861_DIGOUT_NID,
16245 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16246 .channel_mode = alc861_threestack_modes,
4e195a7b 16247 .need_dac_fix = 1,
df694daa
KY
16248 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16249 .adc_nids = alc861_adc_nids,
16250 .input_mux = &alc861_capture_source,
16251 },
16252 [ALC861_6ST_DIG] = {
16253 .mixers = { alc861_base_mixer },
16254 .init_verbs = { alc861_base_init_verbs },
16255 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16256 .dac_nids = alc861_dac_nids,
16257 .dig_out_nid = ALC861_DIGOUT_NID,
16258 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16259 .channel_mode = alc861_8ch_modes,
16260 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16261 .adc_nids = alc861_adc_nids,
16262 .input_mux = &alc861_capture_source,
16263 },
9c7f852e
TI
16264 [ALC660_3ST] = {
16265 .mixers = { alc861_3ST_mixer },
16266 .init_verbs = { alc861_threestack_init_verbs },
16267 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16268 .dac_nids = alc660_dac_nids,
16269 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16270 .channel_mode = alc861_threestack_modes,
4e195a7b 16271 .need_dac_fix = 1,
9c7f852e
TI
16272 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16273 .adc_nids = alc861_adc_nids,
16274 .input_mux = &alc861_capture_source,
16275 },
22309c3e
TI
16276 [ALC861_UNIWILL_M31] = {
16277 .mixers = { alc861_uniwill_m31_mixer },
16278 .init_verbs = { alc861_uniwill_m31_init_verbs },
16279 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16280 .dac_nids = alc861_dac_nids,
16281 .dig_out_nid = ALC861_DIGOUT_NID,
16282 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16283 .channel_mode = alc861_uniwill_m31_modes,
16284 .need_dac_fix = 1,
16285 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16286 .adc_nids = alc861_adc_nids,
16287 .input_mux = &alc861_capture_source,
16288 },
a53d1aec
TD
16289 [ALC861_TOSHIBA] = {
16290 .mixers = { alc861_toshiba_mixer },
f12ab1e0
TI
16291 .init_verbs = { alc861_base_init_verbs,
16292 alc861_toshiba_init_verbs },
a53d1aec
TD
16293 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16294 .dac_nids = alc861_dac_nids,
16295 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16296 .channel_mode = alc883_3ST_2ch_modes,
16297 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16298 .adc_nids = alc861_adc_nids,
16299 .input_mux = &alc861_capture_source,
16300 .unsol_event = alc861_toshiba_unsol_event,
16301 .init_hook = alc861_toshiba_automute,
16302 },
7cdbff94
MD
16303 [ALC861_ASUS] = {
16304 .mixers = { alc861_asus_mixer },
16305 .init_verbs = { alc861_asus_init_verbs },
16306 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16307 .dac_nids = alc861_dac_nids,
16308 .dig_out_nid = ALC861_DIGOUT_NID,
16309 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16310 .channel_mode = alc861_asus_modes,
16311 .need_dac_fix = 1,
16312 .hp_nid = 0x06,
16313 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16314 .adc_nids = alc861_adc_nids,
16315 .input_mux = &alc861_capture_source,
16316 },
56bb0cab
TI
16317 [ALC861_ASUS_LAPTOP] = {
16318 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16319 .init_verbs = { alc861_asus_init_verbs,
16320 alc861_asus_laptop_init_verbs },
16321 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16322 .dac_nids = alc861_dac_nids,
16323 .dig_out_nid = ALC861_DIGOUT_NID,
16324 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16325 .channel_mode = alc883_3ST_2ch_modes,
16326 .need_dac_fix = 1,
16327 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16328 .adc_nids = alc861_adc_nids,
16329 .input_mux = &alc861_capture_source,
16330 },
16331};
df694daa 16332
cfc9b06f
TI
16333/* Pin config fixes */
16334enum {
16335 PINFIX_FSC_AMILO_PI1505,
16336};
16337
cfc9b06f
TI
16338static const struct alc_fixup alc861_fixups[] = {
16339 [PINFIX_FSC_AMILO_PI1505] = {
b5bfbc67
TI
16340 .type = ALC_FIXUP_PINS,
16341 .v.pins = (const struct alc_pincfg[]) {
73413b12
TI
16342 { 0x0b, 0x0221101f }, /* HP */
16343 { 0x0f, 0x90170310 }, /* speaker */
16344 { }
16345 }
cfc9b06f
TI
16346 },
16347};
16348
a9111321 16349static const struct snd_pci_quirk alc861_fixup_tbl[] = {
cfc9b06f
TI
16350 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16351 {}
16352};
df694daa
KY
16353
16354static int patch_alc861(struct hda_codec *codec)
16355{
16356 struct alc_spec *spec;
16357 int board_config;
16358 int err;
16359
dc041e0b 16360 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
df694daa
KY
16361 if (spec == NULL)
16362 return -ENOMEM;
16363
f12ab1e0 16364 codec->spec = spec;
df694daa 16365
f5fcc13c
TI
16366 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16367 alc861_models,
16368 alc861_cfg_tbl);
9c7f852e 16369
f5fcc13c 16370 if (board_config < 0) {
9a11f1aa
TI
16371 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16372 codec->chip_name);
df694daa
KY
16373 board_config = ALC861_AUTO;
16374 }
16375
b5bfbc67
TI
16376 if (board_config == ALC861_AUTO) {
16377 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16378 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16379 }
cfc9b06f 16380
df694daa
KY
16381 if (board_config == ALC861_AUTO) {
16382 /* automatic parse from the BIOS config */
16383 err = alc861_parse_auto_config(codec);
16384 if (err < 0) {
16385 alc_free(codec);
16386 return err;
f12ab1e0 16387 } else if (!err) {
9c7f852e
TI
16388 printk(KERN_INFO
16389 "hda_codec: Cannot set up configuration "
16390 "from BIOS. Using base mode...\n");
df694daa
KY
16391 board_config = ALC861_3ST_DIG;
16392 }
16393 }
16394
680cd536
KK
16395 err = snd_hda_attach_beep_device(codec, 0x23);
16396 if (err < 0) {
16397 alc_free(codec);
16398 return err;
16399 }
16400
df694daa 16401 if (board_config != ALC861_AUTO)
e9c364c0 16402 setup_preset(codec, &alc861_presets[board_config]);
df694daa 16403
df694daa
KY
16404 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16405 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16406
df694daa
KY
16407 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16408 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16409
c7a8eb10
TI
16410 if (!spec->cap_mixer)
16411 set_capture_mixer(codec);
45bdd1c1
TI
16412 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16413
2134ea4f
TI
16414 spec->vmaster_nid = 0x03;
16415
b5bfbc67 16416 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 16417
df694daa 16418 codec->patch_ops = alc_patch_ops;
c97259df 16419 if (board_config == ALC861_AUTO) {
ae6b813a 16420 spec->init_hook = alc861_auto_init;
c97259df
DC
16421#ifdef CONFIG_SND_HDA_POWER_SAVE
16422 spec->power_hook = alc_power_eapd;
16423#endif
16424 }
cb53c626
TI
16425#ifdef CONFIG_SND_HDA_POWER_SAVE
16426 if (!spec->loopback.amplist)
16427 spec->loopback.amplist = alc861_loopbacks;
16428#endif
ea1fb29a 16429
1da177e4
LT
16430 return 0;
16431}
16432
f32610ed
JS
16433/*
16434 * ALC861-VD support
16435 *
16436 * Based on ALC882
16437 *
16438 * In addition, an independent DAC
16439 */
16440#define ALC861VD_DIGOUT_NID 0x06
16441
4c6d72d1 16442static const hda_nid_t alc861vd_dac_nids[4] = {
f32610ed
JS
16443 /* front, surr, clfe, side surr */
16444 0x02, 0x03, 0x04, 0x05
16445};
16446
16447/* dac_nids for ALC660vd are in a different order - according to
16448 * Realtek's driver.
def319f9 16449 * This should probably result in a different mixer for 6stack models
f32610ed
JS
16450 * of ALC660vd codecs, but for now there is only 3stack mixer
16451 * - and it is the same as in 861vd.
16452 * adc_nids in ALC660vd are (is) the same as in 861vd
16453 */
4c6d72d1 16454static const hda_nid_t alc660vd_dac_nids[3] = {
f32610ed
JS
16455 /* front, rear, clfe, rear_surr */
16456 0x02, 0x04, 0x03
16457};
16458
4c6d72d1 16459static const hda_nid_t alc861vd_adc_nids[1] = {
f32610ed
JS
16460 /* ADC0 */
16461 0x09,
16462};
16463
4c6d72d1 16464static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
e1406348 16465
f32610ed
JS
16466/* input MUX */
16467/* FIXME: should be a matrix-type input source selection */
a9111321 16468static const struct hda_input_mux alc861vd_capture_source = {
f32610ed
JS
16469 .num_items = 4,
16470 .items = {
16471 { "Mic", 0x0 },
16472 { "Front Mic", 0x1 },
16473 { "Line", 0x2 },
16474 { "CD", 0x4 },
16475 },
16476};
16477
a9111321 16478static const struct hda_input_mux alc861vd_dallas_capture_source = {
b419f346 16479 .num_items = 2,
272a527c 16480 .items = {
8607f7c4 16481 { "Mic", 0x0 },
28c4edb7 16482 { "Internal Mic", 0x1 },
272a527c
KY
16483 },
16484};
16485
a9111321 16486static const struct hda_input_mux alc861vd_hp_capture_source = {
d1a991a6
KY
16487 .num_items = 2,
16488 .items = {
16489 { "Front Mic", 0x0 },
16490 { "ATAPI Mic", 0x1 },
16491 },
16492};
16493
f32610ed
JS
16494/*
16495 * 2ch mode
16496 */
a9111321 16497static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
f32610ed
JS
16498 { 2, NULL }
16499};
16500
16501/*
16502 * 6ch mode
16503 */
a9111321 16504static const struct hda_verb alc861vd_6stack_ch6_init[] = {
f32610ed
JS
16505 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16506 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16507 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16508 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16509 { } /* end */
16510};
16511
16512/*
16513 * 8ch mode
16514 */
a9111321 16515static const struct hda_verb alc861vd_6stack_ch8_init[] = {
f32610ed
JS
16516 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16517 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16518 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16519 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16520 { } /* end */
16521};
16522
a9111321 16523static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
f32610ed
JS
16524 { 6, alc861vd_6stack_ch6_init },
16525 { 8, alc861vd_6stack_ch8_init },
16526};
16527
a9111321 16528static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
f32610ed
JS
16529 {
16530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16531 .name = "Channel Mode",
16532 .info = alc_ch_mode_info,
16533 .get = alc_ch_mode_get,
16534 .put = alc_ch_mode_put,
16535 },
16536 { } /* end */
16537};
16538
f32610ed
JS
16539/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16540 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16541 */
a9111321 16542static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
f32610ed
JS
16543 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16544 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16545
16546 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16547 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16548
16549 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16550 HDA_OUTPUT),
16551 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16552 HDA_OUTPUT),
16553 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16554 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16555
16556 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16557 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16558
16559 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16560
5f99f86a 16561 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16562 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16563 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16564
5f99f86a 16565 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16566 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16568
16569 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16570 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16571
16572 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16573 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16574
f32610ed
JS
16575 { } /* end */
16576};
16577
a9111321 16578static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
f32610ed
JS
16579 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16580 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16581
16582 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16583
5f99f86a 16584 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
f32610ed
JS
16585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16586 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16587
5f99f86a 16588 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
f32610ed
JS
16589 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16590 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16591
16592 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16593 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16594
16595 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16596 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16597
f32610ed
JS
16598 { } /* end */
16599};
16600
a9111321 16601static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
bdd148a3
KY
16602 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16603 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16604 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16605
16606 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16607
5f99f86a 16608 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
bdd148a3
KY
16609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16611
5f99f86a 16612 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
bdd148a3
KY
16613 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16615
16616 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16617 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16618
16619 { } /* end */
16620};
16621
b419f346 16622/* Pin assignment: Speaker=0x14, HP = 0x15,
8607f7c4 16623 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
272a527c 16624 */
a9111321 16625static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
b419f346
TD
16626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16627 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
272a527c
KY
16628 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16629 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
5f99f86a 16630 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8607f7c4
DH
16631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 16633 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
28c4edb7
DH
16634 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16635 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
272a527c
KY
16636 { } /* end */
16637};
16638
d1a991a6
KY
16639/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16640 * Front Mic=0x18, ATAPI Mic = 0x19,
16641 */
a9111321 16642static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
d1a991a6
KY
16643 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16644 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16645 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16646 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16647 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16648 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16649 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16650 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
ea1fb29a 16651
d1a991a6
KY
16652 { } /* end */
16653};
16654
f32610ed
JS
16655/*
16656 * generic initialization of ADC, input mixers and output mixers
16657 */
a9111321 16658static const struct hda_verb alc861vd_volume_init_verbs[] = {
f32610ed
JS
16659 /*
16660 * Unmute ADC0 and set the default input to mic-in
16661 */
16662 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16663 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16664
16665 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16666 * the analog-loopback mixer widget
16667 */
16668 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
cb53c626
TI
16669 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16670 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16671 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16672 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16673 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
f32610ed
JS
16674
16675 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
bdd148a3
KY
16676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16677 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16678 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
f32610ed 16679 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
f32610ed
JS
16680
16681 /*
16682 * Set up output mixers (0x02 - 0x05)
16683 */
16684 /* set vol=0 to output mixers */
16685 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16689
16690 /* set up input amps for analog loopback */
16691 /* Amp Indices: DAC = 0, mixer = 1 */
16692 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16693 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16694 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16695 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16696 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16697 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16698 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16699 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16700
16701 { }
16702};
16703
16704/*
16705 * 3-stack pin configuration:
16706 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16707 */
a9111321 16708static const struct hda_verb alc861vd_3stack_init_verbs[] = {
f32610ed
JS
16709 /*
16710 * Set pin mode and muting
16711 */
16712 /* set front pin widgets 0x14 for output */
16713 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16714 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16715 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16716
16717 /* Mic (rear) pin: input vref at 80% */
16718 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16719 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16720 /* Front Mic pin: input vref at 80% */
16721 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16722 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16723 /* Line In pin: input */
16724 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16725 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16726 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16727 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16728 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16729 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16730 /* CD pin widget for input */
16731 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16732
16733 { }
16734};
16735
16736/*
16737 * 6-stack pin configuration:
16738 */
a9111321 16739static const struct hda_verb alc861vd_6stack_init_verbs[] = {
f32610ed
JS
16740 /*
16741 * Set pin mode and muting
16742 */
16743 /* set front pin widgets 0x14 for output */
16744 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16745 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16746 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16747
16748 /* Rear Pin: output 1 (0x0d) */
16749 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16750 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16751 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16752 /* CLFE Pin: output 2 (0x0e) */
16753 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16754 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16755 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16756 /* Side Pin: output 3 (0x0f) */
16757 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16758 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16759 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16760
16761 /* Mic (rear) pin: input vref at 80% */
16762 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16763 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16764 /* Front Mic pin: input vref at 80% */
16765 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16766 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16767 /* Line In pin: input */
16768 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16769 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16770 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16772 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16773 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16774 /* CD pin widget for input */
16775 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16776
16777 { }
16778};
16779
a9111321 16780static const struct hda_verb alc861vd_eapd_verbs[] = {
bdd148a3
KY
16781 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16782 { }
16783};
16784
a9111321 16785static const struct hda_verb alc660vd_eapd_verbs[] = {
f9423e7a
KY
16786 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16787 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16788 { }
16789};
16790
a9111321 16791static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
bdd148a3
KY
16792 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16794 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16795 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
ea1fb29a 16796 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
bdd148a3
KY
16797 {}
16798};
16799
4f5d1706 16800static void alc861vd_lenovo_setup(struct hda_codec *codec)
bdd148a3 16801{
a9fd4f3f 16802 struct alc_spec *spec = codec->spec;
a9fd4f3f
TI
16803 spec->autocfg.hp_pins[0] = 0x1b;
16804 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16805 spec->automute = 1;
16806 spec->automute_mode = ALC_AUTOMUTE_AMP;
4f5d1706
TI
16807}
16808
16809static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16810{
d922b51d 16811 alc_hp_automute(codec);
eeb43387 16812 alc88x_simple_mic_automute(codec);
bdd148a3
KY
16813}
16814
16815static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16816 unsigned int res)
16817{
16818 switch (res >> 26) {
bdd148a3 16819 case ALC880_MIC_EVENT:
eeb43387 16820 alc88x_simple_mic_automute(codec);
bdd148a3 16821 break;
a9fd4f3f 16822 default:
d922b51d 16823 alc_sku_unsol_event(codec, res);
a9fd4f3f 16824 break;
bdd148a3
KY
16825 }
16826}
16827
a9111321 16828static const struct hda_verb alc861vd_dallas_verbs[] = {
272a527c
KY
16829 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16830 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16831 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16832 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16833
16834 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16835 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16836 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16837 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16838 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16839 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16840 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16841 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
ea1fb29a 16842
272a527c
KY
16843 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16845 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16847 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16848 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16849 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16850 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16851
16852 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16853 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16854 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16855 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16856 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16857 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16858 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16859 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16860
16861 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16862 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16863 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16864 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16865
16866 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
ea1fb29a 16867 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
272a527c
KY
16868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16869
16870 { } /* end */
16871};
16872
16873/* toggle speaker-output according to the hp-jack state */
4f5d1706 16874static void alc861vd_dallas_setup(struct hda_codec *codec)
272a527c 16875{
a9fd4f3f 16876 struct alc_spec *spec = codec->spec;
272a527c 16877
a9fd4f3f
TI
16878 spec->autocfg.hp_pins[0] = 0x15;
16879 spec->autocfg.speaker_pins[0] = 0x14;
d922b51d
TI
16880 spec->automute = 1;
16881 spec->automute_mode = ALC_AUTOMUTE_AMP;
272a527c
KY
16882}
16883
cb53c626
TI
16884#ifdef CONFIG_SND_HDA_POWER_SAVE
16885#define alc861vd_loopbacks alc880_loopbacks
16886#endif
16887
def319f9 16888/* pcm configuration: identical with ALC880 */
f32610ed
JS
16889#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16890#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16891#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16892#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16893
16894/*
16895 * configuration and preset
16896 */
ea734963 16897static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
f32610ed 16898 [ALC660VD_3ST] = "3stack-660",
983f8ae4 16899 [ALC660VD_3ST_DIG] = "3stack-660-digout",
13c94744 16900 [ALC660VD_ASUS_V1S] = "asus-v1s",
f32610ed
JS
16901 [ALC861VD_3ST] = "3stack",
16902 [ALC861VD_3ST_DIG] = "3stack-digout",
16903 [ALC861VD_6ST_DIG] = "6stack-digout",
bdd148a3 16904 [ALC861VD_LENOVO] = "lenovo",
272a527c 16905 [ALC861VD_DALLAS] = "dallas",
983f8ae4 16906 [ALC861VD_HP] = "hp",
f32610ed
JS
16907 [ALC861VD_AUTO] = "auto",
16908};
16909
a9111321 16910static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
ac3e3741
TI
16911 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16912 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
07e038b3 16913 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
f8f25ba3 16914 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
13c94744 16915 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
6963f84c 16916 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
f32610ed 16917 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
ac3e3741 16918 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
38baf5ad 16919 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
ce577e8c 16920 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
542d7c66 16921 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
b419f346 16922 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
39c5d41f 16923 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
dea0a509 16924 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
625dc0bf 16925 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
f32610ed
JS
16926 {}
16927};
16928
a9111321 16929static const struct alc_config_preset alc861vd_presets[] = {
f32610ed
JS
16930 [ALC660VD_3ST] = {
16931 .mixers = { alc861vd_3st_mixer },
16932 .init_verbs = { alc861vd_volume_init_verbs,
16933 alc861vd_3stack_init_verbs },
16934 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16935 .dac_nids = alc660vd_dac_nids,
f32610ed
JS
16936 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16937 .channel_mode = alc861vd_3stack_2ch_modes,
16938 .input_mux = &alc861vd_capture_source,
16939 },
6963f84c
MC
16940 [ALC660VD_3ST_DIG] = {
16941 .mixers = { alc861vd_3st_mixer },
16942 .init_verbs = { alc861vd_volume_init_verbs,
16943 alc861vd_3stack_init_verbs },
16944 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16945 .dac_nids = alc660vd_dac_nids,
16946 .dig_out_nid = ALC861VD_DIGOUT_NID,
6963f84c
MC
16947 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16948 .channel_mode = alc861vd_3stack_2ch_modes,
16949 .input_mux = &alc861vd_capture_source,
16950 },
f32610ed
JS
16951 [ALC861VD_3ST] = {
16952 .mixers = { alc861vd_3st_mixer },
16953 .init_verbs = { alc861vd_volume_init_verbs,
16954 alc861vd_3stack_init_verbs },
16955 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16956 .dac_nids = alc861vd_dac_nids,
16957 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16958 .channel_mode = alc861vd_3stack_2ch_modes,
16959 .input_mux = &alc861vd_capture_source,
16960 },
16961 [ALC861VD_3ST_DIG] = {
16962 .mixers = { alc861vd_3st_mixer },
16963 .init_verbs = { alc861vd_volume_init_verbs,
16964 alc861vd_3stack_init_verbs },
16965 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16966 .dac_nids = alc861vd_dac_nids,
16967 .dig_out_nid = ALC861VD_DIGOUT_NID,
16968 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16969 .channel_mode = alc861vd_3stack_2ch_modes,
16970 .input_mux = &alc861vd_capture_source,
16971 },
16972 [ALC861VD_6ST_DIG] = {
16973 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16974 .init_verbs = { alc861vd_volume_init_verbs,
16975 alc861vd_6stack_init_verbs },
16976 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16977 .dac_nids = alc861vd_dac_nids,
16978 .dig_out_nid = ALC861VD_DIGOUT_NID,
16979 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16980 .channel_mode = alc861vd_6stack_modes,
16981 .input_mux = &alc861vd_capture_source,
16982 },
bdd148a3
KY
16983 [ALC861VD_LENOVO] = {
16984 .mixers = { alc861vd_lenovo_mixer },
16985 .init_verbs = { alc861vd_volume_init_verbs,
16986 alc861vd_3stack_init_verbs,
16987 alc861vd_eapd_verbs,
16988 alc861vd_lenovo_unsol_verbs },
16989 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16990 .dac_nids = alc660vd_dac_nids,
bdd148a3
KY
16991 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16992 .channel_mode = alc861vd_3stack_2ch_modes,
16993 .input_mux = &alc861vd_capture_source,
16994 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 16995 .setup = alc861vd_lenovo_setup,
a9fd4f3f 16996 .init_hook = alc861vd_lenovo_init_hook,
bdd148a3 16997 },
272a527c
KY
16998 [ALC861VD_DALLAS] = {
16999 .mixers = { alc861vd_dallas_mixer },
17000 .init_verbs = { alc861vd_dallas_verbs },
17001 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17002 .dac_nids = alc861vd_dac_nids,
272a527c
KY
17003 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17004 .channel_mode = alc861vd_3stack_2ch_modes,
17005 .input_mux = &alc861vd_dallas_capture_source,
d922b51d 17006 .unsol_event = alc_sku_unsol_event,
4f5d1706 17007 .setup = alc861vd_dallas_setup,
d922b51d 17008 .init_hook = alc_hp_automute,
d1a991a6
KY
17009 },
17010 [ALC861VD_HP] = {
17011 .mixers = { alc861vd_hp_mixer },
17012 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17013 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17014 .dac_nids = alc861vd_dac_nids,
d1a991a6 17015 .dig_out_nid = ALC861VD_DIGOUT_NID,
d1a991a6
KY
17016 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17017 .channel_mode = alc861vd_3stack_2ch_modes,
17018 .input_mux = &alc861vd_hp_capture_source,
d922b51d 17019 .unsol_event = alc_sku_unsol_event,
4f5d1706 17020 .setup = alc861vd_dallas_setup,
d922b51d 17021 .init_hook = alc_hp_automute,
ea1fb29a 17022 },
13c94744
TI
17023 [ALC660VD_ASUS_V1S] = {
17024 .mixers = { alc861vd_lenovo_mixer },
17025 .init_verbs = { alc861vd_volume_init_verbs,
17026 alc861vd_3stack_init_verbs,
17027 alc861vd_eapd_verbs,
17028 alc861vd_lenovo_unsol_verbs },
17029 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17030 .dac_nids = alc660vd_dac_nids,
17031 .dig_out_nid = ALC861VD_DIGOUT_NID,
17032 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17033 .channel_mode = alc861vd_3stack_2ch_modes,
17034 .input_mux = &alc861vd_capture_source,
17035 .unsol_event = alc861vd_lenovo_unsol_event,
4f5d1706 17036 .setup = alc861vd_lenovo_setup,
a9fd4f3f 17037 .init_hook = alc861vd_lenovo_init_hook,
13c94744 17038 },
f32610ed
JS
17039};
17040
17041/*
17042 * BIOS auto configuration
17043 */
05f5f477
TI
17044static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17045 const struct auto_pin_cfg *cfg)
17046{
7167594a 17047 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
05f5f477
TI
17048}
17049
17050
f32610ed
JS
17051static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17052 hda_nid_t nid, int pin_type, int dac_idx)
17053{
f6c7e546 17054 alc_set_pin_output(codec, nid, pin_type);
f32610ed
JS
17055}
17056
17057static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17058{
17059 struct alc_spec *spec = codec->spec;
17060 int i;
17061
17062 for (i = 0; i <= HDA_SIDE; i++) {
17063 hda_nid_t nid = spec->autocfg.line_out_pins[i];
baba8ee9 17064 int pin_type = get_pin_type(spec->autocfg.line_out_type);
f32610ed
JS
17065 if (nid)
17066 alc861vd_auto_set_output_and_unmute(codec, nid,
baba8ee9 17067 pin_type, i);
f32610ed
JS
17068 }
17069}
17070
17071
17072static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17073{
17074 struct alc_spec *spec = codec->spec;
17075 hda_nid_t pin;
17076
17077 pin = spec->autocfg.hp_pins[0];
def319f9 17078 if (pin) /* connect to front and use dac 0 */
f32610ed 17079 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
f6c7e546
TI
17080 pin = spec->autocfg.speaker_pins[0];
17081 if (pin)
17082 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
f32610ed
JS
17083}
17084
f32610ed
JS
17085#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17086
17087static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17088{
17089 struct alc_spec *spec = codec->spec;
66ceeb6b 17090 struct auto_pin_cfg *cfg = &spec->autocfg;
f32610ed
JS
17091 int i;
17092
66ceeb6b
TI
17093 for (i = 0; i < cfg->num_inputs; i++) {
17094 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 17095 if (alc_is_input_pin(codec, nid)) {
30ea098f 17096 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
e82c025b
TI
17097 if (nid != ALC861VD_PIN_CD_NID &&
17098 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
f32610ed
JS
17099 snd_hda_codec_write(codec, nid, 0,
17100 AC_VERB_SET_AMP_GAIN_MUTE,
17101 AMP_OUT_MUTE);
17102 }
17103 }
17104}
17105
f511b01c
TI
17106#define alc861vd_auto_init_input_src alc882_auto_init_input_src
17107
f32610ed
JS
17108#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17109#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17110
17111/* add playback controls from the parsed DAC table */
569ed348 17112/* Based on ALC880 version. But ALC861VD has separate,
f32610ed
JS
17113 * different NIDs for mute/unmute switch and volume control */
17114static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17115 const struct auto_pin_cfg *cfg)
17116{
ea734963
TI
17117 static const char * const chname[4] = {
17118 "Front", "Surround", "CLFE", "Side"
17119 };
ce764ab2 17120 const char *pfx = alc_get_line_out_pfx(spec, true);
f32610ed 17121 hda_nid_t nid_v, nid_s;
ce764ab2 17122 int i, err, noutputs;
f32610ed 17123
ce764ab2
TI
17124 noutputs = cfg->line_outs;
17125 if (spec->multi_ios > 0)
17126 noutputs += spec->multi_ios;
17127
17128 for (i = 0; i < noutputs; i++) {
f12ab1e0 17129 if (!spec->multiout.dac_nids[i])
f32610ed
JS
17130 continue;
17131 nid_v = alc861vd_idx_to_mixer_vol(
17132 alc880_dac_to_idx(
17133 spec->multiout.dac_nids[i]));
17134 nid_s = alc861vd_idx_to_mixer_switch(
17135 alc880_dac_to_idx(
17136 spec->multiout.dac_nids[i]));
17137
bcb2f0f5 17138 if (!pfx && i == 2) {
f32610ed 17139 /* Center/LFE */
0afe5f89
TI
17140 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17141 "Center",
f12ab1e0
TI
17142 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17143 HDA_OUTPUT));
17144 if (err < 0)
f32610ed 17145 return err;
0afe5f89
TI
17146 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17147 "LFE",
f12ab1e0
TI
17148 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17149 HDA_OUTPUT));
17150 if (err < 0)
f32610ed 17151 return err;
0afe5f89
TI
17152 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17153 "Center",
f12ab1e0
TI
17154 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17155 HDA_INPUT));
17156 if (err < 0)
f32610ed 17157 return err;
0afe5f89
TI
17158 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17159 "LFE",
f12ab1e0
TI
17160 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17161 HDA_INPUT));
17162 if (err < 0)
f32610ed
JS
17163 return err;
17164 } else {
bcb2f0f5 17165 const char *name = pfx;
5a882646
DH
17166 int index = i;
17167 if (!name) {
bcb2f0f5 17168 name = chname[i];
5a882646
DH
17169 index = 0;
17170 }
bcb2f0f5 17171 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5a882646 17172 name, index,
f12ab1e0
TI
17173 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17174 HDA_OUTPUT));
17175 if (err < 0)
f32610ed 17176 return err;
bcb2f0f5 17177 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5a882646 17178 name, index,
bdd148a3 17179 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
f12ab1e0
TI
17180 HDA_INPUT));
17181 if (err < 0)
f32610ed
JS
17182 return err;
17183 }
17184 }
17185 return 0;
17186}
17187
17188/* add playback controls for speaker and HP outputs */
17189/* Based on ALC880 version. But ALC861VD has separate,
17190 * different NIDs for mute/unmute switch and volume control */
17191static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17192 hda_nid_t pin, const char *pfx)
17193{
17194 hda_nid_t nid_v, nid_s;
17195 int err;
f32610ed 17196
f12ab1e0 17197 if (!pin)
f32610ed
JS
17198 return 0;
17199
17200 if (alc880_is_fixed_pin(pin)) {
17201 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17202 /* specify the DAC as the extra output */
f12ab1e0 17203 if (!spec->multiout.hp_nid)
f32610ed
JS
17204 spec->multiout.hp_nid = nid_v;
17205 else
17206 spec->multiout.extra_out_nid[0] = nid_v;
17207 /* control HP volume/switch on the output mixer amp */
17208 nid_v = alc861vd_idx_to_mixer_vol(
17209 alc880_fixed_pin_idx(pin));
17210 nid_s = alc861vd_idx_to_mixer_switch(
17211 alc880_fixed_pin_idx(pin));
17212
0afe5f89 17213 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
f12ab1e0
TI
17214 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17215 if (err < 0)
f32610ed 17216 return err;
0afe5f89 17217 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
f12ab1e0
TI
17218 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17219 if (err < 0)
f32610ed
JS
17220 return err;
17221 } else if (alc880_is_multi_pin(pin)) {
17222 /* set manual connection */
17223 /* we have only a switch on HP-out PIN */
0afe5f89 17224 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
f12ab1e0
TI
17225 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17226 if (err < 0)
f32610ed
JS
17227 return err;
17228 }
17229 return 0;
17230}
17231
17232/* parse the BIOS configuration and set up the alc_spec
17233 * return 1 if successful, 0 if the proper config is not found,
17234 * or a negative error code
17235 * Based on ALC880 version - had to change it to override
17236 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17237static int alc861vd_parse_auto_config(struct hda_codec *codec)
17238{
17239 struct alc_spec *spec = codec->spec;
17240 int err;
4c6d72d1 17241 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
f32610ed 17242
f12ab1e0
TI
17243 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17244 alc861vd_ignore);
17245 if (err < 0)
f32610ed 17246 return err;
f12ab1e0 17247 if (!spec->autocfg.line_outs)
f32610ed
JS
17248 return 0; /* can't find valid BIOS pin config */
17249
f12ab1e0 17250 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
ce764ab2
TI
17251 if (err < 0)
17252 return err;
17253 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
17254 if (err < 0)
17255 return err;
17256 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17257 if (err < 0)
17258 return err;
17259 err = alc861vd_auto_create_extra_out(spec,
17260 spec->autocfg.speaker_pins[0],
17261 "Speaker");
17262 if (err < 0)
17263 return err;
17264 err = alc861vd_auto_create_extra_out(spec,
17265 spec->autocfg.hp_pins[0],
17266 "Headphone");
17267 if (err < 0)
17268 return err;
05f5f477 17269 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 17270 if (err < 0)
f32610ed
JS
17271 return err;
17272
17273 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17274
757899ac 17275 alc_auto_parse_digital(codec);
f32610ed 17276
603c4019 17277 if (spec->kctls.list)
d88897ea 17278 add_mixer(spec, spec->kctls.list);
f32610ed 17279
d88897ea 17280 add_verb(spec, alc861vd_volume_init_verbs);
f32610ed
JS
17281
17282 spec->num_mux_defs = 1;
61b9b9b1 17283 spec->input_mux = &spec->private_imux[0];
f32610ed 17284
776e184e
TI
17285 err = alc_auto_add_mic_boost(codec);
17286 if (err < 0)
17287 return err;
17288
6227cdce 17289 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 17290
f32610ed
JS
17291 return 1;
17292}
17293
17294/* additional initialization for auto-configuration model */
17295static void alc861vd_auto_init(struct hda_codec *codec)
17296{
f6c7e546 17297 struct alc_spec *spec = codec->spec;
f32610ed
JS
17298 alc861vd_auto_init_multi_out(codec);
17299 alc861vd_auto_init_hp_out(codec);
17300 alc861vd_auto_init_analog_input(codec);
f511b01c 17301 alc861vd_auto_init_input_src(codec);
757899ac 17302 alc_auto_init_digital(codec);
f6c7e546 17303 if (spec->unsol_event)
7fb0d78f 17304 alc_inithook(codec);
f32610ed
JS
17305}
17306
f8f25ba3
TI
17307enum {
17308 ALC660VD_FIX_ASUS_GPIO1
17309};
17310
17311/* reset GPIO1 */
f8f25ba3
TI
17312static const struct alc_fixup alc861vd_fixups[] = {
17313 [ALC660VD_FIX_ASUS_GPIO1] = {
b5bfbc67
TI
17314 .type = ALC_FIXUP_VERBS,
17315 .v.verbs = (const struct hda_verb[]) {
73413b12
TI
17316 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17317 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17318 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17319 { }
17320 }
f8f25ba3
TI
17321 },
17322};
17323
a9111321 17324static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
f8f25ba3
TI
17325 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17326 {}
17327};
17328
f32610ed
JS
17329static int patch_alc861vd(struct hda_codec *codec)
17330{
17331 struct alc_spec *spec;
17332 int err, board_config;
17333
17334 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17335 if (spec == NULL)
17336 return -ENOMEM;
17337
17338 codec->spec = spec;
17339
17340 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17341 alc861vd_models,
17342 alc861vd_cfg_tbl);
17343
17344 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
9a11f1aa
TI
17345 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17346 codec->chip_name);
f32610ed
JS
17347 board_config = ALC861VD_AUTO;
17348 }
17349
b5bfbc67
TI
17350 if (board_config == ALC861VD_AUTO) {
17351 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17352 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17353 }
f8f25ba3 17354
f32610ed
JS
17355 if (board_config == ALC861VD_AUTO) {
17356 /* automatic parse from the BIOS config */
17357 err = alc861vd_parse_auto_config(codec);
17358 if (err < 0) {
17359 alc_free(codec);
17360 return err;
f12ab1e0 17361 } else if (!err) {
f32610ed
JS
17362 printk(KERN_INFO
17363 "hda_codec: Cannot set up configuration "
17364 "from BIOS. Using base mode...\n");
17365 board_config = ALC861VD_3ST;
17366 }
17367 }
17368
680cd536
KK
17369 err = snd_hda_attach_beep_device(codec, 0x23);
17370 if (err < 0) {
17371 alc_free(codec);
17372 return err;
17373 }
17374
f32610ed 17375 if (board_config != ALC861VD_AUTO)
e9c364c0 17376 setup_preset(codec, &alc861vd_presets[board_config]);
f32610ed 17377
2f893286 17378 if (codec->vendor_id == 0x10ec0660) {
f9423e7a 17379 /* always turn on EAPD */
d88897ea 17380 add_verb(spec, alc660vd_eapd_verbs);
2f893286
KY
17381 }
17382
f32610ed
JS
17383 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17384 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17385
f32610ed
JS
17386 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17387 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17388
dd704698
TI
17389 if (!spec->adc_nids) {
17390 spec->adc_nids = alc861vd_adc_nids;
17391 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17392 }
17393 if (!spec->capsrc_nids)
17394 spec->capsrc_nids = alc861vd_capsrc_nids;
f32610ed 17395
b59bdf3b 17396 set_capture_mixer(codec);
45bdd1c1 17397 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
f32610ed 17398
2134ea4f
TI
17399 spec->vmaster_nid = 0x02;
17400
b5bfbc67 17401 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7fa90e87 17402
f32610ed
JS
17403 codec->patch_ops = alc_patch_ops;
17404
17405 if (board_config == ALC861VD_AUTO)
17406 spec->init_hook = alc861vd_auto_init;
1c716153 17407 spec->shutup = alc_eapd_shutup;
cb53c626
TI
17408#ifdef CONFIG_SND_HDA_POWER_SAVE
17409 if (!spec->loopback.amplist)
17410 spec->loopback.amplist = alc861vd_loopbacks;
17411#endif
f32610ed
JS
17412
17413 return 0;
17414}
17415
bc9f98a9
KY
17416/*
17417 * ALC662 support
17418 *
17419 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17420 * configuration. Each pin widget can choose any input DACs and a mixer.
17421 * Each ADC is connected from a mixer of all inputs. This makes possible
17422 * 6-channel independent captures.
17423 *
17424 * In addition, an independent DAC for the multi-playback (not used in this
17425 * driver yet).
17426 */
17427#define ALC662_DIGOUT_NID 0x06
17428#define ALC662_DIGIN_NID 0x0a
17429
4c6d72d1 17430static const hda_nid_t alc662_dac_nids[3] = {
4bf4a6c5 17431 /* front, rear, clfe */
bc9f98a9
KY
17432 0x02, 0x03, 0x04
17433};
17434
4c6d72d1 17435static const hda_nid_t alc272_dac_nids[2] = {
622e84cd
KY
17436 0x02, 0x03
17437};
17438
4c6d72d1 17439static const hda_nid_t alc662_adc_nids[2] = {
bc9f98a9 17440 /* ADC1-2 */
b59bdf3b 17441 0x09, 0x08
bc9f98a9 17442};
e1406348 17443
4c6d72d1 17444static const hda_nid_t alc272_adc_nids[1] = {
622e84cd
KY
17445 /* ADC1-2 */
17446 0x08,
17447};
17448
4c6d72d1
TI
17449static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17450static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
622e84cd 17451
e1406348 17452
bc9f98a9
KY
17453/* input MUX */
17454/* FIXME: should be a matrix-type input source selection */
a9111321 17455static const struct hda_input_mux alc662_capture_source = {
bc9f98a9
KY
17456 .num_items = 4,
17457 .items = {
17458 { "Mic", 0x0 },
17459 { "Front Mic", 0x1 },
17460 { "Line", 0x2 },
17461 { "CD", 0x4 },
17462 },
17463};
17464
a9111321 17465static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
bc9f98a9
KY
17466 .num_items = 2,
17467 .items = {
17468 { "Mic", 0x1 },
17469 { "Line", 0x2 },
17470 },
17471};
291702f0 17472
a9111321 17473static const struct hda_input_mux alc663_capture_source = {
6dda9f4a
KY
17474 .num_items = 3,
17475 .items = {
17476 { "Mic", 0x0 },
17477 { "Front Mic", 0x1 },
17478 { "Line", 0x2 },
17479 },
17480};
17481
4f5d1706 17482#if 0 /* set to 1 for testing other input sources below */
a9111321 17483static const struct hda_input_mux alc272_nc10_capture_source = {
9541ba1d
CP
17484 .num_items = 16,
17485 .items = {
17486 { "Autoselect Mic", 0x0 },
17487 { "Internal Mic", 0x1 },
17488 { "In-0x02", 0x2 },
17489 { "In-0x03", 0x3 },
17490 { "In-0x04", 0x4 },
17491 { "In-0x05", 0x5 },
17492 { "In-0x06", 0x6 },
17493 { "In-0x07", 0x7 },
17494 { "In-0x08", 0x8 },
17495 { "In-0x09", 0x9 },
17496 { "In-0x0a", 0x0a },
17497 { "In-0x0b", 0x0b },
17498 { "In-0x0c", 0x0c },
17499 { "In-0x0d", 0x0d },
17500 { "In-0x0e", 0x0e },
17501 { "In-0x0f", 0x0f },
17502 },
17503};
17504#endif
17505
bc9f98a9
KY
17506/*
17507 * 2ch mode
17508 */
a9111321 17509static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
bc9f98a9
KY
17510 { 2, NULL }
17511};
17512
17513/*
17514 * 2ch mode
17515 */
a9111321 17516static const struct hda_verb alc662_3ST_ch2_init[] = {
bc9f98a9
KY
17517 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17518 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17519 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17520 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17521 { } /* end */
17522};
17523
17524/*
17525 * 6ch mode
17526 */
a9111321 17527static const struct hda_verb alc662_3ST_ch6_init[] = {
bc9f98a9
KY
17528 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17529 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17530 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17531 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17532 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17533 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17534 { } /* end */
17535};
17536
a9111321 17537static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
bc9f98a9
KY
17538 { 2, alc662_3ST_ch2_init },
17539 { 6, alc662_3ST_ch6_init },
17540};
17541
17542/*
17543 * 2ch mode
17544 */
a9111321 17545static const struct hda_verb alc662_sixstack_ch6_init[] = {
bc9f98a9
KY
17546 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17547 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17548 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17549 { } /* end */
17550};
17551
17552/*
17553 * 6ch mode
17554 */
a9111321 17555static const struct hda_verb alc662_sixstack_ch8_init[] = {
bc9f98a9
KY
17556 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17557 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17558 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17559 { } /* end */
17560};
17561
a9111321 17562static const struct hda_channel_mode alc662_5stack_modes[2] = {
bc9f98a9
KY
17563 { 2, alc662_sixstack_ch6_init },
17564 { 6, alc662_sixstack_ch8_init },
17565};
17566
17567/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17568 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17569 */
17570
a9111321 17571static const struct snd_kcontrol_new alc662_base_mixer[] = {
bc9f98a9
KY
17572 /* output mixer control */
17573 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
7055ad8a 17574 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17575 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
7055ad8a 17576 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17577 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17578 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17579 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17580 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17581 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17582
17583 /*Input mixer control */
17584 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17585 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17586 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17587 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17588 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17589 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17590 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17591 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
bc9f98a9
KY
17592 { } /* end */
17593};
17594
a9111321 17595static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
bc9f98a9 17596 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17597 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9
KY
17598 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17599 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17600 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17601 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17602 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17603 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17604 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17605 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17606 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17607 { } /* end */
17608};
17609
a9111321 17610static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
bc9f98a9 17611 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
7055ad8a 17612 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
bc9f98a9 17613 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
7055ad8a 17614 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
bc9f98a9
KY
17615 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17616 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
7055ad8a
HRK
17617 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17618 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
bc9f98a9
KY
17619 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17620 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17621 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17622 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17623 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17624 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17625 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17626 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17627 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17628 { } /* end */
17629};
17630
a9111321 17631static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
bc9f98a9
KY
17632 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17633 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
86cd9298
TI
17634 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17635 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
bc9f98a9
KY
17636 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17637 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17638 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17639 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17640 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
bc9f98a9
KY
17641 { } /* end */
17642};
17643
a9111321 17644static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
42171c17
TI
17645 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17646 ALC262_HIPPO_MASTER_SWITCH,
291702f0 17647
5f99f86a 17648 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
17649 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17650 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
291702f0 17651
5f99f86a 17652 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
17653 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17654 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
291702f0
KY
17655 { } /* end */
17656};
17657
a9111321 17658static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
42171c17
TI
17659 ALC262_HIPPO_MASTER_SWITCH,
17660 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8c427226 17661 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8c427226
KY
17662 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17663 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
8c427226
KY
17664 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17669 { } /* end */
17670};
17671
a9111321 17672static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
f1d4e28b
KY
17673 .ops = &snd_hda_bind_vol,
17674 .values = {
17675 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17676 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17677 0
17678 },
17679};
17680
a9111321 17681static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
f1d4e28b
KY
17682 .ops = &snd_hda_bind_sw,
17683 .values = {
17684 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17685 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17686 0
17687 },
17688};
17689
a9111321 17690static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
f1d4e28b
KY
17691 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17692 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17695 { } /* end */
17696};
17697
a9111321 17698static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
f1d4e28b
KY
17699 .ops = &snd_hda_bind_sw,
17700 .values = {
17701 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17702 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17703 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17704 0
17705 },
17706};
17707
a9111321 17708static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
f1d4e28b
KY
17709 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17710 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17711 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17712 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17713 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17714 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17715
17716 { } /* end */
17717};
17718
a9111321 17719static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
f1d4e28b
KY
17720 .ops = &snd_hda_bind_sw,
17721 .values = {
17722 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17723 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17724 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17725 0
17726 },
17727};
17728
a9111321 17729static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
f1d4e28b
KY
17730 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17731 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17733 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17734 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17735 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17736 { } /* end */
17737};
17738
a9111321 17739static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
6dda9f4a
KY
17740 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17741 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
f1d4e28b
KY
17742 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17745 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17746 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17747 { } /* end */
17748};
17749
a9111321 17750static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
f1d4e28b
KY
17751 .ops = &snd_hda_bind_vol,
17752 .values = {
17753 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17754 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17755 0
17756 },
17757};
17758
a9111321 17759static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
f1d4e28b
KY
17760 .ops = &snd_hda_bind_sw,
17761 .values = {
17762 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17763 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17764 0
17765 },
17766};
17767
a9111321 17768static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
f1d4e28b
KY
17769 HDA_BIND_VOL("Master Playback Volume",
17770 &alc663_asus_two_bind_master_vol),
17771 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17772 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
6dda9f4a
KY
17773 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17774 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17775 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b
KY
17776 { } /* end */
17777};
17778
a9111321 17779static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
f1d4e28b
KY
17780 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17781 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17782 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17783 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
6dda9f4a
KY
17786 { } /* end */
17787};
17788
a9111321 17789static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
6dda9f4a
KY
17790 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17791 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17792 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17795
17796 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17798 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17799 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17800 { } /* end */
17801};
17802
a9111321 17803static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
6dda9f4a
KY
17804 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17805 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17806 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17807
17808 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17809 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
10528020
DH
17810 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17811 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
6dda9f4a
KY
17812 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17813 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17814 { } /* end */
17815};
17816
a9111321 17817static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
ebb83eeb
KY
17818 .ops = &snd_hda_bind_sw,
17819 .values = {
17820 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17821 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17822 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17823 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17824 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17825 0
17826 },
17827};
17828
a9111321 17829static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
ebb83eeb
KY
17830 .ops = &snd_hda_bind_sw,
17831 .values = {
17832 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17833 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17834 0
17835 },
17836};
17837
a9111321 17838static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
ebb83eeb
KY
17839 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17840 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17841 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17842 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17843 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17845 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17847 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17848 { } /* end */
17849};
17850
a9111321 17851static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
ebb83eeb
KY
17852 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17853 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17854 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17855 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17856 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17859 { } /* end */
17860};
17861
17862
a9111321 17863static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
bc9f98a9
KY
17864 {
17865 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17866 .name = "Channel Mode",
17867 .info = alc_ch_mode_info,
17868 .get = alc_ch_mode_get,
17869 .put = alc_ch_mode_put,
17870 },
17871 { } /* end */
17872};
17873
a9111321 17874static const struct hda_verb alc662_init_verbs[] = {
bc9f98a9
KY
17875 /* ADC: mute amp left and right */
17876 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17877 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
bc9f98a9 17878
b60dd394
KY
17879 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17880 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17881 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17882 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17883 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17884 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
bc9f98a9
KY
17885
17886 /* Front Pin: output 0 (0x0c) */
17887 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17888 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17889
17890 /* Rear Pin: output 1 (0x0d) */
17891 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17892 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17893
17894 /* CLFE Pin: output 2 (0x0e) */
17895 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17896 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17897
17898 /* Mic (rear) pin: input vref at 80% */
17899 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17900 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17901 /* Front Mic pin: input vref at 80% */
17902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17903 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17904 /* Line In pin: input */
17905 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17906 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17907 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17908 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17909 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17910 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17911 /* CD pin widget for input */
17912 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17913
17914 /* FIXME: use matrix-type input source selection */
17915 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17916 /* Input mixer */
17917 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
291702f0 17918 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6dda9f4a 17919
a7f2371f
TI
17920 { }
17921};
17922
a9111321 17923static const struct hda_verb alc662_eapd_init_verbs[] = {
6dda9f4a
KY
17924 /* always trun on EAPD */
17925 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17926 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
bc9f98a9
KY
17927 { }
17928};
17929
a9111321 17930static const struct hda_verb alc662_sue_init_verbs[] = {
bc9f98a9
KY
17931 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17932 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
291702f0
KY
17933 {}
17934};
17935
a9111321 17936static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
291702f0
KY
17937 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17938 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17939 {}
bc9f98a9
KY
17940};
17941
8c427226 17942/* Set Unsolicited Event*/
a9111321 17943static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
8c427226
KY
17944 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17945 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17946 {}
17947};
17948
a9111321 17949static const struct hda_verb alc663_m51va_init_verbs[] = {
f1d4e28b
KY
17950 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17951 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6dda9f4a
KY
17952 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17953 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
f1d4e28b
KY
17954 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17955 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17957 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17958 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17959 {}
17960};
17961
a9111321 17962static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
f1d4e28b
KY
17963 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17964 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17965 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17966 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17967 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17968 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17969 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17970 {}
17971};
17972
a9111321 17973static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
f1d4e28b
KY
17974 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17975 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17976 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17977 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17978 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17979 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17980 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17981 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17982 {}
17983};
6dda9f4a 17984
a9111321 17985static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
f1d4e28b
KY
17986 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17987 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17988 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17989 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17990 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17991 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17992 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17993 {}
17994};
6dda9f4a 17995
a9111321 17996static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
f1d4e28b
KY
17997 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17998 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17999 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18000 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18001 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18002 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18003 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18004 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18005 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6dda9f4a
KY
18006 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18007 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
f1d4e28b
KY
18008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18009 {}
18010};
18011
a9111321 18012static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
f1d4e28b
KY
18013 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18014 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18015 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18016 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18018 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18019 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18020 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18021 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18022 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18023 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18024 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6dda9f4a
KY
18025 {}
18026};
18027
a9111321 18028static const struct hda_verb alc663_g71v_init_verbs[] = {
6dda9f4a
KY
18029 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18030 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18031 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18032
18033 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18034 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18035 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18036
18037 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18038 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18039 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18040 {}
18041};
18042
a9111321 18043static const struct hda_verb alc663_g50v_init_verbs[] = {
6dda9f4a
KY
18044 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18045 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18046 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18047
18048 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18049 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18050 {}
18051};
18052
a9111321 18053static const struct hda_verb alc662_ecs_init_verbs[] = {
f1d4e28b
KY
18054 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18056 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18057 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18058 {}
18059};
18060
a9111321 18061static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
622e84cd
KY
18062 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18063 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18064 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18069 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18070 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18071 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18072 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18073 {}
18074};
18075
a9111321 18076static const struct hda_verb alc272_dell_init_verbs[] = {
622e84cd
KY
18077 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18078 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18080 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18081 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18083 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18085 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18086 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18087 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18088 {}
18089};
18090
a9111321 18091static const struct hda_verb alc663_mode7_init_verbs[] = {
ebb83eeb
KY
18092 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18093 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18094 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18095 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18099 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18100 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18101 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18104 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18105 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18106 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18107 {}
18108};
18109
a9111321 18110static const struct hda_verb alc663_mode8_init_verbs[] = {
ebb83eeb
KY
18111 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18112 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18113 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18114 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18115 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18117 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18119 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18120 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18121 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18123 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18124 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18126 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18127 {}
18128};
18129
a9111321 18130static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
f1d4e28b
KY
18131 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18132 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18133 { } /* end */
18134};
18135
a9111321 18136static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
622e84cd
KY
18137 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18138 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18139 { } /* end */
18140};
18141
e6a5e1b7 18142static void alc662_lenovo_101e_setup(struct hda_codec *codec)
bc9f98a9 18143{
e6a5e1b7 18144 struct alc_spec *spec = codec->spec;
bc9f98a9 18145
e6a5e1b7
TI
18146 spec->autocfg.hp_pins[0] = 0x1b;
18147 spec->autocfg.line_out_pins[0] = 0x14;
18148 spec->autocfg.speaker_pins[0] = 0x15;
18149 spec->automute = 1;
18150 spec->detect_line = 1;
18151 spec->automute_lines = 1;
18152 spec->automute_mode = ALC_AUTOMUTE_AMP;
bc9f98a9
KY
18153}
18154
4f5d1706
TI
18155static void alc662_eeepc_setup(struct hda_codec *codec)
18156{
18157 struct alc_spec *spec = codec->spec;
18158
18159 alc262_hippo1_setup(codec);
18160 spec->ext_mic.pin = 0x18;
18161 spec->ext_mic.mux_idx = 0;
18162 spec->int_mic.pin = 0x19;
18163 spec->int_mic.mux_idx = 1;
18164 spec->auto_mic = 1;
18165}
18166
4f5d1706 18167static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
8c427226 18168{
42171c17
TI
18169 struct alc_spec *spec = codec->spec;
18170
18171 spec->autocfg.hp_pins[0] = 0x14;
18172 spec->autocfg.speaker_pins[0] = 0x1b;
e9427969
TI
18173 spec->automute = 1;
18174 spec->automute_mode = ALC_AUTOMUTE_AMP;
8c427226
KY
18175}
18176
4f5d1706
TI
18177static void alc663_m51va_setup(struct hda_codec *codec)
18178{
18179 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18180 spec->autocfg.hp_pins[0] = 0x21;
18181 spec->autocfg.speaker_pins[0] = 0x14;
18182 spec->automute_mixer_nid[0] = 0x0c;
18183 spec->automute = 1;
18184 spec->automute_mode = ALC_AUTOMUTE_MIXER;
4f5d1706
TI
18185 spec->ext_mic.pin = 0x18;
18186 spec->ext_mic.mux_idx = 0;
18187 spec->int_mic.pin = 0x12;
ebb83eeb 18188 spec->int_mic.mux_idx = 9;
4f5d1706
TI
18189 spec->auto_mic = 1;
18190}
18191
f1d4e28b 18192/* ***************** Mode1 ******************************/
ebb83eeb
KY
18193static void alc663_mode1_setup(struct hda_codec *codec)
18194{
18195 struct alc_spec *spec = codec->spec;
3b8510ce
TI
18196 spec->autocfg.hp_pins[0] = 0x21;
18197 spec->autocfg.speaker_pins[0] = 0x14;
18198 spec->automute_mixer_nid[0] = 0x0c;
18199 spec->automute = 1;
18200 spec->automute_mode = ALC_AUTOMUTE_MIXER;
ebb83eeb
KY
18201 spec->ext_mic.pin = 0x18;
18202 spec->ext_mic.mux_idx = 0;
18203 spec->int_mic.pin = 0x19;
18204 spec->int_mic.mux_idx = 1;
18205 spec->auto_mic = 1;
18206}
18207
f1d4e28b 18208/* ***************** Mode2 ******************************/
3b8510ce 18209static void alc662_mode2_setup(struct hda_codec *codec)
f1d4e28b 18210{
3b8510ce
TI
18211 struct alc_spec *spec = codec->spec;
18212 spec->autocfg.hp_pins[0] = 0x1b;
18213 spec->autocfg.speaker_pins[0] = 0x14;
18214 spec->automute = 1;
18215 spec->automute_mode = ALC_AUTOMUTE_PIN;
18216 spec->ext_mic.pin = 0x18;
18217 spec->ext_mic.mux_idx = 0;
18218 spec->int_mic.pin = 0x19;
18219 spec->int_mic.mux_idx = 1;
18220 spec->auto_mic = 1;
f1d4e28b
KY
18221}
18222
f1d4e28b 18223/* ***************** Mode3 ******************************/
3b8510ce 18224static void alc663_mode3_setup(struct hda_codec *codec)
f1d4e28b 18225{
3b8510ce
TI
18226 struct alc_spec *spec = codec->spec;
18227 spec->autocfg.hp_pins[0] = 0x21;
18228 spec->autocfg.hp_pins[0] = 0x15;
18229 spec->autocfg.speaker_pins[0] = 0x14;
18230 spec->automute = 1;
18231 spec->automute_mode = ALC_AUTOMUTE_PIN;
18232 spec->ext_mic.pin = 0x18;
18233 spec->ext_mic.mux_idx = 0;
18234 spec->int_mic.pin = 0x19;
18235 spec->int_mic.mux_idx = 1;
18236 spec->auto_mic = 1;
f1d4e28b
KY
18237}
18238
f1d4e28b 18239/* ***************** Mode4 ******************************/
3b8510ce 18240static void alc663_mode4_setup(struct hda_codec *codec)
f1d4e28b 18241{
3b8510ce
TI
18242 struct alc_spec *spec = codec->spec;
18243 spec->autocfg.hp_pins[0] = 0x21;
18244 spec->autocfg.speaker_pins[0] = 0x14;
18245 spec->autocfg.speaker_pins[1] = 0x16;
18246 spec->automute_mixer_nid[0] = 0x0c;
18247 spec->automute_mixer_nid[1] = 0x0e;
18248 spec->automute = 1;
18249 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18250 spec->ext_mic.pin = 0x18;
18251 spec->ext_mic.mux_idx = 0;
18252 spec->int_mic.pin = 0x19;
18253 spec->int_mic.mux_idx = 1;
18254 spec->auto_mic = 1;
f1d4e28b
KY
18255}
18256
f1d4e28b 18257/* ***************** Mode5 ******************************/
3b8510ce 18258static void alc663_mode5_setup(struct hda_codec *codec)
f1d4e28b 18259{
3b8510ce
TI
18260 struct alc_spec *spec = codec->spec;
18261 spec->autocfg.hp_pins[0] = 0x15;
18262 spec->autocfg.speaker_pins[0] = 0x14;
18263 spec->autocfg.speaker_pins[1] = 0x16;
18264 spec->automute_mixer_nid[0] = 0x0c;
18265 spec->automute_mixer_nid[1] = 0x0e;
18266 spec->automute = 1;
18267 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18268 spec->ext_mic.pin = 0x18;
18269 spec->ext_mic.mux_idx = 0;
18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
f1d4e28b
KY
18273}
18274
f1d4e28b 18275/* ***************** Mode6 ******************************/
3b8510ce 18276static void alc663_mode6_setup(struct hda_codec *codec)
f1d4e28b 18277{
3b8510ce
TI
18278 struct alc_spec *spec = codec->spec;
18279 spec->autocfg.hp_pins[0] = 0x1b;
18280 spec->autocfg.hp_pins[0] = 0x15;
18281 spec->autocfg.speaker_pins[0] = 0x14;
18282 spec->automute_mixer_nid[0] = 0x0c;
18283 spec->automute = 1;
18284 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18285 spec->ext_mic.pin = 0x18;
18286 spec->ext_mic.mux_idx = 0;
18287 spec->int_mic.pin = 0x19;
18288 spec->int_mic.mux_idx = 1;
18289 spec->auto_mic = 1;
f1d4e28b
KY
18290}
18291
ebb83eeb 18292/* ***************** Mode7 ******************************/
3b8510ce 18293static void alc663_mode7_setup(struct hda_codec *codec)
ebb83eeb 18294{
3b8510ce
TI
18295 struct alc_spec *spec = codec->spec;
18296 spec->autocfg.hp_pins[0] = 0x1b;
18297 spec->autocfg.hp_pins[0] = 0x21;
18298 spec->autocfg.speaker_pins[0] = 0x14;
18299 spec->autocfg.speaker_pins[0] = 0x17;
18300 spec->automute = 1;
18301 spec->automute_mode = ALC_AUTOMUTE_PIN;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
ebb83eeb
KY
18307}
18308
18309/* ***************** Mode8 ******************************/
3b8510ce 18310static void alc663_mode8_setup(struct hda_codec *codec)
ebb83eeb 18311{
3b8510ce
TI
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x21;
18314 spec->autocfg.hp_pins[1] = 0x15;
18315 spec->autocfg.speaker_pins[0] = 0x14;
18316 spec->autocfg.speaker_pins[0] = 0x17;
18317 spec->automute = 1;
18318 spec->automute_mode = ALC_AUTOMUTE_PIN;
18319 spec->ext_mic.pin = 0x18;
18320 spec->ext_mic.mux_idx = 0;
18321 spec->int_mic.pin = 0x12;
18322 spec->int_mic.mux_idx = 9;
18323 spec->auto_mic = 1;
ebb83eeb
KY
18324}
18325
e6a5e1b7 18326static void alc663_g71v_setup(struct hda_codec *codec)
6dda9f4a 18327{
e6a5e1b7
TI
18328 struct alc_spec *spec = codec->spec;
18329 spec->autocfg.hp_pins[0] = 0x21;
18330 spec->autocfg.line_out_pins[0] = 0x15;
18331 spec->autocfg.speaker_pins[0] = 0x14;
18332 spec->automute = 1;
18333 spec->automute_mode = ALC_AUTOMUTE_AMP;
18334 spec->detect_line = 1;
18335 spec->automute_lines = 1;
18336 spec->ext_mic.pin = 0x18;
18337 spec->ext_mic.mux_idx = 0;
18338 spec->int_mic.pin = 0x12;
18339 spec->int_mic.mux_idx = 9;
18340 spec->auto_mic = 1;
6dda9f4a
KY
18341}
18342
4f5d1706
TI
18343#define alc663_g50v_setup alc663_m51va_setup
18344
a9111321 18345static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
f1d4e28b 18346 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
42171c17 18347 ALC262_HIPPO_MASTER_SWITCH,
f1d4e28b 18348
5f99f86a 18349 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
10528020
DH
18350 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18351 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
f1d4e28b 18352
5f99f86a 18353 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
10528020
DH
18354 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18355 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
f1d4e28b
KY
18356 { } /* end */
18357};
18358
a9111321 18359static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
9541ba1d
CP
18360 /* Master Playback automatically created from Speaker and Headphone */
18361 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18362 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18363 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18364 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18365
8607f7c4
DH
18366 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18367 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5f99f86a 18368 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9541ba1d 18369
28c4edb7
DH
18370 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18371 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5f99f86a 18372 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9541ba1d
CP
18373 { } /* end */
18374};
18375
cb53c626
TI
18376#ifdef CONFIG_SND_HDA_POWER_SAVE
18377#define alc662_loopbacks alc880_loopbacks
18378#endif
18379
bc9f98a9 18380
def319f9 18381/* pcm configuration: identical with ALC880 */
bc9f98a9
KY
18382#define alc662_pcm_analog_playback alc880_pcm_analog_playback
18383#define alc662_pcm_analog_capture alc880_pcm_analog_capture
18384#define alc662_pcm_digital_playback alc880_pcm_digital_playback
18385#define alc662_pcm_digital_capture alc880_pcm_digital_capture
18386
18387/*
18388 * configuration and preset
18389 */
ea734963 18390static const char * const alc662_models[ALC662_MODEL_LAST] = {
bc9f98a9
KY
18391 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18392 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18393 [ALC662_3ST_6ch] = "3stack-6ch",
4bf4a6c5 18394 [ALC662_5ST_DIG] = "5stack-dig",
bc9f98a9 18395 [ALC662_LENOVO_101E] = "lenovo-101e",
b995d76d 18396 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
8c427226 18397 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
f1d4e28b 18398 [ALC662_ECS] = "ecs",
6dda9f4a
KY
18399 [ALC663_ASUS_M51VA] = "m51va",
18400 [ALC663_ASUS_G71V] = "g71v",
18401 [ALC663_ASUS_H13] = "h13",
18402 [ALC663_ASUS_G50V] = "g50v",
f1d4e28b
KY
18403 [ALC663_ASUS_MODE1] = "asus-mode1",
18404 [ALC662_ASUS_MODE2] = "asus-mode2",
18405 [ALC663_ASUS_MODE3] = "asus-mode3",
18406 [ALC663_ASUS_MODE4] = "asus-mode4",
18407 [ALC663_ASUS_MODE5] = "asus-mode5",
18408 [ALC663_ASUS_MODE6] = "asus-mode6",
ebb83eeb
KY
18409 [ALC663_ASUS_MODE7] = "asus-mode7",
18410 [ALC663_ASUS_MODE8] = "asus-mode8",
01f2bd48
TI
18411 [ALC272_DELL] = "dell",
18412 [ALC272_DELL_ZM1] = "dell-zm1",
9541ba1d 18413 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
bc9f98a9
KY
18414 [ALC662_AUTO] = "auto",
18415};
18416
a9111321 18417static const struct snd_pci_quirk alc662_cfg_tbl[] = {
dea0a509 18418 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
622e84cd
KY
18419 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18420 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
f1d4e28b 18421 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
dea0a509 18422 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
cec27c89 18423 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
dea0a509 18424 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
f1d4e28b 18425 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
dea0a509 18426 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
f1d4e28b 18427 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
ebb83eeb
KY
18428 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18429 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
f1d4e28b 18430 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18431 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18432 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18433 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18434 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18435 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
dea0a509 18436 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb
KY
18437 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18438 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
dea0a509
TI
18439 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18440 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18441 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18442 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
ebb83eeb 18443 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
622e84cd
KY
18444 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18445 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18446 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
f1d4e28b 18447 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18448 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18449 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18450 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
622e84cd 18451 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
f1d4e28b 18452 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
dea0a509
TI
18453 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18454 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18455 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
f1d4e28b 18456 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
f1d4e28b 18457 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
622e84cd 18458 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
cec27c89 18459 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
622e84cd
KY
18460 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18461 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
dea0a509
TI
18462 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18463 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18464 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
622e84cd 18465 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
dea0a509
TI
18466 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18467 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
622e84cd 18468 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
dea0a509
TI
18469 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18470 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18471 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18472 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18473 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
622e84cd 18474 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
dea0a509 18475 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
f1d4e28b 18476 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
dea0a509
TI
18477 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18478 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18479 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18480 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
95fe5f2c
HRK
18481 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18482 ALC662_3ST_6ch_DIG),
4dee8baa 18483 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
9541ba1d 18484 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
ebb47241
TI
18485 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18486 ALC662_3ST_6ch_DIG),
6227cdce 18487 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
19c009aa 18488 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
5bd3729f 18489 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
dea0a509 18490 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
238713d4 18491 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
19c009aa 18492 ALC662_3ST_6ch_DIG),
dea0a509
TI
18493 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18494 ALC663_ASUS_H13),
965b76d2 18495 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
bc9f98a9
KY
18496 {}
18497};
18498
a9111321 18499static const struct alc_config_preset alc662_presets[] = {
bc9f98a9 18500 [ALC662_3ST_2ch_DIG] = {
f9e336f6 18501 .mixers = { alc662_3ST_2ch_mixer },
a7f2371f 18502 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18503 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18504 .dac_nids = alc662_dac_nids,
18505 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18506 .dig_in_nid = ALC662_DIGIN_NID,
18507 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18508 .channel_mode = alc662_3ST_2ch_modes,
18509 .input_mux = &alc662_capture_source,
18510 },
18511 [ALC662_3ST_6ch_DIG] = {
f9e336f6 18512 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18513 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18514 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18515 .dac_nids = alc662_dac_nids,
18516 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18517 .dig_in_nid = ALC662_DIGIN_NID,
18518 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18519 .channel_mode = alc662_3ST_6ch_modes,
18520 .need_dac_fix = 1,
18521 .input_mux = &alc662_capture_source,
f12ab1e0 18522 },
bc9f98a9 18523 [ALC662_3ST_6ch] = {
f9e336f6 18524 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
a7f2371f 18525 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18526 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18527 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18528 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18529 .channel_mode = alc662_3ST_6ch_modes,
18530 .need_dac_fix = 1,
18531 .input_mux = &alc662_capture_source,
f12ab1e0 18532 },
bc9f98a9 18533 [ALC662_5ST_DIG] = {
f9e336f6 18534 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
a7f2371f 18535 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
bc9f98a9
KY
18536 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18537 .dac_nids = alc662_dac_nids,
18538 .dig_out_nid = ALC662_DIGOUT_NID,
bc9f98a9
KY
18539 .dig_in_nid = ALC662_DIGIN_NID,
18540 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18541 .channel_mode = alc662_5stack_modes,
18542 .input_mux = &alc662_capture_source,
18543 },
18544 [ALC662_LENOVO_101E] = {
f9e336f6 18545 .mixers = { alc662_lenovo_101e_mixer },
a7f2371f
TI
18546 .init_verbs = { alc662_init_verbs,
18547 alc662_eapd_init_verbs,
18548 alc662_sue_init_verbs },
bc9f98a9
KY
18549 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18550 .dac_nids = alc662_dac_nids,
bc9f98a9
KY
18551 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18552 .channel_mode = alc662_3ST_2ch_modes,
18553 .input_mux = &alc662_lenovo_101e_capture_source,
e6a5e1b7
TI
18554 .unsol_event = alc_sku_unsol_event,
18555 .setup = alc662_lenovo_101e_setup,
18556 .init_hook = alc_inithook,
bc9f98a9 18557 },
291702f0 18558 [ALC662_ASUS_EEEPC_P701] = {
f9e336f6 18559 .mixers = { alc662_eeepc_p701_mixer },
291702f0 18560 .init_verbs = { alc662_init_verbs,
a7f2371f 18561 alc662_eapd_init_verbs,
291702f0
KY
18562 alc662_eeepc_sue_init_verbs },
18563 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18564 .dac_nids = alc662_dac_nids,
291702f0
KY
18565 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18566 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18567 .unsol_event = alc_sku_unsol_event,
4f5d1706 18568 .setup = alc662_eeepc_setup,
e9427969 18569 .init_hook = alc_inithook,
291702f0 18570 },
8c427226 18571 [ALC662_ASUS_EEEPC_EP20] = {
f9e336f6 18572 .mixers = { alc662_eeepc_ep20_mixer,
8c427226
KY
18573 alc662_chmode_mixer },
18574 .init_verbs = { alc662_init_verbs,
a7f2371f 18575 alc662_eapd_init_verbs,
8c427226
KY
18576 alc662_eeepc_ep20_sue_init_verbs },
18577 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18578 .dac_nids = alc662_dac_nids,
8c427226
KY
18579 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18580 .channel_mode = alc662_3ST_6ch_modes,
18581 .input_mux = &alc662_lenovo_101e_capture_source,
e9427969 18582 .unsol_event = alc_sku_unsol_event,
4f5d1706 18583 .setup = alc662_eeepc_ep20_setup,
e9427969 18584 .init_hook = alc_inithook,
8c427226 18585 },
f1d4e28b 18586 [ALC662_ECS] = {
f9e336f6 18587 .mixers = { alc662_ecs_mixer },
f1d4e28b 18588 .init_verbs = { alc662_init_verbs,
a7f2371f 18589 alc662_eapd_init_verbs,
f1d4e28b
KY
18590 alc662_ecs_init_verbs },
18591 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18592 .dac_nids = alc662_dac_nids,
18593 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18594 .channel_mode = alc662_3ST_2ch_modes,
e9427969 18595 .unsol_event = alc_sku_unsol_event,
4f5d1706 18596 .setup = alc662_eeepc_setup,
e9427969 18597 .init_hook = alc_inithook,
f1d4e28b 18598 },
6dda9f4a 18599 [ALC663_ASUS_M51VA] = {
f9e336f6 18600 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18601 .init_verbs = { alc662_init_verbs,
18602 alc662_eapd_init_verbs,
18603 alc663_m51va_init_verbs },
6dda9f4a
KY
18604 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18605 .dac_nids = alc662_dac_nids,
18606 .dig_out_nid = ALC662_DIGOUT_NID,
18607 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18608 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18609 .unsol_event = alc_sku_unsol_event,
4f5d1706 18610 .setup = alc663_m51va_setup,
3b8510ce 18611 .init_hook = alc_inithook,
6dda9f4a
KY
18612 },
18613 [ALC663_ASUS_G71V] = {
f9e336f6 18614 .mixers = { alc663_g71v_mixer },
a7f2371f
TI
18615 .init_verbs = { alc662_init_verbs,
18616 alc662_eapd_init_verbs,
18617 alc663_g71v_init_verbs },
6dda9f4a
KY
18618 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18619 .dac_nids = alc662_dac_nids,
18620 .dig_out_nid = ALC662_DIGOUT_NID,
18621 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18622 .channel_mode = alc662_3ST_2ch_modes,
e6a5e1b7 18623 .unsol_event = alc_sku_unsol_event,
4f5d1706 18624 .setup = alc663_g71v_setup,
e6a5e1b7 18625 .init_hook = alc_inithook,
6dda9f4a
KY
18626 },
18627 [ALC663_ASUS_H13] = {
f9e336f6 18628 .mixers = { alc663_m51va_mixer },
a7f2371f
TI
18629 .init_verbs = { alc662_init_verbs,
18630 alc662_eapd_init_verbs,
18631 alc663_m51va_init_verbs },
6dda9f4a
KY
18632 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18633 .dac_nids = alc662_dac_nids,
18634 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18635 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce
TI
18636 .setup = alc663_m51va_setup,
18637 .unsol_event = alc_sku_unsol_event,
18638 .init_hook = alc_inithook,
6dda9f4a
KY
18639 },
18640 [ALC663_ASUS_G50V] = {
f9e336f6 18641 .mixers = { alc663_g50v_mixer },
a7f2371f
TI
18642 .init_verbs = { alc662_init_verbs,
18643 alc662_eapd_init_verbs,
18644 alc663_g50v_init_verbs },
6dda9f4a
KY
18645 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18646 .dac_nids = alc662_dac_nids,
18647 .dig_out_nid = ALC662_DIGOUT_NID,
18648 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18649 .channel_mode = alc662_3ST_6ch_modes,
18650 .input_mux = &alc663_capture_source,
3b8510ce 18651 .unsol_event = alc_sku_unsol_event,
4f5d1706 18652 .setup = alc663_g50v_setup,
3b8510ce 18653 .init_hook = alc_inithook,
6dda9f4a 18654 },
f1d4e28b 18655 [ALC663_ASUS_MODE1] = {
f9e336f6
TI
18656 .mixers = { alc663_m51va_mixer },
18657 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18658 .init_verbs = { alc662_init_verbs,
a7f2371f 18659 alc662_eapd_init_verbs,
f1d4e28b
KY
18660 alc663_21jd_amic_init_verbs },
18661 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18662 .hp_nid = 0x03,
18663 .dac_nids = alc662_dac_nids,
18664 .dig_out_nid = ALC662_DIGOUT_NID,
18665 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18666 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18667 .unsol_event = alc_sku_unsol_event,
4f5d1706 18668 .setup = alc663_mode1_setup,
3b8510ce 18669 .init_hook = alc_inithook,
f1d4e28b
KY
18670 },
18671 [ALC662_ASUS_MODE2] = {
f9e336f6
TI
18672 .mixers = { alc662_1bjd_mixer },
18673 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18674 .init_verbs = { alc662_init_verbs,
a7f2371f 18675 alc662_eapd_init_verbs,
f1d4e28b
KY
18676 alc662_1bjd_amic_init_verbs },
18677 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18678 .dac_nids = alc662_dac_nids,
18679 .dig_out_nid = ALC662_DIGOUT_NID,
18680 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18681 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18682 .unsol_event = alc_sku_unsol_event,
4f5d1706 18683 .setup = alc662_mode2_setup,
3b8510ce 18684 .init_hook = alc_inithook,
f1d4e28b
KY
18685 },
18686 [ALC663_ASUS_MODE3] = {
f9e336f6
TI
18687 .mixers = { alc663_two_hp_m1_mixer },
18688 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18689 .init_verbs = { alc662_init_verbs,
a7f2371f 18690 alc662_eapd_init_verbs,
f1d4e28b
KY
18691 alc663_two_hp_amic_m1_init_verbs },
18692 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18693 .hp_nid = 0x03,
18694 .dac_nids = alc662_dac_nids,
18695 .dig_out_nid = ALC662_DIGOUT_NID,
18696 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18697 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18698 .unsol_event = alc_sku_unsol_event,
4f5d1706 18699 .setup = alc663_mode3_setup,
3b8510ce 18700 .init_hook = alc_inithook,
f1d4e28b
KY
18701 },
18702 [ALC663_ASUS_MODE4] = {
f9e336f6
TI
18703 .mixers = { alc663_asus_21jd_clfe_mixer },
18704 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18705 .init_verbs = { alc662_init_verbs,
a7f2371f 18706 alc662_eapd_init_verbs,
f1d4e28b
KY
18707 alc663_21jd_amic_init_verbs},
18708 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18709 .hp_nid = 0x03,
18710 .dac_nids = alc662_dac_nids,
18711 .dig_out_nid = ALC662_DIGOUT_NID,
18712 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18713 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18714 .unsol_event = alc_sku_unsol_event,
4f5d1706 18715 .setup = alc663_mode4_setup,
3b8510ce 18716 .init_hook = alc_inithook,
f1d4e28b
KY
18717 },
18718 [ALC663_ASUS_MODE5] = {
f9e336f6
TI
18719 .mixers = { alc663_asus_15jd_clfe_mixer },
18720 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18721 .init_verbs = { alc662_init_verbs,
a7f2371f 18722 alc662_eapd_init_verbs,
f1d4e28b
KY
18723 alc663_15jd_amic_init_verbs },
18724 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18725 .hp_nid = 0x03,
18726 .dac_nids = alc662_dac_nids,
18727 .dig_out_nid = ALC662_DIGOUT_NID,
18728 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18729 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18730 .unsol_event = alc_sku_unsol_event,
4f5d1706 18731 .setup = alc663_mode5_setup,
3b8510ce 18732 .init_hook = alc_inithook,
f1d4e28b
KY
18733 },
18734 [ALC663_ASUS_MODE6] = {
f9e336f6
TI
18735 .mixers = { alc663_two_hp_m2_mixer },
18736 .cap_mixer = alc662_auto_capture_mixer,
f1d4e28b 18737 .init_verbs = { alc662_init_verbs,
a7f2371f 18738 alc662_eapd_init_verbs,
f1d4e28b
KY
18739 alc663_two_hp_amic_m2_init_verbs },
18740 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18741 .hp_nid = 0x03,
18742 .dac_nids = alc662_dac_nids,
18743 .dig_out_nid = ALC662_DIGOUT_NID,
18744 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18745 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18746 .unsol_event = alc_sku_unsol_event,
4f5d1706 18747 .setup = alc663_mode6_setup,
3b8510ce 18748 .init_hook = alc_inithook,
f1d4e28b 18749 },
ebb83eeb
KY
18750 [ALC663_ASUS_MODE7] = {
18751 .mixers = { alc663_mode7_mixer },
18752 .cap_mixer = alc662_auto_capture_mixer,
18753 .init_verbs = { alc662_init_verbs,
a7f2371f 18754 alc662_eapd_init_verbs,
ebb83eeb
KY
18755 alc663_mode7_init_verbs },
18756 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18757 .hp_nid = 0x03,
18758 .dac_nids = alc662_dac_nids,
18759 .dig_out_nid = ALC662_DIGOUT_NID,
18760 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18761 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18762 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18763 .setup = alc663_mode7_setup,
3b8510ce 18764 .init_hook = alc_inithook,
ebb83eeb
KY
18765 },
18766 [ALC663_ASUS_MODE8] = {
18767 .mixers = { alc663_mode8_mixer },
18768 .cap_mixer = alc662_auto_capture_mixer,
18769 .init_verbs = { alc662_init_verbs,
a7f2371f 18770 alc662_eapd_init_verbs,
ebb83eeb
KY
18771 alc663_mode8_init_verbs },
18772 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18773 .hp_nid = 0x03,
18774 .dac_nids = alc662_dac_nids,
18775 .dig_out_nid = ALC662_DIGOUT_NID,
18776 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18777 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18778 .unsol_event = alc_sku_unsol_event,
ebb83eeb 18779 .setup = alc663_mode8_setup,
3b8510ce 18780 .init_hook = alc_inithook,
ebb83eeb 18781 },
622e84cd
KY
18782 [ALC272_DELL] = {
18783 .mixers = { alc663_m51va_mixer },
18784 .cap_mixer = alc272_auto_capture_mixer,
a7f2371f
TI
18785 .init_verbs = { alc662_init_verbs,
18786 alc662_eapd_init_verbs,
18787 alc272_dell_init_verbs },
622e84cd 18788 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18789 .dac_nids = alc272_dac_nids,
622e84cd
KY
18790 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18791 .adc_nids = alc272_adc_nids,
18792 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18793 .capsrc_nids = alc272_capsrc_nids,
18794 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18795 .unsol_event = alc_sku_unsol_event,
4f5d1706 18796 .setup = alc663_m51va_setup,
3b8510ce 18797 .init_hook = alc_inithook,
622e84cd
KY
18798 },
18799 [ALC272_DELL_ZM1] = {
18800 .mixers = { alc663_m51va_mixer },
18801 .cap_mixer = alc662_auto_capture_mixer,
a7f2371f
TI
18802 .init_verbs = { alc662_init_verbs,
18803 alc662_eapd_init_verbs,
18804 alc272_dell_zm1_init_verbs },
622e84cd 18805 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
1bc7cf99 18806 .dac_nids = alc272_dac_nids,
622e84cd
KY
18807 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18808 .adc_nids = alc662_adc_nids,
b59bdf3b 18809 .num_adc_nids = 1,
622e84cd
KY
18810 .capsrc_nids = alc662_capsrc_nids,
18811 .channel_mode = alc662_3ST_2ch_modes,
3b8510ce 18812 .unsol_event = alc_sku_unsol_event,
4f5d1706 18813 .setup = alc663_m51va_setup,
3b8510ce 18814 .init_hook = alc_inithook,
622e84cd 18815 },
9541ba1d
CP
18816 [ALC272_SAMSUNG_NC10] = {
18817 .mixers = { alc272_nc10_mixer },
18818 .init_verbs = { alc662_init_verbs,
a7f2371f 18819 alc662_eapd_init_verbs,
9541ba1d
CP
18820 alc663_21jd_amic_init_verbs },
18821 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18822 .dac_nids = alc272_dac_nids,
18823 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18824 .channel_mode = alc662_3ST_2ch_modes,
4f5d1706 18825 /*.input_mux = &alc272_nc10_capture_source,*/
3b8510ce 18826 .unsol_event = alc_sku_unsol_event,
4f5d1706 18827 .setup = alc663_mode4_setup,
3b8510ce 18828 .init_hook = alc_inithook,
9541ba1d 18829 },
bc9f98a9
KY
18830};
18831
18832
18833/*
18834 * BIOS auto configuration
18835 */
18836
7085ec12 18837/* convert from MIX nid to DAC */
604401a9 18838static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
1304ac89 18839{
604401a9 18840 hda_nid_t list[5];
1304ac89
TI
18841 int i, num;
18842
18843 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18844 for (i = 0; i < num; i++) {
18845 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18846 return list[i];
18847 }
18848 return 0;
7085ec12
TI
18849}
18850
604401a9
TI
18851/* go down to the selector widget before the mixer */
18852static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18853{
18854 hda_nid_t srcs[5];
18855 int num = snd_hda_get_connections(codec, pin, srcs,
18856 ARRAY_SIZE(srcs));
18857 if (num != 1 ||
18858 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18859 return pin;
18860 return srcs[0];
18861}
18862
7085ec12 18863/* get MIX nid connected to the given pin targeted to DAC */
604401a9 18864static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
7085ec12
TI
18865 hda_nid_t dac)
18866{
cc1c452e 18867 hda_nid_t mix[5];
7085ec12
TI
18868 int i, num;
18869
604401a9 18870 pin = alc_go_down_to_selector(codec, pin);
7085ec12
TI
18871 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18872 for (i = 0; i < num; i++) {
604401a9 18873 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
7085ec12
TI
18874 return mix[i];
18875 }
18876 return 0;
18877}
18878
ce764ab2
TI
18879/* select the connection from pin to DAC if needed */
18880static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18881 hda_nid_t dac)
18882{
18883 hda_nid_t mix[5];
18884 int i, num;
18885
18886 pin = alc_go_down_to_selector(codec, pin);
18887 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18888 if (num < 2)
18889 return 0;
18890 for (i = 0; i < num; i++) {
18891 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18892 snd_hda_codec_update_cache(codec, pin, 0,
18893 AC_VERB_SET_CONNECT_SEL, i);
18894 return 0;
18895 }
18896 }
18897 return 0;
18898}
18899
7085ec12 18900/* look for an empty DAC slot */
604401a9 18901static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
7085ec12
TI
18902{
18903 struct alc_spec *spec = codec->spec;
18904 hda_nid_t srcs[5];
18905 int i, j, num;
18906
604401a9 18907 pin = alc_go_down_to_selector(codec, pin);
7085ec12 18908 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
7085ec12 18909 for (i = 0; i < num; i++) {
604401a9 18910 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
7085ec12
TI
18911 if (!nid)
18912 continue;
18913 for (j = 0; j < spec->multiout.num_dacs; j++)
18914 if (spec->multiout.dac_nids[j] == nid)
18915 break;
18916 if (j >= spec->multiout.num_dacs)
18917 return nid;
18918 }
18919 return 0;
18920}
18921
18922/* fill in the dac_nids table from the parsed pin configuration */
18923static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18924 const struct auto_pin_cfg *cfg)
18925{
18926 struct alc_spec *spec = codec->spec;
18927 int i;
18928 hda_nid_t dac;
18929
18930 spec->multiout.dac_nids = spec->private_dac_nids;
18931 for (i = 0; i < cfg->line_outs; i++) {
604401a9 18932 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
7085ec12
TI
18933 if (!dac)
18934 continue;
dda14410 18935 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
7085ec12
TI
18936 }
18937 return 0;
18938}
18939
bcb2f0f5
TI
18940static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18941 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18942{
bcb2f0f5 18943 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
7085ec12
TI
18944 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18945}
18946
bcb2f0f5
TI
18947static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
18948 hda_nid_t nid, int idx, unsigned int chs)
7085ec12 18949{
bcb2f0f5 18950 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
7085ec12
TI
18951 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
18952}
18953
bcb2f0f5
TI
18954#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
18955 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
18956#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
18957 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
7085ec12
TI
18958#define alc662_add_stereo_vol(spec, pfx, nid) \
18959 alc662_add_vol_ctl(spec, pfx, nid, 3)
18960#define alc662_add_stereo_sw(spec, pfx, nid) \
18961 alc662_add_sw_ctl(spec, pfx, nid, 3)
18962
bc9f98a9 18963/* add playback controls from the parsed DAC table */
7085ec12 18964static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
bc9f98a9
KY
18965 const struct auto_pin_cfg *cfg)
18966{
7085ec12 18967 struct alc_spec *spec = codec->spec;
ea734963 18968 static const char * const chname[4] = {
bc9f98a9
KY
18969 "Front", "Surround", NULL /*CLFE*/, "Side"
18970 };
ce764ab2
TI
18971 const char *pfx = alc_get_line_out_pfx(spec, true);
18972 hda_nid_t nid, mix, pin;
18973 int i, err, noutputs;
bc9f98a9 18974
ce764ab2
TI
18975 noutputs = cfg->line_outs;
18976 if (spec->multi_ios > 0)
18977 noutputs += spec->multi_ios;
18978
18979 for (i = 0; i < noutputs; i++) {
7085ec12
TI
18980 nid = spec->multiout.dac_nids[i];
18981 if (!nid)
18982 continue;
ce764ab2
TI
18983 if (i >= cfg->line_outs)
18984 pin = spec->multi_io[i - 1].pin;
18985 else
18986 pin = cfg->line_out_pins[i];
18987 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12 18988 if (!mix)
bc9f98a9 18989 continue;
bcb2f0f5 18990 if (!pfx && i == 2) {
bc9f98a9 18991 /* Center/LFE */
7085ec12 18992 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
bc9f98a9
KY
18993 if (err < 0)
18994 return err;
7085ec12 18995 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
bc9f98a9
KY
18996 if (err < 0)
18997 return err;
7085ec12 18998 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
bc9f98a9
KY
18999 if (err < 0)
19000 return err;
7085ec12 19001 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
bc9f98a9
KY
19002 if (err < 0)
19003 return err;
19004 } else {
bcb2f0f5 19005 const char *name = pfx;
5a882646
DH
19006 int index = i;
19007 if (!name) {
bcb2f0f5 19008 name = chname[i];
5a882646
DH
19009 index = 0;
19010 }
19011 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
bc9f98a9
KY
19012 if (err < 0)
19013 return err;
5a882646 19014 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
bc9f98a9
KY
19015 if (err < 0)
19016 return err;
19017 }
19018 }
19019 return 0;
19020}
19021
19022/* add playback controls for speaker and HP outputs */
7085ec12
TI
19023/* return DAC nid if any new DAC is assigned */
19024static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
bc9f98a9
KY
19025 const char *pfx)
19026{
7085ec12
TI
19027 struct alc_spec *spec = codec->spec;
19028 hda_nid_t nid, mix;
bc9f98a9 19029 int err;
bc9f98a9
KY
19030
19031 if (!pin)
19032 return 0;
604401a9 19033 nid = alc_auto_look_for_dac(codec, pin);
7085ec12 19034 if (!nid) {
7085ec12
TI
19035 /* the corresponding DAC is already occupied */
19036 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19037 return 0; /* no way */
19038 /* create a switch only */
0afe5f89 19039 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
7085ec12 19040 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
24fb9173
TI
19041 }
19042
604401a9 19043 mix = alc_auto_dac_to_mix(codec, pin, nid);
7085ec12
TI
19044 if (!mix)
19045 return 0;
19046 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19047 if (err < 0)
19048 return err;
19049 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19050 if (err < 0)
19051 return err;
19052 return nid;
bc9f98a9
KY
19053}
19054
19055/* create playback/capture controls for input pins */
05f5f477 19056#define alc662_auto_create_input_ctls \
4b7348a1 19057 alc882_auto_create_input_ctls
bc9f98a9
KY
19058
19059static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19060 hda_nid_t nid, int pin_type,
7085ec12 19061 hda_nid_t dac)
bc9f98a9 19062{
7085ec12 19063 int i, num;
ce503f38 19064 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
7085ec12 19065
f6c7e546 19066 alc_set_pin_output(codec, nid, pin_type);
7085ec12 19067 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
7085ec12 19068 for (i = 0; i < num; i++) {
604401a9 19069 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
7085ec12 19070 continue;
0e53f344
TI
19071 /* need the manual connection? */
19072 if (num > 1)
19073 snd_hda_codec_write(codec, nid, 0,
19074 AC_VERB_SET_CONNECT_SEL, i);
19075 /* unmute mixer widget inputs */
19076 snd_hda_codec_write(codec, srcs[i], 0,
19077 AC_VERB_SET_AMP_GAIN_MUTE,
19078 AMP_IN_UNMUTE(0));
19079 snd_hda_codec_write(codec, srcs[i], 0,
19080 AC_VERB_SET_AMP_GAIN_MUTE,
19081 AMP_IN_UNMUTE(1));
7085ec12 19082 return;
bc9f98a9
KY
19083 }
19084}
19085
19086static void alc662_auto_init_multi_out(struct hda_codec *codec)
19087{
19088 struct alc_spec *spec = codec->spec;
7085ec12 19089 int pin_type = get_pin_type(spec->autocfg.line_out_type);
bc9f98a9
KY
19090 int i;
19091
19092 for (i = 0; i <= HDA_SIDE; i++) {
19093 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19094 if (nid)
baba8ee9 19095 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
7085ec12 19096 spec->multiout.dac_nids[i]);
bc9f98a9
KY
19097 }
19098}
19099
19100static void alc662_auto_init_hp_out(struct hda_codec *codec)
19101{
19102 struct alc_spec *spec = codec->spec;
19103 hda_nid_t pin;
19104
19105 pin = spec->autocfg.hp_pins[0];
7085ec12
TI
19106 if (pin)
19107 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19108 spec->multiout.hp_nid);
f6c7e546
TI
19109 pin = spec->autocfg.speaker_pins[0];
19110 if (pin)
7085ec12
TI
19111 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19112 spec->multiout.extra_out_nid[0]);
bc9f98a9
KY
19113}
19114
bc9f98a9
KY
19115#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19116
19117static void alc662_auto_init_analog_input(struct hda_codec *codec)
19118{
19119 struct alc_spec *spec = codec->spec;
66ceeb6b 19120 struct auto_pin_cfg *cfg = &spec->autocfg;
bc9f98a9
KY
19121 int i;
19122
66ceeb6b
TI
19123 for (i = 0; i < cfg->num_inputs; i++) {
19124 hda_nid_t nid = cfg->inputs[i].pin;
05f5f477 19125 if (alc_is_input_pin(codec, nid)) {
30ea098f 19126 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
52ca15b7 19127 if (nid != ALC662_PIN_CD_NID &&
e82c025b 19128 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
bc9f98a9
KY
19129 snd_hda_codec_write(codec, nid, 0,
19130 AC_VERB_SET_AMP_GAIN_MUTE,
19131 AMP_OUT_MUTE);
19132 }
19133 }
19134}
19135
f511b01c
TI
19136#define alc662_auto_init_input_src alc882_auto_init_input_src
19137
ce764ab2
TI
19138/*
19139 * multi-io helper
19140 */
19141static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19142 unsigned int location)
19143{
19144 struct alc_spec *spec = codec->spec;
19145 struct auto_pin_cfg *cfg = &spec->autocfg;
19146 int type, i, num_pins = 0;
19147
19148 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19149 for (i = 0; i < cfg->num_inputs; i++) {
19150 hda_nid_t nid = cfg->inputs[i].pin;
19151 hda_nid_t dac;
19152 unsigned int defcfg, caps;
19153 if (cfg->inputs[i].type != type)
19154 continue;
19155 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19156 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19157 continue;
19158 if (location && get_defcfg_location(defcfg) != location)
19159 continue;
19160 caps = snd_hda_query_pin_caps(codec, nid);
19161 if (!(caps & AC_PINCAP_OUT))
19162 continue;
19163 dac = alc_auto_look_for_dac(codec, nid);
19164 if (!dac)
19165 continue;
19166 spec->multi_io[num_pins].pin = nid;
19167 spec->multi_io[num_pins].dac = dac;
19168 num_pins++;
dda14410 19169 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
ce764ab2
TI
19170 }
19171 }
19172 spec->multiout.num_dacs = 1;
19173 if (num_pins < 2)
19174 return 0;
19175 return num_pins;
19176}
19177
19178static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19179 struct snd_ctl_elem_info *uinfo)
19180{
19181 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19182 struct alc_spec *spec = codec->spec;
19183
19184 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19185 uinfo->count = 1;
19186 uinfo->value.enumerated.items = spec->multi_ios + 1;
19187 if (uinfo->value.enumerated.item > spec->multi_ios)
19188 uinfo->value.enumerated.item = spec->multi_ios;
19189 sprintf(uinfo->value.enumerated.name, "%dch",
19190 (uinfo->value.enumerated.item + 1) * 2);
19191 return 0;
19192}
19193
19194static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19195 struct snd_ctl_elem_value *ucontrol)
19196{
19197 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19198 struct alc_spec *spec = codec->spec;
19199 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19200 return 0;
19201}
19202
19203static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19204{
19205 struct alc_spec *spec = codec->spec;
19206 hda_nid_t nid = spec->multi_io[idx].pin;
19207
19208 if (!spec->multi_io[idx].ctl_in)
19209 spec->multi_io[idx].ctl_in =
19210 snd_hda_codec_read(codec, nid, 0,
19211 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19212 if (output) {
19213 snd_hda_codec_update_cache(codec, nid, 0,
19214 AC_VERB_SET_PIN_WIDGET_CONTROL,
19215 PIN_OUT);
19216 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19217 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19218 HDA_AMP_MUTE, 0);
19219 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19220 } else {
19221 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19222 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19223 HDA_AMP_MUTE, HDA_AMP_MUTE);
19224 snd_hda_codec_update_cache(codec, nid, 0,
19225 AC_VERB_SET_PIN_WIDGET_CONTROL,
19226 spec->multi_io[idx].ctl_in);
19227 }
19228 return 0;
19229}
19230
19231static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19232 struct snd_ctl_elem_value *ucontrol)
19233{
19234 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19235 struct alc_spec *spec = codec->spec;
19236 int i, ch;
19237
19238 ch = ucontrol->value.enumerated.item[0];
19239 if (ch < 0 || ch > spec->multi_ios)
19240 return -EINVAL;
19241 if (ch == (spec->ext_channel_count - 1) / 2)
19242 return 0;
19243 spec->ext_channel_count = (ch + 1) * 2;
19244 for (i = 0; i < spec->multi_ios; i++)
19245 alc_set_multi_io(codec, i, i < ch);
19246 spec->multiout.max_channels = spec->ext_channel_count;
19247 return 1;
19248}
19249
a9111321 19250static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
ce764ab2
TI
19251 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19252 .name = "Channel Mode",
19253 .info = alc_auto_ch_mode_info,
19254 .get = alc_auto_ch_mode_get,
19255 .put = alc_auto_ch_mode_put,
19256};
19257
19258static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19259{
19260 struct alc_spec *spec = codec->spec;
19261 struct auto_pin_cfg *cfg = &spec->autocfg;
19262 unsigned int location, defcfg;
19263 int num_pins;
19264
19265 if (cfg->line_outs != 1 ||
19266 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19267 return 0;
19268
19269 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19270 location = get_defcfg_location(defcfg);
19271
19272 num_pins = alc_auto_fill_multi_ios(codec, location);
19273 if (num_pins > 0) {
19274 struct snd_kcontrol_new *knew;
19275
19276 knew = alc_kcontrol_new(spec);
19277 if (!knew)
19278 return -ENOMEM;
19279 *knew = alc_auto_channel_mode_enum;
19280 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19281 if (!knew->name)
19282 return -ENOMEM;
19283
19284 spec->multi_ios = num_pins;
19285 spec->ext_channel_count = 2;
19286 spec->multiout.num_dacs = num_pins + 1;
19287 }
19288 return 0;
19289}
19290
bc9f98a9
KY
19291static int alc662_parse_auto_config(struct hda_codec *codec)
19292{
19293 struct alc_spec *spec = codec->spec;
19294 int err;
4c6d72d1 19295 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
bc9f98a9
KY
19296
19297 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19298 alc662_ignore);
19299 if (err < 0)
19300 return err;
19301 if (!spec->autocfg.line_outs)
19302 return 0; /* can't find valid BIOS pin config */
19303
7085ec12 19304 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
ce764ab2
TI
19305 if (err < 0)
19306 return err;
19307 err = alc_auto_add_multi_channel_mode(codec);
f12ab1e0
TI
19308 if (err < 0)
19309 return err;
7085ec12 19310 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
f12ab1e0
TI
19311 if (err < 0)
19312 return err;
7085ec12 19313 err = alc662_auto_create_extra_out(codec,
f12ab1e0
TI
19314 spec->autocfg.speaker_pins[0],
19315 "Speaker");
19316 if (err < 0)
19317 return err;
7085ec12
TI
19318 if (err)
19319 spec->multiout.extra_out_nid[0] = err;
19320 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
f12ab1e0
TI
19321 "Headphone");
19322 if (err < 0)
19323 return err;
7085ec12
TI
19324 if (err)
19325 spec->multiout.hp_nid = err;
05f5f477 19326 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
f12ab1e0 19327 if (err < 0)
bc9f98a9
KY
19328 return err;
19329
19330 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19331
757899ac 19332 alc_auto_parse_digital(codec);
bc9f98a9 19333
603c4019 19334 if (spec->kctls.list)
d88897ea 19335 add_mixer(spec, spec->kctls.list);
bc9f98a9
KY
19336
19337 spec->num_mux_defs = 1;
61b9b9b1 19338 spec->input_mux = &spec->private_imux[0];
ea1fb29a 19339
ee979a14
TI
19340 err = alc_auto_add_mic_boost(codec);
19341 if (err < 0)
19342 return err;
19343
6227cdce
KY
19344 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19345 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19346 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19347 else
19348 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4a79ba34 19349
8c87286f 19350 return 1;
bc9f98a9
KY
19351}
19352
19353/* additional initialization for auto-configuration model */
19354static void alc662_auto_init(struct hda_codec *codec)
19355{
f6c7e546 19356 struct alc_spec *spec = codec->spec;
bc9f98a9
KY
19357 alc662_auto_init_multi_out(codec);
19358 alc662_auto_init_hp_out(codec);
19359 alc662_auto_init_analog_input(codec);
f511b01c 19360 alc662_auto_init_input_src(codec);
757899ac 19361 alc_auto_init_digital(codec);
f6c7e546 19362 if (spec->unsol_event)
7fb0d78f 19363 alc_inithook(codec);
bc9f98a9
KY
19364}
19365
6be7948f 19366static void alc272_fixup_mario(struct hda_codec *codec,
b5bfbc67 19367 const struct alc_fixup *fix, int action)
6fc398cb 19368{
b5bfbc67 19369 if (action != ALC_FIXUP_ACT_PROBE)
6fc398cb 19370 return;
6be7948f
TB
19371 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19372 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19373 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19374 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19375 (0 << AC_AMPCAP_MUTE_SHIFT)))
19376 printk(KERN_WARNING
19377 "hda_codec: failed to override amp caps for NID 0x2\n");
19378}
19379
6cb3b707 19380enum {
2df03514 19381 ALC662_FIXUP_ASPIRE,
6cb3b707 19382 ALC662_FIXUP_IDEAPAD,
6be7948f 19383 ALC272_FIXUP_MARIO,
d2ebd479 19384 ALC662_FIXUP_CZC_P10T,
94024cd1 19385 ALC662_FIXUP_SKU_IGNORE,
6cb3b707
DH
19386};
19387
19388static const struct alc_fixup alc662_fixups[] = {
2df03514 19389 [ALC662_FIXUP_ASPIRE] = {
b5bfbc67
TI
19390 .type = ALC_FIXUP_PINS,
19391 .v.pins = (const struct alc_pincfg[]) {
2df03514
DC
19392 { 0x15, 0x99130112 }, /* subwoofer */
19393 { }
19394 }
19395 },
6cb3b707 19396 [ALC662_FIXUP_IDEAPAD] = {
b5bfbc67
TI
19397 .type = ALC_FIXUP_PINS,
19398 .v.pins = (const struct alc_pincfg[]) {
6cb3b707
DH
19399 { 0x17, 0x99130112 }, /* subwoofer */
19400 { }
19401 }
19402 },
6be7948f 19403 [ALC272_FIXUP_MARIO] = {
b5bfbc67
TI
19404 .type = ALC_FIXUP_FUNC,
19405 .v.func = alc272_fixup_mario,
d2ebd479
AA
19406 },
19407 [ALC662_FIXUP_CZC_P10T] = {
19408 .type = ALC_FIXUP_VERBS,
19409 .v.verbs = (const struct hda_verb[]) {
19410 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19411 {}
19412 }
19413 },
94024cd1
DH
19414 [ALC662_FIXUP_SKU_IGNORE] = {
19415 .type = ALC_FIXUP_SKU,
19416 .v.sku = ALC_FIXUP_SKU_IGNORE,
c6b35874 19417 },
6cb3b707
DH
19418};
19419
a9111321 19420static const struct snd_pci_quirk alc662_fixup_tbl[] = {
a6c47a85 19421 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
94024cd1 19422 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
2df03514 19423 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
a0e90acc 19424 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
d4118588 19425 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
6cb3b707 19426 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
d2ebd479 19427 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
6cb3b707
DH
19428 {}
19429};
19430
6be7948f
TB
19431static const struct alc_model_fixup alc662_fixup_models[] = {
19432 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19433 {}
19434};
6cb3b707
DH
19435
19436
bc9f98a9
KY
19437static int patch_alc662(struct hda_codec *codec)
19438{
19439 struct alc_spec *spec;
19440 int err, board_config;
693194f3 19441 int coef;
bc9f98a9
KY
19442
19443 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19444 if (!spec)
19445 return -ENOMEM;
19446
19447 codec->spec = spec;
19448
da00c244
KY
19449 alc_auto_parse_customize_define(codec);
19450
2c3bf9ab
TI
19451 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19452
693194f3
KY
19453 coef = alc_read_coef_idx(codec, 0);
19454 if (coef == 0x8020 || coef == 0x8011)
c027ddcd 19455 alc_codec_rename(codec, "ALC661");
693194f3
KY
19456 else if (coef & (1 << 14) &&
19457 codec->bus->pci->subsystem_vendor == 0x1025 &&
19458 spec->cdefine.platform_type == 1)
c027ddcd 19459 alc_codec_rename(codec, "ALC272X");
693194f3
KY
19460 else if (coef == 0x4011)
19461 alc_codec_rename(codec, "ALC656");
274693f3 19462
bc9f98a9
KY
19463 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19464 alc662_models,
19465 alc662_cfg_tbl);
19466 if (board_config < 0) {
9a11f1aa
TI
19467 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19468 codec->chip_name);
bc9f98a9
KY
19469 board_config = ALC662_AUTO;
19470 }
19471
19472 if (board_config == ALC662_AUTO) {
b5bfbc67
TI
19473 alc_pick_fixup(codec, alc662_fixup_models,
19474 alc662_fixup_tbl, alc662_fixups);
19475 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
bc9f98a9
KY
19476 /* automatic parse from the BIOS config */
19477 err = alc662_parse_auto_config(codec);
19478 if (err < 0) {
19479 alc_free(codec);
19480 return err;
8c87286f 19481 } else if (!err) {
bc9f98a9
KY
19482 printk(KERN_INFO
19483 "hda_codec: Cannot set up configuration "
19484 "from BIOS. Using base mode...\n");
19485 board_config = ALC662_3ST_2ch_DIG;
19486 }
19487 }
19488
dc1eae25 19489 if (has_cdefine_beep(codec)) {
8af2591d
TI
19490 err = snd_hda_attach_beep_device(codec, 0x1);
19491 if (err < 0) {
19492 alc_free(codec);
19493 return err;
19494 }
680cd536
KK
19495 }
19496
bc9f98a9 19497 if (board_config != ALC662_AUTO)
e9c364c0 19498 setup_preset(codec, &alc662_presets[board_config]);
bc9f98a9 19499
bc9f98a9
KY
19500 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19501 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19502
bc9f98a9
KY
19503 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19504 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19505
dd704698
TI
19506 if (!spec->adc_nids) {
19507 spec->adc_nids = alc662_adc_nids;
19508 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19509 }
19510 if (!spec->capsrc_nids)
19511 spec->capsrc_nids = alc662_capsrc_nids;
bc9f98a9 19512
f9e336f6 19513 if (!spec->cap_mixer)
b59bdf3b 19514 set_capture_mixer(codec);
cec27c89 19515
dc1eae25 19516 if (has_cdefine_beep(codec)) {
da00c244
KY
19517 switch (codec->vendor_id) {
19518 case 0x10ec0662:
19519 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19520 break;
19521 case 0x10ec0272:
19522 case 0x10ec0663:
19523 case 0x10ec0665:
19524 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19525 break;
19526 case 0x10ec0273:
19527 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19528 break;
19529 }
cec27c89 19530 }
2134ea4f
TI
19531 spec->vmaster_nid = 0x02;
19532
b5bfbc67
TI
19533 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19534
bc9f98a9 19535 codec->patch_ops = alc_patch_ops;
b5bfbc67 19536 if (board_config == ALC662_AUTO)
bc9f98a9 19537 spec->init_hook = alc662_auto_init;
1c716153 19538 spec->shutup = alc_eapd_shutup;
6cb3b707 19539
bf1b0225
KY
19540 alc_init_jacks(codec);
19541
cb53c626
TI
19542#ifdef CONFIG_SND_HDA_POWER_SAVE
19543 if (!spec->loopback.amplist)
19544 spec->loopback.amplist = alc662_loopbacks;
19545#endif
bc9f98a9
KY
19546
19547 return 0;
19548}
19549
274693f3
KY
19550static int patch_alc888(struct hda_codec *codec)
19551{
19552 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19553 kfree(codec->chip_name);
01e0f137
KY
19554 if (codec->vendor_id == 0x10ec0887)
19555 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19556 else
19557 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
ac2c92e0
TI
19558 if (!codec->chip_name) {
19559 alc_free(codec);
274693f3 19560 return -ENOMEM;
ac2c92e0
TI
19561 }
19562 return patch_alc662(codec);
274693f3 19563 }
ac2c92e0 19564 return patch_alc882(codec);
274693f3
KY
19565}
19566
d1eb57f4
KY
19567/*
19568 * ALC680 support
19569 */
c69aefab 19570#define ALC680_DIGIN_NID ALC880_DIGIN_NID
d1eb57f4
KY
19571#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19572#define alc680_modes alc260_modes
19573
4c6d72d1 19574static const hda_nid_t alc680_dac_nids[3] = {
d1eb57f4
KY
19575 /* Lout1, Lout2, hp */
19576 0x02, 0x03, 0x04
19577};
19578
4c6d72d1 19579static const hda_nid_t alc680_adc_nids[3] = {
d1eb57f4
KY
19580 /* ADC0-2 */
19581 /* DMIC, MIC, Line-in*/
19582 0x07, 0x08, 0x09
19583};
19584
c69aefab
KY
19585/*
19586 * Analog capture ADC cgange
19587 */
66ceeb6b
TI
19588static void alc680_rec_autoswitch(struct hda_codec *codec)
19589{
19590 struct alc_spec *spec = codec->spec;
19591 struct auto_pin_cfg *cfg = &spec->autocfg;
19592 int pin_found = 0;
19593 int type_found = AUTO_PIN_LAST;
19594 hda_nid_t nid;
19595 int i;
19596
19597 for (i = 0; i < cfg->num_inputs; i++) {
19598 nid = cfg->inputs[i].pin;
19599 if (!(snd_hda_query_pin_caps(codec, nid) &
19600 AC_PINCAP_PRES_DETECT))
19601 continue;
19602 if (snd_hda_jack_detect(codec, nid)) {
19603 if (cfg->inputs[i].type < type_found) {
19604 type_found = cfg->inputs[i].type;
19605 pin_found = nid;
19606 }
19607 }
19608 }
19609
19610 nid = 0x07;
19611 if (pin_found)
19612 snd_hda_get_connections(codec, pin_found, &nid, 1);
19613
19614 if (nid != spec->cur_adc)
19615 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19616 spec->cur_adc = nid;
19617 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19618 spec->cur_adc_format);
19619}
19620
c69aefab
KY
19621static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19622 struct hda_codec *codec,
19623 unsigned int stream_tag,
19624 unsigned int format,
19625 struct snd_pcm_substream *substream)
19626{
19627 struct alc_spec *spec = codec->spec;
c69aefab 19628
66ceeb6b 19629 spec->cur_adc = 0x07;
c69aefab
KY
19630 spec->cur_adc_stream_tag = stream_tag;
19631 spec->cur_adc_format = format;
19632
66ceeb6b 19633 alc680_rec_autoswitch(codec);
c69aefab
KY
19634 return 0;
19635}
19636
19637static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19638 struct hda_codec *codec,
19639 struct snd_pcm_substream *substream)
19640{
19641 snd_hda_codec_cleanup_stream(codec, 0x07);
19642 snd_hda_codec_cleanup_stream(codec, 0x08);
19643 snd_hda_codec_cleanup_stream(codec, 0x09);
19644 return 0;
19645}
19646
a9111321 19647static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
c69aefab
KY
19648 .substreams = 1, /* can be overridden */
19649 .channels_min = 2,
19650 .channels_max = 2,
19651 /* NID is set in alc_build_pcms */
19652 .ops = {
19653 .prepare = alc680_capture_pcm_prepare,
19654 .cleanup = alc680_capture_pcm_cleanup
19655 },
19656};
19657
a9111321 19658static const struct snd_kcontrol_new alc680_base_mixer[] = {
d1eb57f4
KY
19659 /* output mixer control */
19660 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19661 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19662 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19663 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5f99f86a
DH
19664 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19665 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19666 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
d1eb57f4
KY
19667 { }
19668};
19669
a9111321 19670static const struct hda_bind_ctls alc680_bind_cap_vol = {
c69aefab
KY
19671 .ops = &snd_hda_bind_vol,
19672 .values = {
19673 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19674 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19675 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19676 0
19677 },
19678};
19679
a9111321 19680static const struct hda_bind_ctls alc680_bind_cap_switch = {
c69aefab
KY
19681 .ops = &snd_hda_bind_sw,
19682 .values = {
19683 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19684 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19685 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19686 0
19687 },
19688};
19689
a9111321 19690static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
c69aefab
KY
19691 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19692 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
d1eb57f4
KY
19693 { } /* end */
19694};
19695
19696/*
19697 * generic initialization of ADC, input mixers and output mixers
19698 */
a9111321 19699static const struct hda_verb alc680_init_verbs[] = {
c69aefab
KY
19700 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19701 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19702 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
d1eb57f4 19703
c69aefab
KY
19704 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19705 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19706 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19707 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19708 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19709 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
d1eb57f4
KY
19710
19711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19712 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19713 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19714 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19715 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
c69aefab
KY
19716
19717 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19718 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
66ceeb6b 19719 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
c69aefab 19720
d1eb57f4
KY
19721 { }
19722};
19723
c69aefab
KY
19724/* toggle speaker-output according to the hp-jack state */
19725static void alc680_base_setup(struct hda_codec *codec)
19726{
19727 struct alc_spec *spec = codec->spec;
19728
19729 spec->autocfg.hp_pins[0] = 0x16;
19730 spec->autocfg.speaker_pins[0] = 0x14;
19731 spec->autocfg.speaker_pins[1] = 0x15;
66ceeb6b
TI
19732 spec->autocfg.num_inputs = 2;
19733 spec->autocfg.inputs[0].pin = 0x18;
19734 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19735 spec->autocfg.inputs[1].pin = 0x19;
86e2959a 19736 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
d922b51d
TI
19737 spec->automute = 1;
19738 spec->automute_mode = ALC_AUTOMUTE_AMP;
c69aefab
KY
19739}
19740
19741static void alc680_unsol_event(struct hda_codec *codec,
19742 unsigned int res)
19743{
19744 if ((res >> 26) == ALC880_HP_EVENT)
d922b51d 19745 alc_hp_automute(codec);
c69aefab
KY
19746 if ((res >> 26) == ALC880_MIC_EVENT)
19747 alc680_rec_autoswitch(codec);
19748}
19749
19750static void alc680_inithook(struct hda_codec *codec)
19751{
d922b51d 19752 alc_hp_automute(codec);
c69aefab
KY
19753 alc680_rec_autoswitch(codec);
19754}
19755
d1eb57f4
KY
19756/* create input playback/capture controls for the given pin */
19757static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19758 const char *ctlname, int idx)
19759{
19760 hda_nid_t dac;
19761 int err;
19762
19763 switch (nid) {
19764 case 0x14:
19765 dac = 0x02;
19766 break;
19767 case 0x15:
19768 dac = 0x03;
19769 break;
19770 case 0x16:
19771 dac = 0x04;
19772 break;
19773 default:
19774 return 0;
19775 }
19776 if (spec->multiout.dac_nids[0] != dac &&
19777 spec->multiout.dac_nids[1] != dac) {
19778 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19779 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19780 HDA_OUTPUT));
19781 if (err < 0)
19782 return err;
19783
19784 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19785 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19786
19787 if (err < 0)
19788 return err;
dda14410 19789 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
d1eb57f4
KY
19790 }
19791
19792 return 0;
19793}
19794
19795/* add playback controls from the parsed DAC table */
19796static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19797 const struct auto_pin_cfg *cfg)
19798{
19799 hda_nid_t nid;
19800 int err;
19801
19802 spec->multiout.dac_nids = spec->private_dac_nids;
19803
19804 nid = cfg->line_out_pins[0];
19805 if (nid) {
19806 const char *name;
19807 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19808 name = "Speaker";
19809 else
19810 name = "Front";
19811 err = alc680_new_analog_output(spec, nid, name, 0);
19812 if (err < 0)
19813 return err;
19814 }
19815
19816 nid = cfg->speaker_pins[0];
19817 if (nid) {
19818 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19819 if (err < 0)
19820 return err;
19821 }
19822 nid = cfg->hp_pins[0];
19823 if (nid) {
19824 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19825 if (err < 0)
19826 return err;
19827 }
19828
19829 return 0;
19830}
19831
19832static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19833 hda_nid_t nid, int pin_type)
19834{
19835 alc_set_pin_output(codec, nid, pin_type);
19836}
19837
19838static void alc680_auto_init_multi_out(struct hda_codec *codec)
19839{
19840 struct alc_spec *spec = codec->spec;
19841 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19842 if (nid) {
19843 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19844 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19845 }
19846}
19847
19848static void alc680_auto_init_hp_out(struct hda_codec *codec)
19849{
19850 struct alc_spec *spec = codec->spec;
19851 hda_nid_t pin;
19852
19853 pin = spec->autocfg.hp_pins[0];
19854 if (pin)
19855 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19856 pin = spec->autocfg.speaker_pins[0];
19857 if (pin)
19858 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19859}
19860
19861/* pcm configuration: identical with ALC880 */
19862#define alc680_pcm_analog_playback alc880_pcm_analog_playback
19863#define alc680_pcm_analog_capture alc880_pcm_analog_capture
19864#define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19865#define alc680_pcm_digital_playback alc880_pcm_digital_playback
c69aefab 19866#define alc680_pcm_digital_capture alc880_pcm_digital_capture
d1eb57f4
KY
19867
19868/*
19869 * BIOS auto configuration
19870 */
19871static int alc680_parse_auto_config(struct hda_codec *codec)
19872{
19873 struct alc_spec *spec = codec->spec;
19874 int err;
4c6d72d1 19875 static const hda_nid_t alc680_ignore[] = { 0 };
d1eb57f4
KY
19876
19877 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19878 alc680_ignore);
19879 if (err < 0)
19880 return err;
c69aefab 19881
d1eb57f4
KY
19882 if (!spec->autocfg.line_outs) {
19883 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19884 spec->multiout.max_channels = 2;
19885 spec->no_analog = 1;
19886 goto dig_only;
19887 }
19888 return 0; /* can't find valid BIOS pin config */
19889 }
19890 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19891 if (err < 0)
19892 return err;
19893
19894 spec->multiout.max_channels = 2;
19895
19896 dig_only:
19897 /* digital only support output */
757899ac 19898 alc_auto_parse_digital(codec);
d1eb57f4
KY
19899 if (spec->kctls.list)
19900 add_mixer(spec, spec->kctls.list);
19901
19902 add_verb(spec, alc680_init_verbs);
d1eb57f4
KY
19903
19904 err = alc_auto_add_mic_boost(codec);
19905 if (err < 0)
19906 return err;
19907
19908 return 1;
19909}
19910
19911#define alc680_auto_init_analog_input alc882_auto_init_analog_input
19912
19913/* init callback for auto-configuration model -- overriding the default init */
19914static void alc680_auto_init(struct hda_codec *codec)
19915{
19916 struct alc_spec *spec = codec->spec;
19917 alc680_auto_init_multi_out(codec);
19918 alc680_auto_init_hp_out(codec);
19919 alc680_auto_init_analog_input(codec);
757899ac 19920 alc_auto_init_digital(codec);
d1eb57f4
KY
19921 if (spec->unsol_event)
19922 alc_inithook(codec);
19923}
19924
19925/*
19926 * configuration and preset
19927 */
ea734963 19928static const char * const alc680_models[ALC680_MODEL_LAST] = {
d4a86d81
TI
19929 [ALC680_BASE] = "base",
19930 [ALC680_AUTO] = "auto",
d1eb57f4
KY
19931};
19932
a9111321 19933static const struct snd_pci_quirk alc680_cfg_tbl[] = {
d1eb57f4
KY
19934 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19935 {}
19936};
19937
a9111321 19938static const struct alc_config_preset alc680_presets[] = {
d1eb57f4
KY
19939 [ALC680_BASE] = {
19940 .mixers = { alc680_base_mixer },
c69aefab 19941 .cap_mixer = alc680_master_capture_mixer,
d1eb57f4
KY
19942 .init_verbs = { alc680_init_verbs },
19943 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19944 .dac_nids = alc680_dac_nids,
d1eb57f4
KY
19945 .dig_out_nid = ALC680_DIGOUT_NID,
19946 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19947 .channel_mode = alc680_modes,
c69aefab
KY
19948 .unsol_event = alc680_unsol_event,
19949 .setup = alc680_base_setup,
19950 .init_hook = alc680_inithook,
19951
d1eb57f4
KY
19952 },
19953};
19954
19955static int patch_alc680(struct hda_codec *codec)
19956{
19957 struct alc_spec *spec;
19958 int board_config;
19959 int err;
19960
19961 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19962 if (spec == NULL)
19963 return -ENOMEM;
19964
19965 codec->spec = spec;
19966
19967 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
19968 alc680_models,
19969 alc680_cfg_tbl);
19970
19971 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
19972 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19973 codec->chip_name);
19974 board_config = ALC680_AUTO;
19975 }
19976
19977 if (board_config == ALC680_AUTO) {
19978 /* automatic parse from the BIOS config */
19979 err = alc680_parse_auto_config(codec);
19980 if (err < 0) {
19981 alc_free(codec);
19982 return err;
19983 } else if (!err) {
19984 printk(KERN_INFO
19985 "hda_codec: Cannot set up configuration "
19986 "from BIOS. Using base mode...\n");
19987 board_config = ALC680_BASE;
19988 }
19989 }
19990
19991 if (board_config != ALC680_AUTO)
19992 setup_preset(codec, &alc680_presets[board_config]);
19993
19994 spec->stream_analog_playback = &alc680_pcm_analog_playback;
c69aefab 19995 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
d1eb57f4 19996 spec->stream_digital_playback = &alc680_pcm_digital_playback;
c69aefab 19997 spec->stream_digital_capture = &alc680_pcm_digital_capture;
d1eb57f4
KY
19998
19999 if (!spec->adc_nids) {
20000 spec->adc_nids = alc680_adc_nids;
20001 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20002 }
20003
20004 if (!spec->cap_mixer)
20005 set_capture_mixer(codec);
20006
20007 spec->vmaster_nid = 0x02;
20008
20009 codec->patch_ops = alc_patch_ops;
20010 if (board_config == ALC680_AUTO)
20011 spec->init_hook = alc680_auto_init;
20012
20013 return 0;
20014}
20015
1da177e4
LT
20016/*
20017 * patch entries
20018 */
a9111321 20019static const struct hda_codec_preset snd_hda_preset_realtek[] = {
1da177e4 20020 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
df694daa 20021 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
f6a92248 20022 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
a361d84b 20023 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
f6a92248 20024 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
ebb83eeb 20025 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
01afd41f 20026 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
ebb83eeb 20027 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
f32610ed 20028 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
bc9f98a9 20029 .patch = patch_alc861 },
f32610ed
JS
20030 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20031 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20032 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
bc9f98a9 20033 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
4953550a 20034 .patch = patch_alc882 },
bc9f98a9
KY
20035 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20036 .patch = patch_alc662 },
6dda9f4a 20037 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
cec27c89 20038 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
6227cdce 20039 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
d1eb57f4 20040 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
f32610ed 20041 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
1da177e4 20042 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
4953550a 20043 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
669faba2 20044 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
4953550a 20045 .patch = patch_alc882 },
cb308f97 20046 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
4953550a 20047 .patch = patch_alc882 },
df694daa 20048 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
01e0f137 20049 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
4442608d 20050 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
4953550a 20051 .patch = patch_alc882 },
274693f3 20052 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
4953550a 20053 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
274693f3 20054 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
1da177e4
LT
20055 {} /* terminator */
20056};
1289e9e8
TI
20057
20058MODULE_ALIAS("snd-hda-codec-id:10ec*");
20059
20060MODULE_LICENSE("GPL");
20061MODULE_DESCRIPTION("Realtek HD-audio codec");
20062
20063static struct hda_codec_preset_list realtek_list = {
20064 .preset = snd_hda_preset_realtek,
20065 .owner = THIS_MODULE,
20066};
20067
20068static int __init patch_realtek_init(void)
20069{
20070 return snd_hda_add_codec_preset(&realtek_list);
20071}
20072
20073static void __exit patch_realtek_exit(void)
20074{
20075 snd_hda_delete_codec_preset(&realtek_list);
20076}
20077
20078module_init(patch_realtek_init)
20079module_exit(patch_realtek_exit)